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

Merge pull request #549 from lamblin/pep8

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