changeset 186:562f308873f0

added ManualNNet
author James Bergstra <bergstrj@iro.umontreal.ca>
date Tue, 13 May 2008 20:10:03 -0400
parents 3d953844abd3
children ebbb0e749565
files mlp.py test_mlp.py
diffstat 2 files changed, 105 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mlp.py	Tue May 13 19:37:29 2008 -0400
+++ b/mlp.py	Tue May 13 20:10:03 2008 -0400
@@ -11,6 +11,74 @@
 import math
 from misc import *
 
+def function(inputs, outputs, linker='c&py'):
+    return theano.function(inputs, outputs, unpack_single=False,linker=linker)
+
+def randshape(*shape): return (numpy.random.rand(*shape) -0.5) * 0.001
+
+class ManualNNet(object):
+    def __init__(self, ninputs, nhid, nclass, lr, nepochs, 
+            linker='c&yp', 
+            hidden_layer=None):
+        class Vars:
+            def __init__(self, lr):
+                lr = t.constant(lr)
+                input = t.matrix('input') # n_examples x n_inputs
+                target = t.ivector('target') # n_examples x 1
+                W2 = t.matrix('W2')
+                b2 = t.vector('b2')
+
+                if hidden_layer:
+                    hidden, hidden_params, hidden_ivals = hidden_layer(input)
+                else:
+                    W1 = t.matrix('W1')
+                    b1 = t.vector('b1')
+                    hidden = t.tanh(b1 + t.dot(input, W1))
+                    hidden_params = [W1, b1]
+                    hidden_ivals = [randshape(ninputs, nhid), randshape(nhid)]
+
+                params = [W2, b2] + hidden_params
+                ivals = [randshape(nhid, nclass), randshape(nclass)]\
+                        + hidden_ivals
+                nll, predictions = crossentropy_softmax_1hot( b2 + t.dot(hidden, W2), target)
+                output_class = t.argmax(predictions,1)
+                loss_01 = t.neq(output_class, target)
+                g_params = t.grad(nll, params)
+                new_params = [t.sub_inplace(p, lr * gp) for p,gp in zip(params, g_params)]
+                self.__dict__.update(locals()); del self.self
+        self.nhid = nhid
+        self.nclass = nclass
+        self.nepochs = nepochs
+        self.v = Vars(lr)
+        self.params = None
+
+    def update(self, trainset):
+        params = self.v.ivals
+        update_fn = function(
+                [self.v.input, self.v.target] + self.v.params,
+                [self.v.nll] + self.v.new_params)
+        for i in xrange(self.nepochs):
+            for input, target in trainset.minibatches(['input', 'target'],
+                    minibatch_size=min(32, len(trainset))):
+                dummy = update_fn(input, target[:,0], *params)
+                if 0: print dummy[0] #the nll
+        return self.use
+    __call__ = update
+
+    def use(self, dset,
+            output_fieldnames=['output_class'],
+            test_stats_collector=None,
+            copy_inputs=False,
+            put_stats_in_output_dataset=True,
+            output_attributes=[]):
+        inputs = [self.v.input, self.v.target] + self.v.params
+        fn = function(inputs, [getattr(self.v, name) for name in output_fieldnames])
+        target = dset.fields()['target'] if ('target' in dset.fields()) else numpy.zeros((1,1),dtype='int64')
+        return ApplyFunctionDataSet(dset, 
+            lambda input, target: fn(input, target[:,0], *self.v.ivals),
+            output_fieldnames)
+
+
 class OneHiddenLayerNNetClassifier(OnlineGradientTLearner):
     """
     Implement a straightforward classicial feedforward
--- a/test_mlp.py	Tue May 13 19:37:29 2008 -0400
+++ b/test_mlp.py	Tue May 13 20:10:03 2008 -0400
@@ -1,6 +1,7 @@
 
 from mlp import *
 import dataset
+import nnet_ops
 
 
 from functools import partial
@@ -64,5 +65,40 @@
     for fieldname in output_ds.fieldNames():
         print fieldname+"=",output_ds[fieldname]
 
-test0()
+def test1():
+    nnet = ManualNNet(2, 10,3,.1,1000)
+    training_set = dataset.ArrayDataSet(numpy.array([[0, 0, 0],
+                                                     [0, 1, 1],
+                                                     [1, 0, 1],
+                                                     [1, 1, 1]]),
+                                        {'input':slice(2),'target':2})
+    fprop=nnet(training_set)
+
+    output_ds = fprop(training_set)
+
+    for fieldname in output_ds.fieldNames():
+        print fieldname+"=",output_ds[fieldname]
 
+def test2():
+    training_set = dataset.ArrayDataSet(numpy.array([[0, 0, 0],
+                                                     [0, 1, 1],
+                                                     [1, 0, 1],
+                                                     [1, 1, 1]]),
+                                        {'input':slice(2),'target':2})
+    nin, nhid=2, 10
+    def sigm_layer(input):
+        W1 = t.matrix('W1')
+        b1 = t.vector('b1')
+        return (nnet_ops.sigmoid(b1 + t.dot(input, W1)),
+                [W1, b1],
+                [(numpy.random.rand(nin, nhid) -0.5) * 0.001, numpy.zeros(nhid)])
+    nnet = ManualNNet(nin, nhid, 3, .1, 1000, hidden_layer=sigm_layer)
+    fprop=nnet(training_set)
+
+    output_ds = fprop(training_set)
+
+    for fieldname in output_ds.fieldNames():
+        print fieldname+"=",output_ds[fieldname]
+test1()
+test2()
+