提交 68631c38 authored 作者: Eric Larsen's avatar Eric Larsen 提交者: Frederic

add infer_shape to AdvancedIncSubtensor and add tests; repair infer_shape of…

add infer_shape to AdvancedIncSubtensor and add tests; repair infer_shape of Reshape allowing for constant desired shape with possibly one entry equal to -1 and add tests
上级 f3fe9427
...@@ -5355,17 +5355,40 @@ class Reshape(Op): ...@@ -5355,17 +5355,40 @@ class Reshape(Op):
# Here, we only simplify if the shape (node.inputs[1]) is a constant, # Here, we only simplify if the shape (node.inputs[1]) is a constant,
# ideally it would suffice to check that it is always non-negative. # ideally it would suffice to check that it is always non-negative.
"""
oshape = [] oshape = []
for i in xrange(self.ndim): for i in xrange(self.ndim):
default_os_i = theano.tensor.opt.Shape_i(i)(node.outputs[0]) default_os_i = theano.tensor.opt.Shape_i(i)(node.outputs[0])
try: try:
os_i = get_constant_value(node.inputs[1][i]).item() os_i = node.inputs[1][i]
if os_i == -1: if os_i == -1:
os_i = default_os_i os_i = default_os_i
except TypeError: except TypeError:
print 'erreur'
os_i = default_os_i os_i = default_os_i
oshape.append(os_i) oshape.append(os_i)
return [tuple(oshape)] return [tuple(oshape)]
"""
# In contrast with the preceding block, the following will handle
# an entry equal to -1 in desired shape
requ = node.inputs[1]
if isinstance(requ, theano.tensor.TensorConstant):
requ = list(requ.data)
requ_part = [ele for ele in requ if ele != -1]
crit = len(requ) - len(requ_part)
if crit == 1:
missing = numpy.prod(ishapes[0]) / numpy.prod(requ_part)
for i, ele in enumerate(requ):
if ele == -1:
requ[i] = missing
elif crit > 1:
raise ValueError('shape argument to Reshape.perform'
' must have at most one entry equal to -1')
return [requ]
else:
return node.env.shape_feature.default_infer_shape(node, ishapes)
def c_code_cache_version(self): def c_code_cache_version(self):
return (2,) return (2,)
...@@ -6205,6 +6228,9 @@ class AdvancedIncSubtensor(Op): ...@@ -6205,6 +6228,9 @@ class AdvancedIncSubtensor(Op):
'out[0] (%s), with shape %s, is not correctly filled.' 'out[0] (%s), with shape %s, is not correctly filled.'
% (out[0], out[0].shape)) % (out[0], out[0].shape))
def infer_shape(self, node, ishapes):
return [ishapes[0]]
def grad(self, inpt, output_gradients): def grad(self, inpt, output_gradients):
x, y = inpt[:2] x, y = inpt[:2]
idxs = inpt[2:] idxs = inpt[2:]
......
...@@ -6074,10 +6074,10 @@ class TestInferShape(utt.InferShapeTester): ...@@ -6074,10 +6074,10 @@ class TestInferShape(utt.InferShapeTester):
tensordot_grad(axes)(admat, bdmat, gzdscal), tensordot_grad(axes)(admat, bdmat, gzdscal),
[admat_val, bdmat_val, gzdscal_val], tensordot_grad) [admat_val, bdmat_val, gzdscal_val], tensordot_grad)
# Note: The two following tests currently fail and should unlikely be # Note: The two following tests currently fail and should unlikely be,
# for the shape of a grad is very simple and similar to that of the inputs. # for the shape of a grad is very simple and similar to that of the inputs.
# Additional tests involving 3-tensors and 4-tensors will be included once # Additional tests involving 3-tensors and 4-tensors will be included once
# this is resolved. Suggestion: first solve issues with 'tensordot' next. # this is resolved.
""" """
gzdscal = dscalar() gzdscal = dscalar()
...@@ -6429,15 +6429,7 @@ class TestInferShape(utt.InferShapeTester): ...@@ -6429,15 +6429,7 @@ class TestInferShape(utt.InferShapeTester):
[SpecifyShape()(adtens4, aivec)], [SpecifyShape()(adtens4, aivec)],
[adtens4_val, aivec_val], SpecifyShape) [adtens4_val, aivec_val], SpecifyShape)
# Mean: basic 3047 # Mean
# TODO: conflict between following lines of _init_ and perform
# in basic.py
#
# elemwise.CAReduce.__init__(self, scal.add, axis)
# output[0] = numpy.mean(input, axis=self.axis)
#
# to be resolved as desired/appropriate
adtens3_val = rand(3, 4, 5) adtens3_val = rand(3, 4, 5)
aiscal_val = 2 aiscal_val = 2
self._compile_and_check([adtens3], self._compile_and_check([adtens3],
...@@ -6597,61 +6589,59 @@ class TestInferShape(utt.InferShapeTester): ...@@ -6597,61 +6589,59 @@ class TestInferShape(utt.InferShapeTester):
[adtens4_val, 2], [adtens4_val, 2],
AdvancedIncSubtensor1) AdvancedIncSubtensor1)
# AdvancedIncSubtensor # AdvancedIncSubtensor
# TODO: The shape is apparently generated correctly but the final
# result is abnormal:
"""
topo_shape:
[AdvancedIncSubtensor{Finplace=ainplace=linplace=sinplace=e, T set_instead_of_incr set_instead_of_incu set_instead_of_ince}(<TensorType(float64, matrix)>, <TensorType(float64, vector)>, TensorConstant{[1 3 2]}, TensorConstant{[0 3 3]}), Shape_i{1}(AdvancedIncSubtensor{Finplace=ainplace=linplace=sinplace=e, T set_instead_of_incr set_instead_of_incu set_instead_of_ince}.0), Shape_i{0}(AdvancedIncSubtensor{Finplace=ainplace=linplace=sinplace=e, T set_instead_of_incr set_instead_of_incu set_instead_of_ince}.0), MakeVector(Shape_i{0}.0, Shape_i{1}.0)]
shapes_function:
MakeVector [@A] '' 3
|Shape_i{0} [@B] '' 2
| |AdvancedIncSubtensor{Finplace=ainplace=linplace=sinplace=e, T set_instead_of_incr set_instead_of_incu set_instead_of_ince} [@C] '' 0
| |<TensorType(float64, matrix)> [@D]
| |<TensorType(float64, vector)> [@E]
| |TensorConstant{[1 3 2]} [@F]
| |TensorConstant{[0 3 3]} [@G]
|Shape_i{1} [@H] '' 1
|AdvancedIncSubtensor{Finplace=ainplace=linplace=sinplace=e, T set_instead_of_incr set_instead_of_incu set_instead_of_ince} [@C] '' 0
remaining op as a class: AdvancedIncSubtensor{Finplace=ainplace=linplace=sinplace=e, T set_instead_of_incr set_instead_of_incu set_instead_of_ince}
(5, 4) [5 4]
aivec_val = [1, 3, 2] aivec_val = [1, 3, 2]
bivec_val = [0, 3, 3] bivec_val = [0, 3, 3]
advec_val = [23, 24, 25] advec_val = [23, 24, 25]
self._compile_and_check([admat, advec], self._compile_and_check([admat, advec],
[set_subtensor(admat[aivec_val, bivec_val], advec)], [set_subtensor(admat[aivec_val, bivec_val], advec)],
[admat_val, advec_val], AdvancedIncSubtensor) [admat_val, advec_val], AdvancedIncSubtensor)
"""
# Reshape # Reshape
# TODO: The shape is apparently generated correctly but the final result is abnormal: # TODO: generalize infer_shape to account for tensor variable
""" # (non-constant) input shape
topo_shape:
[Reshape{2}(<TensorType(float64, matrix)>, <TensorType(int32, vector)>),
Shape_i{1}(Reshape{2}.0), Shape_i{0}(Reshape{2}.0), MakeVector(Shape_i{0}.0, Shape_i{1}.0)]
shapes_function:
MakeVector [@A] '' 3
|Shape_i{0} [@B] '' 2
| |Reshape{2} [@C] '' 0
| |<TensorType(float64, matrix)> [@D]
| |<TensorType(int32, vector)> [@E]
|Shape_i{1} [@F] '' 1
|Reshape{2} [@C] '' 0
remaining op as a class: Reshape{2}
shapes generated:
(4, 3) [4 3]
admat = dmatrix() admat = dmatrix()
aivec = ivector()
ndim = 2 ndim = 2
admat_val = rand(3, 4) admat_val = rand(3, 4)
self._compile_and_check([admat, aivec], self._compile_and_check([admat],
[Reshape(ndim, '_name')(admat, aivec)], [Reshape(ndim)(admat, [4, 3])],
[admat_val, [4, 3]], Reshape) [admat_val], Reshape)
self._compile_and_check([admat],
[Reshape(ndim)(admat, [4, -1])],
[admat_val], Reshape)
# enable when infer_shape is generalized:
# self._compile_and_check([admat, aivec],
# [Reshape(ndim)(admat, aivec)],
# [admat_val, [4, 3]], Reshape)
#
# self._compile_and_check([admat, aivec],
# [Reshape(ndim)(admat, aivec)],
# [admat_val, [4, -1]], Reshape)
adtens4 = dtensor4()
ndim = 4
adtens4_val = rand(2, 4, 3, 5)
self._compile_and_check([adtens4],
[Reshape(ndim)(adtens4, [1, -1, 10, 4])],
[adtens4_val], Reshape)
self._compile_and_check([adtens4],
[Reshape(ndim)(adtens4, [1, 3, 10, 4])],
[adtens4_val], Reshape)
# Tile: basic 5292 # enable when infer_shape is generalized:
# self._compile_and_check([adtens4, aivec],
# [Reshape(ndim)(adtens4, aivec)],
# [adtens4_val, [1, -1, 10, 4]], Reshape)
#
# self._compile_and_check([adtens4, aivec],
# [Reshape(ndim)(adtens4, aivec)],
# [adtens4_val, [1, 3, 10, 4]], Reshape)
# Tile
advec = dvector() advec = dvector()
advec_val = rand(5) advec_val = rand(5)
aivec_val = [3] aivec_val = [3]
...@@ -6675,7 +6665,7 @@ shapes generated: ...@@ -6675,7 +6665,7 @@ shapes generated:
self._compile_and_check([adtens4], self._compile_and_check([adtens4],
[tile(adtens4, aivec_val, ndim)], [tile(adtens4, aivec_val, ndim)],
[adtens4_val], Tile) [adtens4_val], Tile)
"""
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论