提交 3bed4bb1 authored 作者: Joseph Turian's avatar Joseph Turian

merge

...@@ -31,12 +31,15 @@ Op's contract ...@@ -31,12 +31,15 @@ Op's contract
An Op is any object which defines the following methods: An Op is any object which defines the following methods:
- **make_node(*inputs)** - **make_node(*inputs)**
- This method is responsible for creating output Results of a suitable Type
to serve as the outputs of this Op's application. It should put these
outputs into an Apply instance, and return the Apply instance.
- This important function creates an Apply node representing the - This important function creates an Apply node representing the
application of the Op on the inputs provided. If the Op cannot be application of the Op on the inputs provided. If the Op cannot be
applied on these inputs, it must raise an appropriate applied on these inputs, it must raise an appropriate
exception. This method is also responsible for creating Results of exception.
the suitable Type to serve as the outputs of the Op's application.
- **__call__(*inputs)** - **__call__(*inputs)**
...@@ -52,20 +55,54 @@ An Op is any object which defines the following methods: ...@@ -52,20 +55,54 @@ An Op is any object which defines the following methods:
method, the inputs are a list of references to data to operate on method, the inputs are a list of references to data to operate on
and output_storage is a list of storage cells where the results of and output_storage is a list of storage cells where the results of
the computation must be put. the computation must be put.
- This function must be determined by the inputs. That is to say, if it is
evaluated once on inputs A and returned B, then if ever inputs C, equal to
A, are presented again, then outputs equal to B must be returned again.
- **__eq__(self, other)**
- Returning True here is a promise to the optimization system that the other
Op will produce exactly the same graph effects (from perform) as this one,
given identical inputs. This means it will produce the same output values,
it will destroy the same inputs (same destroy_map), and will alias outputs
to the same inputs (same view_map).
- **__hash__(self)**
- If two Op instances compare equal, then they MUST return the same hash
value.
- Equally important, this hash value must not change during the lifetime of
self.
- **__ne__(self, other)**
- Recommended, and default: define as (not (self==other))
- **grad(inputs, output_gradients)** *Optional* - **grad(inputs, output_gradients)** *Optional*
- If the Op you are defining is differentiable, you can define its - If the Op you are defining is differentiable, you can define its
gradient symbolically in this method. Both the inputs and gradient symbolically in this method.
output_gradients are Results and you must return one Result for
each input representing the gradient wrt these inputs provided - Both the inputs and output_gradients will be Results. This function must
that the gradients wrt the outputs are computed by return a list containg one Result (or None) for each input.
output_gradients. Each returned Result represents the gradient wrt that input given the
symbolic gradients wrt each output.
- If the output is not differentiable with respect to any inputs, then this
function should be defined to return [None for i in inputs].
- If this method is not defined, then theano assumes it hsa been forgotten.
Symbolic differentiation will fail on a graph that includes this Op.
- For more information on the use of this method, see ``grad``.
For each method, the *default* is what the Op class defines for you. For each method, the *default* is what the Op class defines for you.
For more details you can go see the documentation for :ref:`op`. For more details, including the interface for providing a C implementation of
perform(), refer to the documentation for :ref:`op`.
......
...@@ -43,7 +43,7 @@ from compile import \ ...@@ -43,7 +43,7 @@ from compile import \
Mode, \ Mode, \
predefined_modes, predefined_linkers, predefined_optimizers, \ predefined_modes, predefined_linkers, predefined_optimizers, \
FunctionMaker, function, OpFromGraph, \ FunctionMaker, function, OpFromGraph, \
Component, External, Member, KitComponent, Method, \ Component, External, Member, Method, \
Composite, ComponentList, ComponentDict, Module, \ Composite, ComponentList, ComponentDict, Module, \
ProfileMode ProfileMode
......
...@@ -998,32 +998,6 @@ FancyModule = Module ...@@ -998,32 +998,6 @@ FancyModule = Module
FancyModuleInstance = ModuleInstance FancyModuleInstance = ModuleInstance
class KitComponent(Component):
"""
Represents a SymbolicInputKit (see io.py).
"""
def __init__(self, kit):
super(KitComponent, self).__init__()
self.kit = kit
def allocate(self, memo):
"""
Allocates a Container for each input in the kit. Sets a key in
the memo that maps the SymbolicInputKit to the list of
Containers.
"""
for input in self.kit.sinputs:
r = input.result
if r not in memo:
input = copy(input)
input.value = gof.Container(r, storage = [None])
memo[r] = input
def build(self, mode, memo):
return [memo[i.result].value for i in self.kit.sinputs]
def func_to_mod(f): def func_to_mod(f):
""" """
Creates a dummy module, with external member variables for the input Creates a dummy module, with external member variables for the input
......
...@@ -159,6 +159,9 @@ class PureOp(object): ...@@ -159,6 +159,9 @@ class PureOp(object):
To see how `Op`, `Type`, `Result`, and `Apply` fit together see the page on :doc:`graph`. To see how `Op`, `Type`, `Result`, and `Apply` fit together see the page on :doc:`graph`.
For more specifications on how these methods should behave: see the `Op Contract` in the
sphinx docs (advanced tutorial on Op-making).
""" """
default_output = None default_output = None
......
...@@ -6,11 +6,11 @@ from basic import * ...@@ -6,11 +6,11 @@ from basic import *
import opt import opt
import blas import blas
import raw_random, rmodule import raw_random, randomstreams
from rmodule import \ from randomstreams import \
RandomKit, RModule RandomStreams
random = RandomKit('random') random = RandomStreams(seed=0xBAD5EED)
"""Imitate the numpy.random symbol with a tensor.random one""" """Imitate the numpy.random symbol with a tensor.random one"""
from elemwise import \ from elemwise import \
......
"""Define RModule, a Module providing random number streams in Theano graphs."""
__docformat__ = "restructuredtext en"
import sys
import functools
from functools import partial
from collections import deque
import numpy
from ...compile import (SymbolicInputKit, SymbolicInput,
Module, module, Method, Member, In, Component)
from ...gof import Container
from ...tensor import raw_random
class KitComponent(Component):
"""
Represents a SymbolicInputKit (see io.py).
"""
def __init__(self, kit):
super(KitComponent, self).__init__()
self.kit = kit
def allocate(self, memo):
"""
Allocates a Container for each input in the kit. Sets a key in
the memo that maps the SymbolicInputKit to the list of
Containers.
"""
for input in self.kit.sinputs:
r = input.result
if r not in memo:
input = copy(input)
input.value = gof.Container(r, storage = [None])
memo[r] = input
def build(self, mode, memo):
return [memo[i.result].value for i in self.kit.sinputs]
class RandomKit(SymbolicInputKit):
def __init__(self, name, value = None):
super(RandomKit, self).__init__(name)
self.value = value
def gen(self, op, *args, **kwargs):
random_state_result = raw_random.random_state_type()
new_r, out = op(random_state_result, *args, **kwargs)
self.add_input(SymbolicInput(random_state_result, update = new_r))
out.rng = new_r
out.auto = self
return out
def distribute(self, value, indices, containers):
rg = partial(numpy.random.RandomState(int(value)).randint, 2**30)
elems = deque(zip(indices, containers))
i = 0
while elems:
index, container = elems.popleft()
while i <= index:
curr = rg()
i += 1
rs = numpy.random.RandomState(int(curr))
container.data = rs
def binomial(self, *args, **kwargs):
return self.gen(raw_random.binomial, *args, **kwargs)
def uniform(self, *args, **kwargs):
return self.gen(raw_random.uniform, *args, **kwargs)
def normal(self, *args, **kwargs):
return self.gen(raw_random.normal, *args, **kwargs)
def random_integers(self, *args, **kwargs):
return self.gen(raw_random.random_integers, *args, **kwargs)
rk = RandomKit('rk', 0xBAD5EED)
class RModule(Module):
"""Module providing random number streams in Theano graphs."""
def __init__(self, components = {}, **kwcomponents):
super(RModule, self).__init__(components, **kwcomponents)
self.random = RandomKit('rkit')
self._rkit = KitComponent(self.random)
def __wrapper__(self, x):
x = module.wrap(x)
if isinstance(x, Method):
x.kits += [self.random]
return x
def _instance_seed(self, inst, seed, recursive = True):
seedgen = numpy.random.RandomState(seed)
if recursive:
#Here, we recurse through all the components (inst2) contained in (inst)
#and seeds each subcomponent that is an RModule
for path, c in self.flat_components_map(True):
if isinstance(c, RModule):
inst2 = inst
for name in path:
inst2 = inst2[name]
# A Kit (c._rkit.kit) contains a list of io.SymbolicIn instances
# and the distribute method takes a value (seed), a list of indices
# and a list of corresponding Container instances. In this
# situation it will reseed all the rngs using the containers
# associated to them.
c._rkit.kit.distribute(seedgen.random_integers(2**30),
xrange(len(inst2._rkit)), inst2._rkit)
else:
self._rkit.kit.distribute(seedgen.random_integers(2**30), xrange(len(inst._rkit)), inst._rkit)
__docformat__ = "restructuredtext en"
import sys
import unittest
import numpy as N
from theano.tensor.deprecated.rmodule import *
from theano import tensor
from theano import compile, gof
if 0:
class T_test_module(unittest.TestCase):
def test_state_propagation(self):
if 1:
print >> sys.stderr, "RModule deprecated"
else:
x = tensor.vector()
rk = RandomKit('rk', 1000)
f = compile.function([x, (rk, [gof.Container(r = gof.generic, storage = [123], name='bla')])], rk.binomial(tensor.shape(x)))
print "RK", rk.value
f['rk'] = 9873456
print "RK", rk.value
rvals = [f([1,2,3,4,6, 7, 8]) for i in xrange(5)]
print rvals
for i in xrange(5-1):
for j in xrange(i+1, 5):
assert not N.all(rvals[i] == rvals[j])
def test_B(self):
"""Test that random numbers change from call to call!
Also, make sure that the seeding strategy doesn't change without failing a test.
Random numbers can't be too random or experiments aren't repeatable. Email theano-dev
before updating the `rvals` in this test.
"""
class B(RModule):
def __init__(self):
super(B, self).__init__()
self.x = compile.Member(tensor.dvector())
self.r = self.random.uniform(tensor.shape(self.x))
self.f = compile.Method([self.x], self.r)
class E(RModule):
def __init__(self):
super(E, self).__init__()
self.b = B()
self.f = compile.Method([self.b.x], self.b.r)
b = E()
m = b.make()
m.seed(1000)
#print m.f(N.ones(5))
#print m.f(N.ones(5))
#print m.f(N.ones(5))
rvals = ["0.74802375876 0.872308123517 0.294830748897 0.803123780003 0.6321109955",
"0.00168744844365 0.278638315678 0.725436793755 0.7788480779 0.629885140994",
"0.545561221664 0.0992011009108 0.847112593242 0.188015424144 0.158046201298",
"0.054382248842 0.563459168529 0.192757276954 0.360455221883 0.174805216702",
"0.961942907777 0.49657319422 0.0316111492826 0.0915054717012 0.195877184515"]
for i in xrange(5):
s = " ".join([str(n) for n in m.f(N.ones(5))])
print s
assert s == rvals[i]
if __name__ == '__main__':
from theano.tests import main
main("test_rmodule")
"""Define RModule, a Module providing random number streams in Theano graphs.""" """Define RandomStreams, providing random number variables for Theano graphs."""
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
import sys
import functools
from functools import partial
from collections import deque
import sys
import numpy import numpy
from ..compile import (SymbolicInputKit, SymbolicInput, from ..compile import module, In, Component
Module, KitComponent, module, Method, Member, In, Component)
from ..gof import Container from ..gof import Container
from ..tensor import raw_random from ..tensor import raw_random
class RandomKit(SymbolicInputKit):
def __init__(self, name, value = None):
super(RandomKit, self).__init__(name)
self.value = value
def gen(self, op, *args, **kwargs):
random_state_result = raw_random.random_state_type()
new_r, out = op(random_state_result, *args, **kwargs)
self.add_input(SymbolicInput(random_state_result, update = new_r))
out.rng = new_r
out.auto = self
return out
def distribute(self, value, indices, containers):
rg = partial(numpy.random.RandomState(int(value)).randint, 2**30)
elems = deque(zip(indices, containers))
i = 0
while elems:
index, container = elems.popleft()
while i <= index:
curr = rg()
i += 1
rs = numpy.random.RandomState(int(curr))
container.data = rs
def binomial(self, *args, **kwargs):
return self.gen(raw_random.binomial, *args, **kwargs)
def uniform(self, *args, **kwargs):
return self.gen(raw_random.uniform, *args, **kwargs)
def normal(self, *args, **kwargs):
return self.gen(raw_random.normal, *args, **kwargs)
def random_integers(self, *args, **kwargs):
return self.gen(raw_random.random_integers, *args, **kwargs)
rk = RandomKit('rk', 0xBAD5EED)
class RModule(Module):
"""Module providing random number streams in Theano graphs."""
def __init__(self, components = {}, **kwcomponents):
super(RModule, self).__init__(components, **kwcomponents)
self.random = RandomKit('rkit')
self._rkit = KitComponent(self.random)
def __wrapper__(self, x):
x = module.wrap(x)
if isinstance(x, Method):
x.kits += [self.random]
return x
def _instance_seed(self, inst, seed, recursive = True):
seedgen = numpy.random.RandomState(seed)
if recursive:
#Here, we recurse through all the components (inst2) contained in (inst)
#and seeds each subcomponent that is an RModule
for path, c in self.flat_components_map(True):
if isinstance(c, RModule):
inst2 = inst
for name in path:
inst2 = inst2[name]
# A Kit (c._rkit.kit) contains a list of io.SymbolicIn instances
# and the distribute method takes a value (seed), a list of indices
# and a list of corresponding Container instances. In this
# situation it will reseed all the rngs using the containers
# associated to them.
c._rkit.kit.distribute(seedgen.random_integers(2**30),
xrange(len(inst2._rkit)), inst2._rkit)
else:
self._rkit.kit.distribute(seedgen.random_integers(2**30), xrange(len(inst._rkit)), inst._rkit)
class RandomStreamsInstance(object): class RandomStreamsInstance(object):
"""RandomStreamsInstance""" """RandomStreamsInstance"""
def __init__(self, random_streams, memo, default_seed): def __init__(self, random_streams, memo, default_seed):
...@@ -168,10 +83,8 @@ class RandomStreamsInstance(object): ...@@ -168,10 +83,8 @@ class RandomStreamsInstance(object):
return return
raise KeyError(item) raise KeyError(item)
class RandomStreams(Component): class RandomStreams(Component):
"""Module with similar interface to numpy.random (numpy.random.RandomState)""" """Module component with similar interface to numpy.random (numpy.random.RandomState)"""
random_state_results = [] random_state_results = []
"""A list of pairs of the form (input_r, output_r). This will be over-ridden by the module """A list of pairs of the form (input_r, output_r). This will be over-ridden by the module
...@@ -183,11 +96,18 @@ class RandomStreams(Component): ...@@ -183,11 +96,18 @@ class RandomStreams(Component):
generator that provides seeds for member streams""" generator that provides seeds for member streams"""
def __init__(self, seed=None): def __init__(self, seed=None):
"""
:type seed: None or int
:param seed: a default seed to initialize the RandomState instances after build. See
`RandomStreamsInstance.__init__` for more details.
"""
super(RandomStreams, self).__init__() super(RandomStreams, self).__init__()
self.random_state_results = [] self.random_state_results = []
self.default_instance_seed = seed self.default_instance_seed = seed
def allocate(self, memo): def allocate(self, memo):
"""override `Component.allocate` """
for old_r, new_r in self.random_state_results: for old_r, new_r in self.random_state_results:
assert old_r not in memo assert old_r not in memo
memo[old_r] = In(old_r, memo[old_r] = In(old_r,
...@@ -196,11 +116,23 @@ class RandomStreams(Component): ...@@ -196,11 +116,23 @@ class RandomStreams(Component):
mutable=True) mutable=True)
def build(self, mode, memo): def build(self, mode, memo):
#print 'MODE', mode """override `Component.build` """
#returns a list of containers
return RandomStreamsInstance(self, memo, self.default_instance_seed) return RandomStreamsInstance(self, memo, self.default_instance_seed)
def gen(self, op, *args, **kwargs): def gen(self, op, *args, **kwargs):
"""Create a new random stream in this container.
:param op: a RandomFunction instance to
:param args: interpreted by `op`
:param kwargs: interpreted by `op`
:returns: The symbolic random draw part of op()'s return value. This function stores
the updated RandomStateType Result for use at `build` time.
:rtype: TensorResult
"""
random_state_result = raw_random.random_state_type() random_state_result = raw_random.random_state_type()
new_r, out = op(random_state_result, *args, **kwargs) new_r, out = op(random_state_result, *args, **kwargs)
out.rng = random_state_result out.rng = random_state_result
...@@ -210,15 +142,28 @@ class RandomStreams(Component): ...@@ -210,15 +142,28 @@ class RandomStreams(Component):
def binomial(self, *args, **kwargs): def binomial(self, *args, **kwargs):
"""Return a symbolic binomial sample """Return a symbolic binomial sample
This is a shortcut for a call to `self.gen`
""" """
return self.gen(raw_random.binomial, *args, **kwargs) return self.gen(raw_random.binomial, *args, **kwargs)
def uniform(self, *args, **kwargs): def uniform(self, *args, **kwargs):
"""Return a symbolic uniform sample
This is a shortcut for a call to `self.gen`
"""
return self.gen(raw_random.uniform, *args, **kwargs) return self.gen(raw_random.uniform, *args, **kwargs)
def normal(self, *args, **kwargs): def normal(self, *args, **kwargs):
"""Return a symbolic normal sample
This is a shortcut for a call to `self.gen`
"""
return self.gen(raw_random.normal, *args, **kwargs) return self.gen(raw_random.normal, *args, **kwargs)
def random_integers(self, *args, **kwargs): def random_integers(self, *args, **kwargs):
"""Return a symbolic random integer sample
This is a shortcut for a call to `self.gen`
"""
return self.gen(raw_random.random_integers, *args, **kwargs) return self.gen(raw_random.random_integers, *args, **kwargs)
...@@ -18,7 +18,7 @@ def cross_entropy(target, output, axis=1): ...@@ -18,7 +18,7 @@ def cross_entropy(target, output, axis=1):
""" """
return -T.mean(target * T.log(output) + (1 - target) * T.log(1 - output), axis=axis) return -T.mean(target * T.log(output) + (1 - target) * T.log(1 - output), axis=axis)
class QuadraticDenoisingAA(T.RModule): class QuadraticDenoisingAA(module.Module):
"""Quadratic de-noising Auto-encoder """Quadratic de-noising Auto-encoder
WRITEME WRITEME
...@@ -59,6 +59,8 @@ class QuadraticDenoisingAA(T.RModule): ...@@ -59,6 +59,8 @@ class QuadraticDenoisingAA(T.RModule):
""" """
super(QuadraticDenoisingAA, self).__init__() super(QuadraticDenoisingAA, self).__init__()
self.random = T.RandomStreams()
# MODEL CONFIGURATION # MODEL CONFIGURATION
# self.regularize = regularize # self.regularize = regularize
self.tie_weights = tie_weights self.tie_weights = tie_weights
...@@ -75,11 +77,11 @@ class QuadraticDenoisingAA(T.RModule): ...@@ -75,11 +77,11 @@ class QuadraticDenoisingAA(T.RModule):
# PARAMETERS # PARAMETERS
if _qfilters is None: if _qfilters is None:
self.qfilters = [theano.Member(T.dmatrix()) for i in xrange(n_quadratic_filters)] self.qfilters = [theano.Member(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.w1 = theano.Member(T.matrix()) if _w1 is None else theano.Member(_w1) self.w1 = theano.Member(T.matrix('w1')) if _w1 is None else theano.Member(_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())
...@@ -87,8 +89,8 @@ class QuadraticDenoisingAA(T.RModule): ...@@ -87,8 +89,8 @@ class QuadraticDenoisingAA(T.RModule):
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()) if _b1 is None else theano.Member(_b1) self.b1 = theano.Member(T.vector('b1')) if _b1 is None else theano.Member(_b1)
self.b2 = theano.Member(T.vector()) if _b2 is None else theano.Member(_b2) self.b2 = theano.Member(T.vector('b2')) if _b2 is None else theano.Member(_b2)
# # REGULARIZATION COST # # REGULARIZATION COST
# self.regularization = self.build_regularization() # self.regularization = self.build_regularization()
...@@ -173,6 +175,7 @@ class QuadraticDenoisingAA(T.RModule): ...@@ -173,6 +175,7 @@ class QuadraticDenoisingAA(T.RModule):
if (input_size is None) ^ (hidden_size is None): if (input_size is None) ^ (hidden_size is None):
raise ValueError("Must specify input_size and hidden_size or neither.") raise ValueError("Must specify input_size and hidden_size or neither.")
super(QuadraticDenoisingAA, self)._instance_initialize(obj, {}) super(QuadraticDenoisingAA, self)._instance_initialize(obj, {})
obj.random.initialize()
if seed is not None: if seed is not None:
R = N.random.RandomState(seed) R = N.random.RandomState(seed)
else: else:
...@@ -189,7 +192,7 @@ class QuadraticDenoisingAA(T.RModule): ...@@ -189,7 +192,7 @@ class QuadraticDenoisingAA(T.RModule):
obj.qfilters = [R.uniform(size = sz, low = -inf, high = inf) * qfilter_relscale \ obj.qfilters = [R.uniform(size = sz, low = -inf, high = inf) * qfilter_relscale \
for qf in self.qfilters] for qf in self.qfilters]
if seed is not None: if seed is not None:
obj.seed(seed, recursive=True) obj.random.seed(seed)
obj.lr = lr obj.lr = lr
......
...@@ -2,9 +2,10 @@ __docformat__ = "restructuredtext en" ...@@ -2,9 +2,10 @@ __docformat__ = "restructuredtext en"
import sys import sys
import unittest import unittest
import numpy as N import numpy
from theano.tensor.rmodule import * from theano.tensor.randomstreams import RandomStreams, raw_random
from theano.compile import Module, Method, Member
from theano import tensor from theano import tensor
from theano import compile, gof from theano import compile, gof
...@@ -122,66 +123,6 @@ class T_RandomStreams(unittest.TestCase): ...@@ -122,66 +123,6 @@ class T_RandomStreams(unittest.TestCase):
assert numpy.all(fn_val1 == numpy_val1) assert numpy.all(fn_val1 == numpy_val1)
class T_test_module(unittest.TestCase):
def test_state_propagation(self):
if 1:
print >> sys.stderr, "RModule deprecated"
else:
x = tensor.vector()
rk = RandomKit('rk', 1000)
f = compile.function([x, (rk, [gof.Container(r = gof.generic, storage = [123], name='bla')])], rk.binomial(tensor.shape(x)))
print "RK", rk.value
f['rk'] = 9873456
print "RK", rk.value
rvals = [f([1,2,3,4,6, 7, 8]) for i in xrange(5)]
print rvals
for i in xrange(5-1):
for j in xrange(i+1, 5):
assert not N.all(rvals[i] == rvals[j])
def test_B(self):
"""Test that random numbers change from call to call!
Also, make sure that the seeding strategy doesn't change without failing a test.
Random numbers can't be too random or experiments aren't repeatable. Email theano-dev
before updating the `rvals` in this test.
"""
class B(RModule):
def __init__(self):
super(B, self).__init__()
self.x = compile.Member(tensor.dvector())
self.r = self.random.uniform(tensor.shape(self.x))
self.f = compile.Method([self.x], self.r)
class E(RModule):
def __init__(self):
super(E, self).__init__()
self.b = B()
self.f = compile.Method([self.b.x], self.b.r)
b = E()
m = b.make()
m.seed(1000)
#print m.f(N.ones(5))
#print m.f(N.ones(5))
#print m.f(N.ones(5))
rvals = ["0.74802375876 0.872308123517 0.294830748897 0.803123780003 0.6321109955",
"0.00168744844365 0.278638315678 0.725436793755 0.7788480779 0.629885140994",
"0.545561221664 0.0992011009108 0.847112593242 0.188015424144 0.158046201298",
"0.054382248842 0.563459168529 0.192757276954 0.360455221883 0.174805216702",
"0.961942907777 0.49657319422 0.0316111492826 0.0915054717012 0.195877184515"]
for i in xrange(5):
s = " ".join([str(n) for n in m.f(N.ones(5))])
print s
assert s == rvals[i]
if __name__ == '__main__': if __name__ == '__main__':
from theano.tests import main from theano.tests import main
main("test_rmodule") main("test_randomstreams")
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论