Skip to content

Commit f647db0

Browse files
committed
network model functions now take the output layer as first argument.
dataset mapper will have to be rewritten, mad more simple
1 parent 4641aaa commit f647db0

File tree

8 files changed

+103
-70
lines changed

8 files changed

+103
-70
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,9 @@ docs/_build/
5252

5353
# PyBuilder
5454
target/
55+
56+
# my stuff
57+
test/
58+
trash/
59+
Mariana/test/
60+
Mariana/trash

Mariana/examples/mnist_mlp.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,12 @@ def load_mnist() :
3333

3434
if __name__ == "__main__" :
3535

36-
miniBatchSize = 20
37-
3836
#Let's define the network
3937
ls = MS.DefaultScenario(lr = 0.01, momentum = 0)
4038
cost = MC.NegativeLogLikelihood()
4139

42-
i = ML.Input(28*28, 'inp')
43-
h = ML.Hidden(500, activation = MA.tanh, decorators = [MD.GlorotTanhInit()], regularizations = [ MR.L1(0), MR.L2(0.0001) ] )
40+
i = ML.Input(28*28, name = 'inp')
41+
h = ML.Hidden(500, activation = MA.tanh, decorators = [MD.GlorotTanhInit()], regularizations = [ MR.L1(0), MR.L2(0.0001) ], name = "hid" )
4442
o = ML.SoftmaxClassifier(10, learningScenario = ls, costObject = cost, name = "out", regularizations = [ MR.L1(0), MR.L2(0.0001) ] )
4543

4644
mlp = i > h > o
@@ -69,7 +67,7 @@ def load_mnist() :
6967
testMaps = testMaps,
7068
validationMaps = validationMaps,
7169
stopCriteria = [earlyStop, epochWall],
72-
trainMiniBatchSize = miniBatchSize
70+
trainMiniBatchSize = 20
7371
)
7472

75-
trainer.start("MLP", mlp)
73+
trainer.start("MLP", mlp, shuffleMinibatches = False)

Mariana/layers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Layer_ABC(object) :
1818

1919
__metaclass__ = ABCMeta
2020

21-
def __init__(self, nbOutputs, saveOutputs = True, decorators = [], name = None) :
21+
def __init__(self, nbOutputs, saveOutputs = False, decorators = [], name = None) :
2222

2323
if name is not None :
2424
self.name = name
@@ -315,7 +315,7 @@ def _setOutputs(self) :
315315
updates.extend(self.learningScenario.getUpdates(l, cost))
316316

317317
for l in self.network.layers.itervalues() :
318-
if l.last_outputs is not l.outputs is not None :
318+
if ( l.last_outputs is not None ) and ( l.outputs is not None ) :
319319
updates.append( (l.last_outputs, l.outputs ) )
320320

321321
self.train = TheanoFunction("train", self, [cost, self.outputs], { "target" : self.target }, updates = updates)

Mariana/network.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ def __init__(self, name):
1111
self.name = name
1212
self.outputFcts = {}
1313

14-
def printGraph(self, outputName) :
14+
def printGraph(self, outputLayer) :
1515
"""Print the theano graph of the function associated with a given output"""
16-
self.outputFcts[outputName].printGraph()
16+
self.outputFcts[outputLayer.name].printGraph()
1717

18-
def addOutput(self, output, fct) :
19-
self.outputFcts[output.name] = fct
18+
def addOutput(self, outputLayer, fct) :
19+
self.outputFcts[outputLayer.name] = fct
2020

21-
def map(self, outputLayerName, **kwargs) :
22-
return self.outputFcts[outputLayerName](**kwargs)
21+
def callTheanoFct(self, outputLayer, **kwargs) :
22+
return self.outputFcts[outputLayer.name](**kwargs)
2323

24-
def __call__(self, outputLayerName, **kwargs) :
25-
return self.map(outputLayerName, **kwargs)
24+
def __call__(self, outputLayer, **kwargs) :
25+
return self.callTheanoFct(outputLayer, **kwargs)
2626

2727
def __repr__(self) :
2828
os = []
2929
for o, v in self.outputFcts.iteritems() :
3030
os.append(o)
3131
os = ', '.join(os)
32-
return "<'%s' for outputs: %s>" % (self.name, os)
32+
return "<theano fct '%s' for output layer: '%s'>" % (self.name, os)
3333

3434
class Network(object) :
3535
"""All theano_x functions of the outputs are accessible through the network interface network.x().

Mariana/tests/tests.py

+27-24
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import unittest
22

3-
from Mariana.layers import *
4-
from Mariana.rules import *
3+
import Mariana.layers as ML
54
import Mariana.decorators as dec
65
import Mariana.costs as MC
76
import Mariana.regularizations as MR
@@ -30,27 +29,29 @@ def trainMLP_xor(self) :
3029
ls = MS.DefaultScenario(lr = 0.1, momentum = 0)
3130
cost = MC.NegativeLogLikelihood()
3231

33-
i = Input(2, 'inp')
34-
h = Hidden(4, activation = MA.tanh, decorators = [dec.GlorotTanhInit()], regularizations = [MR.L1(0), MR.L2(0)])
35-
o = SoftmaxClassifier(2, learningScenario = ls, costObject = cost, name = "out")
32+
i = ML.Input(2, 'inp')
33+
h = ML.Hidden(4, activation = MA.tanh, decorators = [dec.GlorotTanhInit()], regularizations = [MR.L1(0), MR.L2(0)])
34+
o = ML.SoftmaxClassifier(2, learningScenario = ls, costObject = cost, name = "out")
3635

3736
mlp = i > h > o
3837

3938
self.xor_ins = N.array(self.xor_ins)
4039
self.xor_outs = N.array(self.xor_outs)
4140
for i in xrange(1000) :
4241
ii = i%len(self.xor_ins)
43-
mlp.train("out", inp = [ self.xor_ins[ ii ] ], target = [ self.xor_outs[ ii ] ] )
42+
mlp.train(o, inp = [ self.xor_ins[ ii ] ], target = [ self.xor_outs[ ii ] ] )
4443

4544
return mlp
4645

4746
# @unittest.skip("skipping")
4847
def test_xor(self) :
4948
mlp = self.trainMLP_xor()
50-
self.assertEqual(mlp.classify( "out", inp = [ self.xor_ins[0] ] )[0], 0 )
51-
self.assertEqual(mlp.classify( "out", inp = [ self.xor_ins[1] ] )[0], 1 )
52-
self.assertEqual(mlp.classify( "out", inp = [ self.xor_ins[2] ] )[0], 1 )
53-
self.assertEqual(mlp.classify( "out", inp = [ self.xor_ins[3] ] )[0], 0 )
49+
o = mlp.outputs.values()[0]
50+
51+
self.assertEqual(mlp.classify( o, inp = [ self.xor_ins[0] ] )[0], 0 )
52+
self.assertEqual(mlp.classify( o, inp = [ self.xor_ins[1] ] )[0], 1 )
53+
self.assertEqual(mlp.classify( o, inp = [ self.xor_ins[2] ] )[0], 1 )
54+
self.assertEqual(mlp.classify( o, inp = [ self.xor_ins[3] ] )[0], 0 )
5455

5556
# @unittest.skip("skipping")
5657
def test_save_load(self) :
@@ -60,10 +61,12 @@ def test_save_load(self) :
6061
mlp.save("test_save")
6162
mlp2 = cPickle.load(open('test_save.mariana.pkl'))
6263

63-
self.assertEqual(mlp2.classify( "out", inp = [ self.xor_ins[0] ] )[0], 0 )
64-
self.assertEqual(mlp2.classify( "out", inp = [ self.xor_ins[1] ] )[0], 1 )
65-
self.assertEqual(mlp2.classify( "out", inp = [ self.xor_ins[2] ] )[0], 1 )
66-
self.assertEqual(mlp2.classify( "out", inp = [ self.xor_ins[3] ] )[0], 0 )
64+
65+
o = mlp.outputs.values()[0]
66+
self.assertEqual(mlp2.classify( o, inp = [ self.xor_ins[0] ] )[0], 0 )
67+
self.assertEqual(mlp2.classify( o, inp = [ self.xor_ins[1] ] )[0], 1 )
68+
self.assertEqual(mlp2.classify( o, inp = [ self.xor_ins[2] ] )[0], 1 )
69+
self.assertEqual(mlp2.classify( o, inp = [ self.xor_ins[3] ] )[0], 0 )
6770

6871
os.remove('test_save.mariana.pkl')
6972

@@ -72,11 +75,11 @@ def test_composite(self) :
7275
ls = MS.DefaultScenario(lr = 0.1, momentum = 0)
7376
cost = MC.NegativeLogLikelihood()
7477

75-
inp = Input(2, 'inp')
76-
h1 = Hidden(2, activation = MA.tanh, name = "h1")
77-
h2 = Hidden(2, activation = MA.tanh, name = "h2")
78-
o = SoftmaxClassifier(2, learningScenario = ls, costObject = cost, name = "out")
79-
c = Composite(name = "Comp")
78+
inp = ML.Input(2, 'inp')
79+
h1 = ML.Hidden(2, activation = MA.tanh, name = "h1")
80+
h2 = ML.Hidden(2, activation = MA.tanh, name = "h2")
81+
o = ML.SoftmaxClassifier(2, learningScenario = ls, costObject = cost, name = "out")
82+
c = ML.Composite(name = "Comp")
8083

8184
inp > h1 > c
8285
inp > h2 > c
@@ -86,12 +89,12 @@ def test_composite(self) :
8689
self.xor_outs = N.array(self.xor_outs)
8790
for i in xrange(1000) :
8891
ii = i%len(self.xor_ins)
89-
mlp.train("out", inp = [ self.xor_ins[ ii ] ], target = [ self.xor_outs[ ii ] ])
92+
mlp.train(o, inp = [ self.xor_ins[ ii ] ], target = [ self.xor_outs[ ii ] ])
9093

91-
self.assertEqual(mlp.classify( "out", inp = [ self.xor_ins[0] ] )[0], 0 )
92-
self.assertEqual(mlp.classify( "out", inp = [ self.xor_ins[1] ] )[0], 1 )
93-
self.assertEqual(mlp.classify( "out", inp = [ self.xor_ins[2] ] )[0], 1 )
94-
self.assertEqual(mlp.classify( "out", inp = [ self.xor_ins[3] ] )[0], 0 )
94+
self.assertEqual(mlp.classify( o, inp = [ self.xor_ins[0] ] )[0], 0 )
95+
self.assertEqual(mlp.classify( o, inp = [ self.xor_ins[1] ] )[0], 1 )
96+
self.assertEqual(mlp.classify( o, inp = [ self.xor_ins[2] ] )[0], 1 )
97+
self.assertEqual(mlp.classify( o, inp = [ self.xor_ins[3] ] )[0], 0 )
9598

9699
if __name__ == '__main__' :
97100
unittest.main()

Mariana/training/datasetmaps.py

+37-18
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
import numpy, random, time
33

44
class ListSet(object) :
5-
def __init__(self, values) :
5+
def __init__(self, values, name = None) :
66
self.values = values
7-
self.name = time.clock() + random.randint(0, 100)
7+
if name is not None :
8+
self.name = name
9+
else :
10+
self.name = time.clock() + random.randint(0, 100)
811

912
def getAll(self) :
1013
return self.values
@@ -149,6 +152,7 @@ def __init__(self):
149152

150153
self.minLen = 0
151154
self.runIds = []
155+
self.mustInit = True
152156

153157
def mapInput(self, lst, layer) :
154158
if layer.name in self.layerNames :
@@ -210,6 +214,9 @@ def syncLayers(self, refLayer, layer) :
210214
self.layerNames.add(layer.name)
211215

212216
def shuffle(self) :
217+
if self.mustInit :
218+
self._init()
219+
213220
for s in self.sets.itervalues() :
214221
if s.__class__ is ClassSuperset :
215222
s.setMinLen(self.minLen)
@@ -219,29 +226,35 @@ def shuffle(self) :
219226
self.runIds = range(self.minLen)
220227
random.shuffle(self.runIds)
221228

229+
def _init(self) :
230+
self.runIds = range(self.minLen)
231+
self.mustInit = False
232+
222233
def getBatches(self, i, size) :
223234
"""Returns a random set of examples for each class, all classes have an equal chance of apperance
224235
regardless of their number of elements. If you want the limit to be length of the whole set
225236
instead of a mini batch you can set size to "all".
226237
"""
227-
238+
if self.mustInit :
239+
self._init()
240+
228241
inps = {}
229242
outs = {}
230-
for ii in self.runIds[i: i+size] :
231-
for k, v in self.sets.iteritems() :
232-
elmt = v[ii: ii+size]
233-
if v.__class__ is ClassSuperset :
243+
ii = self.runIds[i]
244+
for k, v in self.sets.iteritems() :
245+
elmt = v[ii: ii+size]
246+
if v.__class__ is ClassSuperset :
247+
l = self.inputSets[k]
248+
inps[l.name] = elmt[0]
249+
l = self.outputSets[k]
250+
outs[l.name] = elmt[1]
251+
else :
252+
try :
234253
l = self.inputSets[k]
235-
inps[l.name] = elmt[0]
254+
inps[l.name] = elmt
255+
except :
236256
l = self.outputSets[k]
237-
outs[l.name] = elmt[1]
238-
else :
239-
try :
240-
l = self.inputSets[k]
241-
inps[l.name] = elmt
242-
except :
243-
l = self.outputSets[k]
244-
outs[l.name] = elmt
257+
outs[l.name] = elmt
245258

246259
for k, layers in self.syncedLayers.iteritems() :
247260
for l in layers :
@@ -257,12 +270,15 @@ def getBatches(self, i, size) :
257270
except KeyError :
258271
outs[l.name] = outs[k]
259272
else :
260-
raise ValueError("Synced layer ''%s is neither an input nor an output" % l.name)
273+
raise ValueError("Synced layer ''%s is neither an input nor an output layer" % l.name)
261274

262275
return (inps, outs)
263276

264277
def getAll(self) :
265278
"""Returns the whole batch"""
279+
if self.mustInit :
280+
self._init()
281+
266282
inps = {}
267283
outs = {}
268284

@@ -294,12 +310,15 @@ def getAll(self) :
294310
except KeyError :
295311
outs[l.name] = outs[k]
296312
else :
297-
raise ValueError("Synced layer ''%s is neither an input nor an output" % l.name)
313+
raise ValueError("Synced layer ''%s is neither an input nor an output layer" % l.name)
298314

299315
return (inps, outs)
300316

301317
def getOutputNames(self) :
302318
return self.outputLayerNames
303319

320+
def __repr__(self) :
321+
return "<DatasetMapper len: %s, sets: %s, inputs: %s, outputs: %s>" % (self.minLen, len(self.sets), len(self.inputSets), len(self.outputSets))
322+
304323
def __len__(self) :
305324
return self.minLen

Mariana/training/recoders.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import sys
1+
import sys, os
22
from pyGeno.tools.parsers.CSVTools import CSVFile
33

44
class Recorder_ABC(object) :
@@ -21,7 +21,7 @@ def __init__(self, filename, verbose = True):
2121

2222
self.bestScores = {}
2323
self.currentScores = {}
24-
24+
2525
self.csvLegend = None
2626
self.csvFile = None
2727

@@ -43,7 +43,8 @@ def _fillLine(csvFile, score, bestScore, setName, setLen, outputName, **csvValue
4343
self.length += 1
4444
if self.csvLegend is None :
4545
self.csvLegend = store["hyperParameters"].keys()
46-
self.csvLegend.extend( ["score", "best_score", "set", "output"] )
46+
self.csvLegend.extend(store["runInfos"].keys())
47+
self.csvLegend.extend( ["score", "best_score", "best_score_commit", "set", "output"] )
4748

4849
self.csvFile = CSVFile(legend = self.csvLegend)
4950
self.csvFile.streamToFile( self.filename, writeRate = 1 )
@@ -58,14 +59,16 @@ def _fillLine(csvFile, score, bestScore, setName, setLen, outputName, **csvValue
5859
self.bestScores[theSet][outputName] = (score, self.length)
5960
model.save("best-%s-%s" % (theSet, self.filename))
6061

62+
muchData = store["hyperParameters"]
63+
muchData.update(store["runInfos"])
6164
_fillLine(
6265
self.csvFile,
6366
self.currentScores[theSet][outputName],
6467
self.bestScores[theSet][outputName],
6568
theSet,
6669
store["setSizes"][theSet],
6770
outputName,
68-
**store["hyperParameters"]
71+
**muchData
6972
)
7073

7174

@@ -75,7 +78,7 @@ def _fillLine(csvFile, score, bestScore, setName, setLen, outputName, **csvValue
7578
def printCurrentState(self) :
7679
"""prints the current state stored in the recorder"""
7780
if self.length > 0 :
78-
print "\n==>rec: ggplot2, commit %s:" % self.length
81+
print "\n==>rec: ggplot2, commit %s, pid: %s:" % (self.length, os.getpid())
7982
for setName, scores in self.bestScores.iteritems() :
8083
print " |-%s set" % setName
8184
for outputName in scores :

0 commit comments

Comments
 (0)