提交 4f6c4303 authored 作者: Razvan Pascanu's avatar Razvan Pascanu

merge

......@@ -372,8 +372,8 @@ the given tolerance.
The parameters are as follows:
* op: something that behaves like an Op instance with a single output
(can be for instance a python function combining multiple ops, or calling
an op with some of the inputs being fixed to specific values).
(can be for instance a python function that combines multiple ops, or that
calls an op with some of the inputs being fixed to specific values).
* pt: the list of numpy.ndarrays to use as inputs to the op
......@@ -392,15 +392,19 @@ Here is an example showing how to use verify_grad:
>>> # being used is Flatten(), which takes a single input).
>>> a_val = numpy.asarray([[0,1,2],[3,4,5]], dtype='float64')
>>> tensor.verify_grad(tensor.Flatten(), [a_val])
>>> # Testing gradient w.r.t. to a subset of an op's inputs. This is useful
>>> # in particular when the gradient w.r.t. some of the inputs cannot be
>>> # computed by finite difference (e.g. for discrete inputs), which would
>>> # cause verify_grad to crash.
Here is another example, showing how to verify the gradient w.r.t. a subset of
an Op's inputs. This is useful in particular when the gradient w.r.t. some of
the inputs cannot be computed by finite difference (e.g. for discrete inputs),
which would cause verify_grad to crash.
>>> def test_crossentropy_softmax_grad():
>>> op = tensor.nnet.crossentropy_softmax_argmax_1hot_with_bias
>>> def op_with_fixed_y_idx(x, b):
>>> # Input `y_idx` of this Op takes integer values, so we fix them
>>> # to some constant array.
>>> # Although this op has multiple outputs, we can return only one.
>>> # Here, we return the first output only, and fix the value of the
>>> # `y_idx` input to some constant array.
>>> # Here, we return the first output only.
>>> return op(x, b, y_idx=numpy.asarray([0, 2]))[0]
>>> x_val = numpy.asarray([[-1, 0, 1], [3, 2, 1]], dtype='float64')
>>> b_val = numpy.asarray([1, 2, 3], dtype='float64')
......
......@@ -60,8 +60,8 @@ The parameter in T.dscalar('x') in the first line is the name of this variable(i
The function I compiled is too slow, what's up?
-----------------------------------------------
First, make sure you're running in FAST_RUN mode, by passing ``mode='FAST_RUN'``
to ``theano.function`` or ``theano.make`` or by setting to ``PROFILE_MODE``
the flags :attr:`config.mode`. Some
to ``theano.function`` or ``theano.make`` or by setting to ``FAST_RUN``
the flag :attr:`config.mode`. Some
operations have excruciatingly slow Python implementations and that
can negatively effect the performance of FAST_COMPILE.
......
......@@ -17,10 +17,10 @@ def _asarray(a, dtype=None, order=None):
http://projects.scipy.org/numpy/ticket/870.
Currently, this issue has only been causing trouble when the target
data type is 'int32', on some computers. As a result, this is the only
situation where we may do more than a simple call to ``numpy.asarray``. If
it turns out that a similar problem can occur for more data type, this
function should be updated accordingly.
data type is 'int32' or 'int64', on some computers. As a result, we
silently fix it only in this situation: if a type mismatch is detected
with another data type, an exception is raised (if that happens, then this
function may need to be modified to also handle this other data type).
This function's name starts with a '_' to indicate that it is meant to be
used internally. It is imported so as to be available directly through
......@@ -28,12 +28,24 @@ def _asarray(a, dtype=None, order=None):
"""
dtype = numpy.dtype(dtype) # Convert into dtype object.
rval = numpy.asarray(a, dtype=dtype, order=order)
numpy_int32 = numpy.dtype(numpy.int32)
if (dtype is numpy_int32 and rval.dtype is not numpy_int32):
# Enfore the numpy.int32 dtype.
return rval.view(dtype=numpy_int32)
# Note that dtype comparison must be done by comparing their `num`
# attribute. One cannot assume that two identical data types are pointers
# towards the same object (e.g. under Windows this appears not to be the
# case).
if rval.dtype.num != dtype.num:
# Type mismatch between the data type we asked for, and the one
# returned by numpy.asarray.
if (dtype.num == numpy.dtype(numpy.int32).num or
dtype.num == numpy.dtype(numpy.int64).num):
# Silent fix.
return rval.view(dtype=dtype)
else:
# Unexpected mismatch: better know what is going on!
raise TypeError('numpy.array did not return the data type we '
'asked for (%s #%s), instead it returned type %s #%s: function '
'theano._asarray may need to be extended to handle this '
'data type as well.' %
(dtype, dtype.num, rval.dtype, rval.dtype.num))
else:
# Using ``numpy.asarray`` should work just fine.
# Debug assert if we want to detect other failure cases (untested):
# assert rval.dtype is dtype
return rval
......@@ -2,9 +2,10 @@
"""
import gof
from copy import copy
import sys
import sys,os
from theano import config
from gof import Op, Apply
from theano.gof.python25 import any
class Print(Op):
"""This identity-like Op has the side effect of printing a message followed by its inputs
......@@ -299,3 +300,58 @@ pprint.assign(lambda pstate, r: hasattr(pstate, 'target') and pstate.target is n
pp = pprint
def pydotprint(fct, outfile=os.path.join(config.compiledir,'theano.pydotprint.png')):
"""
print to a file in png format the graph of op of a compile theano fct.
:param fct: the theano fct returned by theano.function.
:param outfile: the output file where to put the graph.
In the graph, box are an Apply Node(the execution of an op) and elipse are variable.
If variable have name they are used as the text(if multiple var have the same name, they will be merged in the graph). Otherwise, if a constant, we print the value and finaly we print the type + an uniq number to don't have multiple var merged.
We print the op of the apply in the Apply box with a number that represent the toposort order of application of those Apply.
"""
import pydot as pd
g=pd.Dot()
var_id={}
def var_name(var):
if var.name is not None:
varstr = var.name
elif isinstance(var,gof.Constant):
varstr = str(var.data)
else:
#a var id is needed as otherwise var with the same type will be merged in the graph.
i = var_id.get(var,None)
if i is None:
var_id[var]=len(var_id)
i = var_id[var]
varstr = str(var.type)+' '+str(i)
return varstr
for node_idx,node in enumerate(fct.maker.env.toposort()):
astr=str(node.op).replace(':','_')+' '+str(node_idx)
g.add_node(pd.Node(astr,shape='box'))
for var in node.inputs:
varstr=var_name(var)
if var.owner is None:
g.add_node(pd.Node(varstr,color='green'))
g.add_edge(pd.Edge(varstr,astr))
for var in node.outputs:
varstr=var_name(var)
g.add_edge(pd.Edge(astr,varstr))
if any([x[0]=='output' for x in var.env.clients(var)]):
g.add_node(pd.Node(varstr,color='blue'))
g.write_png(outfile, prog='dot')
print 'The output file is available at',outfile
#from matplotlib import pyplot
#image=pyplot.imread(outfile)
#pyplot.imshow(image)
#import pdb;pdb.set_trace()
......@@ -412,7 +412,7 @@ class Scan(theano.Op):
warning('Can not compute gradients if inplace or updates ' \
'are used. Use force_gradient if you know for sure '\
'that the gradient can be computed automatically.')
return [None for i in inputs]
return [None for i in args]
else:
# forward pass
y = self(*args)
......
......@@ -638,7 +638,8 @@ class TensorType(Type):
# Easy constructors
def tensor(*args, **kwargs):
return TensorType(*args, **kwargs).make_variable()
name = kwargs.get('name',None)
return TensorType(*args, **kwargs).make_variable(name=name)
def _multi(*fns):
def f2(f, *names):
......@@ -1307,8 +1308,8 @@ class MaxAndArgmax(Op):
axis = _as_tensor_variable(axis)
inputs = [x, axis]
broadcastable = [False] * (x.type.ndim - 1) #TODO: be less conservative
outputs = [tensor(x.type.dtype, broadcastable),
tensor('int32', broadcastable)]
outputs = [tensor(x.type.dtype, broadcastable,name='max'),
tensor('int32', broadcastable,name='argmax')]
return Apply(self, inputs, outputs)
def perform(self, node, (x, axis), (max, max_idx)):
max[0] = numpy.asarray(numpy.max(x, axis))
......@@ -1336,6 +1337,8 @@ class MaxAndArgmax(Op):
xmax_pad = shape_padright(xmax)
g_x = eq(xmax_pad, x) * g_max_pad
return g_x, None
def __str__(self):
return self.__class__.__name__
_max_and_argmax = MaxAndArgmax()
@_redefine_asRoutine(_max_and_argmax)
......@@ -2897,6 +2900,9 @@ class ARange(Op):
def __hash__(self):
return hash(self.dtype)
def __str__(self):
return self.__class__.__name__
def make_node(self, start, stop, step):
start, stop, step = map(as_tensor_variable, (start, stop, step))
assert start.ndim == 0
......
......@@ -9,7 +9,7 @@ import numpy
import theano
import theano.tensor as tensor
from theano import gof, Op, tensor, config
from theano.gof.python25 import any
import logging
_logger=logging.getLogger("theano.signal.conv")
def _debug(*msg):
......@@ -383,10 +383,10 @@ class ConvOp(Op):
from scipy.signal.signaltools import _valfrommode, _bvalfromboundary
from scipy.signal.sigtools import _convolve2d
imshp = self.imshp
if imshp is None:
if imshp is None or any([x is None for x in imshp]):
imshp = tuple(img2d.shape[1:])
kshp = self.kshp
if kshp is None:
if kshp is None or any([x is None for x in kshp]):
kshp = tuple(filtersflipped.shape[2:])
bsize = self.bsize
if bsize is None:
......@@ -398,16 +398,21 @@ class ConvOp(Op):
imshp_logical = self.imshp_logical
if imshp_logical is None:
imshp_logical = imshp
if numpy.any([x is None for x in imshp_logical]):
imshp_logical = tuple(img2d.shape[1:])
kshp_logical = self.kshp_logical
if kshp_logical is None:
kshp_logical = kshp
if numpy.any([x is None for x in kshp_logical]):
kshp = tuple(filtersflipped.shape[2:])
if self.fulloutshp is not None:
fulloutshp = tuple(self.fulloutshp)
else:
fulloutshp = tuple(ConvOp.getOutputShape(imshp_logical, kshp_logical, (1,1), self.out_mode))
if z[0] is None:
if z[0] is None or z[0].shape!=(bsize,)+(nkern,)+fulloutshp:
z[0] = numpy.zeros((bsize,)+(nkern,)+fulloutshp,
dtype=img2d.dtype)
zz=z[0]
......
......@@ -114,6 +114,8 @@ class SoftmaxWithBias(gof.Op):
return type(self) == type(other)
def __hash__(self):
return tensor.hashtype(self)
def __str__(self):
return self.__class__.__name__
def make_node(self, x, b):
x = tensor.as_tensor_variable(x)
......@@ -284,6 +286,9 @@ class SoftmaxGrad(gof.Op):
def __hash__(self):
return tensor.hashtype(self)
def __str__(self):
return self.__class__.__name__
def make_node(self, dy, sm, **kwargs):
dy = tensor.as_tensor_variable(dy)
sm = tensor.as_tensor_variable(sm)
......@@ -376,6 +381,8 @@ class Softmax(gof.Op):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def __str__(self):
return self.__class__.__name__
def make_node(self, x):
x = tensor.as_tensor_variable(x)
......@@ -818,6 +825,8 @@ class CrossentropyCategorical1HotGrad(gof.Op):
return type(self) == type(other)
def __hash__(self):
return tensor.hashtype(self)
def __str__(self):
return self.__class__.__name__
def make_node(self, g_y, coding_dist, true_one_of_n):
return gof.Apply(self, [g_y, coding_dist, true_one_of_n], [coding_dist.type()])
def perform(self, node, (g_y, coding_dist, true_one_of_n), (g_coding_strg,)):
......@@ -848,6 +857,8 @@ class CrossentropyCategorical1Hot(gof.Op):
return type(self) == type(other)
def __hash__(self):
return tensor.hashtype(self)
def __str__(self):
return self.__class__.__name__
def make_node(self, coding_dist, true_one_of_n):
"""
:type coding_dist: dense matrix
......@@ -1346,6 +1357,8 @@ class Prepend_scalar_constant_to_each_row(gof.Op):
return (type(self) == type(other)) and (self.val == other.val)
def __hash__(self):
return tensor.hashtype(self) ^ hash(self.val.value)
def __str__(self):
return '%s{%s}'%(self.__class__.__name__,self.val)
def make_node(self, mat):
#check type of input
......@@ -1383,6 +1396,8 @@ class Prepend_scalar_to_each_row(gof.Op):
return (type(self) == type(other))
def __hash__(self):
return tensor.hashtype(self)
def __str__(self):
return self.__class__.__name__
def make_node(self, val, mat):
#check type of input
......
......@@ -94,6 +94,9 @@ class TestConv2D(unittest.TestCase):
self.validate((3,2,8,8), (4,2,5,5), 'full')
self.validate((3,2,7,5), (5,2,2,3), 'full')
# test filter same size as input
def test_img_kernel_same_shape(self):
self.validate((3,2,3,3), (4,2,3,3), 'full')
self.validate((3,2,3,3), (4,2,3,3), 'valid')
def test_unroll_patch_false(self):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论