Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add im2sequence op. #4866

Merged
merged 25 commits into from
Jan 23, 2018
Merged

Conversation

gongweibao
Copy link
Contributor

Fix #4715

"Output of BlockExpandOp op should not be null.");

auto in_dim = ctx->GetInputDim("X");
PADDLE_ENFORCE_EQ(in_dim.size(), 4, "Input format must be NCHW.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Input(x) must be 4D tensor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

int block_height, int block_width,
int stride_height, int stride_width,
int padding_height, int padding_width,
int& outputHeight, int& outputWidth) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里觉得类似conv , pool的写法,一组参数(不用height, width都在这里计算)就好了,用的地方调用多次就好了。另外,函数命名: "CamelCase": https://google.github.io/styleguide/cppguide.html#Function_Names

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx. Fixed.


auto in_dim = ctx->GetInputDim("X");
PADDLE_ENFORCE_EQ(in_dim.size(), 4, "Input format must be NCHW.");
PADDLE_ENFORCE_GE(in_dim[0], 1, "Input batchsize must >= 1.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better not to do this check for batch size. Maybe the batch size is a special value in the compile time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没太看懂。in_dim[0]这一维可以忽略?或者==0?

Copy link
Contributor

@wanghaoshuang wanghaoshuang Jan 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have removed this checker.

// output_height * output_width, stepSize is equal
// input_channels * blockHeight * blockWidth
ctx->SetOutputDim(
"Out", {N, output_height, output_width, C, block_height, block_width});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output shape is not correct.

Height = N * output_height * output_width,
Width = C * block_height * block_width

Please to look the original implementation carefully and confirm it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx. Fixed.

ctx->SetOutputDim(
"Out", {N, output_height, output_width, C, block_height, block_width});

// ctx->ShareLoD("X", /*->*/ "Out");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to set LoD in the InferShape. And the input is tenor without lod and the output is LoDTensor with lod.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

暂时先在run time计算并设置了LoD,并增加TODO注释:待InferShape 开放 set_lod接口后,将计算LoD逻辑转移到InferShape

1 + (2 * paddingWidth + img_width - blockWidth + strideWidth - 1) /
strideWidth;

The expand method is the same with ExpandConvLayer, but saved the transposed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no ExpandConvLayer in the new framework. And the original comments in the BlockExpandLayer is not good. This comment is for users. Actually, the users do not familiar with the implementation details in code. Please help to improve the doc. And maybe the simple examples are also to help to explain clearly.

Copy link
Contributor

@wanghaoshuang wanghaoshuang Jan 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an exmple.

void Compute(const framework::ExecutionContext& ctx) const override {
using namespace framework;
const Tensor* in = ctx.Input<Tensor>("X");
Tensor* out = ctx.Output<Tensor>("Out");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

老框架这个层有两个主要的特点:1. 对输入按照Sliding Window展开 2. 给输出填充LoD.

因为输入是Tensor,输出LoD是定长序列,按照现在这样实现,这个Op后面还需要接一个设置LoD的Op。 不然,需要在这个Op里设置输出的LoD。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx. Fixed.


for (int i = 0; i < N; i++) {
Tensor src = in->Slice<T>(i, i + 1).Resize({C, img_height, img_width});
Tensor dst = out->Slice<T>(i, i + 1).Resize(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update code, since Slice has removed template T.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

'strideWidth': 1,
'paddingHeight': 1,
'paddingWidth': 1,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要测试更多的case, stride>1, blockHeight, blockWidth不相等的情况。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

增加了batch_size>1的case, 并重构了单测代码,方便增加测试用例。

strideHeight = attrs['strideHeight']
strideWidth = attrs['strideWidth']
paddingHeight = attrs['paddingHeight']
paddingWidth = attrs['paddingWidth']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里Python的命名混合了多种,比如: input_channels, inputHeight,觉得修改一致吧。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

1. Add lod to output
2. Fix im2col arguments list
3. Refine code and doc
4. Fix output shape
@wanghaoshuang wanghaoshuang requested review from pkuyym and removed request for hedaoyuan January 17, 2018 03:18
protected:
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"),
"Input of BlockExpandOp should not be null.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Input --> Input(X)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

PADDLE_ENFORCE(ctx->HasInput("X"),
"Input of BlockExpandOp should not be null.");
PADDLE_ENFORCE(ctx->HasOutput("Out"),
"Output of BlockExpandOp op should not be null.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Output --> Output(Out)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

int padding_height = ctx->Attrs().Get<int>("padding_height");
int padding_width = ctx->Attrs().Get<int>("padding_width");

int batch_size = in_dim[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to confirm the layout is NCHW.

Copy link
Contributor

@wanghaoshuang wanghaoshuang Jan 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the layout of input tensor is not available in InferShape context. So I add layout checker into the runtime. I add a TODO comments to remind me adding layout checker after 'layout' being available in framework.proto .

namespace paddle {
namespace operators {

class BlockExpandOp : public framework::OperatorWithKernel {
Copy link
Contributor

@pkuyym pkuyym Jan 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can discuss the name of this operator. It seems that BlockExpandOp isn't self-explain well. I think we need a better name here such as flatten_block_conv_way_op

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename 'block_expand' to im2sequence. Because this op is actually a wrapper of im2col functor.

// TODO(wanghaoshuang): Move this to InferShape
framework::LoD lod(1);
for (int i = 0, offset = 0; i < batch_size + 1; ++i) {
lod[0].push_back(offset);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reserve memory for lod[0] first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx. Fixed.


def get_output_shape(attrs, x):
img_height = x.shape[2]
img_width = x.shape[3]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to pass x.shape instead x.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx. Fixed.

@wanghaoshuang wanghaoshuang changed the title Block expand op. Add im2sequence op. Jan 17, 2018
AddAttr<int>("stride_height", "(int)height of stride.");
AddAttr<int>("stride_width", "(int)width of stride.");
AddAttr<int>("padding_height", "(int)height of padding.");
AddAttr<int>("padding_width", "(int)width of padding.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The attributes are too much. Please refer the attribues in https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/conv_op.cc#L112

Use std::vector<int> instead of int .

AddAttr<std::vector<int>>("kernels", ...) // or blocks?
AddAttr<std::vector<int>>("strides", ...)
AddAttr<std::vector<int>>("paddings", ...)

inline int get_output_size(int img_size, int block_size, int stride,
int padding) {
return (1 + (img_size + 2 * padding - block_size + stride - 1) / stride);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_output_size -> OutputSize, make the name same with https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/conv_op.h#L30

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OutputSize seems not a good name for a function. GetOutputSize may be a better one.


auto in_dim = ctx->GetInputDim("X");
PADDLE_ENFORCE_EQ(in_dim.size(), 4,
"Input(X) format must be 4D tensor, eg., NCHW.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove redundant whitespace char.

inline int get_output_size(int img_size, int block_size, int stride,
int padding) {
return (1 + (img_size + 2 * padding - block_size + stride - 1) / stride);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OutputSize seems not a good name for a function. GetOutputSize may be a better one.

Copy link
Contributor

@qingqing01 qingqing01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Im2SequenceOp以后想出更合理在更正~

@wanghaoshuang wanghaoshuang merged commit 6d2cfe9 into PaddlePaddle:develop Jan 23, 2018
@wanghaoshuang wanghaoshuang moved this from DOING to DONE in Computer Vision on Fluid Jan 23, 2018
@gongweibao gongweibao deleted the blockexpand branch January 17, 2021 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

None yet

4 participants