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

deprecated RModule, added comments to RandomStreams

上级 0786f2af
......@@ -6,11 +6,11 @@ from basic import *
import opt
import blas
import raw_random, rmodule
from rmodule import \
RandomKit, RModule
import raw_random, randomstreams
from randomstreams import \
RandomStreams
random = RandomKit('random')
random = RandomStreams(seed=0xBAD5EED)
"""Imitate the numpy.random symbol with a tensor.random one"""
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, KitComponent, module, Method, Member, In, Component)
from ...gof import Container
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)
"""Define RModule, a Module providing random number streams in Theano graphs."""
"""Define RandomStreams, providing random number variables for Theano graphs."""
__docformat__ = "restructuredtext en"
import sys
import functools
from functools import partial
from collections import deque
import sys
import numpy
from ..compile import (SymbolicInputKit, SymbolicInput,
Module, KitComponent, module, Method, Member, In, Component)
from ..compile import module, In, Component
from ..gof import Container
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):
"""RandomStreamsInstance"""
def __init__(self, random_streams, memo, default_seed):
......@@ -168,10 +83,8 @@ class RandomStreamsInstance(object):
return
raise KeyError(item)
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 = []
"""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):
generator that provides seeds for member streams"""
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__()
self.random_state_results = []
self.default_instance_seed = seed
def allocate(self, memo):
"""override `Component.allocate` """
for old_r, new_r in self.random_state_results:
assert old_r not in memo
memo[old_r] = In(old_r,
......@@ -196,11 +116,23 @@ class RandomStreams(Component):
mutable=True)
def build(self, mode, memo):
#print 'MODE', mode
#returns a list of containers
"""override `Component.build` """
return RandomStreamsInstance(self, memo, self.default_instance_seed)
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()
new_r, out = op(random_state_result, *args, **kwargs)
out.rng = random_state_result
......@@ -210,15 +142,28 @@ class RandomStreams(Component):
def binomial(self, *args, **kwargs):
"""Return a symbolic binomial sample
This is a shortcut for a call to `self.gen`
"""
return self.gen(raw_random.binomial, *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)
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)
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)
......@@ -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)
class QuadraticDenoisingAA(T.RModule):
class QuadraticDenoisingAA(module.Module):
"""Quadratic de-noising Auto-encoder
WRITEME
......@@ -59,6 +59,8 @@ class QuadraticDenoisingAA(T.RModule):
"""
super(QuadraticDenoisingAA, self).__init__()
self.random = T.RandomStreams()
# MODEL CONFIGURATION
# self.regularize = regularize
self.tie_weights = tie_weights
......@@ -75,11 +77,11 @@ class QuadraticDenoisingAA(T.RModule):
# PARAMETERS
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:
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 not tie_weights:
self.w2 = theano.Member(T.matrix())
......@@ -87,8 +89,8 @@ class QuadraticDenoisingAA(T.RModule):
self.w2 = self.w1.T
else:
self.w2 = theano.Member(_w2)
self.b1 = theano.Member(T.vector()) if _b1 is None else theano.Member(_b1)
self.b2 = theano.Member(T.vector()) if _b2 is None else theano.Member(_b2)
self.b1 = theano.Member(T.vector('b1')) if _b1 is None else theano.Member(_b1)
self.b2 = theano.Member(T.vector('b2')) if _b2 is None else theano.Member(_b2)
# # REGULARIZATION COST
# self.regularization = self.build_regularization()
......@@ -173,6 +175,7 @@ class QuadraticDenoisingAA(T.RModule):
if (input_size is None) ^ (hidden_size is None):
raise ValueError("Must specify input_size and hidden_size or neither.")
super(QuadraticDenoisingAA, self)._instance_initialize(obj, {})
obj.random.initialize()
if seed is not None:
R = N.random.RandomState(seed)
else:
......@@ -189,7 +192,7 @@ class QuadraticDenoisingAA(T.RModule):
obj.qfilters = [R.uniform(size = sz, low = -inf, high = inf) * qfilter_relscale \
for qf in self.qfilters]
if seed is not None:
obj.seed(seed, recursive=True)
obj.random.seed(seed)
obj.lr = lr
......
__docformat__ = "restructuredtext en"
import sys
import unittest
import numpy
from theano.tensor.randomstreams import RandomStreams, raw_random
from theano.compile import Module, Method, Member
from theano import tensor
from theano import compile, gof
class T_RandomStreams(unittest.TestCase):
def test_basics(self):
m = Module()
m.random = RandomStreams(234)
m.fn = Method([], m.random.uniform((2,2)))
m.gn = Method([], m.random.normal((2,2)))
made = m.make()
made.random.initialize()
fn_val0 = made.fn()
fn_val1 = made.fn()
gn_val0 = made.gn()
rng_seed = numpy.random.RandomState(234).randint(2**30)
rng = numpy.random.RandomState(int(rng_seed)) #int() is for 32bit
#print fn_val0
numpy_val0 = rng.uniform(size=(2,2))
numpy_val1 = rng.uniform(size=(2,2))
#print numpy_val0
assert numpy.all(fn_val0 == numpy_val0)
assert numpy.all(fn_val1 == numpy_val1)
def test_seed_in_initialize(self):
m = Module()
m.random = RandomStreams(234)
m.fn = Method([], m.random.uniform((2,2)))
made = m.make()
made.random.initialize(seed=888)
fn_val0 = made.fn()
fn_val1 = made.fn()
rng_seed = numpy.random.RandomState(888).randint(2**30)
rng = numpy.random.RandomState(int(rng_seed)) #int() is for 32bit
#print fn_val0
numpy_val0 = rng.uniform(size=(2,2))
numpy_val1 = rng.uniform(size=(2,2))
#print numpy_val0
assert numpy.all(fn_val0 == numpy_val0)
assert numpy.all(fn_val1 == numpy_val1)
def test_seed_fn(self):
m = Module()
m.random = RandomStreams(234)
m.fn = Method([], m.random.uniform((2,2)))
made = m.make()
made.random.initialize(seed=789)
made.random.seed(888)
fn_val0 = made.fn()
fn_val1 = made.fn()
rng_seed = numpy.random.RandomState(888).randint(2**30)
rng = numpy.random.RandomState(int(rng_seed)) #int() is for 32bit
#print fn_val0
numpy_val0 = rng.uniform(size=(2,2))
numpy_val1 = rng.uniform(size=(2,2))
#print numpy_val0
assert numpy.all(fn_val0 == numpy_val0)
assert numpy.all(fn_val1 == numpy_val1)
def test_getitem(self):
m = Module()
m.random = RandomStreams(234)
out = m.random.uniform((2,2))
m.fn = Method([], out)
made = m.make()
made.random.initialize(seed=789)
made.random.seed(888)
rng = numpy.random.RandomState()
rng.set_state(made.random[out.rng].get_state())
fn_val0 = made.fn()
fn_val1 = made.fn()
numpy_val0 = rng.uniform(size=(2,2))
numpy_val1 = rng.uniform(size=(2,2))
assert numpy.all(fn_val0 == numpy_val0)
assert numpy.all(fn_val1 == numpy_val1)
def test_setitem(self):
m = Module()
m.random = RandomStreams(234)
out = m.random.uniform((2,2))
m.fn = Method([], out)
made = m.make()
made.random.initialize(seed=789)
made.random.seed(888)
rng = numpy.random.RandomState(823874)
made.random[out.rng] = numpy.random.RandomState(823874)
fn_val0 = made.fn()
fn_val1 = made.fn()
numpy_val0 = rng.uniform(size=(2,2))
numpy_val1 = rng.uniform(size=(2,2))
assert numpy.all(fn_val0 == numpy_val0)
assert numpy.all(fn_val1 == numpy_val1)
if __name__ == '__main__':
from theano.tests import main
main("test_randomstreams")
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论