-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloglinear.py
116 lines (88 loc) · 3.06 KB
/
loglinear.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import numpy as np
STUDENT={'name': 'Daniel Greenspan_Eilon Bashari',
'ID': '308243948_308576933'}
def softmax(x):
"""
Compute the softmax vector.
x: a n-dim vector (numpy array)
returns: an n-dim vector (numpy array) of softmax values
"""
# YOUR CODE HERE
# Your code should be fast, so use a vectorized implementation using numpy,
# don't use any loops.
# With a vectorized implementation, the code should be no more than 2 lines.
#
exp = np.exp(x - np.max(x))
x = exp / exp.sum(axis=0)
return x
def classifier_output(x, params):
"""
Return the output layer (class probabilities)
of a log-linear classifier with given params on input x.
"""
W, b = params
log_linear_vec = np.array(np.dot(x, W) + b)
probs = softmax(log_linear_vec)
return probs
def predict(x, params):
"""
Returnss the prediction (highest scoring class id) of a
a log-linear classifier with given parameters on input x.
params: a list of the form [(W, b)]
W: matrix
b: vector
"""
return np.argmax(classifier_output(x, params))
def loss_and_gradients(x, y, params):
"""
Compute the loss and the gradients at point x with given parameters.
y is a scalar indicating the correct label.
returns:
loss,[gW,gb]
loss: scalar
gW: matrix, gradients of W
gb: vector, gradients of b
"""
p = classifier_output(x,params)
gb = p.copy()
gb[y] -= 1
gW = np.outer(x, gb)
loss = -np.log(classifier_output(x, params)[y])
return loss, [gW, gb]
def create_classifier(in_dim, out_dim):
"""
returns the parameters (W,b) for a log-linear classifier
with input dimension in_dim and output dimension out_dim.
"""
W = np.zeros((in_dim, out_dim))
b = np.zeros(out_dim)
return [W,b]
if __name__ == '__main__':
# Sanity checks for softmax. If these fail, your softmax is definitely wrong.
# If these pass, it may or may not be correct.
test1 = softmax(np.array([1,2]))
print test1
assert np.amax(np.fabs(test1 - np.array([0.26894142, 0.73105858]))) <= 1e-6
test2 = softmax(np.array([1001,1002]))
print test2
assert np.amax(np.fabs(test2 - np.array( [0.26894142, 0.73105858]))) <= 1e-6
test3 = softmax(np.array([-1001,-1002]))
print test3
assert np.amax(np.fabs(test3 - np.array([0.73105858, 0.26894142]))) <= 1e-6
# Sanity checks. If these fail, your gradient calculation is definitely wrong.
# If they pass, it is likely, but not certainly, correct.
from grad_check import gradient_check
W,b = create_classifier(3,4)
def _loss_and_W_grad(W):
global b
loss,grads = loss_and_gradients([1,2,3],0,[W,b])
return loss,grads[0]
def _loss_and_b_grad(b):
global W
loss,grads = loss_and_gradients([1,2,3],0,[W,b])
return loss,grads[1]
for _ in xrange(10):
W = np.random.randn(W.shape[0],W.shape[1])
b = np.random.randn(b.shape[0])
gradient_check(_loss_and_b_grad, b)
gradient_check(_loss_and_W_grad, W)