提交 c31223aa authored 作者: james@X40's avatar james@X40

changes to Module, removed Member from user API

上级 1a722462
"""Driver of graph construction, optimization, and linking. """Driver of graph construction, optimization, and linking.
""" """
__docformat__ = "restructuredtext en"
import copy_reg import copy_reg
import cPickle import cPickle
......
...@@ -19,7 +19,7 @@ This structure contains numbers and functions, and is ready for computation. ...@@ -19,7 +19,7 @@ This structure contains numbers and functions, and is ready for computation.
""" """
__doc__='restructuredtext en' __docformat__ = "restructuredtext en"
from theano import gof from theano import gof
from theano.printing import pprint from theano.printing import pprint
...@@ -302,8 +302,6 @@ class Member(_RComponent): ...@@ -302,8 +302,6 @@ class Member(_RComponent):
""" """
return memo[self.r].value return memo[self.r].value
class Method(Component): class Method(Component):
def __init__(self, inputs, outputs, updates = {}, kits = [], **kwupdates): def __init__(self, inputs, outputs, updates = {}, kits = [], **kwupdates):
...@@ -345,35 +343,50 @@ class Method(Component): ...@@ -345,35 +343,50 @@ class Method(Component):
raise TypeError('Expected a Component with subtype Member or External.') raise TypeError('Expected a Component with subtype Member or External.')
return result return result
def resolve_result(self, x): def resolve_result(self, x, passthrough=(gof.Result)):
if isinstance(x, gof.Result): if isinstance(x, passthrough):
return x return x
elif isinstance(x, _RComponent): elif isinstance(x, _RComponent):
return x.r return x.r
else: else:
return self.resolve(x).r return self.resolve(x).r
def resolve_all(self): def resolve_inputs(self):
""" if isinstance(self.inputs, (io.In, gof.Result, str)):
Resolves all inputs, outputs and updates that were given as
strings so that the fields contain the corresponding Result
instances instead.
"""
if isinstance(self.inputs, (gof.Result, str)):
inputs = [self.inputs] inputs = [self.inputs]
else: else:
inputs = list(self.inputs) inputs = list(self.inputs)
self.inputs = [self.resolve_result(input) for input in inputs] self.inputs = [self.resolve_result(input,
if isinstance(self.outputs, (list, tuple, ComponentList)): passthrough=(gof.Result, io.In)) for input in inputs]
self.outputs = [self.resolve_result(output) for output in self.outputs]
def resolve_outputs(self):
if isinstance(self.outputs, (io.Out, gof.Result, str)):
output = self.outputs
self.outputs = self.resolve_result(output,
passthrough=(gof.Result, io.Out))
else: else:
self.outputs = self.resolve_result(self.outputs) outputs = list(self.outputs)
self.outputs = [self.resolve_result(output,
passthrough=(gof.Result, io.Out)) for output in outputs]
def resolve_updates(self):
updates = self.updates updates = self.updates
self.updates = {} self.updates = {}
for k, v in updates.iteritems(): for k, v in updates.iteritems():
k, v = self.resolve_result(k), self.resolve_result(v) k, v = self.resolve_result(k), self.resolve_result(v)
self.updates[k] = v self.updates[k] = v
def resolve_all(self):
"""
Resolves all inputs, outputs and updates that were given as
strings so that the fields contain the corresponding Result
instances instead.
"""
self.resolve_inputs()
self.resolve_outputs()
self.resolve_updates()
def allocate(self, memo): def allocate(self, memo):
""" """
Method allocates nothing. Method allocates nothing.
...@@ -399,24 +412,57 @@ class Method(Component): ...@@ -399,24 +412,57 @@ class Method(Component):
' Verify that it is indeed a Member of the' ' Verify that it is indeed a Member of the'
' enclosing module or of one of its submodules.' % (r, self.name, self)) ' enclosing module or of one of its submodules.' % (r, self.name, self))
else: else:
return io.In(result = r, value = gof.Container(r, storage = [None]), mutable = False) return io.In(result=r,
# Wrap the inputs in In instances. TODO: allow the inputs to _be_ In instances value=gof.Container(r, storage=[None]),
mutable=False)
inputs = self.inputs inputs = self.inputs
inputs = [io.In(result = input,
value = get_storage(input).value, # Deal with explicit inputs
mutable = False) inputs = []
for input in inputs] for input in self.inputs:
# Add the members to update to the inputs. TODO: see above if type(input) is io.In:
inputs += [io.In(result = k, inputs.append(input)
update = v, elif isinstance(input, gof.Result):
value = get_storage(k, not allocate_all).value, input_in = io.In(
mutable = True, result=input,
strict = True) mutable=False)
for k, v in self.updates.iteritems()] inputs.append(input_in)
else:
raise TypeError(input, type(input))
# Deal with updates
for k, v in self.updates.iteritems():
assert isinstance(k, gof.Result)
assert isinstance(v, gof.Result)
#identify an input for result k
input_k = None
for input in inputs:
if input.result == k:
input_k = input
print 'METHOD UPDATE', k, v, input_k
if input_k is None:
# this is an implicit input,
# use shared storage
input_k = io.In(
result=k,
update=v,
value=get_storage(k, not allocate_all).value,
mutable=True)
inputs.append(input_k)
else:
# this was an explicit input
# don't use shared storage
input_k.update=v
input_k.mutable=True
outputs = self.outputs outputs = self.outputs
_inputs = [x.result for x in inputs] _inputs = [x.result for x in inputs]
# Grab the results that are not accessible from either the inputs or the updates. # Grab the results that are not accessible from either the inputs or the updates.
for input in gof.graph.inputs((list(outputs) if isinstance(outputs, (list, tuple)) else [outputs]) outputs_list = list(outputs) if isinstance(outputs, (list, tuple)) else [outputs]
outputs_result_list = [o.result if isinstance(o, io.Out) else o for o in outputs_list]
for input in gof.graph.inputs(outputs_result_list
+ [x.update for x in inputs if getattr(x, 'update', False)], + [x.update for x in inputs if getattr(x, 'update', False)],
blockers = _inputs): blockers = _inputs):
if input not in _inputs: if input not in _inputs:
...@@ -424,9 +470,12 @@ class Method(Component): ...@@ -424,9 +470,12 @@ class Method(Component):
# but otherwise they are immutable. # but otherwise they are immutable.
if isinstance(input, gof.Value): # and not isinstance(input, gof.Constant): if isinstance(input, gof.Value): # and not isinstance(input, gof.Constant):
storage = get_storage(input) storage = get_storage(input)
storage.value = input.data assert type(storage) is io.In
container = storage.value
container.value = input.data
else: else:
storage = get_storage(input, not allocate_all) storage = get_storage(input, not allocate_all)
assert type(storage) is io.In
inputs.append(storage) inputs.append(storage)
return F.function(inputs, outputs, mode) return F.function(inputs, outputs, mode)
...@@ -467,8 +516,6 @@ class Method(Component): ...@@ -467,8 +516,6 @@ class Method(Component):
raise TypeError("'Method' object is not callable" raise TypeError("'Method' object is not callable"
" (Hint: compile your module first. See Component.make())") " (Hint: compile your module first. See Component.make())")
class CompositeInstance(object): class CompositeInstance(object):
""" """
Generic type which various Composite subclasses are intended to Generic type which various Composite subclasses are intended to
...@@ -579,6 +626,7 @@ class Composite(Component): ...@@ -579,6 +626,7 @@ class Composite(Component):
def __getitem__(self, item): def __getitem__(self, item):
# Uses get() internally # Uses get() internally
print 'COMPOSITE GETITEM', item
x = self.get(item) x = self.get(item)
if isinstance(x, (External, Member)): if isinstance(x, (External, Member)):
return x.r return x.r
...@@ -617,6 +665,8 @@ class ComponentList(Composite): ...@@ -617,6 +665,8 @@ class ComponentList(Composite):
_components = _components[0] _components = _components[0]
self._components = [] self._components = []
for c in _components: for c in _components:
if not isinstance(c, Component):
raise TypeError(c, type(c))
self.append(c) self.append(c)
def resolve(self, name): def resolve(self, name):
...@@ -723,7 +773,7 @@ class ComponentDictInstance(CompositeInstance): ...@@ -723,7 +773,7 @@ class ComponentDictInstance(CompositeInstance):
# Set it if it's not there # Set it if it's not there
# TODO: is this needed here? move to ModuleInstance? # TODO: is this needed here? move to ModuleInstance?
self.__items__[item] = value self.__items__[item] = value
return else:
super(ComponentDictInstance, self).__setitem__(item, value) super(ComponentDictInstance, self).__setitem__(item, value)
def __str__(self): def __str__(self):
...@@ -736,6 +786,11 @@ class ComponentDictInstance(CompositeInstance): ...@@ -736,6 +786,11 @@ class ComponentDictInstance(CompositeInstance):
strings.append('%s%s' % (pre, str(v).replace('\n', '\n' + ' '*len(pre)))) strings.append('%s%s' % (pre, str(v).replace('\n', '\n' + ' '*len(pre))))
return '{%s}' % '\n'.join(strings).replace('\n', '\n ') return '{%s}' % '\n'.join(strings).replace('\n', '\n ')
def initialize(self, init={}, **kwinit):
for k, initv in dict(init, **kwinit).iteritems():
self[k] = initv
class ComponentDict(Composite): class ComponentDict(Composite):
InstanceType = ComponentDictInstance # Type used by build() to make the instance InstanceType = ComponentDictInstance # Type used by build() to make the instance
...@@ -743,8 +798,13 @@ class ComponentDict(Composite): ...@@ -743,8 +798,13 @@ class ComponentDict(Composite):
def __init__(self, components = {}, **kwcomponents): def __init__(self, components = {}, **kwcomponents):
super(ComponentDict, self).__init__() super(ComponentDict, self).__init__()
components = dict(components, **kwcomponents) components = dict(components, **kwcomponents)
for val in components.itervalues():
if not isinstance(val, Component):
raise TypeError(val, type(val))
self.__dict__['_components'] = components self.__dict__['_components'] = components
def resolve(self, name): def resolve(self, name):
name = canonicalize(name) name = canonicalize(name)
item = self.get(name[0]) item = self.get(name[0])
...@@ -804,22 +864,35 @@ __autowrappers = [] ...@@ -804,22 +864,35 @@ __autowrappers = []
def register_wrapper(condition, wrapper): def register_wrapper(condition, wrapper):
__autowrappers.append((condition, wrapper)) __autowrappers.append((condition, wrapper))
def wrapper(x):
"""Returns a wrapper function appropriate for `x`
Returns None if not appropriate wrapper is found
"""
for condition, wrap_fn in __autowrappers:
if condition(x):
return wrap_fn
return None
def wrap(x): def wrap(x):
""" """
Wraps x in a Component. Wrappers can be registered using Wraps x in a Component. Wrappers can be registered using
register_wrapper to allow wrapping more types. register_wrapper to allow wrapping more types.
""" """
if isinstance(x, Component): w = wrapper(x)
return x if w is not None:
for condition, wrapper in __autowrappers: return w(x)
if condition(x): else:
return wrapper(x)
return x return x
def dict_wrap(d): def dict_wrap(d):
d_copy = {}
for k,v in d.iteritems(): for k,v in d.iteritems():
d[k]=wrap(v) d_copy[k]=wrap(v)
return d return d_copy
# Component -> itself
register_wrapper(lambda x: isinstance(x, Component),
lambda x: x)
# Result -> Member # Result -> Member
register_wrapper(lambda x: isinstance(x, gof.Result) and not x.owner, register_wrapper(lambda x: isinstance(x, gof.Result) and not x.owner,
...@@ -831,13 +904,12 @@ register_wrapper(lambda x: isinstance(x, gof.Result) and x.owner, ...@@ -831,13 +904,12 @@ register_wrapper(lambda x: isinstance(x, gof.Result) and x.owner,
# [[Result1], {Result2}, Result3...] -> ComponentList(Member(Result1), Member(Result2), ...) # [[Result1], {Result2}, Result3...] -> ComponentList(Member(Result1), Member(Result2), ...)
register_wrapper(lambda x: isinstance(x, (list, tuple)) \ register_wrapper(lambda x: isinstance(x, (list, tuple)) \
and all(isinstance(r, (gof.Result,Component,list, and all(wrapper(r) is not None for r in x),
tuple, dict)) for r in x),
lambda x: ComponentList(*map(wrap, x))) lambda x: ComponentList(*map(wrap, x)))
#{ "name1":{Component,Result,list,tuple,dict},...} -> ComponentDict({Component,Result,list,tuple,dict},...) #{ "name1":{Component,Result,list,tuple,dict},...} -> ComponentDict({Component,Result,list,tuple,dict},...)
register_wrapper(lambda x: isinstance(x, dict) \ register_wrapper(lambda x: isinstance(x, dict) \
and all(isinstance(r,(Component,gof.Result,list,tuple,dict)) for r in x.itervalues()), and all(wrapper(r) is not None for r in x.itervalues()),
lambda x: ComponentDict(dict_wrap(x))) lambda x: ComponentDict(dict_wrap(x)))
class Curry: class Curry:
...@@ -913,7 +985,7 @@ class Module(ComponentDict): ...@@ -913,7 +985,7 @@ class Module(ComponentDict):
self.__set_name__(value) self.__set_name__(value)
return return
def remove_member(v): def identify_member(v):
if isinstance(v, (Member, External)): if isinstance(v, (Member, External)):
return v.r return v.r
elif isinstance(v, (gof.Result,Method,Module)): elif isinstance(v, (gof.Result,Method,Module)):
...@@ -921,20 +993,20 @@ class Module(ComponentDict): ...@@ -921,20 +993,20 @@ class Module(ComponentDict):
elif isinstance(v,(int,bool)): elif isinstance(v,(int,bool)):
return v return v
elif isinstance(v, (list)): elif isinstance(v, (list)):
return map(remove_member,v) return map(identify_member,v)
elif isinstance(v, (tuple)): elif isinstance(v, (tuple)):
return tuple(map(remove_member,v)) return tuple(map(identify_member,v))
elif isinstance(v,dict): elif isinstance(v,dict):
v_copy = dict()
for k,vv in v.iteritems(): for k,vv in v.iteritems():
v[k]=remove_member(vv) v_copy[k]=identify_member(vv)
return v return v
else: else:
# raise NotImplementedError # raise NotImplementedError
# print "WARNING: unknow:",v # print "WARNING: unknow:",v
return v return v
value=remove_member(value) value=identify_member(value)
if not hasattr(self,"local_attr"): if not hasattr(self,"local_attr"):
self.__dict__["local_attr"]={} self.__dict__["local_attr"]={}
...@@ -944,11 +1016,18 @@ class Module(ComponentDict): ...@@ -944,11 +1016,18 @@ class Module(ComponentDict):
for k,v in self.local_attr.iteritems(): for k,v in self.local_attr.iteritems():
self.__setattr__(k,v) self.__setattr__(k,v)
inst = super(Module, self).build(mode, memo) inst = super(Module, self).build(mode, memo)
assert isinstance(inst, ModuleInstance)
for method in dir(self): for method in dir(self):
# Any method with a name like '_instance_XXX' is added to # Any method with a name like '_instance_XXX' is added to
# the object built under the name obj.XXX # the object built under the name obj.XXX
if method.startswith('_instance_'): if method.startswith('_instance_'):
setattr(inst, method[10:], Curry(self, method, inst)) new_methodname = method[len('_instance_'):]
new_obj = Curry(self, method, inst)
# setattr doesn't work here because we overrode __setattr__
# setattr(inst, new_methodname, new_obj)
inst.__dict__[new_methodname] = new_obj
assert getattr(inst, new_methodname) == new_obj
#print 'ADDING METHOD', method, 'to', id(inst), new_methodname, getattr(inst, new_methodname)
return inst return inst
def _instance_initialize(self, inst, init = {}, **kwinit): def _instance_initialize(self, inst, init = {}, **kwinit):
......
#!/usr/bin/env python #!/usr/bin/env python
import numpy as N import numpy as N
from theano import Op, Apply, tensor as T, Module, Member, Method, Mode, compile from theano import Op, Apply, tensor as T, Module, Method, Mode, compile
from theano.gof import OpSub, TopoOptimizer from theano.gof import OpSub, TopoOptimizer
from pylearn.algorithms.minimizer import make_minimizer # minimizer
from theano.printing import Print from theano.printing import Print
#import sgd #until Olivier's module-import thing works better
#################### ####################
# Library-type stuff # Library-type stuff
...@@ -14,8 +12,6 @@ from theano.printing import Print ...@@ -14,8 +12,6 @@ from theano.printing import Print
from theano.compile import module from theano.compile import module
from theano import tensor as T from theano import tensor as T
from pylearn.algorithms.minimizer import minimizer_factory
class StochasticGradientDescent(module.FancyModule): class StochasticGradientDescent(module.FancyModule):
"""Fixed stepsize gradient descent""" """Fixed stepsize gradient descent"""
def __init__(self, args, cost, params, gradients=None, stepsize=None, WEIRD_STUFF=True): def __init__(self, args, cost, params, gradients=None, stepsize=None, WEIRD_STUFF=True):
...@@ -28,18 +24,18 @@ class StochasticGradientDescent(module.FancyModule): ...@@ -28,18 +24,18 @@ class StochasticGradientDescent(module.FancyModule):
self.stepsize_init = None self.stepsize_init = None
if stepsize is None: if stepsize is None:
self.stepsize = module.Member(T.dscalar()) self.stepsize = (T.dscalar())
elif isinstance(stepsize, T.TensorResult): elif isinstance(stepsize, T.TensorResult):
self.stepsize = stepsize self.stepsize = stepsize
else: else:
if self.WEIRD_STUFF: if self.WEIRD_STUFF:
#TODO: why is this necessary? why does the else clause not work? #TODO: why is this necessary? why does the else clause not work?
# self.stepsize = module.Member(T.dscalar(), init = stepsize) # self.stepsize = module.Member(T.dscalar(), init = stepsize)
self.stepsize = module.Member(T.dscalar()) self.stepsize = (T.dscalar())
self.stepsize_init = stepsize self.stepsize_init = stepsize
else: else:
# self.stepsize = module.Member(T.value(stepsize)) # self.stepsize = module.Member(T.value(stepsize))
self.stepsize = module.Member(T.constant(stepsize))#work! self.stepsize = (T.constant(stepsize))#work!
if self.stepsize.ndim != 0: if self.stepsize.ndim != 0:
raise ValueError('stepsize must be a scalar', stepsize) raise ValueError('stepsize must be a scalar', stepsize)
...@@ -62,7 +58,6 @@ class StochasticGradientDescent(module.FancyModule): ...@@ -62,7 +58,6 @@ class StochasticGradientDescent(module.FancyModule):
pass pass
@minimizer_factory('sgd')
def sgd_minimizer(stepsize=None, **args): def sgd_minimizer(stepsize=None, **args):
def m(i,c,p,g=None): def m(i,c,p,g=None):
return StochasticGradientDescent(i, c, p, stepsize=stepsize, **args) return StochasticGradientDescent(i, c, p, stepsize=stepsize, **args)
...@@ -100,6 +95,9 @@ class TanhRnn(Op): ...@@ -100,6 +95,9 @@ class TanhRnn(Op):
return Apply(self, [x, z0, A], [z]) return Apply(self, [x, z0, A], [z])
def perform(self, node, (x,z0,A), out): def perform(self, node, (x,z0,A), out):
assert x is not None
assert z0 is not None
assert A is not None
T,M = x.shape T,M = x.shape
z = N.zeros((T+1, M)) z = N.zeros((T+1, M))
z[0] = z0 z[0] = z0
...@@ -160,10 +158,10 @@ class ExampleRNN(Module): ...@@ -160,10 +158,10 @@ class ExampleRNN(Module):
self.n_vis = n_vis self.n_vis = n_vis
#recurrent weight matrix in latent space #recurrent weight matrix in latent space
self.z0 = Member(T.dvector()) self.z0 = (T.dvector())
self.w = Member(T.dmatrix()) self.w = (T.dmatrix())
self.params = [self.w] self.params = [self.z0, self.w]
#input and target #input and target
x, y = T.dmatrix(), T.dmatrix() x, y = T.dmatrix(), T.dmatrix()
...@@ -175,6 +173,7 @@ class ExampleRNN(Module): ...@@ -175,6 +173,7 @@ class ExampleRNN(Module):
self.minimizer = minimizer([x, y], self.cost, self.params) self.minimizer = minimizer([x, y], self.cost, self.params)
def _instance_initialize(self, obj): def _instance_initialize(self, obj):
print 'INITIALIZE EXAMPLE RNN'
n_vis = self.n_vis n_vis = self.n_vis
rng = N.random.RandomState(2342) rng = N.random.RandomState(2342)
...@@ -184,14 +183,14 @@ class ExampleRNN(Module): ...@@ -184,14 +183,14 @@ class ExampleRNN(Module):
obj.minimizer.initialize() obj.minimizer.initialize()
def test_example_rnn(): def test_example_rnn():
minimizer_fn = make_minimizer('sgd', stepsize = 0.001) minimizer_fn = sgd_minimizer(stepsize = 0.001)
n_vis = 5 n_vis = 5
n_out = 3 n_out = 3
n_hid = 4 n_hid = 4
rnn_module = ExampleRNN(n_vis, minimizer_fn) rnn_module = ExampleRNN(n_vis, minimizer_fn)
rnn = rnn_module.make(mode='FAST_RUN') rnn = rnn_module.make()
rng = N.random.RandomState(7722342) rng = N.random.RandomState(7722342)
x = rng.randn(10,n_vis) x = rng.randn(10,n_vis)
...@@ -211,6 +210,7 @@ def test_example_rnn(): ...@@ -211,6 +210,7 @@ def test_example_rnn():
print i, rnn.minimizer.step_cost(x, y), rnn.minimizer.stepsize print i, rnn.minimizer.step_cost(x, y), rnn.minimizer.stepsize
else: else:
rnn.minimizer.step_cost(x, y) rnn.minimizer.step_cost(x, y)
assert rnn.minimizer.step_cost(x,y) < -20 #it starts around -.28
def test_WEIRD_STUFF(): def test_WEIRD_STUFF():
n_vis = 3 n_vis = 3
...@@ -223,8 +223,8 @@ def test_WEIRD_STUFF(): ...@@ -223,8 +223,8 @@ def test_WEIRD_STUFF():
LAG = 4 LAG = 4
y[LAG:] = x[:-LAG, 0:n_vis] y[LAG:] = x[:-LAG, 0:n_vis]
minimizer_fn1 = make_minimizer('sgd', stepsize = 0.001, WEIRD_STUFF = False) minimizer_fn1 = sgd_minimizer(stepsize = 0.001, WEIRD_STUFF = False)
minimizer_fn2 = make_minimizer('sgd', stepsize = 0.001, WEIRD_STUFF = True) minimizer_fn2 = sgd_minimizer(stepsize = 0.001, WEIRD_STUFF = True)
rnn_module1 = ExampleRNN(n_vis, minimizer_fn1) rnn_module1 = ExampleRNN(n_vis, minimizer_fn1)
rnn_module2 = ExampleRNN(n_vis, minimizer_fn2) rnn_module2 = ExampleRNN(n_vis, minimizer_fn2)
rnn1 = rnn_module1.make(mode='FAST_RUN') rnn1 = rnn_module1.make(mode='FAST_RUN')
......
#!/usr/bin/env python #!/usr/bin/env python
"""Test compile.module"""
__docformat__ = "restructuredtext en"
import cPickle, numpy, unittest import cPickle, numpy, unittest
from theano.compile.module import * from theano.compile.module import *
import theano.tensor as T import theano.tensor as T
import sys import sys
import theano import theano
#TODO: add test for module.make(member=init_value) #TODO: add test for module.make(member=init_value)
class T_test_module(unittest.TestCase): class T_module(unittest.TestCase):
def test_whats_up_with_submembers(self): def test_whats_up_with_submembers(self):
class Blah(FancyModule): class Blah(Module):
def __init__(self, stepsize): def __init__(self, stepsize):
super(Blah, self).__init__() super(Blah, self).__init__()
self.stepsize = Member(T.value(stepsize)) self.stepsize = T.value(stepsize)
x = T.dscalar() x = T.dscalar()
self.step = Method([x], x - self.stepsize) self.step = Method([x], x - self.stepsize)
B = Blah(0.0) B = Blah(0.0)
b = B.make(mode='FAST_RUN') b = B.make(mode='FAST_RUN')
assert b.stepsize == 0.0
b.step(1.0) b.step(1.0)
assert b.stepsize == 0.0 assert b.stepsize == 0.0
...@@ -57,8 +63,23 @@ class T_test_module(unittest.TestCase): ...@@ -57,8 +63,23 @@ class T_test_module(unittest.TestCase):
assert isinstance(m1.x,(gof.Result)) assert isinstance(m1.x,(gof.Result))
assert isinstance(m1.y,(gof.Result)) assert isinstance(m1.y,(gof.Result))
for i in [m1.lx[0], m1.ly[0], m1.llx[0][0], m1.lly[0][0], m1.ltx[0][0], m1.lty[0][0], m1.ldx[0]['x'], m1.ldy[0]['y'], m1.tx[0], m1.ty[0], m1.tlx[0][0], m1.tly[0][0], m1.ttx[0][0], m1.tty[0][0], m1.tdx[0]['x'], m1.tdy[0]['y'], m1.dx['x'], m1.dy['y'], m1.dlx['x'][0], m1.dly['y'][0], m1.dtx['x'][0], m1.dty['y'][0], m1.ddx['x']['x'], m1.ddy['y']['y']]: for i, obj in enumerate([
assert isinstance(i,(gof.Result)) m1.lx[0], #0
m1.llx[0][0],
m1.ltx[0][0],
m1.ldx[0]['x'],
m1.lty[0][0],#5
m1.ldy[0]['y'],
m1.ly[0],
m1.lly[0][0],
m1.tx[0], #8
m1.ty[0], m1.tlx[0][0],
m1.tly[0][0], m1.ttx[0][0], m1.tty[0][0], m1.tdx[0]['x'],
m1.tdy[0]['y'], m1.dx['x'],
m1.dy['y'], m1.dlx['x'][0], m1.dly['y'][0],
m1.dtx['x'][0], m1.dty['y'][0], m1.ddx['x']['x'],
m1.ddy['y']['y']]):
assert isinstance(obj,(gof.Result))
inst=m1.make() inst=m1.make()
...@@ -98,23 +119,72 @@ class T_test_module(unittest.TestCase): ...@@ -98,23 +119,72 @@ class T_test_module(unittest.TestCase):
for i,j in zip(get_l2(),range(len(get_l2()))): for i,j in zip(get_l2(),range(len(get_l2()))):
assert i[0]==j assert i[0]==j
local_test(lambda:T.dscalar(),lambda:Member(T.dscalar())) local_test(lambda:T.dscalar(),lambda:T.dscalar())
local_test(lambda:T.value(1),lambda:Member(T.value(2))) local_test(lambda:T.value(1),lambda:T.value(2))
local_test(lambda:T.constant(1),lambda:Member(T.constant(2))) local_test(lambda:T.constant(1),lambda:T.constant(2))
def test_compound_structure_assignment(self): def test_list_assign(self):
"""Test that list members can be assigned list-wise""" """Test that list members can be assigned list-wise"""
def local_test(x,y): def local_test(x,y):
m1=Module() m1=Module()
m1.l=[x(), y()]#cast Result]
#create a list with some results in it
m1.l=[x(), y()]
# create a Method that makes the second list element a shared Member
m1.f=Method([], m1.l[1]) m1.f=Method([], m1.l[1])
m1.g=Method([], m1.l[0])
m = m1.make() m = m1.make()
#assign 4 and 5 to the two results' containers in m
m.l = [4, 5] m.l = [4, 5]
print 'm.f', m.f()
assert numpy.all(5 == m.f())
assert numpy.all(4 == m.g())
local_test(lambda:T.dscalar(),lambda:T.dscalar())
local_test(lambda:T.value(1),lambda:T.value(2))
def test_tuple_assign(self):
"""Test that list members can be assigned tuple-wise"""
def local_test(x,y):
m1=Module()
m1.l=(x(), y())
# create a Method that makes the second list element a shared Member
m1.g=Method([], m1.l[0])
m1.f=Method([], m1.l[1])
m = m1.make()
#assign 4 and 5 to the two results' containers in m
m.l = (4, 5)
assert 5 == m.f() assert 5 == m.f()
assert 4 == m.g()
local_test(lambda:T.dscalar(),lambda:Member(T.dscalar())) local_test(lambda:T.dscalar(),lambda:T.dscalar())
local_test(lambda:T.value(1),lambda:Member(T.value(2))) local_test(lambda:T.value(1),lambda:T.value(2))
local_test(lambda:T.constant(1),lambda:Member(T.constant(2)))
def test_dict_assign(self):
"""Test that list members can be assigned dict-wise"""
def local_test(x,y):
m1=Module()
##DICT
m1.l={'x':x(), 'y':y()}
# create a Method that makes the second list element a shared Member
m1.f=Method([], m1.l['y'])
m1.g=Method([], m1.l['x'])
m = m1.make()
#assign 4 and 5 to the two results' containers in m
m.l = dict(x=4, y=5)
assert 5 == m.f()
assert 4 == m.g()
print 'dscalar test'
local_test(lambda:T.dscalar(),lambda:T.dscalar())
print 'value test'
local_test(lambda:T.value(1),lambda:T.value(2))
def test_method_in_list_or_dict(self): def test_method_in_list_or_dict(self):
...@@ -201,7 +271,7 @@ class T_test_module(unittest.TestCase): ...@@ -201,7 +271,7 @@ class T_test_module(unittest.TestCase):
m2=Module() m2=Module()
x=T.dscalar() x=T.dscalar()
populate_module(m1,x) populate_module(m1,x)
populate_module(m2,Member(x)) populate_module(m2,x)
#m1.x and m2.x should not be shared as their is no hierarchi link between them. #m1.x and m2.x should not be shared as their is no hierarchi link between them.
inst1=m1.make() inst1=m1.make()
inst2=m2.make() inst2=m2.make()
...@@ -248,8 +318,8 @@ class T_test_module(unittest.TestCase): ...@@ -248,8 +318,8 @@ class T_test_module(unittest.TestCase):
m4=Module() m4=Module()
x=T.dscalar() x=T.dscalar()
populate_module(m1,x) populate_module(m1,x)
populate_module(m2,Member(x)) populate_module(m2,(x))
populate_module(m4,Member(x)) populate_module(m4,(x))
#m1.x and m2.x should not be shared as their is no hierarchi link between them. #m1.x and m2.x should not be shared as their is no hierarchi link between them.
inst1=m1.make() inst1=m1.make()
inst2=m2.make() inst2=m2.make()
...@@ -325,33 +395,59 @@ class T_test_module(unittest.TestCase): ...@@ -325,33 +395,59 @@ class T_test_module(unittest.TestCase):
print >> sys.stderr, "MODULE TEST IMPLEMENTED BUT WE DON'T KNOW WHAT WE WANT AS A RESULT" print >> sys.stderr, "MODULE TEST IMPLEMENTED BUT WE DON'T KNOW WHAT WE WANT AS A RESULT"
def test_shared_method_N(self):
"""Test that Methods can be shared an arbitrary number of times between many submodules and
internal data structures."""
#put them in subModules, sub-sub-Modules, shared between a list and a dict, shared between
#a list and a submodule with a dictionary, etc...
print >> sys.stderr, "WARNING MODULE TEST NOT IMPLEMENTED"
def test_member_method_inputs(self): def test_member_method_inputs(self):
"""Test that module Members can be named as Method inputs, in which case the function will """Test that module Members can be named as Method inputs, in which case the function will
*not* use the storage allocated for the Module's version of that Member. *not* use the storage allocated for the Module's version of that Member.
si le module a un membre x et qu''une fct un parametre appele x qui n''est pas le membre cela doit etre bien traiter. """
les poids ne change pas
# test that explicit Method inputs don't use shared storage
M = Module()
M.x = T.dscalar()
M.y = T.dscalar()
M.f = Method([M.x], M.x + M.y)
M.g = Method([M.y], M.x - M.y)
m = M.make()
m.y = 77
assert m.f(23) == 100
assert m.x == None
m.x = 1000
assert m.g(23) == 977
assert m.y == 77
assert m.x == 1000
"""
print >> sys.stderr, "WARNING MODULE TEST NOT IMPLEMENTED"
def test_member_input_flags(self): def test_member_input_flags(self):
"""Test that we can manipulate the mutable, strict, etc. flags (see SymbolicInput) of """Test that we can manipulate the mutable, strict, etc. flags (see SymbolicInput) of
Method inputs""" Method inputs"""
print >> sys.stderr, "WARNING MODULE TEST NOT IMPLEMENTED"
M = Module()
M.x = T.dvector()
M.y = T.dvector()
xval= numpy.asarray([0, 0.5])
M.f = Method([io.In(M.x,
mutable=True,
update=(M.x - M.y),
value=xval)], M.x + M.y)
m = M.make()
m.y = numpy.asarray([1, 2])
assert numpy.all(m.f(xval) == [1, 2.5])
assert numpy.all(xval == [-1, -1.5])
def test_member_output_flags(self): def test_member_output_flags(self):
"""Test that we can manipulate the output flags (just 'borrow' I think, see SymbolicOutput) """Test that we can manipulate the output flags (just 'borrow' I think, see SymbolicOutput)
of Method outputs""" of Method outputs"""
print >> sys.stderr, "WARNING MODULE TEST NOT IMPLEMENTED" M = Module()
M.x = T.dvector()
M.f = Method([M.x], io.Out(M.x*4, borrow=True))
m = M.make()
v0 = m.f([5, 8])
v0_copy = v0 * 1
m.f([3, 2])
assert numpy.all(v0 != v0_copy)
def test_sanity_check_mode(self): def test_sanity_check_mode(self):
"""Test that Module.make(self) can take the same list of Modes that function can, so we can """Test that Module.make(self) can take the same list of Modes that function can, so we can
...@@ -396,8 +492,8 @@ class T_test_module(unittest.TestCase): ...@@ -396,8 +492,8 @@ class T_test_module(unittest.TestCase):
def test_pickle(): def test_pickle():
"""Test that a module can be pickled""" """Test that a module can be pickled"""
M = Module() M = Module()
M.x = Member(T.dmatrix()) M.x = (T.dmatrix())
M.y = Member(T.dmatrix()) M.y = (T.dmatrix())
a = T.dmatrix() a = T.dmatrix()
M.f = Method([a], a + M.x + M.y) M.f = Method([a], a + M.x + M.y)
M.g = Method([a], a * M.x * M.y) M.g = Method([a], a * M.x * M.y)
...@@ -418,13 +514,11 @@ def test_pickle(): ...@@ -418,13 +514,11 @@ def test_pickle():
assert m_dup.x is m_dup.g.input_storage[1].data assert m_dup.x is m_dup.g.input_storage[1].data
assert m_dup.y is m_dup.g.input_storage[2].data assert m_dup.y is m_dup.g.input_storage[2].data
from numpy.testing import *
@dec.knownfailureif(True, "These branch cuts are known to fail")
def test_pickle_aliased_memory(): def test_pickle_aliased_memory():
try:
M = Module() M = Module()
M.x = Member(T.dmatrix()) M.x = (T.dmatrix())
M.y = Member(T.dmatrix()) M.y = (T.dmatrix())
a = T.dmatrix() a = T.dmatrix()
M.f = Method([a], a + M.x + M.y) M.f = Method([a], a + M.x + M.y)
M.g = Method([a], a * M.x * M.y) M.g = Method([a], a * M.x * M.y)
...@@ -450,6 +544,9 @@ def test_pickle_aliased_memory(): ...@@ -450,6 +544,9 @@ def test_pickle_aliased_memory():
assert m.y[0,0] == 3.142 assert m.y[0,0] == 3.142
m_dup.x[1,0] = 3.142 m_dup.x[1,0] = 3.142
assert m_dup.y[0,0] == 3.142 assert m_dup.y[0,0] == 3.142
except Exception, e:
raise Exception('Known Failure: These branch cuts are known to fail', str(e))
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -70,27 +70,36 @@ class QuadraticDenoisingAA(module.Module): ...@@ -70,27 +70,36 @@ class QuadraticDenoisingAA(module.Module):
# ACQUIRE/MAKE INPUT # ACQUIRE/MAKE INPUT
if not input: if not input:
input = T.matrix('input') input = T.matrix('input')
self.input = theano.External(input) #self.input = theano.External(input)
self.input = (input)
# HYPER-PARAMETERS # HYPER-PARAMETERS
self.lr = theano.Member(T.scalar()) #self.lr = theano.Member(T.scalar())
self.lr = (T.scalar())
# PARAMETERS # PARAMETERS
if _qfilters is None: if _qfilters is None:
self.qfilters = [theano.Member(T.dmatrix('q%i'%i)) for i in xrange(n_quadratic_filters)] #self.qfilters = [theano.Member(T.dmatrix('q%i'%i)) for i in xrange(n_quadratic_filters)]
self.qfilters = [(T.dmatrix('q%i'%i)) for i in xrange(n_quadratic_filters)]
else: else:
self.qfilters = [theano.Member(q) for q in _qfilters] #self.qfilters = [theano.Member(q) for q in _qfilters]
self.qfilters = [(q) for q in _qfilters]
self.w1 = theano.Member(T.matrix('w1')) if _w1 is None else theano.Member(_w1) #self.w1 = theano.Member(T.matrix('w1')) if _w1 is None else theano.Member(_w1)
self.w1 = (T.matrix('w1')) if _w1 is None else (_w1)
if _w2 is None: if _w2 is None:
if not tie_weights: if not tie_weights:
self.w2 = theano.Member(T.matrix()) #self.w2 = theano.Member(T.matrix())
self.w2 = (T.matrix())
else: else:
self.w2 = self.w1.T self.w2 = self.w1.T
else: else:
self.w2 = theano.Member(_w2) #self.w2 = theano.Member(_w2)
self.b1 = theano.Member(T.vector('b1')) if _b1 is None else theano.Member(_b1) self.w2 = (_w2)
self.b2 = theano.Member(T.vector('b2')) if _b2 is None else theano.Member(_b2) #self.b1 = theano.Member(T.vector('b1')) if _b1 is None else theano.Member(_b1)
self.b1 = (T.vector('b1')) if _b1 is None else (_b1)
#self.b2 = theano.Member(T.vector('b2')) if _b2 is None else theano.Member(_b2)
self.b2 = (T.vector('b2')) if _b2 is None else (_b2)
# # REGULARIZATION COST # # REGULARIZATION COST
# self.regularization = self.build_regularization() # self.regularization = self.build_regularization()
...@@ -212,7 +221,8 @@ class SigmoidXEQuadraticDenoisingAA(QuadraticDenoisingAA): ...@@ -212,7 +221,8 @@ class SigmoidXEQuadraticDenoisingAA(QuadraticDenoisingAA):
""" """
def build_corrupted_input(self): def build_corrupted_input(self):
self.noise_level = theano.Member(T.scalar()) #self.noise_level = theano.Member(T.scalar())
self.noise_level = (T.scalar())
return self.random.binomial(T.shape(self.input), 1, 1 - self.noise_level) * self.input return self.random.binomial(T.shape(self.input), 1, 1 - self.noise_level) * self.input
def hid_activation_function(self, activation): def hid_activation_function(self, activation):
...@@ -262,12 +272,17 @@ class Module_Nclass(module.FancyModule): ...@@ -262,12 +272,17 @@ class Module_Nclass(module.FancyModule):
def __init__(self, x=None, targ=None, w=None, b=None, lr=None, regularize=False): def __init__(self, x=None, targ=None, w=None, b=None, lr=None, regularize=False):
super(Module_Nclass, self).__init__() #boilerplate super(Module_Nclass, self).__init__() #boilerplate
self.x = module.Member(x) if x is not None else T.matrix('input') #self.x = module.Member(x) if x is not None else T.matrix('input')
self.targ = module.Member(targ) if targ is not None else T.lvector() self.x = (x) if x is not None else T.matrix('input')
#self.targ = module.Member(targ) if targ is not None else T.lvector()
self.targ = (targ) if targ is not None else T.lvector()
self.w = module.Member(w) if w is not None else module.Member(T.dmatrix()) #self.w = module.Member(w) if w is not None else module.Member(T.dmatrix())
self.b = module.Member(b) if b is not None else module.Member(T.dvector()) self.w = (w) if w is not None else (T.dmatrix())
self.lr = module.Member(lr) if lr is not None else module.Member(T.dscalar()) #self.b = module.Member(b) if b is not None else module.Member(T.dvector())
self.b = (b) if b is not None else (T.dvector())
#self.lr = module.Member(lr) if lr is not None else module.Member(T.dscalar())
self.lr = (lr) if lr is not None else (T.dscalar())
self.params = [p for p in [self.w, self.b] if p.owner is None] self.params = [p for p in [self.w, self.b] if p.owner is None]
...@@ -355,7 +370,8 @@ class ConvolutionalMLP(module.FancyModule): ...@@ -355,7 +370,8 @@ class ConvolutionalMLP(module.FancyModule):
): ):
super(ConvolutionalMLP, self).__init__() super(ConvolutionalMLP, self).__init__()
self.lr = module.Member(T.scalar()) #self.lr = module.Member(T.scalar())
self.lr = (T.scalar())
self.inputs = [T.dmatrix() for i in range(window_size)] self.inputs = [T.dmatrix() for i in range(window_size)]
self.targ = T.lvector() self.targ = T.lvector()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论