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