提交 eced0049 authored 作者: Sina Honari's avatar Sina Honari

first commit to remove Flatten Op

上级 33bda7ca
...@@ -318,7 +318,7 @@ if cuda_available: ...@@ -318,7 +318,7 @@ if cuda_available:
GpuDimShuffle, GpuCAReduce, GpuReshape, GpuContiguous, GpuDimShuffle, GpuCAReduce, GpuReshape, GpuContiguous,
GpuSubtensor, GpuIncSubtensor, GpuSubtensor, GpuIncSubtensor,
GpuAdvancedSubtensor1, GpuAdvancedIncSubtensor1, GpuAdvancedSubtensor1, GpuAdvancedIncSubtensor1,
GpuFlatten, GpuShape, GpuAlloc, GpuAllocEmpty, GpuSplit, gpu_flatten, GpuFlatten, GpuShape, GpuAlloc, GpuAllocEmpty, GpuSplit,
GpuJoin, fscalar, fvector, fmatrix, frow, fcol, GpuJoin, fscalar, fvector, fmatrix, frow, fcol,
ftensor3, ftensor4, ftensor3, ftensor4,
scalar, vector, matrix, row, col, scalar, vector, matrix, row, col,
......
...@@ -3322,18 +3322,33 @@ class GpuIncSubtensor(tensor.IncSubtensor, GpuOp): ...@@ -3322,18 +3322,33 @@ class GpuIncSubtensor(tensor.IncSubtensor, GpuOp):
return () return ()
class GpuFlatten(gof.HideC, tensor.Flatten, GpuOp): #class GpuFlatten(gof.HideC, tensor.Reshape, GpuOp):
""" # """
Implement Flatten on the gpu. # Implement Flatten on the gpu.
#
""" # """
#
def make_node(self, x): # def make_node(self, x):
assert isinstance(x.type, CudaNdarrayType) # warnings.warn(
rval = tensor.Flatten.make_node(self, x) # "GpuFlatten class is deprecated, "
host_out_broadcastable = rval.outputs[0].type.broadcastable # "please use gpu_flatten method instead.",
out_type = CudaNdarrayType(broadcastable=host_out_broadcastable) # DeprecationWarning,
return Apply(self, [x], [out_type()]) # stacklevel=4)
# assert isinstance(x.type, CudaNdarrayType)
# rval = tensor.Reshape.make_node(self, x, [tensor.prod(x.shape)])
# host_out_broadcastable = rval.outputs[0].type.broadcastable
# out_type = CudaNdarrayType(broadcastable=host_out_broadcastable)
# return Apply(self, [x], [out_type()])
def gpu_flatten(x, outdim=1):
x = as_cuda_ndarray_variable(x)
if outdim > 1:
dims = tuple(x.shape[:outdim-1])+(theano.tensor.prod(x.shape[outdim-1:]),)
else:
dims = (-1,)
return GpuReshape(outdim)(x, dims)
class GpuShape(tensor.Shape, GpuOp): class GpuShape(tensor.Shape, GpuOp):
......
...@@ -3,7 +3,7 @@ import copy ...@@ -3,7 +3,7 @@ import copy
from theano import Op from theano import Op
from theano.gof import local_optimizer from theano.gof import local_optimizer
from theano.sandbox.cuda import cuda_available, GpuOp from theano.sandbox.cuda import cuda_available, GpuOp
from theano.sandbox.cuda.basic_ops import GpuFlatten from theano.sandbox.cuda.basic_ops import gpu_flatten
from theano.tensor.extra_ops import CumsumOp from theano.tensor.extra_ops import CumsumOp
if cuda_available: if cuda_available:
...@@ -453,7 +453,7 @@ def use_gpu_cumsum(node): ...@@ -453,7 +453,7 @@ def use_gpu_cumsum(node):
x = gpu_from_host(x) x = gpu_from_host(x)
if axis is None and x.ndim > 1: if axis is None and x.ndim > 1:
x = GpuFlatten()(x) x = gpu_flatten(x)
# ``gpu_cumsum`` assume array has been flattened if needed. # ``gpu_cumsum`` assume array has been flattened if needed.
if axis is None: if axis is None:
......
...@@ -24,7 +24,9 @@ from theano.sandbox.cuda.basic_ops import ( ...@@ -24,7 +24,9 @@ from theano.sandbox.cuda.basic_ops import (
gpu_eye, gpu_contiguous, gpu_eye, gpu_contiguous,
gpu_from_host, host_from_gpu, GpuFromHost, HostFromGpu, gpu_from_host, host_from_gpu, GpuFromHost, HostFromGpu,
GpuContiguous, GpuContiguous,
GpuElemwise, GpuDimShuffle, GpuReshape, GpuCAReduce, GpuFlatten, GpuElemwise, GpuDimShuffle, GpuReshape, GpuCAReduce,
# GpuFlatten,
gpu_flatten,
GpuSubtensor, GpuAdvancedSubtensor1, GpuSubtensor, GpuAdvancedSubtensor1,
GpuAdvancedIncSubtensor1, GpuAdvancedIncSubtensor1_dev20, GpuAdvancedIncSubtensor1, GpuAdvancedIncSubtensor1_dev20,
GpuIncSubtensor, gpu_alloc, GpuAlloc, gpu_shape, GpuSplit, GpuAllocEmpty) GpuIncSubtensor, gpu_alloc, GpuAlloc, gpu_shape, GpuSplit, GpuAllocEmpty)
...@@ -152,7 +154,7 @@ cpu_ops_moved_to_gpu = [ ...@@ -152,7 +154,7 @@ cpu_ops_moved_to_gpu = [
tensor.elemwise.All, tensor.elemwise.Any, tensor.elemwise.All, tensor.elemwise.Any,
tensor.elemwise.CAReduceDtype, tensor.elemwise.Sum, tensor.elemwise.CAReduceDtype, tensor.elemwise.Sum,
tensor.elemwise.Prod, tensor.elemwise.ProdWithoutZeros, tensor.elemwise.Prod, tensor.elemwise.ProdWithoutZeros,
tensor.Reshape, tensor.Flatten, tensor.Subtensor, tensor.Reshape, tensor.flatten, tensor.Subtensor,
tensor.AdvancedSubtensor1, tensor.AdvancedIncSubtensor1, tensor.AdvancedSubtensor1, tensor.AdvancedIncSubtensor1,
tensor.IncSubtensor, tensor.Shape, tensor.Join, tensor.IncSubtensor, tensor.Shape, tensor.Join,
tensor.Alloc, tensor.Eye] tensor.Alloc, tensor.Eye]
...@@ -972,23 +974,23 @@ def local_gpu_reshape(node): ...@@ -972,23 +974,23 @@ def local_gpu_reshape(node):
return False return False
@register_opt() #@register_opt()
@local_optimizer([gpu_from_host, tensor.Flatten]) #@local_optimizer([gpu_from_host, tensor.Reshape])
def local_gpu_flatten(node): #def local_gpu_flatten(node):
if isinstance(node.op, GpuFromHost): # if isinstance(node.op, GpuFromHost):
host_input = node.inputs[0] # host_input = node.inputs[0]
if host_input.owner and \ # if host_input.owner and \
isinstance(host_input.owner.op, tensor.Flatten): # isinstance(host_input.owner.op, tensor.Reshape):
outdim = host_input.owner.op.outdim # outdim = host_input.owner.op.outdim
return [GpuFlatten(outdim)( # return [GpuFlatten(outdim)(
as_cuda_ndarray_variable(host_input.owner.inputs[0]))] # as_cuda_ndarray_variable(host_input.owner.inputs[0]))]
if isinstance(node.op, tensor.Flatten): # if isinstance(node.op, tensor.Reshape):
x, = node.inputs # x, shp= node.inputs
outdim = node.op.outdim # outdim = node.op.outdim
if x.owner and isinstance(x.owner.op, HostFromGpu): # if x.owner and isinstance(x.owner.op, HostFromGpu):
gpu_x, = x.owner.inputs # gpu_x, = x.owner.inputs
return [host_from_gpu(GpuFlatten(outdim)(gpu_x))] # return [host_from_gpu(GpuFlatten(outdim)(gpu_x))]
return False # return False
@register_opt() @register_opt()
......
...@@ -307,7 +307,7 @@ def test_flatten(): ...@@ -307,7 +307,7 @@ def test_flatten():
x = cuda.fmatrix('x') x = cuda.fmatrix('x')
f = theano.function([x], x.flatten(), mode=mode_with_gpu) f = theano.function([x], x.flatten(), mode=mode_with_gpu)
assert any([node for node in f.maker.fgraph.toposort() assert any([node for node in f.maker.fgraph.toposort()
if isinstance(node.op, B.GpuFlatten)]) if isinstance(node.op, B.GpuReshape)])
assert len(f([[0., 0.], [0., 0.]]).shape) == 1 assert len(f([[0., 0.], [0., 0.]]).shape) == 1
......
差异被折叠。
...@@ -377,7 +377,7 @@ class T_softplus_opts(unittest.TestCase): ...@@ -377,7 +377,7 @@ class T_softplus_opts(unittest.TestCase):
f = theano.function([x], out, mode=self.m) f = theano.function([x], out, mode=self.m)
topo = f.maker.fgraph.toposort() topo = f.maker.fgraph.toposort()
assert len(topo) == 3 assert len(topo) == 3
assert isinstance(topo[0].op, T.Flatten) tensor.is_flatten(topo[0])
assert isinstance(topo[1].op.scalar_op, assert isinstance(topo[1].op.scalar_op,
theano.tensor.nnet.sigm.ScalarSoftplus) theano.tensor.nnet.sigm.ScalarSoftplus)
assert isinstance(topo[2].op.scalar_op, theano.scalar.Neg) assert isinstance(topo[2].op.scalar_op, theano.scalar.Neg)
......
...@@ -3877,24 +3877,24 @@ def local_useless_split(node): ...@@ -3877,24 +3877,24 @@ def local_useless_split(node):
################ ################
# Flatten Opts # # Flatten Opts #
################ ################
@register_canonicalize #@register_canonicalize
@register_stabilize #@register_stabilize
@gof.local_optimizer([T.Flatten]) #@gof.local_optimizer([T.Flatten])
def local_flatten_lift(node): #def local_flatten_lift(node):
""" # ""
Flatten(UnaryElemwise(x)) -> UnaryElemwise(Flatten(x)) # Flatten(UnaryElemwise(x)) -> UnaryElemwise(Flatten(x))
#
This optimization is needed by optimization # This optimization is needed by optimization
nnet/sigm.py:log1msigm_to_softplus to get applied when there is a flatten. # nnet/sigm.py:log1msigm_to_softplus to get applied when there is a flatten.
#
""" # ""
if (isinstance(node.op, T.Flatten) and # if (isinstance(node.op, T.Flatten) and
node.inputs[0].owner and # node.inputs[0].owner and
isinstance(node.inputs[0].owner.op, T.Elemwise) and # isinstance(node.inputs[0].owner.op, T.Elemwise) and
len(node.inputs[0].owner.inputs) == 1): # len(node.inputs[0].owner.inputs) == 1):
f = node.op(node.inputs[0].owner.inputs[0]) # f = node.op(node.inputs[0].owner.inputs[0])
e = node.inputs[0].owner.op(f) # e = node.inputs[0].owner.op(f)
return [e] # return [e]
################## ##################
# Reshape opts # # Reshape opts #
......
...@@ -32,7 +32,7 @@ from theano.tensor import (_shared, wvector, bvector, autocast_float_as, ...@@ -32,7 +32,7 @@ from theano.tensor import (_shared, wvector, bvector, autocast_float_as,
alloc, as_tensor_variable, tensor_from_scalar, ARange, autocast_float, alloc, as_tensor_variable, tensor_from_scalar, ARange, autocast_float,
clip, constant, default, dot, clip, constant, default, dot,
dmatrix, dscalar, dvector, eq, eye, fill, flatten, inverse_permutation, dmatrix, dscalar, dvector, eq, eye, fill, flatten, inverse_permutation,
tensor4, permute_row_elements, Flatten, fmatrix, fscalars, grad, tensor4, permute_row_elements, fmatrix, fscalars, grad,
inplace, iscalar, matrix, minimum, matrices, maximum, mul, neq, inplace, iscalar, matrix, minimum, matrices, maximum, mul, neq,
Reshape, row, scalar, scalars, second, smallest, stack, sub, Tensor, Reshape, row, scalar, scalars, second, smallest, stack, sub, Tensor,
tensor_copy, tensordot, TensorType, Tri, tri, tril, triu, unbroadcast, tensor_copy, tensordot, TensorType, Tri, tri, tril, triu, unbroadcast,
...@@ -5147,11 +5147,6 @@ def test_make_column_matrix_broadcastable(): ...@@ -5147,11 +5147,6 @@ def test_make_column_matrix_broadcastable():
def test_flatten_outdimNone(): def test_flatten_outdimNone():
"""Flatten always returns a copy of the array. There is no danger
with in-place operations and thus no need to test it.
"""
a = dmatrix() a = dmatrix()
c = flatten(a) c = flatten(a)
f = inplace_func([a], c) f = inplace_func([a], c)
...@@ -5161,7 +5156,7 @@ def test_flatten_outdimNone(): ...@@ -5161,7 +5156,7 @@ def test_flatten_outdimNone():
f = inplace_func([a], c) f = inplace_func([a], c)
assert numpy.all(f(a_val) == c_val) assert numpy.all(f(a_val) == c_val)
utt.verify_grad(Flatten(), [a_val]) utt.verify_grad(flatten, [a_val])
def test_flatten_scalar(): def test_flatten_scalar():
...@@ -5174,7 +5169,7 @@ def test_flatten_scalar(): ...@@ -5174,7 +5169,7 @@ def test_flatten_scalar():
f = inplace_func([a], c) f = inplace_func([a], c)
assert numpy.all(f(a_val) == c_val) assert numpy.all(f(a_val) == c_val)
# utt.verify_grad(Flatten(), [a_val]) #TODO: fix verify_grd to work on scalars # utt.verify_grad(flatten, [a_val]) #TODO: fix verify_grd to work on scalars
def test_flatten_outdim1(): def test_flatten_outdim1():
...@@ -5187,7 +5182,7 @@ def test_flatten_outdim1(): ...@@ -5187,7 +5182,7 @@ def test_flatten_outdim1():
f = inplace_func([a], c) f = inplace_func([a], c)
assert numpy.all(f(a_val) == c_val) assert numpy.all(f(a_val) == c_val)
utt.verify_grad(Flatten(1), [a_val]) utt.verify_grad(flatten, [a_val])
def test_flatten_outdim2(): def test_flatten_outdim2():
...@@ -5199,7 +5194,7 @@ def test_flatten_outdim2(): ...@@ -5199,7 +5194,7 @@ def test_flatten_outdim2():
f = inplace_func([a], c) f = inplace_func([a], c)
assert numpy.all(f(a_val) == a_val) assert numpy.all(f(a_val) == a_val)
utt.verify_grad(Flatten(2), [a_val]) utt.verify_grad(flatten, [a_val])
def test_flatten_outdim2_of_3(): def test_flatten_outdim2_of_3():
...@@ -5213,7 +5208,7 @@ def test_flatten_outdim2_of_3(): ...@@ -5213,7 +5208,7 @@ def test_flatten_outdim2_of_3():
f = inplace_func([a], c) f = inplace_func([a], c)
assert numpy.all(f(a_val) == c_val) assert numpy.all(f(a_val) == c_val)
utt.verify_grad(Flatten(2), [a_val]) utt.verify_grad(flatten, [a_val])
def test_flatten_broadcastable(): def test_flatten_broadcastable():
...@@ -7128,24 +7123,27 @@ class TestInferShape(utt.InferShapeTester): ...@@ -7128,24 +7123,27 @@ class TestInferShape(utt.InferShapeTester):
# Flatten # Flatten
atens3 = tensor3() atens3 = tensor3()
atens3_val = rand(4, 5, 3) atens3_val = rand(4, 5, 3)
for outdim in (3, 2, 1): self._compile_and_check([atens3],
self._compile_and_check([atens3], [flatten(atens3, 1)],
[Flatten(outdim)(atens3)], [atens3_val], Reshape)
[atens3_val], Flatten) #for outdim in (3, 2, 1):
# self._compile_and_check([atens3],
amat = matrix() # [flatten(atens3, outdim)],
amat_val = rand(4, 5) # [atens3_val], Reshape)
for outdim in (2, 1):
self._compile_and_check([amat], #amat = matrix()
[Flatten(outdim)(amat)], #amat_val = rand(4, 5)
[amat_val], Flatten) #for outdim in (2, 1):
# self._compile_and_check([amat],
avec = vector() # [flatten(amat, outdim)],
avec_val = rand(4) # [amat_val], Reshape)
outdim = 1
self._compile_and_check([avec], #avec = vector()
[Flatten(outdim)(avec)], #avec_val = rand(4)
[avec_val], Flatten) #outdim = 1
#self._compile_and_check([avec],
# [flatten(avec, outdim)],
# [avec_val], Reshape)
# Eye # Eye
aiscal = iscalar() aiscal = iscalar()
......
...@@ -60,6 +60,7 @@ from theano.tests import unittest_tools as utt ...@@ -60,6 +60,7 @@ from theano.tests import unittest_tools as utt
from theano.compile.mode import optdb from theano.compile.mode import optdb
from theano.compile import Mode from theano.compile import Mode
from nose.plugins.attrib import attr from nose.plugins.attrib import attr
from theano.tensor.basic import flatten, is_flatten
mode_opt = theano.config.mode mode_opt = theano.config.mode
if mode_opt == 'FAST_COMPILE': if mode_opt == 'FAST_COMPILE':
...@@ -5879,18 +5880,19 @@ def test_local_useless_split(): ...@@ -5879,18 +5880,19 @@ def test_local_useless_split():
def test_local_flatten_lift(): def test_local_flatten_lift():
for i in xrange(1, 4): for i in xrange(1, 4):
op = tensor.Flatten(i)
x = tensor.tensor4() x = tensor.tensor4()
out = op(T.exp(x)) out = tensor.flatten(T.exp(x), i)
assert out.ndim == i assert out.ndim == i
mode = compile.mode.get_default_mode() mode = compile.mode.get_default_mode()
mode = mode.including('local_flatten_lift') mode = mode.including('local_flatten_lift')
f = theano.function([x], out, mode=mode) f = theano.function([x], out, mode=mode)
f(numpy.random.rand(5, 4, 3, 2).astype(config.floatX)) x_np = numpy.random.rand(5, 4, 3, 2).astype(config.floatX)
out_np = f(x_np)
topo = f.maker.fgraph.toposort() topo = f.maker.fgraph.toposort()
assert len(topo) == 2 shape_out_np = tuple(x_np.shape[:i-1])+(numpy.prod(x_np.shape[i-1:]),)
assert isinstance(topo[0].op, tensor.Flatten) assert shape_out_np == out_np.shape
assert isinstance(topo[1].op, tensor.Elemwise) tensor.is_flatten(topo[0], outdim=i)
assert isinstance(topo[-1].op, tensor.Elemwise)
class Test_Reshape(unittest.TestCase): class Test_Reshape(unittest.TestCase):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论