提交 ab56ecc1 authored 作者: Olivier Delalleau's avatar Olivier Delalleau

Merge pull request #549 from lamblin/pep8

Pep8
from theano import gof from theano import gof
from theano import gradient as G from theano import gradient as G
from function_module import orig_function from function_module import orig_function
...@@ -33,16 +32,19 @@ class OpFromGraph(gof.Op): ...@@ -33,16 +32,19 @@ class OpFromGraph(gof.Op):
e2 = op(x, y, z) + op(z, y, x) e2 = op(x, y, z) + op(z, y, x)
fn = function([x, y, z], [e2]) fn = function([x, y, z], [e2])
""" """
def __init__(self, inputs, outputs, grad_depth = 1, **kwargs): def __init__(self, inputs, outputs, grad_depth=1, **kwargs):
if not isinstance(outputs, list): if not isinstance(outputs, list):
raise TypeError('outputs must be list', outputs) raise TypeError('outputs must be list', outputs)
for i in inputs + outputs: for i in inputs + outputs:
if not isinstance(i, gof.Variable): if not isinstance(i, gof.Variable):
raise TypeError('inputs and outputs must be Variable instances', i) raise TypeError(
'inputs and outputs must be Variable instances', i)
if 'updates' in kwargs: if 'updates' in kwargs:
raise TypeError('updates are not allowed in kwargs') raise TypeError('updates are not allowed in kwargs')
# TODO: the graph may have implicit inputs like Value and SharedVariable instances.
# TODO: the graph may have implicit inputs like Value and
# SharedVariable instances.
# what impact to they have on the validity of this Op? # what impact to they have on the validity of this Op?
self.fn = orig_function(inputs, outputs, **kwargs) self.fn = orig_function(inputs, outputs, **kwargs)
self.inputs = inputs self.inputs = inputs
...@@ -52,7 +54,8 @@ class OpFromGraph(gof.Op): ...@@ -52,7 +54,8 @@ class OpFromGraph(gof.Op):
if grad_depth > 0: if grad_depth > 0:
output_grads = [t() for t in self.output_types] output_grads = [t() for t in self.output_types]
gd = G.grad_sources_inputs(zip(self.outputs, output_grads), self.inputs) gd = G.grad_sources_inputs(zip(self.outputs, output_grads),
self.inputs)
gs = map(gd.get, self.inputs) gs = map(gd.get, self.inputs)
self.grad_ops = [] self.grad_ops = []
for g in gs: for g in gs:
...@@ -63,8 +66,9 @@ class OpFromGraph(gof.Op): ...@@ -63,8 +66,9 @@ class OpFromGraph(gof.Op):
# to compute the gradient, so we ignore them. # to compute the gradient, so we ignore them.
self.grad_ops.append(OpFromGraph(inputs + output_grads, self.grad_ops.append(OpFromGraph(inputs + output_grads,
[g], [g],
grad_depth = grad_depth - 1, grad_depth=grad_depth - 1,
on_unused_input='ignore')) on_unused_input='ignore'))
def __eq__(self, other): def __eq__(self, other):
#TODO: recognize a copy #TODO: recognize a copy
return self is other return self is other
...@@ -76,7 +80,8 @@ class OpFromGraph(gof.Op): ...@@ -76,7 +80,8 @@ class OpFromGraph(gof.Op):
def make_node(self, *inputs): def make_node(self, *inputs):
for input, type in zip(inputs, self.input_types): for input, type in zip(inputs, self.input_types):
if not type == input.type: if not type == input.type:
raise TypeError("Wrong type, expected %s but got %s" % (type, input.type)) raise TypeError("Wrong type, expected %s but got %s"
% (type, input.type))
return gof.Apply(self, return gof.Apply(self,
inputs, inputs,
[type() for type in self.output_types]) [type() for type in self.output_types])
...@@ -85,8 +90,8 @@ class OpFromGraph(gof.Op): ...@@ -85,8 +90,8 @@ class OpFromGraph(gof.Op):
variables = self.fn(*inputs) variables = self.fn(*inputs)
assert len(variables) == len(outputs) assert len(variables) == len(outputs)
for output, variable in zip(outputs, variables): for output, variable in zip(outputs, variables):
##TODO: when function's output-borrowing semantics are correct, we wont need this ##TODO: when function's output-borrowing semantics are correct,
# copy anymore # we wont need this copy anymore
output[0] = variable.copy() output[0] = variable.copy()
def grad(self, inputs, output_grads): def grad(self, inputs, output_grads):
...@@ -94,5 +99,3 @@ class OpFromGraph(gof.Op): ...@@ -94,5 +99,3 @@ class OpFromGraph(gof.Op):
return [go(*(inputs + output_grads)) for go in self.grad_ops] return [go(*(inputs + output_grads)) for go in self.grad_ops]
else: else:
raise NotImplementedError raise NotImplementedError
import numpy import numpy
import unittest import unittest
import copy
import theano import theano
from theano.tensor import Tensor, TensorType from theano.tensor import Tensor, TensorType
from theano.compile.sharedvalue import * from theano.compile.sharedvalue import *
class Test_SharedVariable(unittest.TestCase): class Test_SharedVariable(unittest.TestCase):
def test_ctors(self): def test_ctors(self):
if 0: #when using an implementation that handles scalars with Scalar type if 0:
# when using an implementation that handles scalars with
# Scalar type
assert shared(7).type == Scalar('int64') assert shared(7).type == Scalar('int64')
assert shared(7.0).type == Scalar('float64') assert shared(7.0).type == Scalar('float64')
assert shared(7, dtype='float64').type == Scalar('float64') assert shared(7, dtype='float64').type == Scalar('float64')
...@@ -24,14 +26,16 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -24,14 +26,16 @@ class Test_SharedVariable(unittest.TestCase):
assert shared(numpy.float32(7)).type == theano.tensor.fscalar assert shared(numpy.float32(7)).type == theano.tensor.fscalar
# test tensor constructor # test tensor constructor
b = shared(numpy.zeros((5,5), dtype='int32')) b = shared(numpy.zeros((5, 5), dtype='int32'))
assert b.type == TensorType('int32', broadcastable=[False,False]) assert b.type == TensorType('int32', broadcastable=[False, False])
b = shared(numpy.random.rand(4,5)) b = shared(numpy.random.rand(4, 5))
assert b.type == TensorType('float64', broadcastable=[False,False]) assert b.type == TensorType('float64', broadcastable=[False, False])
b = shared(numpy.random.rand(5,1,2)) b = shared(numpy.random.rand(5, 1, 2))
assert b.type == TensorType('float64', broadcastable=[False,False,False]) assert b.type == TensorType('float64',
broadcastable=[False, False, False])
assert shared([]).type == generic assert shared([]).type == generic
def badfunc(): def badfunc():
shared(7, bad_kw=False) shared(7, bad_kw=False)
self.assertRaises(TypeError, badfunc) self.assertRaises(TypeError, badfunc)
...@@ -70,7 +74,7 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -70,7 +74,7 @@ class Test_SharedVariable(unittest.TestCase):
SharedVariable( SharedVariable(
name='u', name='u',
type=Tensor(broadcastable=[False], dtype='float64'), type=Tensor(broadcastable=[False], dtype='float64'),
value=[1, 2], #different dtype and not a numpy array value=[1, 2], # different dtype and not a numpy array
strict=False) strict=False)
# here the value is not castable, and we're not strict about it, # here the value is not castable, and we're not strict about it,
...@@ -79,7 +83,7 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -79,7 +83,7 @@ class Test_SharedVariable(unittest.TestCase):
SharedVariable( SharedVariable(
name='u', name='u',
type=Tensor(broadcastable=[False], dtype='float64'), type=Tensor(broadcastable=[False], dtype='float64'),
value=dict(), #not an array by any stretch value=dict(), # not an array by any stretch
strict=False) strict=False)
assert 0 assert 0
except TypeError: except TypeError:
...@@ -96,10 +100,10 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -96,10 +100,10 @@ class Test_SharedVariable(unittest.TestCase):
strict=False) strict=False)
# check that assignments to value are cast properly # check that assignments to value are cast properly
u.set_value([3,4]) u.set_value([3, 4])
assert type(u.get_value()) is numpy.ndarray assert type(u.get_value()) is numpy.ndarray
assert str(u.get_value(borrow=True).dtype) == 'float64' assert str(u.get_value(borrow=True).dtype) == 'float64'
assert numpy.all(u.get_value() == [3,4]) assert numpy.all(u.get_value() == [3, 4])
# check that assignments of nonsense fail # check that assignments of nonsense fail
try: try:
...@@ -109,7 +113,7 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -109,7 +113,7 @@ class Test_SharedVariable(unittest.TestCase):
pass pass
# check that an assignment of a perfect value results in no copying # check that an assignment of a perfect value results in no copying
uval = theano._asarray([5,6,7,8], dtype='float64') uval = theano._asarray([5, 6, 7, 8], dtype='float64')
u.set_value(uval, borrow=True) u.set_value(uval, borrow=True)
assert u.get_value(borrow=True) is uval assert u.get_value(borrow=True) is uval
...@@ -149,10 +153,8 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -149,10 +153,8 @@ class Test_SharedVariable(unittest.TestCase):
assert b.type == theano.tensor.dscalar assert b.type == theano.tensor.dscalar
self.assertRaises(TypeError, f, b, 8) self.assertRaises(TypeError, f, b, 8)
c = shared(numpy.zeros((5,5), dtype='float32')) b = shared(numpy.zeros((5, 5), dtype='float32'))
self.assertRaises(TypeError, f, b, numpy.random.rand(5,5)) self.assertRaises(TypeError, f, b, numpy.random.rand(5, 5))
def test_tensor_strict(self): def test_tensor_strict(self):
def f(var, val): def f(var, val):
...@@ -192,19 +194,16 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -192,19 +194,16 @@ class Test_SharedVariable(unittest.TestCase):
# assert b.type == theano.tensor.dvector # assert b.type == theano.tensor.dvector
# self.assertRaises(TypeError, f, b, 8) # self.assertRaises(TypeError, f, b, 8)
c = shared(numpy.zeros((5,5), dtype='float32')) b = shared(numpy.zeros((5, 5), dtype='float32'))
self.assertRaises(TypeError, f, b, numpy.random.rand(5,5)) self.assertRaises(TypeError, f, b, numpy.random.rand(5, 5))
def test_scalar_floatX(self): def test_scalar_floatX(self):
# # the test should assure that floatX is not used in the shared
# the test should assure that floatX is not used in the shared constructor for scalars # constructor for scalars Shared values can change, and since we don't
# Shared values can change, and since we don't know the range they might take, we # know the range they might take, we should keep the same
# should keep the same bit width / precision as the original value used to create the # bit width / precision as the original value used to create the
# shared variable. # shared variable.
#
# Since downcasting of a value now raises an Exception, # Since downcasting of a value now raises an Exception,
...@@ -213,48 +212,46 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -213,48 +212,46 @@ class Test_SharedVariable(unittest.TestCase):
b = shared(numpy.int64(7), allow_downcast=True) b = shared(numpy.int64(7), allow_downcast=True)
assert b.type == theano.tensor.lscalar assert b.type == theano.tensor.lscalar
f(b,8.23) f(b, 8.23)
assert b.get_value()==8 assert b.get_value() == 8
b = shared(numpy.int32(7), allow_downcast=True) b = shared(numpy.int32(7), allow_downcast=True)
assert b.type == theano.tensor.iscalar assert b.type == theano.tensor.iscalar
f(b,8.23) f(b, 8.23)
assert b.get_value()==8 assert b.get_value() == 8
b = shared(numpy.int16(7), allow_downcast=True) b = shared(numpy.int16(7), allow_downcast=True)
assert b.type == theano.tensor.wscalar assert b.type == theano.tensor.wscalar
f(b,8.23) f(b, 8.23)
assert b.get_value()==8 assert b.get_value() == 8
b = shared(numpy.int8(7), allow_downcast=True) b = shared(numpy.int8(7), allow_downcast=True)
assert b.type == theano.tensor.bscalar assert b.type == theano.tensor.bscalar
f(b,8.23) f(b, 8.23)
assert b.get_value()==8 assert b.get_value() == 8
b = shared(numpy.float64(7.234), allow_downcast=True) b = shared(numpy.float64(7.234), allow_downcast=True)
assert b.type == theano.tensor.dscalar assert b.type == theano.tensor.dscalar
f(b,8) f(b, 8)
assert b.get_value()==8 assert b.get_value() == 8
b = shared(numpy.float32(7.234), allow_downcast=True) b = shared(numpy.float32(7.234), allow_downcast=True)
assert b.type == theano.tensor.fscalar assert b.type == theano.tensor.fscalar
f(b,8) f(b, 8)
assert b.get_value()==8 assert b.get_value() == 8
b = shared(numpy.float(7.234), allow_downcast=True) b = shared(numpy.float(7.234), allow_downcast=True)
assert b.type == theano.tensor.dscalar assert b.type == theano.tensor.dscalar
f(b,8) f(b, 8)
assert b.get_value()==8 assert b.get_value() == 8
b = shared(7.234, allow_downcast=True) b = shared(7.234, allow_downcast=True)
assert b.type == theano.tensor.dscalar assert b.type == theano.tensor.dscalar
f(b,8) f(b, 8)
assert b.get_value()==8 assert b.get_value() == 8
c = shared(numpy.zeros((5,5), dtype='float32'), allow_downcast=True)
self.assertRaises(TypeError, f, b, numpy.random.rand(5,5))
b = shared(numpy.zeros((5, 5), dtype='float32'), allow_downcast=True)
self.assertRaises(TypeError, f, b, numpy.random.rand(5, 5))
def test_tensor_floatX(self): def test_tensor_floatX(self):
def f(var, val): def f(var, val):
...@@ -262,32 +259,32 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -262,32 +259,32 @@ class Test_SharedVariable(unittest.TestCase):
b = shared(numpy.int64([7]), allow_downcast=True) b = shared(numpy.int64([7]), allow_downcast=True)
assert b.type == theano.tensor.lvector assert b.type == theano.tensor.lvector
f(b,[8.23]) f(b, [8.23])
assert b.get_value() == 8 assert b.get_value() == 8
b = shared(numpy.int32([7]), allow_downcast=True) b = shared(numpy.int32([7]), allow_downcast=True)
assert b.type == theano.tensor.ivector assert b.type == theano.tensor.ivector
f(b,[8.23]) f(b, [8.23])
assert b.get_value() == 8 assert b.get_value() == 8
b = shared(numpy.int16([7]), allow_downcast=True) b = shared(numpy.int16([7]), allow_downcast=True)
assert b.type == theano.tensor.wvector assert b.type == theano.tensor.wvector
f(b,[8.23]) f(b, [8.23])
assert b.get_value() == 8 assert b.get_value() == 8
b = shared(numpy.int8([7]), allow_downcast=True) b = shared(numpy.int8([7]), allow_downcast=True)
assert b.type == theano.tensor.bvector assert b.type == theano.tensor.bvector
f(b,[8.23]) f(b, [8.23])
assert b.get_value() == 8 assert b.get_value() == 8
b = shared(numpy.float64([7.234]), allow_downcast=True) b = shared(numpy.float64([7.234]), allow_downcast=True)
assert b.type == theano.tensor.dvector assert b.type == theano.tensor.dvector
f(b,[8]) f(b, [8])
assert b.get_value() == 8 assert b.get_value() == 8
b = shared(numpy.float32([7.234]), allow_downcast=True) b = shared(numpy.float32([7.234]), allow_downcast=True)
assert b.type == theano.tensor.fvector assert b.type == theano.tensor.fvector
f(b,[8]) f(b, [8])
assert b.get_value() == 8 assert b.get_value() == 8
#numpy.float([7.234]) don't work #numpy.float([7.234]) don't work
...@@ -300,10 +297,12 @@ class Test_SharedVariable(unittest.TestCase): ...@@ -300,10 +297,12 @@ class Test_SharedVariable(unittest.TestCase):
# assert b.type == theano.tensor.dvector # assert b.type == theano.tensor.dvector
# f(b,[8]) # f(b,[8])
b = shared(numpy.asarray([7.234],dtype=theano.config.floatX), allow_downcast=True) b = shared(numpy.asarray([7.234], dtype=theano.config.floatX),
allow_downcast=True)
assert b.dtype == theano.config.floatX assert b.dtype == theano.config.floatX
f(b,[8]) f(b, [8])
assert b.get_value() == 8 assert b.get_value() == 8
c = shared(numpy.zeros((5,5), dtype='float32'), allow_downcast=True) b = shared(numpy.zeros((5, 5), dtype='float32'),
self.assertRaises(TypeError, f, b, numpy.random.rand(5,5)) allow_downcast=True)
self.assertRaises(TypeError, f, b, numpy.random.rand(5, 5))
差异被折叠。
""" """
Helper functions to make gof backwards compatible (tested on python 2.4 and 2.5) Helper functions to make gof backwards compatible
(tested on python 2.4 and 2.5)
""" """
import collections import collections
import sys import sys
if sys.version_info[:2] < (2,5): if sys.version_info[:2] < (2, 5):
def all(iterable): def all(iterable):
for element in iterable: for element in iterable:
...@@ -55,16 +57,19 @@ if sys.version_info[:2] < (2,5): ...@@ -55,16 +57,19 @@ if sys.version_info[:2] < (2,5):
raise TypeError('first argument must be callable') raise TypeError('first argument must be callable')
dict.__init__(self, *a, **kw) dict.__init__(self, *a, **kw)
self.default_factory = default_factory self.default_factory = default_factory
def __getitem__(self, key): def __getitem__(self, key):
try: try:
return dict.__getitem__(self, key) return dict.__getitem__(self, key)
except KeyError: except KeyError:
return self.__missing__(key) return self.__missing__(key)
def __missing__(self, key): def __missing__(self, key):
if self.default_factory is None: if self.default_factory is None:
raise KeyError(key) raise KeyError(key)
self[key] = value = self.default_factory() self[key] = value = self.default_factory()
return value return value
def __reduce__(self): def __reduce__(self):
if self.default_factory is None: if self.default_factory is None:
args = tuple() args = tuple()
...@@ -72,14 +77,18 @@ if sys.version_info[:2] < (2,5): ...@@ -72,14 +77,18 @@ if sys.version_info[:2] < (2,5):
args = self.default_factory, args = self.default_factory,
# consider replacing items() with iteritems() # consider replacing items() with iteritems()
return type(self), args, None, None, self.items() return type(self), args, None, None, self.items()
def copy(self): def copy(self):
return self.__copy__() return self.__copy__()
def __copy__(self): def __copy__(self):
return type(self)(self.default_factory, self) return type(self)(self.default_factory, self)
def __deepcopy__(self, memo): def __deepcopy__(self, memo):
import copy import copy
return type(self)(self.default_factory, return type(self)(self.default_factory,
copy.deepcopy(self.items())) copy.deepcopy(self.items()))
def __repr__(self): def __repr__(self):
return 'defaultdict(%s, %s)' % (self.default_factory, return 'defaultdict(%s, %s)' % (self.default_factory,
dict.__repr__(self)) dict.__repr__(self))
...@@ -90,14 +99,15 @@ else: ...@@ -90,14 +99,15 @@ else:
import __builtin__ import __builtin__
all = __builtin__.all all = __builtin__.all
any = __builtin__.any any = __builtin__.any
import functools, collections import collections
import functools
partial = functools.partial partial = functools.partial
defaultdict = collections.defaultdict defaultdict = collections.defaultdict
deque = collections.deque deque = collections.deque
__all__ = ['all', 'any'] __all__ = ['all', 'any']
if sys.version_info[:2] < (2,6): if sys.version_info[:2] < (2, 6):
# Borrowed from Python docs # Borrowed from Python docs
def combinations(iterable, r): def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD # combinations('ABCD', 2) --> AB AC AD BC BD CD
...@@ -115,18 +125,17 @@ if sys.version_info[:2] < (2,6): ...@@ -115,18 +125,17 @@ if sys.version_info[:2] < (2,6):
else: else:
return return
indices[i] += 1 indices[i] += 1
for j in range(i+1, r): for j in range(i + 1, r):
indices[j] = indices[j-1] + 1 indices[j] = indices[j - 1] + 1
yield tuple(pool[i] for i in indices) yield tuple(pool[i] for i in indices)
def product(*args, **kwds): def product(*args, **kwds):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
pools = map(tuple, args) * kwds.get('repeat', 1) pools = map(tuple, args) * kwds.get('repeat', 1)
result = [[]] result = [[]]
for pool in pools: for pool in pools:
result = [x+[y] for x in result for y in pool] result = [x + [y] for x in result for y in pool]
for prod in result: for prod in result:
yield tuple(prod) yield tuple(prod)
......
...@@ -21,7 +21,6 @@ from theano.tensor import opt, get_constant_value ...@@ -21,7 +21,6 @@ from theano.tensor import opt, get_constant_value
from theano import gof from theano import gof
from theano.gof.python25 import maxsize from theano.gof.python25 import maxsize
from theano.compile import optdb from theano.compile import optdb
from theano import config
from theano.compile.function_module import deep_copy_op from theano.compile.function_module import deep_copy_op
import scan_op import scan_op
...@@ -97,7 +96,6 @@ def remove_constants_and_unused_inputs_scan(node): ...@@ -97,7 +96,6 @@ def remove_constants_and_unused_inputs_scan(node):
try: try:
# This works if input is a constant that has all entries # This works if input is a constant that has all entries
# equal # equal
val = tensor.get_constant_value(node.inputs[idx + 1])
givens[op_ins[idx]] = node.inputs[idx + 1].clone()[0] givens[op_ins[idx]] = node.inputs[idx + 1].clone()[0]
except TypeError: except TypeError:
pass pass
...@@ -729,7 +727,6 @@ class ScanSaveMem(gof.Optimizer): ...@@ -729,7 +727,6 @@ class ScanSaveMem(gof.Optimizer):
nw_slice = (fslice,) + tuple(old_slices[1:]) nw_slice = (fslice,) + tuple(old_slices[1:])
nw_pos = inv_compress_map[idx] nw_pos = inv_compress_map[idx]
nw_out = new_outs[nw_pos]
subtens = tensor.basic.Subtensor(nw_slice) subtens = tensor.basic.Subtensor(nw_slice)
# slice inputs # slice inputs
...@@ -748,7 +745,6 @@ class ScanSaveMem(gof.Optimizer): ...@@ -748,7 +745,6 @@ class ScanSaveMem(gof.Optimizer):
for pos, old_outs in old_outputs: for pos, old_outs in old_outputs:
if len(old_outs) > 0: if len(old_outs) > 0:
nw_pos = compress_map[pos] nw_pos = compress_map[pos]
nw_out = new_outs[nw_pos]
for k, old in enumerate(old_outs): for k, old in enumerate(old_outs):
# Get the correct slice # Get the correct slice
cnf_slice, old_slices = slices[pos][k] cnf_slice, old_slices = slices[pos][k]
...@@ -1066,7 +1062,6 @@ def scan_merge_inouts(node): ...@@ -1066,7 +1062,6 @@ def scan_merge_inouts(node):
else: else:
a_inner_outs = a.inner_outputs a_inner_outs = a.inner_outputs
inner_outputs = scan_utils.clone(a_inner_outs, replace=inp_equiv) inner_outputs = scan_utils.clone(a_inner_outs, replace=inp_equiv)
orig_outputs = a.outer_outputs
op = scan_op.Scan(inner_inputs, inner_outputs, info) op = scan_op.Scan(inner_inputs, inner_outputs, info)
outputs = op(*outer_inputs) outputs = op(*outer_inputs)
......
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论