@ -7025,9 +7025,9 @@ def reshape(x, shape, actual_shape=None, act=None, inplace=False, name=None):
Gives a new shape to the input Tensor without changing its data .
The target shape can be given by : attr : ` shape ` or : attr : ` actual_shape ` .
: attr : ` shape ` is a list of integer while : attr : ` actual_shape ` is a tensor
: attr : ` shape ` is a list of integer or tensor variable while : attr : ` actual_shape ` is a tensor
variable . : attr : ` actual_shape ` has a higher priority than : attr : ` shape `
if it is provided , while : attr : ` shape ` still should be set correctly to
if it is provided and it only contains integer , while : attr : ` shape ` still should be set correctly to
gurantee shape inference in compile - time .
Some tricks exist when specifying the target shape .
@ -7059,15 +7059,22 @@ def reshape(x, shape, actual_shape=None, act=None, inplace=False, name=None):
besides - 1 , 0 means the actual dimension value is going to be copied from
the corresponding dimension of x .
* * Warning : * * the parameter : attr : ` actual_shape ` will be deprecated in the future and only use : attr : ` shape ` instead .
Args :
x ( variable ) : The input tensor .
shape ( list ) : The new shape . At most one dimension of the new shape can
be - 1.
shape ( list | tuple | Variable ) : The new shape . At most one dimension of the new shape can
be - 1. If : attr : ` shape ` is a list or tuple , it can contain Variable or not and
the shape of Variable must be [ 1 ] .
actual_shape ( variable ) : An optional input . If provided , reshape
according to this given shape rather than
: attr : ` shape ` specifying shape . That is to
say : attr : ` actual_shape ` has a higher priority
than : attr : ` shape ` .
than : attr : ` shape ( list | tuple ) ` but not : attr : ` shape ( Variable ) ` . \
This argument : attr : ` actual_shape ` will be removed in a future version . \
Instructions for updating : : attr : ` actual_shape ` is deprecated ,
only use : attr : ` shape ` instead .
act ( str ) : The non - linear activation to be applied to the reshaped tensor
variable .
inplace ( bool ) : If ` ` inplace ` ` is ` True ` , the input and output of ` ` layers . reshape ` `
@ -7089,64 +7096,89 @@ def reshape(x, shape, actual_shape=None, act=None, inplace=False, name=None):
. . code - block : : python
import paddle . fluid as fluid
data = fluid . layers . data (
name = ' data ' , shape = [ 2 , 4 , 6 ] , dtype = ' float32 ' )
reshaped = fluid . layers . reshape (
x = data , shape = [ - 1 , 0 , 3 , 2 ] , inplace = True )
# example 1:
# attr shape is a list which doesn't contain tensor Variable.
data_1 = fluid . layers . data (
name = ' data_1 ' , shape = [ 2 , 4 , 6 ] , dtype = ' float32 ' )
reshaped_1 = fluid . layers . reshape (
x = data_1 , shape = [ - 1 , 0 , 3 , 2 ] , inplace = True )
# example 2:
# attr shape is a list which contains tensor Variable.
data_2 = fluid . layers . fill_constant ( [ 2 , 25 ] , " int32 " , 3 )
dim = fluid . layers . fill_constant ( [ 1 ] , " int32 " , 5 )
reshaped_2 = fluid . layers . reshape ( data_2 , shape = [ dim , 10 ] )
"""
if not ( isinstance ( shape , list ) or isinstance ( shape , tuple ) ) :
raise ValueError ( " Input shape must be a python list or tuple. " )
if not isinstance ( shape , ( list , tuple , Variable ) ) :
raise TypeError (
" Input shape must be an Variable or python list or tuple. " )
inputs = { " X " : x }
if isinstance ( actual_shape , Variable ) :
inputs [ " Shape " ] = actual_shape
elif actual_shape is not None :
raise TypeError ( " actual_shape should either be Variable or None " )
# Validate the shape
unk_dim_idx = - 1
contain_var = False
for dim_idx , dim_size in enumerate ( shape ) :
if isinstance ( dim_size , Variable ) :
contain_var = True
continue
if dim_size == - 1 :
assert unk_dim_idx == - 1 , (
" Only one dimension in shape can be unknown. " )
unk_dim_idx = dim_idx
elif dim_size == 0 :
assert dim_idx < len ( x . shape ) , (
" The indice of 0s in shape can not exceed Rank(X). " )
else :
assert dim_size > 0 , (
" Each dimension size given in shape must not be negtive "
" except one unknown dimension. " )
if not isinstance ( actual_shape , Variable ) and ( actual_shape is not None ) :
raise TypeError ( " actual_shape should either be Variable or None. " )
helper = LayerHelper ( " reshape2 " , * * locals ( ) )
inputs = { " X " : x }
attrs = { }
def contain_var ( one_list ) :
for ele in one_list :
if isinstance ( ele , Variable ) :
return True
return False
def get_new_shape_tensor ( list_shape ) :
new_shape_tensor = [ ]
for dim in list_shape :
if isinstance ( dim , Variable ) :
dim . stop_gradient = True
new_shape_tensor . append ( dim )
else :
assert ( isinstance ( dim , int ) )
temp_out = helper . create_variable_for_type_inference ( ' int32 ' )
fill_constant ( [ 1 ] , ' int32 ' , dim , force_cpu = True , out = temp_out )
new_shape_tensor . append ( temp_out )
return new_shape_tensor
def get_attr_shape ( list_shape ) :
unk_dim_idx = - 1
attrs_shape = [ ]
for dim_idx , dim_size in enumerate ( list_shape ) :
if isinstance ( dim_size , Variable ) :
attrs_shape . append ( - 1 )
else :
attrs_shape . append ( dim_size )
if dim_size == - 1 :
assert unk_dim_idx == - 1 , (
" Only one dimension in shape can be unknown. " )
unk_dim_idx = dim_idx
elif dim_size == 0 :
assert dim_idx < len ( x . shape ) , (
" The indice of 0s in shape can not exceed Rank(X). " )
else :
assert dim_size > 0 , (
" Each dimension size given in shape must not be negtive "
" except one unknown dimension. " )
return attrs_shape
if in_dygraph_mode ( ) :
inputs = { ' X ' : x }
attrs = { ' shape ' : shape }
else :
if contain_var :
new_shape_tensor = [ ]
for dim in shape :
if isinstance ( dim , Variable ) :
dim . stop_gradient = True
new_shape_tensor . append ( dim )
else :
assert ( isinstance ( dim , int ) )
temp_out = helper . create_variable_for_type_inference (
' int32 ' )
fill_constant (
[ 1 ] , ' int32 ' , dim , force_cpu = True , out = temp_out )
new_shape_tensor . append ( temp_out )
inputs [ ' ShapeTensor ' ] = new_shape_tensor
attrs = { }
if isinstance ( shape , Variable ) :
shape . stop_gradient = True
inputs [ " Shape " ] = shape
elif isinstance ( shape , ( list , tuple ) ) :
assert len ( shape ) > 0 , (
" The size of argument(shape) can ' t be zero. " )
attrs [ " shape " ] = get_attr_shape ( shape )
if contain_var ( shape ) :
inputs [ ' ShapeTensor ' ] = get_new_shape_tensor ( shape )
elif isinstance ( actual_shape , Variable ) :
actual_shape . stop_gradient = True
inputs [ " Shape " ] = actual_shape
else :
attrs = { ' shape ' : shape }
out = x if inplace else helper . create_variable_for_type_inference (
dtype = x . dtype )
x_shape = helper . create_variable_for_type_inference ( dtype = x . dtype )