Skip to content

Commit 7105962

Browse files
authored
Merge pull request #636 from wangyang59/unifyConv
Unify conv
2 parents 98f4c76 + 09a5b8b commit 7105962

File tree

11 files changed

+303
-20
lines changed

11 files changed

+303
-20
lines changed

paddle/gserver/layers/ConvProjection.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ void ConvProjection::getConvParams() {
5959

6060
void ConvProjection::initCudnn() {
6161
hl_create_filter_descriptor(
62-
&filterDesc_, channels_, numFilters_, filterH_, filterW_);
62+
&filterDesc_, channels_ / groups_, numFilters_ / groups_,
63+
filterH_, filterW_);
6364
hl_create_tensor_descriptor(&inputDesc_);
6465
hl_create_tensor_descriptor(&outputDesc_);
6566
hl_create_convolution_descriptor(&convDesc_,
@@ -86,7 +87,7 @@ void ConvProjection::initCudnn() {
8687
void ConvProjection::reshapeTensorDesc(int batchSize) {
8788
hl_tensor_reshape(inputDesc_,
8889
batchSize,
89-
channels_,
90+
channels_ / groups_,
9091
imageH_,
9192
imageW_,
9293
channels_ * imageH_ * imageW_,
@@ -115,7 +116,7 @@ void ConvProjection::reshapeTensorDesc(int batchSize) {
115116

116117
hl_tensor_reshape(outputDesc_,
117118
batchSize,
118-
numFilters_,
119+
numFilters_ / groups_,
119120
outputH_,
120121
outputW_,
121122
nStride,

paddle/gserver/layers/ExpandConvBaseLayer.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ void ExpandConvBaseLayer::expandFwdOnce(MatrixPtr image,
145145
real *expInData = expandInput_->getData();
146146
for (int g = 0; g < groups_[inIdx]; ++g) {
147147
MatrixPtr A =
148-
Matrix::create(wgtData, subK, subM, true, useGpu_); // mark transpose
148+
Matrix::create(wgtData, subM, subK, false, useGpu_); // mark transpose
149149
MatrixPtr B = Matrix::create(expInData, subK, subN, false, useGpu_);
150150
MatrixPtr C = Matrix::create(outData, subM, subN, false, useGpu_);
151151
C->mul(A, B, 1, 1);
@@ -182,7 +182,7 @@ void ExpandConvBaseLayer::bpropActs(MatrixPtr out,
182182
// create temporary matrix
183183
MatrixPtr C = Matrix::create(expandInData, subK, subN, false, useGpu_);
184184
MatrixPtr B = Matrix::create(localGradData, subM, subN, false, useGpu_);
185-
MatrixPtr A = Matrix::create(wgtData, subK, subM, false, useGpu_);
185+
MatrixPtr A = Matrix::create(wgtData, subM, subK, true, useGpu_);
186186
C->mul(A, B); // mul
187187

188188
// clear the temporary matrix
@@ -247,10 +247,10 @@ void ExpandConvBaseLayer::bpropWeights(MatrixPtr image,
247247

248248
// expand-mul one-group by one
249249
for (int g = 0; g < groups_[inpIdx]; g++) {
250-
MatrixPtr A = Matrix::create(expandInData, subK, subN, false, useGpu_);
251-
MatrixPtr B = Matrix::create(gradData, subM, subN, true, useGpu_);
252-
MatrixPtr C = Matrix::create(wGradData, subK, subM, false, useGpu_);
253-
C->mul(A, B, 1, 1);
250+
MatrixPtr A = Matrix::create(expandInData, subK, subN, true, useGpu_);
251+
MatrixPtr B = Matrix::create(gradData, subM, subN, false, useGpu_);
252+
MatrixPtr C = Matrix::create(wGradData, subM, subK, false, useGpu_);
253+
C->mul(B, A, 1, 1);
254254

255255
A->clear();
256256
B->clear();

paddle/gserver/tests/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ add_unittest_without_exec(test_ConvTrans
3434

3535
add_test(NAME test_ConvTrans
3636
COMMAND test_ConvTrans)
37+
################# test_ConvUnify #######################
38+
add_unittest_without_exec(test_ConvUnify
39+
test_ConvUnify.cpp
40+
LayerGradUtil.cpp
41+
TestUtil.cpp)
3742

43+
add_test(NAME test_ConvUnify
44+
COMMAND test_ConvUnify)
3845
################## test_Evaluator #######################
3946
add_unittest(test_Evaluator
4047
test_Evaluator.cpp

paddle/gserver/tests/img_conv_a.conf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ conv = img_conv_layer(input=data, filter_size=1, filter_size_y=1,
3434
num_channels=8,
3535
num_filters=16, stride=1,
3636
bias_attr=True,
37-
act=LinearActivation())
37+
act=LinearActivation(),
38+
groups=2)
3839

3940
outputs(concat, conv)

paddle/gserver/tests/img_conv_b.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ proj2 = conv_projection(input=data, filter_size=1, filter_size_y=1,
2424
concat = concat_layer(input=[proj1, proj2], bias_attr=False, act=ReluActivation())
2525

2626
proj = conv_projection(input=data, filter_size=1, filter_size_y=1,
27-
num_channels=8, num_filters=16, stride=1)
27+
num_channels=8, num_filters=16, stride=1, groups=2)
2828

2929
with mixed_layer(bias_attr=True, act=LinearActivation()) as conv:
3030
conv += proj
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#edit-mode: -*- python -*-
2+
# Copyright (c) 2016 Baidu, Inc. All Rights Reserved
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
from paddle.trainer_config_helpers import *
17+
18+
settings(batch_size=10)
19+
data = data_layer(name ="input", size=8*16*16)
20+
conv1 = img_conv_layer(input=data, filter_size=1, filter_size_y=1,
21+
num_channels=8,
22+
num_filters=16, stride=1,
23+
bias_attr=False,
24+
act=ReluActivation(),
25+
layer_type="exconv")
26+
conv2 = img_conv_layer(input=data, filter_size=1, filter_size_y=1,
27+
num_channels=8,
28+
num_filters=16, stride=1,
29+
bias_attr=False,
30+
act=ReluActivation(),
31+
layer_type="exconv")
32+
33+
concat = concat_layer(input=[conv1, conv2])
34+
35+
conv = img_conv_layer(input=data, filter_size=1, filter_size_y=1,
36+
num_channels=8,
37+
num_filters=16, stride=1,
38+
bias_attr=True,
39+
act=LinearActivation(),
40+
groups=2,
41+
layer_type="exconv")
42+
43+
outputs(concat, conv)
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
15+
#include <gtest/gtest.h>
16+
#include <vector>
17+
#include <string>
18+
#include "paddle/gserver/layers/DataLayer.h"
19+
#include "ModelConfig.pb.h"
20+
#include "paddle/trainer/Trainer.h"
21+
#include "paddle/utils/GlobalConstants.h"
22+
#include "paddle/gserver/layers/ExpandConvTransLayer.h"
23+
#include "paddle/math/MathUtils.h"
24+
25+
#include "TestUtil.h"
26+
#include "LayerGradUtil.h"
27+
28+
using namespace paddle; // NOLINT
29+
using namespace std; // NOLINT
30+
31+
P_DECLARE_bool(use_gpu);
32+
P_DECLARE_int32(gpu_id);
33+
P_DECLARE_double(checkgrad_eps);
34+
P_DECLARE_bool(thread_local_rand_use_global_seed);
35+
P_DECLARE_bool(prev_batch_state);
36+
37+
// Do one forward pass of convTrans layer and check to see if its output
38+
// matches the given result
39+
MatrixPtr doOneConvTest(size_t imgSize, size_t output_x, size_t stride,
40+
size_t padding, size_t filter_size, size_t channel,
41+
size_t numfilters, size_t groups, MatrixPtr& inputData,
42+
real* param, bool useGpu) {
43+
TestConfig config;
44+
config.biasSize = numfilters;
45+
if (useGpu) {
46+
config.layerConfig.set_type("cudnn_conv");
47+
} else {
48+
config.layerConfig.set_type("exconv");
49+
}
50+
config.layerConfig.set_num_filters(numfilters);
51+
config.layerConfig.set_partial_sum(1);
52+
config.layerConfig.set_shared_biases(true);
53+
54+
size_t weightSize = channel* filter_size * filter_size *
55+
config.layerConfig.num_filters() / groups;
56+
config.inputDefs.push_back({INPUT_DATA, "layer_0",
57+
imgSize * imgSize * channel,
58+
weightSize});
59+
LayerInputConfig* input = config.layerConfig.add_inputs();
60+
ConvConfig* conv = input->mutable_conv_conf();
61+
conv->set_filter_size(filter_size);
62+
conv->set_filter_size_y(filter_size);
63+
conv->set_channels(channel);
64+
conv->set_padding(padding);
65+
conv->set_padding_y(padding);
66+
conv->set_stride(stride);
67+
conv->set_stride_y(stride);
68+
conv->set_groups(groups);
69+
conv->set_filter_channels(channel/groups);
70+
conv->set_img_size(imgSize);
71+
conv->set_output_x(output_x);
72+
73+
config.layerConfig.set_size(conv->output_x() * conv->output_x() *
74+
config.layerConfig.num_filters());
75+
config.layerConfig.set_name("conv");
76+
77+
std::vector<DataLayerPtr> dataLayers;
78+
LayerMap layerMap;
79+
vector<Argument> datas;
80+
initDataLayer(config, &dataLayers, &datas, &layerMap, "conv",
81+
1, false, useGpu);
82+
dataLayers[0]->getOutputValue()->zeroMem();
83+
dataLayers[0]->getOutputValue()->copyFrom(*inputData);
84+
85+
// test layer initialize
86+
std::vector<ParameterPtr> parameters;
87+
LayerPtr convLayer;
88+
initTestLayer(config, &layerMap, &parameters, &convLayer);
89+
convLayer->getBiasParameter()->zeroMem();
90+
convLayer->getParameters()[0]->zeroMem();
91+
convLayer->getParameters()[0]->getBuf(PARAMETER_VALUE)->copyFrom(param,
92+
weightSize);
93+
convLayer->forward(PASS_GC);
94+
95+
return convLayer->getOutputValue();
96+
}
97+
98+
TEST(Layer, convParaUnified) {
99+
#ifndef PADDLE_ONLY_CPU
100+
MatrixPtr input, resultCpu, resultGpu;
101+
input = Matrix::create(1, 4 * 4, false, false);
102+
float inputData[] = {1, 2, 3, 4,
103+
5, 6, 7, 8,
104+
9, 10, 11, 12,
105+
13, 14, 15, 16};
106+
float param[] = {1, 2, 3, 4, 5, 6, 7, 8, 9,
107+
9, 8, 7, 6, 5, 4, 3, 2, 1};
108+
109+
input->setData(inputData);
110+
111+
resultCpu = doOneConvTest(/* imgSize */ 4,
112+
/* output_x */ 2,
113+
/* stride */ 1,
114+
/* padding */ 0,
115+
/* filter_size */ 3,
116+
/*channel*/ 1,
117+
/*numfilters*/ 2,
118+
/*groups*/ 1,
119+
input, param, false);
120+
121+
resultGpu = doOneConvTest(/* imgSize */ 4,
122+
/* output_x */ 2,
123+
/* stride */ 1,
124+
/* padding */ 0,
125+
/* filter_size */ 3,
126+
/*channel*/ 1,
127+
/*numfilters*/ 2,
128+
/*groups*/ 1,
129+
input, param, true);
130+
checkMatrixEqual(resultCpu, resultGpu);
131+
132+
input = Matrix::create(1, 3 * 3 * 2, false, false);
133+
float inputData2[] = {1, 2, 3,
134+
4, 5, 6,
135+
7, 8, 9,
136+
137+
10, 11, 12,
138+
13, 14, 15,
139+
16, 17, 18};
140+
float param2[] = {1, 2, 3, 4, 5, 6, 7, 8,
141+
8, 7, 6, 5, 4, 3, 2, 1};
142+
143+
input->setData(inputData2);
144+
145+
resultCpu = doOneConvTest(/* imgSize */ 3,
146+
/* output_x */ 2,
147+
/* stride */ 1,
148+
/* padding */ 0,
149+
/* filter_size */ 2,
150+
/*channel*/ 2,
151+
/*numfilters*/ 2,
152+
/*groups*/ 1,
153+
input, param2, false);
154+
155+
resultGpu = doOneConvTest(/* imgSize */ 3,
156+
/* output_x */ 2,
157+
/* stride */ 1,
158+
/* padding */ 0,
159+
/* filter_size */ 2,
160+
/*channel*/ 2,
161+
/*numfilters*/ 2,
162+
/*groups*/ 1,
163+
input, param2, true);
164+
checkMatrixEqual(resultCpu, resultGpu);
165+
166+
167+
float param3[] = {1, 2, 3, 4,
168+
4, 3, 2, 1};
169+
170+
resultCpu = doOneConvTest(/* imgSize */ 3,
171+
/* output_x */ 2,
172+
/* stride */ 1,
173+
/* padding */ 0,
174+
/* filter_size */ 2,
175+
/*channel*/ 2,
176+
/*numfilters*/ 2,
177+
/*groups*/ 2,
178+
input, param3, false);
179+
180+
resultGpu = doOneConvTest(/* imgSize */ 3,
181+
/* output_x */ 2,
182+
/* stride */ 1,
183+
/* padding */ 0,
184+
/* filter_size */ 2,
185+
/*channel*/ 2,
186+
/*numfilters*/ 2,
187+
/*groups*/ 2,
188+
input, param3, true);
189+
checkMatrixEqual(resultCpu, resultGpu);
190+
#endif
191+
}
192+
193+
int main(int argc, char** argv) {
194+
testing::InitGoogleTest(&argc, argv);
195+
initMain(argc, argv);
196+
FLAGS_thread_local_rand_use_global_seed = true;
197+
srand(1);
198+
return RUN_ALL_TESTS();
199+
}

paddle/gserver/tests/test_LayerGrad.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,8 @@ TEST(Projection, scaling) {
166166
}
167167
}
168168

169-
#ifndef PADDLE_ONLY_CPU
170-
TEST(Projection, conv) {
171-
const int NUM_FILTERS = 16;
169+
void testProjectionConv(size_t groups) {
170+
const int NUM_FILTERS = 18;
172171
const int FILTER_SIZE = 2;
173172
const int FILTER_SIZE_Y = 3;
174173
const int CHANNELS = 3;
@@ -186,7 +185,7 @@ TEST(Projection, conv) {
186185
conv->set_padding_y(1);
187186
conv->set_stride(2);
188187
conv->set_stride_y(2);
189-
conv->set_groups(1);
188+
conv->set_groups(groups);
190189
conv->set_filter_channels(conv->channels() / conv->groups());
191190
conv->set_img_size(IMAGE_SIZE);
192191
int output_x = outputSize(conv->img_size(),
@@ -206,13 +205,20 @@ TEST(Projection, conv) {
206205
testProjectionGrad(
207206
conf,
208207
INPUT_DATA,
209-
/* parameterSize */ NUM_FILTERS * CHANNELS * FILTER_SIZE * FILTER_SIZE_Y,
208+
/* parameterSize */ NUM_FILTERS * CHANNELS * FILTER_SIZE * FILTER_SIZE_Y
209+
/ groups,
210210
/* batchSize */ 100,
211211
true,
212212
false,
213213
NUM_FILTERS,
214214
true);
215215
}
216+
217+
#ifndef PADDLE_ONLY_CPU
218+
TEST(Projection, conv) {
219+
testProjectionConv(1);
220+
testProjectionConv(3);
221+
}
216222
#endif
217223

218224
TEST(Layer, BilinearInterpLayer) {

paddle/gserver/tests/test_NetworkCompare.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,16 @@ TEST(Compare, img_conv) {
255255
compareNetwork(config_file_a, config_file_b);
256256
FLAGS_use_gpu = useGpu;
257257
}
258+
259+
// Test cudnn_conv and exconv give the same result
260+
TEST(Compare, img_conv2) {
261+
std::string config_file_a = "./gserver/tests/img_conv_a.conf";
262+
std::string config_file_b = "./gserver/tests/img_conv_c.conf";
263+
bool useGpu = FLAGS_use_gpu;
264+
FLAGS_use_gpu = true;
265+
compareNetwork(config_file_a, config_file_b);
266+
FLAGS_use_gpu = useGpu;
267+
}
258268
#endif
259269

260270
P_DEFINE_string(config_file_a, "", "config of one network to compare");

0 commit comments

Comments
 (0)