Skip to content

Commit 985e4ab

Browse files
authored
Add Python wrap of conv2d_transpose and its unittest (#5946)
* Add Python wrap of conv2d_transpose and its unittest * Follow comments * Fix format
1 parent 0aceeee commit 985e4ab

File tree

4 files changed

+112
-14
lines changed

4 files changed

+112
-14
lines changed

paddle/operators/conv_transpose_op.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ Conv2DTransposeOpMaker::Conv2DTransposeOpMaker(
7474
"The format of output tensor is also NCHW.");
7575
AddAttr<std::vector<int>>(
7676
"strides",
77-
"(vector<int> defalut:{1, 1}), the strides(h_stride, w_stride) of "
77+
"(vector<int> default:{1, 1}), the strides(h_stride, w_stride) of "
7878
"convolution transpose operator.")
7979
.SetDefault({1, 1});
8080
AddAttr<std::vector<int>>(
8181
"paddings",
82-
"(vector<int> defalut:{0, 0}), the paddings(h_pad, w_pad) of convolution "
82+
"(vector<int> default:{0, 0}), the paddings(h_pad, w_pad) of convolution "
8383
"transpose operator.")
8484
.SetDefault({0, 0});
8585
AddComment(R"DOC(
@@ -101,8 +101,8 @@ The input(X) size and output(Out) size may be different.
101101
Output:
102102
Output shape: (N, C_out, H_out, W_out)
103103
where
104-
H_out = (H_in - 1) * strides[0] - 2 * paddings[0] + filter_size[0];
105-
W_out = (W_in - 1) * strides[1] - 2 * paddings[1] + filter_size[1];
104+
H_out = (H_in - 1) * strides[0] - 2 * paddings[0] + H_f;
105+
W_out = (W_in - 1) * strides[1] - 2 * paddings[1] + W_f;
106106
)DOC");
107107
}
108108

@@ -130,12 +130,12 @@ Conv3DTransposeOpMaker::Conv3DTransposeOpMaker(
130130
"the number of channels, D is the depth of the feature, H is the "
131131
"height of the feature, and W is the width of the feature.");
132132
AddAttr<std::vector<int>>("strides",
133-
"(vector<int> defalut:{1, 1, 1}), the "
133+
"(vector<int> default:{1, 1, 1}), the "
134134
"strides{d_stride, h_stride, w_stride} of "
135135
"convolution transpose operator.")
136136
.SetDefault({1, 1, 1});
137137
AddAttr<std::vector<int>>("paddings",
138-
"(vector<int> defalut:{0, 0, 0}), paddings(d_pad, "
138+
"(vector<int> default:{0, 0, 0}), paddings(d_pad, "
139139
"h_pad, w_pad) of convolution transpose operator.")
140140
.SetDefault({0, 0, 0});
141141
AddComment(R"DOC(
@@ -158,9 +158,9 @@ The input(X) size and output(Out) size may be different.
158158
Output:
159159
Output shape: (N, C_out, D_out, H_out, W_out)
160160
where
161-
D_out = (D_in - 1) * strides[0] - 2 * paddings[0] + filter_size[0];
162-
H_out = (H_in - 1) * strides[1] - 2 * paddings[1] + filter_size[1];
163-
W_out = (W_in - 1) * strides[2] - 2 * paddings[2] + filter_size[2];
161+
D_out = (D_in - 1) * strides[0] - 2 * paddings[0] + D_f;
162+
H_out = (H_in - 1) * strides[1] - 2 * paddings[1] + H_f;
163+
W_out = (W_in - 1) * strides[2] - 2 * paddings[2] + W_f;
164164
)DOC");
165165
}
166166

paddle/operators/detail/send_recv.proto

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ syntax = "proto3";
1717
package sendrecv;
1818

1919
service SendRecvService {
20-
// For parameter server round-robin like hashing, do not split tensors.
20+
// For parameter server round-robin like hashing, do not split tensors.
2121
// Send and recv only one tensor
2222
rpc SendVariable(VariableMessage) returns (VariableMessage) {}
2323
}
@@ -32,6 +32,4 @@ message VariableMessage {
3232
bytes serialized = 2;
3333
}
3434

35-
message VoidMessage {
36-
37-
}
35+
message VoidMessage {}

python/paddle/v2/fluid/layers.py

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import core
22
import proto.framework_pb2 as framework_pb2
33
from framework import OpProtoHolder, Variable, Program, Operator
4-
from initializer import Constant, Normal, Xavier
4+
from initializer import Constant, Normal, Xavier, Initializer
55
from paddle.v2.fluid.layer_helper import LayerHelper, unique_name
66
import re
77
import cStringIO
@@ -1587,6 +1587,97 @@ def array_length(array, main_program=None):
15871587
return tmp
15881588

15891589

1590+
def conv2d_transpose(input,
1591+
num_filters,
1592+
output_size=None,
1593+
filter_size=None,
1594+
padding=None,
1595+
stride=None,
1596+
param_attr=None,
1597+
param_initializer=None,
1598+
main_program=None,
1599+
startup_program=None):
1600+
"""
1601+
The transpose of conv2d layer.
1602+
1603+
This layer is also known as deconvolution layer.
1604+
1605+
Args:
1606+
input(Variable): The input image with [N, C, H, W] format.
1607+
num_filters(int): The number of filter. It is as same as the output
1608+
image channel.
1609+
output_size(int|tuple|None): The output image size. If output size is a
1610+
tuple, it must contain two integers, (image_H, image_W). This
1611+
parameter only works when filter_size is None.
1612+
filter_size(int|tuple|None): The filter size. If filter_size is a tuple,
1613+
it must contain two integers, (filter_size_H, filter_size_W).
1614+
Otherwise, the filter will be a square. None if use output size to
1615+
calculate filter_size
1616+
padding(int|tuple): The padding size. If padding is a tuple, it must
1617+
contain two integers, (padding_H, padding_W). Otherwise, the
1618+
padding_H = padding_W = padding.
1619+
stride(int|tuple): The stride size. If stride is a tuple, it must
1620+
contain two integers, (stride_H, stride_W). Otherwise, the
1621+
stride_H = stride_W = stride.
1622+
param_attr: Parameter Attribute.
1623+
param_initializer(Initializer): Parameter Initializer. Default is Xavier
1624+
main_program(Program): the main program
1625+
startup_program(Program): the startup program
1626+
1627+
Returns:
1628+
Variable: Output image.
1629+
"""
1630+
helper = LayerHelper("conv2d_transpose", **locals())
1631+
if not isinstance(input, Variable):
1632+
raise TypeError("Input of conv2d_transpose must be Variable")
1633+
input_channel = input.shape[1]
1634+
1635+
op_attr = dict()
1636+
1637+
if isinstance(padding, int):
1638+
op_attr['paddings'] = [padding, padding]
1639+
elif padding is not None:
1640+
op_attr['paddings'] = padding
1641+
1642+
if isinstance(stride, int):
1643+
op_attr['strides'] = stride
1644+
elif stride is not None:
1645+
op_attr['strides'] = stride
1646+
1647+
if filter_size is None:
1648+
if output_size is None:
1649+
raise ValueError("output_size must be set when filter_size is None")
1650+
if isinstance(output_size, int):
1651+
output_size = [output_size, output_size]
1652+
1653+
padding = op_attr.get('paddings', [0, 0])
1654+
stride = op_attr.get('strides', [1, 1])
1655+
1656+
h_in = input.shape[2]
1657+
w_in = input.shape[3]
1658+
filter_size_h = output_size[0] - (h_in - 1) * stride[0] + 2 * padding[0]
1659+
filter_size_w = output_size[1] - (w_in - 1) * stride[1] + 2 * padding[1]
1660+
filter_size = [filter_size_h, filter_size_w]
1661+
elif isinstance(filter_size, int):
1662+
filter_size = [filter_size, filter_size]
1663+
1664+
filter_shape = [input_channel, num_filters] + filter_size
1665+
img_filter = helper.create_parameter(
1666+
dtype=input.dtype,
1667+
shape=filter_shape,
1668+
attr=helper.param_attr,
1669+
initializer=param_initializer)
1670+
1671+
out = helper.create_tmp_variable(dtype=input.dtype)
1672+
helper.append_op(
1673+
type='conv2d_transpose',
1674+
inputs={'Input': [input],
1675+
'Filter': [img_filter]},
1676+
outputs={'Output': out},
1677+
attrs=op_attr)
1678+
return out
1679+
1680+
15901681
class ConditionalBlockGuard(BlockGuard):
15911682
def __init__(self, block):
15921683
if not isinstance(block, ConditionalBlock):

python/paddle/v2/fluid/tests/test_layers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ def test_simple_conv2d(self):
6565

6666
print str(program)
6767

68+
def test_conv2d_transpose(self):
69+
program = Program()
70+
kwargs = {'main_program': program}
71+
img = layers.data(
72+
name='pixel', shape=[3, 2, 2], dtype='float32', **kwargs)
73+
layers.conv2d_transpose(
74+
input=img, num_filters=10, output_size=28, **kwargs)
75+
print str(program)
76+
6877
def test_recognize_digits_conv(self):
6978
program = Program()
7079

0 commit comments

Comments
 (0)