-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
deconv op implementing ... #4739
Conversation
paddle/operators/deconv2d_op.cc
Outdated
|
||
for (int i = 0; i < paddings.size(); ++i) { | ||
PADDLE_ENFORCE_EQ(paddings[i], 0, "No Padding allowed in deconv op."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check should be placed in "Deconv2DOpMaker", the current attribute checker doesn't support 'vector' type. @Canpio
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For vector
is not supported by AttrChecker
right now, we can only do check jobs in the infer shape.
paddle/operators/deconv2d_op.cc
Outdated
|
||
PADDLE_ENFORCE_EQ(in_dims.size(), 4, "Deconv2DOp input should be 4-D."); | ||
PADDLE_ENFORCE_EQ(filter_dims.size(), 4, "Deconv2DOp filter should be 4-D."); | ||
PADDLE_ENFORCE_EQ(in_dims[1], filter_dims[0], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Deconv2DOp filter should be 4-D." -> "Deconv2DOp filter should be 4-D tensor."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.cc
Outdated
"The input tensor of deconvolution operator. " | ||
"The format of input tensor is NMHW. Where N is batch size, M is the " | ||
"number of input channels, H and W is the height and width of image."); | ||
AddInput("Filter", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Deconv case is a little different from Conv case. Like in Caffe2, Conv2d use NCHW for input and MCHW for filter and produces a tensor of shape NMHW; Caffe2 Deconv applies NCHW for input, CMHW for filter and produces output tensor with shape NMHW. I will make it clear in my codes.
paddle/operators/deconv2d_op.cc
Outdated
"The format of output tensor is also NCHW."); | ||
AddAttr<std::vector<int>>("strides", "strides of deconvolution operator.") | ||
.SetDefault({1, 1}); | ||
AddAttr<std::vector<int>>("paddings", "paddings of deconvolution operator.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attribute checker should be placed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @Canpio said, for current version to pass, we temporarily put our check here.
paddle/operators/deconv2d_op.h
Outdated
public: | ||
void Compute(const framework::ExecutionContext& context) const override { | ||
const Tensor* input = context.Input<Tensor>("Input"); | ||
// filter will be reshaped, so we do not use constant pointer here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of "The filter will be reshaped in the calculations, so it should not be constant pointer." ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.h
Outdated
context.Input<Tensor>(framework::GradVarName("Output")); | ||
|
||
// For filter, we do not use const pointer b/c we will do reshape | ||
// but we should avoid modifying its value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add period.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.h
Outdated
context.Output<Tensor>(framework::GradVarName("Filter")); | ||
|
||
std::vector<int> strides = context.Attr<std::vector<int>>("strides"); | ||
// Actually, no paddings and groups allowed in deconv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add period.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.h
Outdated
|
||
int C = output_grad->dims()[1]; // output channels | ||
int O_H = output_grad->dims()[2]; | ||
int O_W = output_grad->dims()[3]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.cc
Outdated
"number of input channels, H and W is the height and width of image."); | ||
AddInput("Filter", | ||
"The filter tensor of deconvolution operator." | ||
"The format of the filter tensor is MCHW, where M is the number of " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"MCHW" - >"NCHW"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.cc
Outdated
"input image channels, C is the number of output image channels, " | ||
"H and W is height and width of filter. " | ||
"We enforce groups number == 1 and padding == 0 in our " | ||
"deconvolution Scenario."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We enforce groups number == 1 and padding == 0 in our deconvolution Scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.cc
Outdated
namespace paddle { | ||
namespace operators { | ||
|
||
void Deconv2DOp::InferShape(framework::InferShapeContext* ctx) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the comments: tensorflow/tensorflow#256 (comment)
How about rename Conv2DTranspose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestion!
paddle/operators/deconv2d_op.cc
Outdated
"Input", | ||
"The input tensor of deconvolution operator. " | ||
"The format of input tensor is NMHW. Where N is batch size, M is the " | ||
"number of input channels, H and W is the height and width of image."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"(Tensor) The input tensor of transposed 2D convolution operator. "
The () is used to denote the type, same as the following annotations.
NMHW -> NCHW
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.h
Outdated
|
||
#pragma once | ||
|
||
#include "glog/logging.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove glog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.h
Outdated
|
||
for (int i = 0; i < N; i++) { | ||
// batch with size (M, H * W) | ||
Tensor input_batch = input->Slice<T>(i, i + 1).Resize(input_matrix_shape); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update code, since the Slice
removed the template T.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.h
Outdated
|
||
std::vector<int> strides = context.Attr<std::vector<int>>("strides"); | ||
|
||
// no paddings and groups allowed in deconv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If to do in next PR, add TODO comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. As we discussed separately, it may be worth trying to speed up GPU performance by using CUDNN convolution kernels in a future PR.
paddle/operators/deconv2d_op.h
Outdated
// but will be reshaped into a two-dimensional matrix shape | ||
// to call the matrix multiplication interface. | ||
Tensor col_matrix = col; | ||
col_matrix.Resize(col_matrix_shape); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That copy assign works as intended, but it looks a little unnatural to me at first glance, since for e.g. std::vector, copy assign copies the data. However, copy assignment does share data in this case because the data is stored inside a std::shared_ptr inside the Tensor class. Nevertheless, I would suggest the more explicit:
Tensor col_matrix;
col_matrix.ShareDataWith(col);
(I realize this is carried over from conv2d_op.h - maybe you could change it there, too?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
paddle/operators/deconv2d_op.h
Outdated
// input need to compute gradient | ||
if (input_grad) { | ||
Tensor col_matrix = col; | ||
DDim col_matrix_shape = {C * K_H * K_W, H * W}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above comment. I would prefer the more explicit:
Tensor col_matrix;
col_matrix.ShareDataWith(col);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
PADDLE_ENFORCE_EQ(filter_dims.size(), 4, | ||
"Conv2DTransposeOp filter should be 4-D tensor."); | ||
PADDLE_ENFORCE_EQ(in_dims[1], filter_dims[0], | ||
"input and kernel input dimension should be equal."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
->"In Conv2DTransposeOp, The input channel should be the same as the number of filters."
The convolution transpose operation calculates the output based on the input, filter | ||
and strides, paddings, groups parameters. The size of each dimension of the | ||
parameters is checked in the infer-shape. | ||
)DOC"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to give how to calculate the output height/width according to the input height/with, padding and stride size.
The doc of Pytorch is good.
std::vector<int> strides = context.Attr<std::vector<int>>("strides"); | ||
|
||
// TODO(Zhuoyuan): Paddings can be added in future. | ||
// groups will alway be disabled in conv2dtranspose. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The attribution of group should be available in conv2dtranspose. Reference Pytorch
for (int i = 0; i < batch_size; i++) { | ||
// batch with size (M, h * w) | ||
Tensor input_batch = input->Slice(i, i + 1).Resize(input_matrix_shape); | ||
// filter size: (M, c * k_h * k_w) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can delete this comment or write in line 119.
// batch with size (c, o_h * o_w) | ||
Tensor output_grad_batch = | ||
output_grad->Slice(i, i + 1).Resize(output_shape); | ||
// filter of size (m, c * k_h * k_w) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
self.dilations = [1, 1] | ||
self.input_size = [2, 3, 5, 5] # NCHW | ||
f_c = self.input_size[1] | ||
self.filter_size = [f_c, 6, 3, 3] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the calculation is not very time-consuming, you can write several border test examples.
No description provided.