提交 a6e64242 编写于 作者: C caoying03

follow comments.

上级 c87d11a7
......@@ -44,22 +44,22 @@ class ReshapeOp : public framework::OperatorWithKernel {
ctx->SetOutputDim("Out", x_dims);
} else {
ctx->SetOutputDim("Out", framework::make_ddim(output_shape));
// FIXME(caoying): When shape of the output tensor is determined during
// runtime, LoD information of X will not passed to the output.
if (shape[0] == x_dims[0]) {
// Only pass LoD when the first dimension of output and Input(X)
// are the same.
ctx->ShareLoD("X", /*->*/ "Out");
}
}
// NOTE: Reshape op cannot reshape an input sequence batch into an output
// sequence batch that has a different number of time steps.
// Here output always shares the LoD information with input. But if
// Attr(shape) contains 0 or -1, the actual output shape can only be
// determined during runtime. The check for wheather it is a valid output
// sequence batch is performed in runtime.
ctx->ShareLoD("X", /*->*/ "Out");
}
private:
bool ValidateShape(const std::vector<int> &shape,
const framework::DDim &input_dim,
std::vector<int64_t> &output_shape) const {
// only one dimension canbe set to -1, whose size will be automatically
// only one dimension can be set to -1, whose size will be automatically
// infered.
const int64_t unknown_index = -1;
const auto in_size = framework::product(input_dim);
......@@ -82,7 +82,7 @@ class ReshapeOp : public framework::OperatorWithKernel {
}
PADDLE_ENFORCE_LE(
neg_dims_idx.size(), 1,
"Only one input dimension of Attr(shape) may be unknown.");
"Only one input dimension of Attr(shape) can be unknown.");
output_shape.resize(shape.size(), 0);
std::transform(shape.begin(), shape.end(), output_shape.begin(),
......@@ -113,22 +113,46 @@ class ReshapeOpMaker : public framework::OpProtoAndCheckerMaker {
AddAttr<std::vector<int>>(
"shape", "(std::vector<int>) Target shape of reshape operator.");
AddAttr<bool>("inplace",
"Change the source tensor's shape without copy memory.")
.SetDefault(true);
"(default: false) Change the source tensor's shape without "
"memory copy. When Attr(inplace) is set true, the output "
"tensor shares memory with Input(X), otherwise, a new output "
"tensor is created, and its data are copied from Input(x).")
.SetDefault(false);
AddComment(R"DOC(
Reshape Operator.
Reshape Input(X) into the shape specified by Attr(shape).
Reshape Input(X) into the shape specified by Attr(shape). The data in Input(X)
are unchanged.
Examples:
1. Given a 3-D tensor Input(X) with a shape [2, 4, 6], and the target shape
specified by Attr(shape) is [6, 8], the reshape operator will transform Input(X)
into a 2-D tensor with shape [6, 8] and leaving Input(X)'s data unchanged.
1. Given a 3-D tensor Input(X) with a shape [2, 4, 6], and the target shape
specified by Attr(shape) is [2, 3, -1, 2], the reshape operator will transform
Input(X) into a 4-D tensor with shape [2, 3, 4, 2] and leaving Input(X)'s data
unchanged. In this case, one and only dimension of Attr(shape) can be set to -1,
the value of this dimension is inferred from the total element number of
Input(X) and remaining dimensions.
1. Given a 3-D tensor Input(X) with a shape [2, 4, 6], and the target shape
specified by Attr(shape) is [-1, 0, 3, 2], the reshape operator will transform
Input(X) into a 4-D tensor with shape [2, 4, 3, 2] and leaving Input(X)'s data
unchanged. In this case, besides -1, 0 means the actual dimension value is going
to be copied from the corresponding dimension of Input(X).
An example:
Given a 2-D tensor X with 2 rows and 2 columns : [[1, 2], [3, 4]]
Note:
and target shape = [1, 4], the reshape operator will transform
the tensor X into a 2-D tensor: [[1, 2, 3, 4]]
1. One and only one dimension in Attr(shape) can be set -1. In this case,
the actual dimension value will be infered from the total element number of
Input(X) and remaining dimensions.
1. More than one dimensions in Attr(shape) can be set to 0, which means the real
dimension value will be copied from Input(X) at runtime. Note that the index of
0 can not access Rank(X). For example, Input(X) is a 3-D tensor with shape
[2, 3, 4], Attr(shape) = [2, 3, 2, 0] is an invalid input.
One dimension in the target shape can be set -1, representing that its
size is unknown. In this case, the real dimension will be infered from
the original shape of Input(X) and other dimensions in the target shape.
)DOC");
}
};
......
......@@ -24,11 +24,21 @@ template <typename DeviceContext, typename T>
class ReshapeKernel : public framework::OpKernel<T> {
public:
void Compute(const framework::ExecutionContext& ctx) const {
auto* out = ctx.Output<framework::Tensor>("Out");
auto* in = ctx.Input<framework::Tensor>("X");
auto* out = ctx.Output<framework::LoDTensor>("Out");
auto* in = ctx.Input<framework::LoDTensor>("X");
auto out_dims =
ValidateShape(ctx.Attr<std::vector<int>>("shape"), in->dims());
if (!in->lod().empty()) {
PADDLE_ENFORCE_EQ(
out_dims[0], in->dims()[0],
"Reshape operator cannot reshape an input sequence batch "
"into an output sequence batch that has a different "
"number of time steps. Please consider using "
"sequence_reshape op.");
}
bool inplace = ctx.Attr<bool>("inplace");
if (!inplace) {
out->mutable_data<T>(ctx.GetPlace());
......
......@@ -130,9 +130,9 @@ def detection_output(loc,
code_type='decode_center_size')
old_shape = scores.shape
scores = ops.reshape(x=scores, shape=(-1, old_shape[-1]))
scores = nn.reshape(x=scores, shape=(-1, old_shape[-1]))
scores = nn.softmax(input=scores)
scores = ops.reshape(x=scores, shape=old_shape)
scores = nn.reshape(x=scores, shape=old_shape)
scores = nn.transpose(scores, perm=[0, 2, 1])
nmsed_outs = helper.create_tmp_variable(dtype=decoded_box.dtype)
......
......@@ -3299,13 +3299,35 @@ def autoincreased_step_counter(counter_name=None, begin=1, step=1):
def reshape(x, shape, act=None, inplace=True, name=None):
"""
Gives a new shape to Tensor without changing its data.
This layer takes a tensor as input and the attribute shape specifying the
new shape. The shape attribute must be specified. At most one dimension of
the new shape can be -1. In this case, the value is inferred from the size
of the tensor and the remaining dimensions. A dimension could also be 0,
in which case the actual dimension value is going to be copied from the
input tensor.
Gives a new shape to the input Tensor without changing its data.
This layer takes a tensor and the attribute shape which specifies the
new shape as its inputs. The shape attribute must be given. It cannot be
empty. One and only one dimension of shape can be -1. More than one
dimension of shape can be 0.
-1 means the value of this dimension is inferred from the total element
number of x and remaining dimensions.
0 means the actual dimension value is going to be copied from the
corresponding dimension of x.
1. Given a 3-D tensor x with a shape [2, 4, 6], and the target shape
specified by Attr(shape) is [6, 8], the reshape operator will transform x
into a 2-D tensor with shape [6, 8] and leaving x's data unchanged.
1. Given a 3-D tensor x with a shape [2, 4, 6], and the target shape
specified by Attr(shape) is [2, 3, -1, 2], the reshape operator will
transform x into a 4-D tensor with shape [2, 3, 4, 2] and leaving x's data
unchanged. In this case, one and only dimension of Attr(shape) can be set
to -1, the value of this dimension is inferred from the total element number
of x and remaining dimensions.
1. Given a 3-D tensor x with a shape [2, 4, 6], and the target shape
specified by Attr(shape) is [-1, 0, 3, 2], the reshape operator will
transform x into a 4-D tensor with shape [2, 4, 3, 2] and leaving x's data
unchanged. In this case, besides -1, 0 means the actual dimension value is
going to be copied from the corresponding dimension of x during runtime.
Args:
input(variable): The input tensor.
......@@ -3320,18 +3342,10 @@ def reshape(x, shape, act=None, inplace=True, name=None):
Examples:
.. code-block:: python
Given a 2-D tensor X with shape [2 x 2], and the new shape: [1, 4].
The reshape layer will change tensor X into a 2-D tensor with
shape [1 x 4] with its data unchanged.
Given a 3-D tensor x with shape [2, 3, 4] and the new shape: [3, -1].
The reshape layer will change tensor X into a 2-D tensor with shape:
[3 x 8] with its data unchanged.
Given a 3-D tensor x with shape [2, 3, 8] and the new shape:
[-1, 0, 2, 2]. The reshape layer will change tensor X into a 4-D tensor
with shape [4, 3, 2, 2] with its data unchanged.
data = fluid.layers.data(name='data', shape=[2, 4, 6], dtype='float32')
reshaped = fluid.layers.reshape(
x=data, shape=[-1, 0, 3, 2], act='tanh', inplace=True
)
"""
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册