Mercurial > pylearn
comparison mlp_factory_approach.py @ 189:8f58abb943d4
many changes to NeuralNet
author | James Bergstra <bergstrj@iro.umontreal.ca> |
---|---|
date | Wed, 14 May 2008 14:50:07 -0400 |
parents | ebbb0e749565 |
children | aa7a3ecbcc90 |
comparison
equal
deleted
inserted
replaced
188:f01ac276c6fb | 189:8f58abb943d4 |
---|---|
4 import numpy | 4 import numpy |
5 import nnet_ops | 5 import nnet_ops |
6 | 6 |
7 def _randshape(*shape): | 7 def _randshape(*shape): |
8 return (numpy.random.rand(*shape) -0.5) * 0.001 | 8 return (numpy.random.rand(*shape) -0.5) * 0.001 |
9 def _function(inputs, outputs, linker='c&py'): | |
10 return theano.function(inputs, outputs, unpack_single=False,linker=linker) | |
11 | 9 |
12 class NeuralNet(object): | 10 class NeuralNet(object): |
13 | 11 |
14 class Model(object): | 12 class _Model(object): |
15 def __init__(self, nnet, params): | 13 def __init__(self, nnet, params): |
16 self.nnet = nnet | 14 self.nnet = nnet |
17 self.params = params | 15 self.params = params |
18 | 16 |
19 def update(self, trainset, stopper=None): | 17 def update(self, trainset, stopper=None): |
20 """Update this model from more training data.""" | 18 """Update this model from more training data.""" |
21 v = self.nnet.v | 19 v = self.nnet.v |
22 params = self.params | 20 params = self.params |
23 update_fn = _function([v.input, v.target] + v.params, [v.nll] + v.new_params) | 21 update_fn = self.nnet._fn([v.input, v.target] + v.params, [v.nll] + v.new_params) |
24 if stopper is not None: | 22 if stopper is not None: |
25 raise NotImplementedError() | 23 raise NotImplementedError() |
26 else: | 24 else: |
27 for i in xrange(100): | 25 for i in xrange(100): |
28 for input, target in trainset.minibatches(['input', 'target'], | 26 for input, target in trainset.minibatches(['input', 'target'], |
35 test_stats_collector=None, | 33 test_stats_collector=None, |
36 copy_inputs=False, | 34 copy_inputs=False, |
37 put_stats_in_output_dataset=True, | 35 put_stats_in_output_dataset=True, |
38 output_attributes=[]): | 36 output_attributes=[]): |
39 """Apply this model (as a function) to new data""" | 37 """Apply this model (as a function) to new data""" |
40 inputs = [self.nnet.v.input, self.nnet.v.target] + self.nnet.v.params | 38 v = self.nnet.v |
41 fn = _function(inputs, [getattr(self.nnet.v, name) for name in output_fieldnames]) | 39 outputs = [getattr(self.nnet.v, name) for name in output_fieldnames] |
42 if 'target' in testset.fields(): | 40 if 'target' in testset: |
41 fn = self.nnet._fn([v.input, v.target] + v.params, outputs) | |
43 return dataset.ApplyFunctionDataSet(testset, | 42 return dataset.ApplyFunctionDataSet(testset, |
44 lambda input, target: fn(input, target[:,0], *self.params), | 43 lambda input, target: fn(input, target[:,0], *self.params), |
45 output_fieldnames) | 44 output_fieldnames) |
46 else: | 45 else: |
46 fn = self.nnet._fn([v.input] + v.params, outputs) | |
47 return dataset.ApplyFunctionDataSet(testset, | 47 return dataset.ApplyFunctionDataSet(testset, |
48 lambda input: fn(input, numpy.zeros(1,dtype='int64'), *self.params), | 48 lambda input: fn(input, *self.params), |
49 output_fieldnames) | 49 output_fieldnames) |
50 def _fn(self, inputs, outputs): | |
51 #it is possible for this function to implement function caching | |
52 #... but not necessarily desirable. | |
53 #- caching ruins the possibility of multi-threaded learning | |
54 #- caching demands more efficiency in the face of resizing inputs | |
55 #- caching makes it really hard to borrow references to function outputs | |
56 return theano.function(inputs, outputs, unpack_single=False, linker=self.linker) | |
50 | 57 |
51 def __init__(self, ninputs, nhid, nclass, lr, nepochs, | 58 def __init__(self, ninputs, nhid, nclass, lr, nepochs, |
52 l2coef=0.0, | 59 l2coef=0.0, |
53 linker='c&yp', | 60 linker='c&py', |
54 hidden_layer=None): | 61 hidden_layer=None): |
55 class Vars: | 62 class Vars: |
56 def __init__(self, lr, l2coef): | 63 def __init__(self, lr, l2coef): |
57 lr = t.constant(lr) | 64 lr = t.constant(lr) |
58 l2coef = t.constant(l2coef) | 65 l2coef = t.constant(l2coef) |
70 hid_params = [W1, b1] | 77 hid_params = [W1, b1] |
71 hid_regularization = l2coef * t.sum(W1*W1) | 78 hid_regularization = l2coef * t.sum(W1*W1) |
72 hid_ivals = lambda : [_randshape(ninputs, nhid), _randshape(nhid)] | 79 hid_ivals = lambda : [_randshape(ninputs, nhid), _randshape(nhid)] |
73 | 80 |
74 params = [W2, b2] + hid_params | 81 params = [W2, b2] + hid_params |
75 nll, predictions = nnet_ops.crossentropy_softmax_1hot( b2 + t.dot(hid, W2), target) | 82 activations = b2 + t.dot(hid, W2) |
83 nll, predictions = nnet_ops.crossentropy_softmax_1hot(activations, target) | |
76 regularization = l2coef * t.sum(W2*W2) + hid_regularization | 84 regularization = l2coef * t.sum(W2*W2) + hid_regularization |
77 output_class = t.argmax(predictions,1) | 85 output_class = t.argmax(activations,1) |
78 loss_01 = t.neq(output_class, target) | 86 loss_01 = t.neq(output_class, target) |
79 g_params = t.grad(nll + regularization, params) | 87 g_params = t.grad(nll + regularization, params) |
80 new_params = [t.sub_inplace(p, lr * gp) for p,gp in zip(params, g_params)] | 88 new_params = [t.sub_inplace(p, lr * gp) for p,gp in zip(params, g_params)] |
81 self.__dict__.update(locals()); del self.self | 89 self.__dict__.update(locals()); del self.self |
82 self.nhid = nhid | 90 self.nhid = nhid |
83 self.nclass = nclass | 91 self.nclass = nclass |
84 self.nepochs = nepochs | 92 self.nepochs = nepochs |
85 self.v = Vars(lr, l2coef) | 93 self.v = Vars(lr, l2coef) |
86 self.params = None | 94 self.params = None |
95 self.linker = linker | |
87 | 96 |
88 def __call__(self, trainset=None, iparams=None): | 97 def __call__(self, trainset=None, iparams=None): |
89 if iparams is None: | 98 if iparams is None: |
90 iparams = [_randshape(self.nhid, self.nclass), _randshape(self.nclass)]\ | 99 iparams = [_randshape(self.nhid, self.nclass), _randshape(self.nclass)]\ |
91 + self.v.hid_ivals() | 100 + self.v.hid_ivals() |
92 rval = NeuralNet.Model(self, iparams) | 101 rval = NeuralNet._Model(self, iparams) |
93 if trainset: | 102 if trainset: |
94 rval.update(trainset) | 103 rval.update(trainset) |
95 return rval | 104 return rval |
96 | 105 |
97 | 106 |