提交 bd11e130 authored 作者: Frédéric Bastien's avatar Frédéric Bastien

Merge pull request #3074 from harlouci/flake8_v2

flake8
差异被折叠。
...@@ -266,7 +266,7 @@ SOMEPATH/Canopy_64bit/User/lib/python2.7/site-packages/numpy/distutils/system_in ...@@ -266,7 +266,7 @@ SOMEPATH/Canopy_64bit/User/lib/python2.7/site-packages/numpy/distutils/system_in
# Using "conda install mkl" will install both, as well as # Using "conda install mkl" will install both, as well as
# optimized versions of numpy and scipy. # optimized versions of numpy and scipy.
try: try:
import mkl import mkl #noqa
except ImportError as e: except ImportError as e:
_logger.info('Conda mkl is not available: %s', e) _logger.info('Conda mkl is not available: %s', e)
else: else:
...@@ -1599,11 +1599,11 @@ class GemmOptimizer(Optimizer): ...@@ -1599,11 +1599,11 @@ class GemmOptimizer(Optimizer):
) )
did_something = True did_something = True
nb_replacement += 1 nb_replacement += 1
except InconsistencyError as e: except InconsistencyError:
# TODO: retry other applications of gemm (see comment # TODO: retry other applications of gemm (see comment
# in _gemm_from_node) # in _gemm_from_node)
nb_inconsistency_replace += 1 nb_inconsistency_replace += 1
except ReplacementDidntRemovedError as e: except ReplacementDidntRemovedError:
nb_replacement_didn_t_remove += 1 nb_replacement_didn_t_remove += 1
self.warned = True self.warned = True
fgraph.remove_feature(u) fgraph.remove_feature(u)
......
差异被折叠。
...@@ -28,7 +28,6 @@ def _scal_inplace(symbol): ...@@ -28,7 +28,6 @@ def _scal_inplace(symbol):
def chk(pstate, r): def chk(pstate, r):
if not r.owner: if not r.owner:
return False return False
op = r.owner.op
return r.owner.op == rval return r.owner.op == rval
pprint.assign(chk, printing.FunctionPrinter(symbolname.replace('_inplace', '='))) pprint.assign(chk, printing.FunctionPrinter(symbolname.replace('_inplace', '=')))
......
差异被折叠。
"""Define random number Type (`RandomStateType`) and Op (`RandomFunction`).""" """Define random number Type (`RandomStateType`) and Op (`RandomFunction`)."""
from __future__ import print_function from __future__ import print_function
__docformat__ = "restructuredtext en"
import sys import sys
from copy import copy from copy import copy
...@@ -15,6 +15,8 @@ from theano import gof ...@@ -15,6 +15,8 @@ from theano import gof
from six import string_types from six import string_types
from theano.compile import optdb from theano.compile import optdb
__docformat__ = "restructuredtext en"
class RandomStateType(gof.Type): class RandomStateType(gof.Type):
"""A Type wrapper for numpy.random.RandomState """A Type wrapper for numpy.random.RandomState
...@@ -85,13 +87,13 @@ class RandomStateType(gof.Type): ...@@ -85,13 +87,13 @@ class RandomStateType(gof.Type):
# Register RandomStateType's C code for ViewOp. # Register RandomStateType's C code for ViewOp.
theano.compile.register_view_op_c_code( theano.compile.register_view_op_c_code(
RandomStateType, RandomStateType,
""" """
Py_XDECREF(%(oname)s); Py_XDECREF(%(oname)s);
%(oname)s = %(iname)s; %(oname)s = %(iname)s;
Py_XINCREF(%(oname)s); Py_XINCREF(%(oname)s);
""", """,
1) 1)
random_state_type = RandomStateType() random_state_type = RandomStateType()
...@@ -135,9 +137,8 @@ class RandomFunction(gof.Op): ...@@ -135,9 +137,8 @@ class RandomFunction(gof.Op):
and self.ndim_added == other.ndim_added and self.ndim_added == other.ndim_added
def __hash__(self): def __hash__(self):
return hash(type(self)) ^ hash(self.fn) \ return (hash(type(self)) ^ hash(self.fn) ^ hash(self.outtype) ^
^ hash(self.outtype) \ hash(self.inplace) ^ hash(self.ndim_added))
^ hash(self.inplace) ^ hash(self.ndim_added)
def __getstate__(self): def __getstate__(self):
return self.state return self.state
...@@ -233,7 +234,6 @@ class RandomFunction(gof.Op): ...@@ -233,7 +234,6 @@ class RandomFunction(gof.Op):
# copy of r if self.inplace is False # copy of r if self.inplace is False
r, shape, args = inputs[0], inputs[1], inputs[2:] r, shape, args = inputs[0], inputs[1], inputs[2:]
assert type(r) == numpy.random.RandomState, (type(r), r) assert type(r) == numpy.random.RandomState, (type(r), r)
r_orig = r
# If shape == [], that means no shape is enforced, and numpy is # If shape == [], that means no shape is enforced, and numpy is
# trusted to draw the appropriate number of samples, numpy uses # trusted to draw the appropriate number of samples, numpy uses
...@@ -245,16 +245,16 @@ class RandomFunction(gof.Op): ...@@ -245,16 +245,16 @@ class RandomFunction(gof.Op):
shape = tuple(shape) shape = tuple(shape)
if (shape is not None and if (shape is not None and
self.outtype.ndim != len(shape) + self.ndim_added): self.outtype.ndim != len(shape) + self.ndim_added):
raise ValueError('Shape mismatch: self.outtype.ndim (%i) !=' raise ValueError('Shape mismatch: self.outtype.ndim (%i) !='
' len(shape) (%i) + self.ndim_added (%i)' ' len(shape) (%i) + self.ndim_added (%i)'
% (self.outtype.ndim, len(shape), self.ndim_added)) % (self.outtype.ndim, len(shape), self.ndim_added))
if not self.inplace: if not self.inplace:
r = copy(r) r = copy(r)
rout[0] = r rout[0] = r
rval = self.fn(r, *(args + [shape])) rval = self.fn(r, *(args + [shape]))
if not isinstance(rval, numpy.ndarray) \ if (not isinstance(rval, numpy.ndarray) or
or str(rval.dtype) != node.outputs[1].type.dtype: str(rval.dtype) != node.outputs[1].type.dtype):
rval = theano._asarray(rval, dtype=node.outputs[1].type.dtype) rval = theano._asarray(rval, dtype=node.outputs[1].type.dtype)
# When shape is None, numpy has a tendency to unexpectedly # When shape is None, numpy has a tendency to unexpectedly
...@@ -288,7 +288,7 @@ class RandomFunction(gof.Op): ...@@ -288,7 +288,7 @@ class RandomFunction(gof.Op):
def grad(self, inputs, outputs): def grad(self, inputs, outputs):
return [theano.gradient.grad_undefined(self, k, inp, return [theano.gradient.grad_undefined(self, k, inp,
'No gradient defined through raw random numbers op') 'No gradient defined through raw random numbers op')
for k, inp in enumerate(inputs)] for k, inp in enumerate(inputs)]
def R_op(self, inputs, eval_points): def R_op(self, inputs, eval_points):
...@@ -325,8 +325,8 @@ def _infer_ndim_bcast(ndim, shape, *args): ...@@ -325,8 +325,8 @@ def _infer_ndim_bcast(ndim, shape, *args):
else: else:
if shape_ndim != ndim: if shape_ndim != ndim:
raise ValueError('ndim should be equal to len(shape), but\n', raise ValueError('ndim should be equal to len(shape), but\n',
'ndim = %s, len(shape) = %s, shape = %s' 'ndim = %s, len(shape) = %s, shape = %s'
% (ndim, shape_ndim, shape)) % (ndim, shape_ndim, shape))
bcast = [] bcast = []
pre_v_shape = [] pre_v_shape = []
...@@ -353,7 +353,8 @@ def _infer_ndim_bcast(ndim, shape, *args): ...@@ -353,7 +353,8 @@ def _infer_ndim_bcast(ndim, shape, *args):
break break
else: else:
if n_a_i == 0: if n_a_i == 0:
raise ValueError(('Auto-shape of -1 must overlap' raise ValueError((
'Auto-shape of -1 must overlap'
'with the shape of one of the broadcastable' 'with the shape of one of the broadcastable'
'inputs')) 'inputs'))
else: else:
...@@ -373,7 +374,7 @@ def _infer_ndim_bcast(ndim, shape, *args): ...@@ -373,7 +374,7 @@ def _infer_ndim_bcast(ndim, shape, *args):
# but we need to know ndim # but we need to know ndim
if not args: if not args:
raise TypeError(('_infer_ndim_bcast cannot infer shape without' raise TypeError(('_infer_ndim_bcast cannot infer shape without'
' either shape or args')) ' either shape or args'))
template = reduce(lambda a, b: a + b, args) template = reduce(lambda a, b: a + b, args)
v_shape = template.shape v_shape = template.shape
bcast = template.broadcastable bcast = template.broadcastable
...@@ -463,7 +464,7 @@ def uniform(random_state, size=None, low=0.0, high=1.0, ndim=None, dtype=None): ...@@ -463,7 +464,7 @@ def uniform(random_state, size=None, low=0.0, high=1.0, ndim=None, dtype=None):
dtype = tensor.scal.upcast(theano.config.floatX, low.dtype, high.dtype) dtype = tensor.scal.upcast(theano.config.floatX, low.dtype, high.dtype)
ndim, size, bcast = _infer_ndim_bcast(ndim, size, low, high) ndim, size, bcast = _infer_ndim_bcast(ndim, size, low, high)
op = RandomFunction('uniform', op = RandomFunction('uniform',
tensor.TensorType(dtype=dtype, broadcastable=bcast)) tensor.TensorType(dtype=dtype, broadcastable=bcast))
return op(random_state, size, low, high) return op(random_state, size, low, high)
...@@ -487,7 +488,7 @@ def normal(random_state, size=None, avg=0.0, std=1.0, ndim=None, dtype=None): ...@@ -487,7 +488,7 @@ def normal(random_state, size=None, avg=0.0, std=1.0, ndim=None, dtype=None):
dtype = tensor.scal.upcast(theano.config.floatX, avg.dtype, std.dtype) dtype = tensor.scal.upcast(theano.config.floatX, avg.dtype, std.dtype)
ndim, size, bcast = _infer_ndim_bcast(ndim, size, avg, std) ndim, size, bcast = _infer_ndim_bcast(ndim, size, avg, std)
op = RandomFunction('normal', op = RandomFunction('normal',
tensor.TensorType(dtype=dtype, broadcastable=bcast)) tensor.TensorType(dtype=dtype, broadcastable=bcast))
return op(random_state, size, avg, std) return op(random_state, size, avg, std)
...@@ -517,7 +518,8 @@ def binomial(random_state, size=None, n=1, p=0.5, ndim=None, ...@@ -517,7 +518,8 @@ def binomial(random_state, size=None, n=1, p=0.5, ndim=None,
# p=numpy.asarray([.1, .2, .3], dtype='float64')) # p=numpy.asarray([.1, .2, .3], dtype='float64'))
n = tensor.cast(n, 'int32') n = tensor.cast(n, 'int32')
op = RandomFunction('binomial', op = RandomFunction('binomial',
tensor.TensorType(dtype=dtype, broadcastable=(False,) * ndim)) tensor.TensorType(dtype=dtype,
broadcastable=(False,) * ndim))
return op(random_state, size, n, p) return op(random_state, size, n, p)
...@@ -583,7 +585,7 @@ def random_integers(random_state, size=None, low=0, high=1, ndim=None, ...@@ -583,7 +585,7 @@ def random_integers(random_state, size=None, low=0, high=1, ndim=None,
high = tensor.as_tensor_variable(high) high = tensor.as_tensor_variable(high)
ndim, size, bcast = _infer_ndim_bcast(ndim, size, low, high) ndim, size, bcast = _infer_ndim_bcast(ndim, size, low, high)
op = RandomFunction(random_integers_helper, op = RandomFunction(random_integers_helper,
tensor.TensorType(dtype=dtype, broadcastable=bcast)) tensor.TensorType(dtype=dtype, broadcastable=bcast))
return op(random_state, size, low, high) return op(random_state, size, low, high)
...@@ -719,8 +721,9 @@ def permutation(random_state, size=None, n=1, ndim=None, dtype='int64'): ...@@ -719,8 +721,9 @@ def permutation(random_state, size=None, n=1, ndim=None, dtype='int64'):
ndim, size, bcast = _infer_ndim_bcast(ndim, size) ndim, size, bcast = _infer_ndim_bcast(ndim, size)
# print "NDIM", ndim, size # print "NDIM", ndim, size
op = RandomFunction(permutation_helper, op = RandomFunction(permutation_helper,
tensor.TensorType(dtype=dtype, broadcastable=bcast + (False,)), tensor.TensorType(dtype=dtype,
ndim_added=1) broadcastable=bcast + (False,)),
ndim_added=1)
return op(random_state, size, n) return op(random_state, size, n)
...@@ -738,14 +741,11 @@ def multinomial_helper(random_state, n, pvals, size): ...@@ -738,14 +741,11 @@ def multinomial_helper(random_state, n, pvals, size):
ndim = len(size) ndim = len(size)
else: else:
ndim = max(n.ndim, pvals.ndim - 1) ndim = max(n.ndim, pvals.ndim - 1)
out_ndim = ndim + 1
# broadcast n to ndim dimensions and pvals to ndim+1 # broadcast n to ndim dimensions and pvals to ndim+1
if n.ndim > ndim: if n.ndim > ndim:
raise ValueError( raise ValueError('n.ndim (%i) should not be larger than len(size) (%i)'
'n.ndim (%i) should not be larger than len(size) (%i)' % (n.ndim, ndim), n, size)
% (n.ndim, ndim),
n, size)
if n.ndim < ndim: if n.ndim < ndim:
n = n.reshape((1,) * (ndim - n.ndim) + n.shape) n = n.reshape((1,) * (ndim - n.ndim) + n.shape)
...@@ -788,7 +788,7 @@ def multinomial_helper(random_state, n, pvals, size): ...@@ -788,7 +788,7 @@ def multinomial_helper(random_state, n, pvals, size):
# because mtrand.pyx has a ValueError that will trigger if # because mtrand.pyx has a ValueError that will trigger if
# sum(pvals[:-1]) > 1.0 # sum(pvals[:-1]) > 1.0
pvi = pvi * (1.0 - 5e-5) pvi = pvi * (1.0 - 5e-5)
#pvi = pvi * .9 # pvi = pvi * .9
pisum = numpy.sum(pvi) pisum = numpy.sum(pvi)
elif pvi[-1] < 5e-5: # will this even work? elif pvi[-1] < 5e-5: # will this even work?
pvi = pvi * (1.0 - 5e-5) pvi = pvi * (1.0 - 5e-5)
...@@ -859,8 +859,9 @@ def multinomial(random_state, size=None, n=1, pvals=[0.5, 0.5], ...@@ -859,8 +859,9 @@ def multinomial(random_state, size=None, n=1, pvals=[0.5, 0.5],
ndim, size, bcast = _infer_ndim_bcast(ndim, size, n, tmp) ndim, size, bcast = _infer_ndim_bcast(ndim, size, n, tmp)
bcast = bcast + (pvals.type.broadcastable[-1],) bcast = bcast + (pvals.type.broadcastable[-1],)
op = RandomFunction(multinomial_helper, op = RandomFunction(multinomial_helper,
tensor.TensorType(dtype=dtype, broadcastable=bcast), tensor.TensorType(dtype=dtype,
ndim_added=1) broadcastable=bcast),
ndim_added=1)
return op(random_state, size, n, pvals) return op(random_state, size, n, pvals)
......
"""Define RandomStreams, providing random number variables for Theano """Define RandomStreams, providing random number variables for Theano
graphs. graphs.
""" """
__docformat__ = "restructuredtext en"
import copy import copy
import numpy import numpy
from theano.compile.sharedvalue import (SharedVariable, shared_constructor, from theano.compile.sharedvalue import (SharedVariable, shared_constructor,
shared) shared)
from theano.tensor import raw_random from theano.tensor import raw_random
__docformat__ = "restructuredtext en"
class RandomStateSharedVariable(SharedVariable): class RandomStateSharedVariable(SharedVariable):
pass pass
...@@ -77,7 +79,7 @@ class RandomStreams(raw_random.RandomStreamsBase): ...@@ -77,7 +79,7 @@ class RandomStreams(raw_random.RandomStreamsBase):
for old_r, new_r in self.state_updates: for old_r, new_r in self.state_updates:
old_r_seed = seedgen.randint(2 ** 30) old_r_seed = seedgen.randint(2 ** 30)
old_r.set_value(numpy.random.RandomState(int(old_r_seed)), old_r.set_value(numpy.random.RandomState(int(old_r_seed)),
borrow=True) borrow=True)
def __getitem__(self, item): def __getitem__(self, item):
"""Retrieve the numpy RandomState instance associated with a """Retrieve the numpy RandomState instance associated with a
......
...@@ -41,10 +41,10 @@ def tensor_constructor(value, name=None, strict=False, allow_downcast=None, ...@@ -41,10 +41,10 @@ def tensor_constructor(value, name=None, strict=False, allow_downcast=None,
broadcastable = (False,) * len(value.shape) broadcastable = (False,) * len(value.shape)
type = TensorType(value.dtype, broadcastable=broadcastable) type = TensorType(value.dtype, broadcastable=broadcastable)
return TensorSharedVariable(type=type, return TensorSharedVariable(type=type,
value=numpy.array(value, copy=(not borrow)), value=numpy.array(value, copy=(not borrow)),
name=name, name=name,
strict=strict, strict=strict,
allow_downcast=allow_downcast) allow_downcast=allow_downcast)
# TensorSharedVariable brings in the tensor operators, is not ideal, but works # TensorSharedVariable brings in the tensor operators, is not ideal, but works
...@@ -85,8 +85,10 @@ def scalar_constructor(value, name=None, strict=False, allow_downcast=None, ...@@ -85,8 +85,10 @@ def scalar_constructor(value, name=None, strict=False, allow_downcast=None,
# Do not pass the dtype to asarray because we want this to fail if # Do not pass the dtype to asarray because we want this to fail if
# strict is True and the types do not match. # strict is True and the types do not match.
rval = ScalarSharedVariable(type=tensor_type, rval = ScalarSharedVariable(type=tensor_type,
value=numpy.array(value, copy=True), value=numpy.array(value, copy=True),
name=name, strict=strict, allow_downcast=allow_downcast) name=name,
strict=strict,
allow_downcast=allow_downcast)
return rval return rval
except Exception: except Exception:
traceback.print_exc() traceback.print_exc()
......
import logging import logging
logger = logging.getLogger(__name__)
import numpy
import warnings import warnings
from six.moves import xrange from six.moves import xrange
from theano.gof import Op, Apply import numpy
from theano.tensor import as_tensor_variable, dot, DimShuffle, Dot
from theano.tensor.blas import Dot22
from theano import tensor
import theano.tensor
from theano.tensor.opt import (register_stabilize,
register_specialize, register_canonicalize)
from theano.gof import local_optimizer
from theano.gof.opt import Optimizer
from theano.gradient import DisconnectedType
try: try:
import scipy.linalg import scipy.linalg
...@@ -24,6 +11,13 @@ except ImportError: ...@@ -24,6 +11,13 @@ except ImportError:
# some ops (e.g. Cholesky, Solve, A_Xinv_b) won't work # some ops (e.g. Cholesky, Solve, A_Xinv_b) won't work
imported_scipy = False imported_scipy = False
from theano import tensor
import theano.tensor
from theano.tensor import as_tensor_variable
from theano.gof import Op, Apply
logger = logging.getLogger(__name__)
MATRIX_STRUCTURES = ( MATRIX_STRUCTURES = (
'general', 'general',
'symmetric', 'symmetric',
...@@ -123,7 +117,6 @@ class CholeskyGrad(Op): ...@@ -123,7 +117,6 @@ class CholeskyGrad(Op):
F[k, k] /= (2 * L[k, k]) F[k, k] /= (2 * L[k, k])
else: else:
F = numpy.triu(dz) F = numpy.triu(dz)
M = N - 1
for k in xrange(N - 1, -1, -1): for k in xrange(N - 1, -1, -1):
for j in xrange(k + 1, N): for j in xrange(k + 1, N):
for i in xrange(j, N): for i in xrange(j, N):
...@@ -182,7 +175,7 @@ class Solve(Op): ...@@ -182,7 +175,7 @@ class Solve(Op):
else: else:
rval = scipy.linalg.solve(A, b) rval = scipy.linalg.solve(A, b)
output_storage[0][0] = rval output_storage[0][0] = rval
# computes shape of x where x = inv(A) * b # computes shape of x where x = inv(A) * b
def infer_shape(self, node, shapes): def infer_shape(self, node, shapes):
Ashape, Bshape = shapes Ashape, Bshape = shapes
......
...@@ -28,7 +28,7 @@ class SortOp(theano.Op): ...@@ -28,7 +28,7 @@ class SortOp(theano.Op):
def make_node(self, input, axis=-1): def make_node(self, input, axis=-1):
input = theano.tensor.as_tensor_variable(input) input = theano.tensor.as_tensor_variable(input)
if (axis is None or if (axis is None or
(isinstance(axis, theano.Constant) and axis.data is None)): (isinstance(axis, theano.Constant) and axis.data is None)):
axis = theano.Constant(theano.gof.generic, None) axis = theano.Constant(theano.gof.generic, None)
# axis=None flattens the array before sorting # axis=None flattens the array before sorting
out_type = tensor(dtype=input.dtype, broadcastable=[False]) out_type = tensor(dtype=input.dtype, broadcastable=[False])
...@@ -45,7 +45,7 @@ class SortOp(theano.Op): ...@@ -45,7 +45,7 @@ class SortOp(theano.Op):
def infer_shape(self, node, inputs_shapes): def infer_shape(self, node, inputs_shapes):
if (isinstance(node.inputs[1], theano.Constant) and if (isinstance(node.inputs[1], theano.Constant) and
node.inputs[1].data is None): node.inputs[1].data is None):
# That means axis = None, # That means axis = None,
# So the array is flattened before being sorted # So the array is flattened before being sorted
return [(mul(*inputs_shapes[0]),)] return [(mul(*inputs_shapes[0]),)]
...@@ -64,16 +64,17 @@ class SortOp(theano.Op): ...@@ -64,16 +64,17 @@ class SortOp(theano.Op):
" matrix (and axis is None or 0) and tensor3") " matrix (and axis is None or 0) and tensor3")
if a.ndim == 1: if a.ndim == 1:
idx = argsort(*inputs, kind=self.kind, order=self.order) idx = argsort(*inputs, kind=self.kind, order=self.order)
# rev_idx = numpy.where(idx[None, :]==numpy.arange(5)[:,None])[1] # rev_idx = numpy.where(idx[None, :]==numpy.arange(5)[:,None])[1]
rev_idx = theano.tensor.eq(idx[None, :], rev_idx = theano.tensor.eq(idx[None, :],
arange(a.shape[0])[:, None]).nonzero()[1] arange(a.shape[0])[:, None]).nonzero()[1]
inp_grad = output_grads[0][rev_idx] inp_grad = output_grads[0][rev_idx]
elif a.ndim == 2: elif a.ndim == 2:
if (axis is None or if (axis is None or
(isinstance(axis, theano.Constant) and axis.data is None)): (isinstance(axis, theano.Constant) and axis.data is None)):
idx = argsort(*inputs, kind=self.kind, order=self.order) idx = argsort(*inputs, kind=self.kind, order=self.order)
rev_idx = theano.tensor.eq(idx[None, :], rev_idx = theano.tensor.eq(
arange(a.shape[0]*a.shape[1])[:, None]).nonzero()[1] idx[None, :],
arange(a.shape[0] * a.shape[1])[:, None]).nonzero()[1]
inp_grad = output_grads[0][rev_idx].reshape(a.shape) inp_grad = output_grads[0][rev_idx].reshape(a.shape)
elif (axis == 0 or elif (axis == 0 or
(isinstance(axis, theano.Constant) and axis.data == 0)): (isinstance(axis, theano.Constant) and axis.data == 0)):
...@@ -85,7 +86,7 @@ class SortOp(theano.Op): ...@@ -85,7 +86,7 @@ class SortOp(theano.Op):
indices = self.__get_argsort_indices(a, axis) indices = self.__get_argsort_indices(a, axis)
inp_grad = output_grads[0][indices[0], indices[1], indices[2]] inp_grad = output_grads[0][indices[0], indices[1], indices[2]]
elif (axis is None or elif (axis is None or
(isinstance(axis, theano.Constant) and axis.data is None)): (isinstance(axis, theano.Constant) and axis.data is None)):
rev_idx = self.__get_argsort_indices(a, axis) rev_idx = self.__get_argsort_indices(a, axis)
inp_grad = output_grads[0][rev_idx].reshape(a.shape) inp_grad = output_grads[0][rev_idx].reshape(a.shape)
axis_grad = theano.gradient.grad_undefined( axis_grad = theano.gradient.grad_undefined(
...@@ -103,13 +104,13 @@ class SortOp(theano.Op): ...@@ -103,13 +104,13 @@ class SortOp(theano.Op):
list of lenght len(a.shape) otherwise list of lenght len(a.shape) otherwise
""" """
# The goal is to get gradient wrt input from gradient # The goal is to get gradient wrt input from gradient
# wrt sort(input, axis) # wrt sort(input, axis)
idx = argsort(a, axis, kind=self.kind, order=self.order) idx = argsort(a, axis, kind=self.kind, order=self.order)
# rev_idx is the reverse of previous argsort operation # rev_idx is the reverse of previous argsort operation
rev_idx = argsort(idx, axis, kind=self.kind, order=self.order) rev_idx = argsort(idx, axis, kind=self.kind, order=self.order)
if (axis is None or if (axis is None or
(isinstance(axis, theano.Constant) and axis.data is None)): (isinstance(axis, theano.Constant) and axis.data is None)):
return rev_idx return rev_idx
indices = [] indices = []
if axis.data >= 0: if axis.data >= 0:
...@@ -120,7 +121,7 @@ class SortOp(theano.Op): ...@@ -120,7 +121,7 @@ class SortOp(theano.Op):
if i == axis_data: if i == axis_data:
indices.append(rev_idx) indices.append(rev_idx)
else: else:
index_shape = [1] * a.ndim index_shape = [1] * a.ndim
index_shape[i] = a.shape[i] index_shape[i] = a.shape[i]
# it's a way to emulate numpy.ogrid[0: a.shape[0], 0: a.shape[1], 0: a.shape[2]] # it's a way to emulate numpy.ogrid[0: a.shape[0], 0: a.shape[1], 0: a.shape[2]]
indices.append(theano.tensor.arange(a.shape[i]).reshape(index_shape)) indices.append(theano.tensor.arange(a.shape[i]).reshape(index_shape))
...@@ -178,28 +179,27 @@ class ArgSortOp(theano.Op): ...@@ -178,28 +179,27 @@ class ArgSortOp(theano.Op):
return hash(type(self)) ^ hash(self.order) ^ hash(self.kind) return hash(type(self)) ^ hash(self.order) ^ hash(self.kind)
def __str__(self): def __str__(self):
return (self.__class__.__name__ return (self.__class__.__name__ +
+ "{%s, %s}" % (self.kind, str(self.order))) "{%s, %s}" % (self.kind, str(self.order)))
def make_node(self, input, axis=-1): def make_node(self, input, axis=-1):
input = theano.tensor.as_tensor_variable(input) input = theano.tensor.as_tensor_variable(input)
if (axis is None or if (axis is None or
(isinstance(axis, theano.Constant) and axis.data is None)): (isinstance(axis, theano.Constant) and axis.data is None)):
axis = theano.Constant(theano.gof.generic, None) axis = theano.Constant(theano.gof.generic, None)
bcast = [False] bcast = [False]
else: else:
axis = theano.tensor.as_tensor_variable(axis) axis = theano.tensor.as_tensor_variable(axis)
bcast = input.type.broadcastable bcast = input.type.broadcastable
return theano.Apply(self, [input, axis], return theano.Apply(self, [input, axis], [theano.tensor.TensorType(
[theano.tensor.TensorType(dtype="int64", broadcastable=bcast)()]) dtype="int64", broadcastable=bcast)()])
def perform(self, node, inputs, output_storage): def perform(self, node, inputs, output_storage):
a = inputs[0] a = inputs[0]
axis = inputs[1] axis = inputs[1]
z = output_storage[0] z = output_storage[0]
z[0] = theano._asarray( z[0] = theano._asarray(np.argsort(a, axis, self.kind, self.order),
np.argsort(a, axis, self.kind, self.order), dtype=node.outputs[0].dtype)
dtype=node.outputs[0].dtype)
def infer_shape(self, node, inputs_shapes): def infer_shape(self, node, inputs_shapes):
if (isinstance(node.inputs[1], theano.Constant) and if (isinstance(node.inputs[1], theano.Constant) and
......
from copy import copy from copy import copy
import os
import sys import sys
from textwrap import dedent from textwrap import dedent
import warnings import warnings
import logging import logging
_logger = logging.getLogger("theano.tensor.subtensor")
import numpy import numpy
from six.moves import xrange from six.moves import xrange
...@@ -32,6 +30,7 @@ if config.cxx: ...@@ -32,6 +30,7 @@ if config.cxx:
except ImportError: except ImportError:
pass pass
_logger = logging.getLogger("theano.tensor.subtensor")
# Do a lazy import of the sparse module # Do a lazy import of the sparse module
sparse_module_ref = None sparse_module_ref = None
...@@ -336,9 +335,9 @@ class Subtensor(Op): ...@@ -336,9 +335,9 @@ class Subtensor(Op):
theano.tensor.wscalar, theano.tensor.bscalar] theano.tensor.wscalar, theano.tensor.bscalar]
invalid_tensor_types = [theano.tensor.fscalar, theano.tensor.dscalar, invalid_tensor_types = [theano.tensor.fscalar, theano.tensor.dscalar,
theano.tensor.cscalar, theano.tensor.zscalar] theano.tensor.cscalar, theano.tensor.zscalar]
if (isinstance(entry, gof.Variable) if (isinstance(entry, gof.Variable) and
and (entry.type in invalid_scal_types (entry.type in invalid_scal_types or
or entry.type in invalid_tensor_types)): entry.type in invalid_tensor_types)):
raise TypeError("Expected an integer") raise TypeError("Expected an integer")
if isinstance(entry, gof.Variable) and entry.type in scal_types: if isinstance(entry, gof.Variable) and entry.type in scal_types:
...@@ -346,13 +345,13 @@ class Subtensor(Op): ...@@ -346,13 +345,13 @@ class Subtensor(Op):
elif isinstance(entry, gof.Type) and entry in scal_types: elif isinstance(entry, gof.Type) and entry in scal_types:
return entry return entry
if (isinstance(entry, gof.Variable) if (isinstance(entry, gof.Variable) and
and entry.type in tensor_types entry.type in tensor_types and
and numpy.all(entry.type.broadcastable)): numpy.all(entry.type.broadcastable)):
return scal.get_scalar_type(entry.type.dtype) return scal.get_scalar_type(entry.type.dtype)
elif (isinstance(entry, gof.Type) elif (isinstance(entry, gof.Type) and
and entry in tensor_types entry in tensor_types and
and numpy.all(entry.broadcastable)): numpy.all(entry.broadcastable)):
return scal.get_scalar_type(entry.dtype) return scal.get_scalar_type(entry.dtype)
elif slice_ok and isinstance(entry, slice): elif slice_ok and isinstance(entry, slice):
a = entry.start a = entry.start
...@@ -425,8 +424,9 @@ class Subtensor(Op): ...@@ -425,8 +424,9 @@ class Subtensor(Op):
conv(val.step)) conv(val.step))
else: else:
try: try:
return get_scalar_constant_value(val, return get_scalar_constant_value(
only_process_constants=only_process_constants) val,
only_process_constants=only_process_constants)
except theano.tensor.NotScalarConstantError: except theano.tensor.NotScalarConstantError:
if allow_partial: if allow_partial:
return val return val
...@@ -477,8 +477,8 @@ class Subtensor(Op): ...@@ -477,8 +477,8 @@ class Subtensor(Op):
% (input.type, expected_type)) % (input.type, expected_type))
# infer the broadcasting pattern # infer the broadcasting pattern
padded = (self.get_constant_idx((None,)+inputs, allow_partial=True) padded = (self.get_constant_idx((None,) + inputs, allow_partial=True) +
+ [slice(None, None, None)] * (x.type.ndim - len(idx_list))) [slice(None, None, None)] * (x.type.ndim - len(idx_list)))
broadcastable = [] broadcastable = []
for i, (p, bc) in enumerate(izip(padded, x.type.broadcastable)): for i, (p, bc) in enumerate(izip(padded, x.type.broadcastable)):
if isinstance(p, slice): if isinstance(p, slice):
...@@ -528,9 +528,9 @@ class Subtensor(Op): ...@@ -528,9 +528,9 @@ class Subtensor(Op):
if isinstance(idx, slice): if isinstance(idx, slice):
# If it is the default (None, None, None) slice, or a variant, # If it is the default (None, None, None) slice, or a variant,
# the shape will be xl # the shape will be xl
if ((idx.start in [None, 0]) if ((idx.start in [None, 0]) and
and (idx.stop in [None, sys.maxsize]) (idx.stop in [None, sys.maxsize]) and
and (idx.step is None or idx.step == 1)): (idx.step is None or idx.step == 1)):
outshp.append(xl) outshp.append(xl)
else: else:
cnf = get_canonical_form_slice(idx, xl)[0] cnf = get_canonical_form_slice(idx, xl)[0]
...@@ -556,8 +556,7 @@ class Subtensor(Op): ...@@ -556,8 +556,7 @@ class Subtensor(Op):
first = x.zeros_like().astype(theano.config.floatX) first = x.zeros_like().astype(theano.config.floatX)
else: else:
first = IncSubtensor(self.idx_list)(x.zeros_like(), gz, *rest) first = IncSubtensor(self.idx_list)(x.zeros_like(), gz, *rest)
return ([first] return ([first] + [DisconnectedType()()] * len(rest))
+ [DisconnectedType()()] * len(rest))
def connection_pattern(self, node): def connection_pattern(self, node):
...@@ -1034,8 +1033,7 @@ def inc_subtensor(x, y, inplace=False, set_instead_of_inc=False, ...@@ -1034,8 +1033,7 @@ def inc_subtensor(x, y, inplace=False, set_instead_of_inc=False,
dim_offset = x.ndim - y.ndim dim_offset = x.ndim - y.ndim
for dim in xrange(y.ndim): for dim in xrange(y.ndim):
if (x.broadcastable[dim + dim_offset] if (x.broadcastable[dim + dim_offset] and not y.broadcastable[dim]):
and not y.broadcastable[dim]):
# It is acceptable to try to increment a subtensor with a # It is acceptable to try to increment a subtensor with a
# broadcastable dim with a tensor that is not broadcastable # broadcastable dim with a tensor that is not broadcastable
# on that dimension. However, its length must then be 1. # on that dimension. However, its length must then be 1.
...@@ -2133,9 +2131,9 @@ class AdvancedIncSubtensor(Op): ...@@ -2133,9 +2131,9 @@ class AdvancedIncSubtensor(Op):
return hash((type(self), self.inplace, self.set_instead_of_inc)) return hash((type(self), self.inplace, self.set_instead_of_inc))
def __eq__(self, other): def __eq__(self, other):
return (type(self) == type(other) return (type(self) == type(other) and
and self.inplace == other.inplace self.inplace == other.inplace and
and self.set_instead_of_inc == other.set_instead_of_inc) self.set_instead_of_inc == other.set_instead_of_inc)
def __str__(self): def __str__(self):
return "%s{%s, %s}" % (self.__class__.__name__, return "%s{%s, %s}" % (self.__class__.__name__,
......
...@@ -79,11 +79,11 @@ def shape_of_variables(fgraph, input_shapes): ...@@ -79,11 +79,11 @@ def shape_of_variables(fgraph, input_shapes):
if not hasattr(fgraph, 'shape_feature'): if not hasattr(fgraph, 'shape_feature'):
fgraph.attach_feature(theano.tensor.opt.ShapeFeature()) fgraph.attach_feature(theano.tensor.opt.ShapeFeature())
input_dims = [dimension for inp in fgraph.inputs input_dims = [dimension for inp in fgraph.inputs
for dimension in fgraph.shape_feature.shape_of[inp]] for dimension in fgraph.shape_feature.shape_of[inp]]
output_dims = [dimension for shape in fgraph.shape_feature.shape_of.values() output_dims = [dimension for shape in fgraph.shape_feature.shape_of.values()
for dimension in shape] for dimension in shape]
compute_shapes = theano.function(input_dims, output_dims) compute_shapes = theano.function(input_dims, output_dims)
...@@ -93,8 +93,8 @@ def shape_of_variables(fgraph, input_shapes): ...@@ -93,8 +93,8 @@ def shape_of_variables(fgraph, input_shapes):
" interface changed. Now by default, it clones the graph it receives." " interface changed. Now by default, it clones the graph it receives."
" To have the old behavior, give it this new parameter `clone=False`.") " To have the old behavior, give it this new parameter `clone=False`.")
numeric_input_dims = [dim for inp in fgraph.inputs numeric_input_dims = [dim for inp in fgraph.inputs
for dim in input_shapes[inp]] for dim in input_shapes[inp]]
numeric_output_dims = compute_shapes(*numeric_input_dims) numeric_output_dims = compute_shapes(*numeric_input_dims)
sym_to_num_dict = dict(izip(output_dims, numeric_output_dims)) sym_to_num_dict = dict(izip(output_dims, numeric_output_dims))
......
import copy import copy
import pdb
import sys
import traceback as tb import traceback as tb
import warnings import warnings
...@@ -41,9 +39,9 @@ class _tensor_py_operators: ...@@ -41,9 +39,9 @@ class _tensor_py_operators:
# CASTS # CASTS
# REMOVED THESE BECAUSE PYTHON appears to require __int__ to return # REMOVED THESE BECAUSE PYTHON appears to require __int__ to return
# an int. -JB 20081112 # an int. -JB 20081112
#def __int__(self): return convert_to_int32(self) # def __int__(self): return convert_to_int32(self)
#def __float__(self): return convert_to_float64(self) # def __float__(self): return convert_to_float64(self)
#def __complex__(self): return convert_to_complex128(self) # def __complex__(self): return convert_to_complex128(self)
# COMPARISONS # COMPARISONS
_is_nonzero = True _is_nonzero = True
...@@ -68,7 +66,6 @@ class _tensor_py_operators: ...@@ -68,7 +66,6 @@ class _tensor_py_operators:
rval._is_nonzero = False rval._is_nonzero = False
return rval return rval
def __nonzero__(self): def __nonzero__(self):
# Python 2.x # Python 2.x
return self.__bool__() return self.__bool__()
...@@ -215,7 +212,7 @@ class _tensor_py_operators: ...@@ -215,7 +212,7 @@ class _tensor_py_operators:
# DO NOT USE THESE BECAUSE INPLACE OPS SHOULD BE INSERTED # DO NOT USE THESE BECAUSE INPLACE OPS SHOULD BE INSERTED
# BY OPTIMIZATIONS ONLY # BY OPTIMIZATIONS ONLY
## ARITHMETIC - INPLACE # ARITHMETIC - INPLACE
# def __iadd__(self, other): # def __iadd__(self, other):
# return _add_inplace(self, other) # return _add_inplace(self, other)
# def __isub__(self, other): # def __isub__(self, other):
...@@ -642,7 +639,8 @@ class TensorVariable(_tensor_py_operators, Variable): ...@@ -642,7 +639,8 @@ class TensorVariable(_tensor_py_operators, Variable):
elif config.warn_float64 == "raise": elif config.warn_float64 == "raise":
raise Exception(msg) raise Exception(msg)
elif config.warn_float64 == 'pdb': elif config.warn_float64 == 'pdb':
import pdb; pdb.set_trace() import pdb
pdb.set_trace()
TensorType.Variable = TensorVariable TensorType.Variable = TensorVariable
...@@ -744,8 +742,8 @@ class TensorConstant(_tensor_py_operators, Constant): ...@@ -744,8 +742,8 @@ class TensorConstant(_tensor_py_operators, Constant):
def __init__(self, type, data, name=None): def __init__(self, type, data, name=None):
Constant.__init__(self, type, data, name) Constant.__init__(self, type, data, name)
if (isinstance(data, numpy.ndarray) and if (isinstance(data, numpy.ndarray) and
data.ndim > 0 and data.ndim > 0 and
len(numpy.unique(data)) == 1): len(numpy.unique(data)) == 1):
self.tag.unique_value = numpy.unique(data)[0] self.tag.unique_value = numpy.unique(data)[0]
else: else:
self.tag.unique_value = None self.tag.unique_value = None
......
...@@ -13,12 +13,15 @@ class XlogX(scalar.UnaryScalarOp): ...@@ -13,12 +13,15 @@ class XlogX(scalar.UnaryScalarOp):
if x == 0.0: if x == 0.0:
return 0.0 return 0.0
return x * numpy.log(x) return x * numpy.log(x)
def impl(self, x): def impl(self, x):
return XlogX.st_impl(x) return XlogX.st_impl(x)
def grad(self, inputs, grads): def grad(self, inputs, grads):
x, = inputs x, = inputs
gz, = grads gz, = grads
return [gz * (1 + scalar.log(x))] return [gz * (1 + scalar.log(x))]
def c_code(self, node, name, inputs, outputs, sub): def c_code(self, node, name, inputs, outputs, sub):
x, = inputs x, = inputs
z, = outputs z, = outputs
...@@ -28,7 +31,8 @@ class XlogX(scalar.UnaryScalarOp): ...@@ -28,7 +31,8 @@ class XlogX(scalar.UnaryScalarOp):
? 0.0 ? 0.0
: %(x)s * log(%(x)s);""" % locals() : %(x)s * log(%(x)s);""" % locals()
raise NotImplementedError('only floatingpoint is implemented') raise NotImplementedError('only floatingpoint is implemented')
scalar_xlogx = XlogX(scalar.upgrade_to_float, name='scalar_xlogx')
scalar_xlogx = XlogX(scalar.upgrade_to_float, name='scalar_xlogx')
xlogx = Elemwise(scalar_xlogx, name='xlogx') xlogx = Elemwise(scalar_xlogx, name='xlogx')
...@@ -41,12 +45,15 @@ class XlogY0(scalar.BinaryScalarOp): ...@@ -41,12 +45,15 @@ class XlogY0(scalar.BinaryScalarOp):
if x == 0.0: if x == 0.0:
return 0.0 return 0.0
return x * numpy.log(y) return x * numpy.log(y)
def impl(self, x, y): def impl(self, x, y):
return XlogY0.st_impl(x, y) return XlogY0.st_impl(x, y)
def grad(self, inputs, grads): def grad(self, inputs, grads):
x, y = inputs x, y = inputs
gz, = grads gz, = grads
return [gz * scalar.log(y), gz * x / y] return [gz * scalar.log(y), gz * x / y]
def c_code(self, node, name, inputs, outputs, sub): def c_code(self, node, name, inputs, outputs, sub):
x, y = inputs x, y = inputs
z, = outputs z, = outputs
...@@ -56,5 +63,6 @@ class XlogY0(scalar.BinaryScalarOp): ...@@ -56,5 +63,6 @@ class XlogY0(scalar.BinaryScalarOp):
? 0.0 ? 0.0
: %(x)s * log(%(y)s);""" % locals() : %(x)s * log(%(y)s);""" % locals()
raise NotImplementedError('only floatingpoint is implemented') raise NotImplementedError('only floatingpoint is implemented')
scalar_xlogy0 = XlogY0(scalar.upgrade_to_float, name='scalar_xlogy0')
scalar_xlogy0 = XlogY0(scalar.upgrade_to_float, name='scalar_xlogy0')
xlogy0 = Elemwise(scalar_xlogy0, name='xlogy0') xlogy0 = Elemwise(scalar_xlogy0, name='xlogy0')
...@@ -57,30 +57,17 @@ whitelist_flake8 = [ ...@@ -57,30 +57,17 @@ whitelist_flake8 = [
"typed_list/tests/test_type.py", "typed_list/tests/test_type.py",
"typed_list/tests/test_opt.py", "typed_list/tests/test_opt.py",
"typed_list/tests/test_basic.py", "typed_list/tests/test_basic.py",
"tensor/var.py",
"tensor/sharedvar.py",
"tensor/inplace.py",
"tensor/slinalg.py",
"tensor/shared_randomstreams.py",
"tensor/subtensor.py",
"tensor/elemwise.py",
"tensor/xlogx.py",
"tensor/blas_headers.py", "tensor/blas_headers.py",
"tensor/utils.py",
"tensor/type.py", "tensor/type.py",
"tensor/fourier.py", "tensor/fourier.py",
"tensor/sort.py",
"tensor/__init__.py", "tensor/__init__.py",
"tensor/opt_uncanonicalize.py", "tensor/opt_uncanonicalize.py",
"tensor/opt.py",
"tensor/blas.py", "tensor/blas.py",
"tensor/extra_ops.py", "tensor/extra_ops.py",
"tensor/nlinalg.py", "tensor/nlinalg.py",
"tensor/blas_c.py", "tensor/blas_c.py",
"tensor/elemwise_cgen.py", "tensor/elemwise_cgen.py",
"tensor/raw_random.py",
"tensor/blas_scipy.py", "tensor/blas_scipy.py",
"tensor/basic.py",
"tensor/tests/test_subtensor.py", "tensor/tests/test_subtensor.py",
"tensor/tests/test_utils.py", "tensor/tests/test_utils.py",
"tensor/tests/test_nlinalg.py", "tensor/tests/test_nlinalg.py",
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论