Skip to content

Commit fb20187

Browse files
author
wangyang59
committed
deconv layer implementation modification following luotao1 comments
1 parent 3d72e94 commit fb20187

File tree

7 files changed

+115
-126
lines changed

7 files changed

+115
-126
lines changed

paddle/gserver/layers/ConvBaseLayer.cpp

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -89,42 +89,41 @@ size_t ConvBaseLayer::calOutputSize() {
8989
clearAndReserve(&outputW_);
9090
size_t layerSize = 0;
9191

92-
if (!isDeconv_) {
92+
auto setLayerSize = [&](IntV& inH, IntV& inW, IntV& outH, IntV& outW) {
9393
for (size_t i = 0; i < inputLayers_.size(); i++) {
94-
imgSizeH_.push_back(inputLayers_[i]->getOutput().getFrameHeight());
95-
imgSizeW_.push_back(inputLayers_[i]->getOutput().getFrameWidth());
96-
if (imgSizeH_[i] == 0)
97-
imgSizeH_[i] = config_.inputs(i).conv_conf().img_size();
98-
if (imgSizeW_[i] == 0)
99-
imgSizeW_[i] = config_.inputs(i).conv_conf().img_size();
100-
outputH_.push_back(
101-
outputSize(imgSizeH_[i], filterSizeY_[i], paddingY_[i], strideY_[i]));
102-
outputW_.push_back(
103-
outputSize(imgSizeW_[i], filterSize_[i], padding_[i], stride_[i]));
104-
CHECK_EQ(outputH_[i], outputH_[0]);
105-
CHECK_EQ(outputW_[i], outputW_[0]);
94+
inH.push_back(inputLayers_[i]->getOutput().getFrameHeight());
95+
inW.push_back(inputLayers_[i]->getOutput().getFrameWidth());
96+
if (isDeconv_) {
97+
if (inH[i] == 0)
98+
inH[i] = config_.inputs(i).conv_conf().output_x();
99+
if (inW[i] == 0)
100+
inW[i] = config_.inputs(i).conv_conf().output_x();
101+
outH.push_back(
102+
imageSize(inH[i], filterSizeY_[i], paddingY_[i], strideY_[i]));
103+
outW.push_back(
104+
imageSize(inW[i], filterSize_[i], padding_[i], stride_[i]));
105+
} else {
106+
if (inH[i] == 0)
107+
inH[i] = config_.inputs(i).conv_conf().img_size();
108+
if (inW[i] == 0)
109+
inW[i] = config_.inputs(i).conv_conf().img_size();
110+
outH.push_back(
111+
outputSize(inH[i], filterSizeY_[i], paddingY_[i], strideY_[i]));
112+
outW.push_back(
113+
outputSize(inW[i], filterSize_[i], padding_[i], stride_[i]));
114+
CHECK_EQ(outH[i], outH[0]);
115+
CHECK_EQ(outW[i], outW[0]);
116+
}
106117
}
107-
getOutput().setFrameHeight(outputH_[0]);
108-
getOutput().setFrameWidth(outputW_[0]);
109-
layerSize = outputH_[0] * outputW_[0] * size_t(numFilters_);
118+
getOutput().setFrameHeight(outH[0]);
119+
getOutput().setFrameWidth(outW[0]);
120+
layerSize = outH[0] * outW[0] * size_t(numFilters_);
121+
};
122+
123+
if (isDeconv_) {
124+
setLayerSize(outputH_, outputW_, imgSizeH_, imgSizeW_);
110125
} else {
111-
for (size_t i = 0; i < inputLayers_.size(); i++) {
112-
outputH_.push_back(inputLayers_[i]->getOutput().getFrameHeight());
113-
outputW_.push_back(inputLayers_[i]->getOutput().getFrameWidth());
114-
if (outputH_[i] == 0)
115-
outputH_[i] = config_.inputs(i).conv_conf().output_x();
116-
if (outputW_[i] == 0)
117-
outputW_[i] = config_.inputs(i).conv_conf().output_x();
118-
imgSizeH_.push_back(
119-
imageSize(outputH_[i], filterSizeY_[i], paddingY_[i], strideY_[i]));
120-
imgSizeW_.push_back(
121-
imageSize(outputW_[i], filterSize_[i], padding_[i], stride_[i]));
122-
CHECK_EQ(imgSizeH_[i], imgSizeH_[0]);
123-
CHECK_EQ(imgSizeW_[i], imgSizeW_[0]);
124-
}
125-
getOutput().setFrameHeight(imgSizeH_[0]);
126-
getOutput().setFrameWidth(imgSizeW_[0]);
127-
layerSize = imgSizeH_[0] * imgSizeW_[0] * size_t(numFilters_);
126+
setLayerSize(imgSizeH_, imgSizeW_, outputH_, outputW_);
128127
}
129128

130129
return layerSize;

paddle/gserver/layers/ConvBaseLayer.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ class ConvBaseLayer : public Layer {
7878
/// of output size.
7979
bool caffeMode_;
8080

81-
82-
8381
public:
8482
explicit ConvBaseLayer(const LayerConfig& config) : Layer(config) {}
8583

paddle/gserver/layers/ExpandConvBaseLayer.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ bool ExpandConvBaseLayer::init(const LayerMap &layerMap,
3131
* convTrans, and in other functions too.
3232
* */
3333
int channel;
34-
int nf;
34+
int numFilters;
3535
/* Initialize the projection */
3636
for (auto &inputConfig : config_.inputs()) {
3737
const ConvConfig &conf = inputConfig.conv_conf();
38-
nf = (!isDeconv_) ? numFilters_ : conf.channels();
39-
subM_.push_back(nf / conf.groups());
38+
numFilters = isDeconv_ ? conf.channels() : numFilters_;
39+
subM_.push_back(numFilters / conf.groups());
4040
subN_.push_back(conf.output_x() * conf.output_x());
41-
channel = (!isDeconv_) ? conf.channels() : numFilters_;
41+
channel = isDeconv_ ? numFilters_ : conf.channels();
4242
subK_.push_back(channel * conf.filter_size() * conf.filter_size() /
4343
conf.groups());
4444
/* Consistent caffe mode for multiple input */
@@ -99,7 +99,7 @@ void ExpandConvBaseLayer::addUnsharedBias() {
9999

100100
void ExpandConvBaseLayer::expandOneFrame(MatrixPtr image, size_t startIdx,
101101
int inIdx) {
102-
int channel = (!isDeconv_) ? channels_[inIdx] : numFilters_;
102+
int channel = isDeconv_ ? numFilters_ : channels_[inIdx];
103103

104104
resetExpandInput(subK_[inIdx] * groups_[inIdx], subN_[inIdx]);
105105
real *imgData = image->getData() + startIdx * image->getWidth();
@@ -122,10 +122,10 @@ void ExpandConvBaseLayer::expandFwdOnce(MatrixPtr image, MatrixPtr out,
122122

123123
expandOneFrame(image, startIdx, inIdx);
124124

125-
int nf = (!isDeconv_) ? numFilters_ : channels_[inIdx];
125+
int numFilters = isDeconv_ ? channels_[inIdx] : numFilters_;
126126

127127
real *outData =
128-
out->getData() + startIdx * subN * nf;
128+
out->getData() + startIdx * subN * numFilters;
129129

130130
real *wgtData = weights_[inIdx]->getW()->getData();
131131
real *expInData = expandInput_->getData();
@@ -147,7 +147,7 @@ void ExpandConvBaseLayer::expandFwdOnce(MatrixPtr image, MatrixPtr out,
147147

148148
void ExpandConvBaseLayer::bpropActs(MatrixPtr out, MatrixPtr image,
149149
int inpIdx) {
150-
int channel = (!isDeconv_) ? channels_[inpIdx] : numFilters_;
150+
int channel = isDeconv_ ? numFilters_ : channels_[inpIdx];
151151

152152
int subM = subM_[inpIdx];
153153
int subN = subN_[inpIdx];

paddle/gserver/tests/test_ConvTrans.cpp

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -189,58 +189,55 @@ void doOneConvtTest(size_t imgSize, size_t output_x, size_t stride,
189189
}
190190

191191
TEST(Layer, convTransLayerFwd2) {
192-
size_t imgSize, output_x, stride, padding, filter_size;
193192
MatrixPtr result;
194-
195-
imgSize = 5;
196-
output_x = 1;
197-
stride = 1;
198-
padding = 0;
199-
filter_size = 5;
200-
result = Matrix::create(1, imgSize * imgSize, false, false);
193+
result = Matrix::create(1, 5 * 5, false, false);
201194
result->zeroMem();
202195
result->add(1.0);
203-
doOneConvtTest(imgSize, output_x, stride, padding, filter_size, result);
196+
doOneConvtTest(/* imgSize */ 5,
197+
/* output_x */ 1,
198+
/* stride */ 1,
199+
/* padding */ 0,
200+
/* filter_size */ 5,
201+
result);
204202

205-
imgSize = 5;
206-
output_x = 2;
207-
stride = 1;
208-
padding = 0;
209-
filter_size = 4;
210203
float resultData[] = {1, 2, 2, 2, 1,
211204
2, 4, 4, 4, 2,
212205
2, 4, 4, 4, 2,
213206
2, 4, 4, 4, 2,
214207
1, 2, 2, 2, 1};
215-
result = Matrix::create(resultData, 1, imgSize * imgSize, false, false);
216-
doOneConvtTest(imgSize, output_x, stride, padding, filter_size, result);
217-
218-
imgSize = 5;
219-
output_x = 2;
220-
stride = 2;
221-
padding = 1;
222-
filter_size = 5;
208+
result->setData(resultData);
209+
doOneConvtTest(/* imgSize */ 5,
210+
/* output_x */ 2,
211+
/* stride */ 1,
212+
/* padding */ 0,
213+
/* filter_size */ 4,
214+
result);
215+
223216
float resultData2[] = {1, 2, 2, 2, 1,
224217
2, 4, 4, 4, 2,
225218
2, 4, 4, 4, 2,
226219
2, 4, 4, 4, 2,
227220
1, 2, 2, 2, 1};
228-
result = Matrix::create(resultData2, 1, imgSize * imgSize, false, false);
229-
doOneConvtTest(imgSize, output_x, stride, padding, filter_size, result);
230-
231-
imgSize = 5;
232-
output_x = 2;
233-
stride = 2;
234-
padding = 0;
235-
filter_size = 3;
221+
result->setData(resultData2);
222+
doOneConvtTest(/* imgSize */ 5,
223+
/* output_x */ 2,
224+
/* stride */ 2,
225+
/* padding */ 1,
226+
/* filter_size */ 5,
227+
result);
228+
236229
float resultData3[] = {1, 1, 2, 1, 1,
237230
1, 1, 2, 1, 1,
238231
2, 2, 4, 2, 2,
239232
1, 1, 2, 1, 1,
240233
1, 1, 2, 1, 1};
241-
result = Matrix::create(resultData3, 1, imgSize * imgSize, false, false);
242-
doOneConvtTest(imgSize, output_x, stride, padding, filter_size, result);
243-
}
234+
result->setData(resultData3);
235+
doOneConvtTest(/* imgSize */ 5,
236+
/* output_x */ 2,
237+
/* stride */ 2,
238+
/* padding */ 0,
239+
/* filter_size */ 3,
240+
result);}
244241

245242
int main(int argc, char** argv) {
246243
testing::InitGoogleTest(&argc, argv);

paddle/gserver/tests/test_LayerGrad.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,12 +351,10 @@ void testConvTransLayer(const string& type, bool trans, bool useGpu) {
351351

352352
TEST(Layer, convTransLayer) {
353353
testConvTransLayer("exconvt", /* trans= */ false, /* useGpu= */ false);
354-
/*
355354
#ifndef PADDLE_ONLY_CPU
356-
testConvLayer("exconv", trans= false, useGpu= true);
357-
testConvLayer("cudnn_conv", trans= false, useGpu= true);
355+
testConvTransLayer("exconvt", /* trans= */ false, /* useGpu= */ true);
356+
// testConvLayer("cudnn_conv", /* trans= */ false, /* useGpu= */ true);
358357
#endif
359-
*/
360358
}
361359

362360
TEST(Layer, blockExpandLayer) {

python/paddle/trainer/config_parser.py

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,11 @@ def parse_norm(norm, input_layer_name, norm_conf):
10821082
else:
10831083
norm_conf.scale /= norm.size ** 2
10841084

1085-
def parse_conv(conv, input_layer_name, conv_conf):
1085+
'''
1086+
caffe_mode: compute the output size using floor instead of ceil,
1087+
which is consistent of caffe and CuDNN's convention.
1088+
'''
1089+
def parse_conv(conv, input_layer_name, conv_conf, trans=False):
10861090
conv_conf.filter_size = conv.filter_size
10871091
conv_conf.filter_size_y = conv.filter_size_y
10881092
conv_conf.channels = conv.channels
@@ -1093,49 +1097,41 @@ def parse_conv(conv, input_layer_name, conv_conf):
10931097
conv_conf.groups = conv.groups
10941098
conv_conf.filter_channels = conv.channels / conv.groups
10951099
conv_conf.caffe_mode = conv.caffe_mode
1096-
1097-
img_pixels = g_layer_map[input_layer_name].size / conv.channels
1098-
print('channels=%d size=%d'%(conv.channels,
1099-
g_layer_map[input_layer_name].size))
1100-
conv_conf.img_size = int(img_pixels ** 0.5)
1101-
config_assert((conv_conf.img_size ** 2) == img_pixels,
1102-
("Input layer %s: Incorrect input image size %d for input "
1103-
+ "image pixels %d")
1104-
% (input_layer_name, conv_conf.img_size, img_pixels))
1105-
conv_conf.output_x = cnn_output_size(conv_conf.img_size, conv_conf.filter_size,
1106-
conv_conf.padding, conv_conf.stride,
1107-
conv_conf.caffe_mode)
1108-
1109-
1110-
def parse_conv_trans(conv, input_layer_name, conv_conf, num_filters):
1111-
conv_conf.filter_size = conv.filter_size
1112-
conv_conf.filter_size_y = conv.filter_size_y
1113-
conv_conf.channels = conv.channels
1114-
conv_conf.padding = conv.padding
1115-
conv_conf.padding_y = conv.padding_y
1116-
conv_conf.stride = conv.stride
1117-
conv_conf.stride_y = conv.stride_y
1118-
conv_conf.groups = conv.groups
1119-
conv_conf.filter_channels = num_filters / conv.groups
1120-
conv_conf.caffe_mode = conv.caffe_mode
1121-
1122-
outputSize = g_layer_map[input_layer_name].size / conv.channels
1123-
print('channels=%d size=%d'%(conv.channels,
1124-
g_layer_map[input_layer_name].size))
1125-
conv_conf.output_x = int(outputSize ** 0.5)
1126-
config_assert((conv_conf.output_x ** 2) == outputSize,
1127-
("Input layer %s: Incorrect input image size %d for input "
1128-
+ "image pixels %d")
1129-
% (input_layer_name, conv_conf.output_x, outputSize))
1130-
if conv.caffe_mode:
1131-
conv_conf.img_size = \
1132-
(conv_conf.output_x - 1) * conv.stride \
1133-
+ conv.filter_size - 2 * conv.padding
1100+
1101+
if not trans:
1102+
img_pixels = g_layer_map[input_layer_name].size / conv.channels
1103+
print('channels=%d size=%d'%(conv.channels,
1104+
g_layer_map[input_layer_name].size))
1105+
conv_conf.img_size = int(img_pixels ** 0.5)
1106+
config_assert((conv_conf.img_size ** 2) == img_pixels,
1107+
("Input layer %s: Incorrect input image size %d for input "
1108+
+ "image pixels %d")
1109+
% (input_layer_name, conv_conf.img_size, img_pixels))
1110+
if conv.caffe_mode:
1111+
conv_conf.output_x = \
1112+
1 + int(math.floor((2 * conv.padding + conv_conf.img_size \
1113+
- conv.filter_size) / float(conv.stride)))
1114+
else:
1115+
conv_conf.output_x = \
1116+
1 + int(math.ceil((2 * conv.padding + conv_conf.img_size \
1117+
- conv.filter_size) / float(conv.stride)))
11341118
else:
1135-
conv_conf.img_size = \
1136-
(conv_conf.output_x - 2) * conv.stride \
1137-
+ conv.filter_size - 2 * conv.padding + 1
1138-
1119+
outputSize = g_layer_map[input_layer_name].size / conv.channels
1120+
print('channels=%d size=%d'%(conv.channels,
1121+
g_layer_map[input_layer_name].size))
1122+
conv_conf.output_x = int(outputSize ** 0.5)
1123+
config_assert((conv_conf.output_x ** 2) == outputSize,
1124+
("Input layer %s: Incorrect input image size %d for input "
1125+
+ "image pixels %d")
1126+
% (input_layer_name, conv_conf.output_x, outputSize))
1127+
if conv.caffe_mode:
1128+
conv_conf.img_size = \
1129+
(conv_conf.output_x - 1) * conv.stride \
1130+
+ conv.filter_size - 2 * conv.padding
1131+
else:
1132+
conv_conf.img_size = \
1133+
(conv_conf.output_x - 2) * conv.stride \
1134+
+ conv.filter_size - 2 * conv.padding + 1
11391135

11401136
def parse_block_expand(block_expand, input_layer_name, block_expand_conf):
11411137
block_expand_conf.channels = block_expand.channels
@@ -1685,10 +1681,11 @@ def __init__(
16851681

16861682
for input_index in xrange(len(self.inputs)):
16871683
input_layer = self.get_input_layer(input_index)
1688-
parse_conv_trans(
1684+
parse_conv(
16891685
self.inputs[input_index].conv,
16901686
input_layer.name,
1691-
self.config.inputs[input_index].conv_conf, num_filters)
1687+
self.config.inputs[input_index].conv_conf, num_filters,
1688+
trans=True)
16921689
conv_conf = self.config.inputs[input_index].conv_conf
16931690
psize = self.calc_parameter_size(conv_conf)
16941691
print("output size for %s is %d " % (name, conv_conf.output_x))

python/paddle/trainer_config_helpers/layers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"pooling_layer", "lstmemory", "last_seq", "first_seq",
3737
"cos_sim", "hsigmoid", "conv_projection",
3838
"regression_cost", 'classification_cost', "LayerOutput",
39-
'img_conv_layer', 'img_convTrans_layer', 'img_pool_layer', 'batch_norm_layer',
39+
'img_conv_layer', 'img_pool_layer', 'batch_norm_layer',
4040
'img_cmrnorm_layer', 'addto_layer',
4141
'concat_layer', 'lstm_step_layer', 'recurrent_group',
4242
'memory', 'StaticInput', 'expand_layer', 'scaling_layer',

0 commit comments

Comments
 (0)