# HG changeset patch # User James Bergstra # Date 1210791007 14400 # Node ID 8f58abb943d45f30159dfa5c394276d4f25a3dc3 # Parent f01ac276c6fbdd2b41e364577cd4648171451e5a many changes to NeuralNet diff -r f01ac276c6fb -r 8f58abb943d4 mlp_factory_approach.py --- a/mlp_factory_approach.py Wed May 14 14:49:08 2008 -0400 +++ b/mlp_factory_approach.py Wed May 14 14:50:07 2008 -0400 @@ -6,12 +6,10 @@ def _randshape(*shape): return (numpy.random.rand(*shape) -0.5) * 0.001 -def _function(inputs, outputs, linker='c&py'): - return theano.function(inputs, outputs, unpack_single=False,linker=linker) class NeuralNet(object): - class Model(object): + class _Model(object): def __init__(self, nnet, params): self.nnet = nnet self.params = params @@ -20,7 +18,7 @@ """Update this model from more training data.""" v = self.nnet.v params = self.params - update_fn = _function([v.input, v.target] + v.params, [v.nll] + v.new_params) + update_fn = self.nnet._fn([v.input, v.target] + v.params, [v.nll] + v.new_params) if stopper is not None: raise NotImplementedError() else: @@ -37,20 +35,29 @@ put_stats_in_output_dataset=True, output_attributes=[]): """Apply this model (as a function) to new data""" - inputs = [self.nnet.v.input, self.nnet.v.target] + self.nnet.v.params - fn = _function(inputs, [getattr(self.nnet.v, name) for name in output_fieldnames]) - if 'target' in testset.fields(): + v = self.nnet.v + outputs = [getattr(self.nnet.v, name) for name in output_fieldnames] + if 'target' in testset: + fn = self.nnet._fn([v.input, v.target] + v.params, outputs) return dataset.ApplyFunctionDataSet(testset, lambda input, target: fn(input, target[:,0], *self.params), output_fieldnames) else: + fn = self.nnet._fn([v.input] + v.params, outputs) return dataset.ApplyFunctionDataSet(testset, - lambda input: fn(input, numpy.zeros(1,dtype='int64'), *self.params), + lambda input: fn(input, *self.params), output_fieldnames) + def _fn(self, inputs, outputs): + #it is possible for this function to implement function caching + #... but not necessarily desirable. + #- caching ruins the possibility of multi-threaded learning + #- caching demands more efficiency in the face of resizing inputs + #- caching makes it really hard to borrow references to function outputs + return theano.function(inputs, outputs, unpack_single=False, linker=self.linker) def __init__(self, ninputs, nhid, nclass, lr, nepochs, l2coef=0.0, - linker='c&yp', + linker='c&py', hidden_layer=None): class Vars: def __init__(self, lr, l2coef): @@ -72,9 +79,10 @@ hid_ivals = lambda : [_randshape(ninputs, nhid), _randshape(nhid)] params = [W2, b2] + hid_params - nll, predictions = nnet_ops.crossentropy_softmax_1hot( b2 + t.dot(hid, W2), target) + activations = b2 + t.dot(hid, W2) + nll, predictions = nnet_ops.crossentropy_softmax_1hot(activations, target) regularization = l2coef * t.sum(W2*W2) + hid_regularization - output_class = t.argmax(predictions,1) + output_class = t.argmax(activations,1) loss_01 = t.neq(output_class, target) g_params = t.grad(nll + regularization, params) new_params = [t.sub_inplace(p, lr * gp) for p,gp in zip(params, g_params)] @@ -84,12 +92,13 @@ self.nepochs = nepochs self.v = Vars(lr, l2coef) self.params = None + self.linker = linker def __call__(self, trainset=None, iparams=None): if iparams is None: iparams = [_randshape(self.nhid, self.nclass), _randshape(self.nclass)]\ + self.v.hid_ivals() - rval = NeuralNet.Model(self, iparams) + rval = NeuralNet._Model(self, iparams) if trainset: rval.update(trainset) return rval