-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathosR.py
executable file
·148 lines (120 loc) · 5.34 KB
/
osR.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import numpy as np
import theano
import theano.tensor as T
class OneSidedCostRegressor(object):
def __init__(self, input, n_in, n_out):
# initialize with 0 the weights W as a matrix of shape (n_in, n_out)
self.W = theano.shared(
value=np.zeros(
(n_in, n_out),
dtype=theano.config.floatX
),
name='W',
borrow=True
)
# initialize the baises b as a vector of n_out 0s
self.b = theano.shared(
value=np.zeros(
(n_out,),
dtype=theano.config.floatX
),
name='b',
borrow=True
)
# keep track of model input
self.input = input
# symbolic variable of cost vector in terms of a single example;
# for a batch of examples, it's a matrix, so don't get confused
# with the variable name `cost_vector`
self.cost_vector = T.matrix('cost_vector')
# symbolic variable of Z_{n,k}
self.Z_nk = T.matrix('Z_nk')
self.cost_predicted_given_x = T.dot(self.input, self.W) + self.b
# elementwise comparison with 0
self.xi = T.maximum((self.Z_nk * (self.cost_predicted_given_x - self.cost_vector)), 0.)
# define the linear one-sisded regression loss
self.one_sided_regression_loss = T.sum(self.xi)
# symbolic description of how to compute prediction as class whose
# cost is minimum
self.y_pred = T.argmin(self.cost_predicted_given_x, axis=1)
# parameters of the model
self.params = [self.W, self.b]
# symbolic variable of labels, will only be used for computing 0/1 errors
self.y = T.ivector('y')
# compute the 0/1 loss
self.error = T.mean(T.neq(self.y_pred, self.y))
# when a new example comes in, the model first computes (predicts) its
# cost on classifying into each class (a vector) by
# `self.cost_predicted_given_x`; then the model will predict this new
# example as label with the smallest cost;
# self.future_cost = T.sum(self.cost_vector[T.arange(self.y_pred.shape[0]), self.y_pred])
self.future_cost = T.mean(self.cost_vector[T.arange(self.y_pred.shape[0]), self.y_pred])
def sgd_optimize(self, train_set, test_set, n_epochs, learning_rate, batch_size):
""" Optimizing model parameters by stochastic gradient descent """
train_set_x, train_set_y, train_set_c = train_set
test_set_x, test_set_y, test_set_c = test_set
train_set_z = np.zeros(train_set_c.shape) - 1
for i in xrange(train_set_z.shape[0]):
train_set_z[i][train_set_y[i]] = 1
from toolbox import make_shared_data
train_set_x = make_shared_data(train_set_x)
train_set_c = make_shared_data(train_set_c)
train_set_z = make_shared_data(train_set_z)
train_set_y = T.cast(make_shared_data(train_set_y), 'int32')
test_set_x = make_shared_data(test_set_x)
test_set_c = make_shared_data(test_set_c)
test_set_y = T.cast(make_shared_data(test_set_y), 'int32')
print '... building the model'
index = T.lscalar() # symbolic variable for index to a mini-batch
cost = self.one_sided_regression_loss
gparams = [T.grad(cost, param) for param in self.params]
train_model = theano.function(
inputs=[index],
outputs=cost,
updates=[
(param, param - learning_rate * gparam)
for param, gparam in zip(self.params, gparams)
],
givens={
self.input: train_set_x[index * batch_size: (index + 1) * batch_size],
self.cost_vector: train_set_c[index * batch_size: (index + 1) * batch_size],
self.Z_nk: train_set_z[index * batch_size: (index + 1) * batch_size]
},
name='train_model'
)
in_sample_result = theano.function(
inputs=[],
outputs=[self.error, self.future_cost],
givens={
self.input: train_set_x,
self.y: train_set_y,
self.cost_vector: train_set_c
},
name='in_sample_result'
)
out_sample_result = theano.function(
inputs=[],
outputs=[self.error, self.future_cost],
givens={
self.input: test_set_x,
self.y: test_set_y,
self.cost_vector: test_set_c
},
name='out_sample_result'
)
n_train_batches = train_set_x.get_value(borrow=True).shape[0] / batch_size
print '... training the model'
best_Cout = np.inf
corresponding_Eout = np.inf
for epoch in xrange(n_epochs):
print 'epoch #%d' % (epoch + 1)
for batch_index in xrange(n_train_batches):
batch_cost = train_model(batch_index)
Ein, Cin = in_sample_result()
Eout, Cout = out_sample_result()
if Cout < best_Cout:
best_Cout = Cout
corresponding_Eout = Eout
print ' better performance achieved ... best_Cout = %f' % best_Cout
print 'after training %d epochs, best_Cout = %f, and corresponding_Eout = %f' \
% (n_epochs, best_Cout, corresponding_Eout)