From 1f516fa0ef7a29fd79bf92202c553fb41d4a7047 Mon Sep 17 00:00:00 2001 From: xzl Date: Wed, 19 Jul 2017 22:21:27 +0800 Subject: [PATCH] modify format, and modify the layer grad test, op test --- paddle/function/ConvOpTest.cpp | 383 +++++++++------------- paddle/gserver/layers/ExpandConvLayer.cpp | 17 +- paddle/gserver/tests/test_LayerGrad.cpp | 11 +- 3 files changed, 168 insertions(+), 243 deletions(-) diff --git a/paddle/function/ConvOpTest.cpp b/paddle/function/ConvOpTest.cpp index 27609fbbd4..c96c8d9eea 100644 --- a/paddle/function/ConvOpTest.cpp +++ b/paddle/function/ConvOpTest.cpp @@ -25,95 +25,89 @@ enum TestType { kBackwardFilterTest = 2, }; -enum LayerType { - convolutionType = 0, - depthwiseConvolutionType = 1, -}; - template class ConvolutionTest { public: ConvolutionTest(const std::string& conv1, const std::string& conv2, - LayerType layerType, TestType type, + bool useGroups = true, std::string algo = "auto") { for (size_t batchSize : {1, 32}) { for (size_t inputSize : {7, 14, 54}) { for (size_t filterSize : {1, 3, 5}) { for (size_t inputChannels : {3, 64}) { for (size_t outputChannels : {3, 64, 128}) { - if (inputChannels > outputChannels) break; - if (layerType == depthwiseConvolutionType && - outputChannels % inputChannels != 0) - break; - - size_t groups = 1; - - if (layerType == depthwiseConvolutionType) { - groups = inputChannels; - } - - for (size_t stride : {1, 2}) { - for (size_t padding : {0, 1}) { - if (padding >= filterSize) break; - size_t outputSize = - (inputSize - filterSize + 2 * padding + stride) / stride; - VLOG(3) << " batchSize=" << batchSize - << " inputChannels=" << inputChannels - << " inputHeight=" << inputSize - << " inputWidth=" << inputSize - << " outputChannels=" << outputChannels - << " filterHeight=" << filterSize - << " filterWidth=" << filterSize - << " outputHeight=" << outputSize - << " outputWidth=" << outputSize - << " stride=" << stride << " padding=" << padding; - - std::vector paddings = {padding, padding}; - std::vector strides = {stride, stride}; - Compare2Function test( - conv1, - conv2, - FuncConfig() - .set("paddings", paddings) - .set("strides", strides) - .set("groups", groups) - .set("algo", algo)); - - TensorShape input{ - batchSize, inputChannels, inputSize, inputSize}; - - TensorShape filter; - if (layerType == depthwiseConvolutionType) - filter = TensorShape({groups, - outputChannels / groups, - (size_t)1, - filterSize, - filterSize}); - else - filter = TensorShape({outputChannels, - inputChannels, - filterSize, - filterSize}); - TensorShape output{ - batchSize, outputChannels, outputSize, outputSize}; - - if (type == kForwardTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.run(); - } else if (type == kBackwardInputTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, input), ADD_TO); - test.run(); - } else if (type == kBackwardFilterTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.run(); + for (size_t groups : {1, 3, 64}) { + if (inputChannels > outputChannels) break; + if (groups != 1 && + (inputChannels != groups || outputChannels % groups != 0)) + continue; + if (!useGroups) groups = 1; + + for (size_t stride : {1, 2}) { + for (size_t padding : {0, 1}) { + if (padding >= filterSize) break; + size_t outputSize = + (inputSize - filterSize + 2 * padding + stride) / + stride; + VLOG(3) << " batchSize=" << batchSize + << " inputChannels=" << inputChannels + << " inputHeight=" << inputSize + << " inputWidth=" << inputSize + << " outputChannels=" << outputChannels + << " filterHeight=" << filterSize + << " filterWidth=" << filterSize + << " outputHeight=" << outputSize + << " outputWidth=" << outputSize + << " stride=" << stride << " padding=" << padding; + + std::vector paddings = {padding, padding}; + std::vector strides = {stride, stride}; + Compare2Function test( + conv1, + conv2, + FuncConfig() + .set("paddings", paddings) + .set("strides", strides) + .set("groups", groups) + .set("algo", algo)); + + TensorShape input{ + batchSize, inputChannels, inputSize, inputSize}; + + TensorShape filter; + if (groups > 1) + filter = TensorShape({groups, + outputChannels / groups, + inputChannels / groups, + filterSize, + filterSize}); + else + filter = TensorShape({outputChannels, + inputChannels, + filterSize, + filterSize}); + TensorShape output{ + batchSize, outputChannels, outputSize, outputSize}; + + if (type == kForwardTest) { + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); + test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, output)); + test.run(); + } else if (type == kBackwardInputTest) { + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); + test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, input), + ADD_TO); + test.run(); + } else if (type == kBackwardFilterTest) { + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); + test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, filter)); + test.run(); + } } } } @@ -132,8 +126,8 @@ class ConvolutionTest2 { public: ConvolutionTest2(const std::string& conv1, const std::string& conv2, - LayerType layerType, TestType type, + bool useGroups = true, std::string algo = "auto") { for (size_t batchSize : {16}) { for (size_t inputHeight : {7, 31}) { @@ -142,78 +136,78 @@ public: for (size_t filterWidth : {3, 7}) { for (size_t inputChannels : {7}) { for (size_t outputChannels : {7, 32}) { - if (layerType == depthwiseConvolutionType && - outputChannels % inputChannels != 0) - break; - - size_t groups = 1; - - if (layerType == depthwiseConvolutionType) { - groups = inputChannels; - } - size_t stride = 1; - size_t padding = 0; - size_t outputHeight = - (inputHeight - filterHeight + 2 * padding + stride) / - stride; - size_t outputWidth = - (inputWidth - filterWidth + 2 * padding + stride) / - stride; - VLOG(3) << " batchSize=" << batchSize - << " inputChannels=" << inputChannels - << " inputHeight=" << inputHeight - << " inputWidth=" << inputWidth - << " outputChannels=" << outputChannels - << " filterHeight=" << filterHeight - << " filterWidth=" << filterWidth - << " outputHeight=" << outputHeight - << " outputWidth=" << outputWidth - << " stride=" << stride << " padding=" << padding; - - std::vector paddings = {padding, padding}; - std::vector strides = {stride, stride}; - Compare2Function test( - conv1, - conv2, - FuncConfig() - .set("paddings", paddings) - .set("strides", strides) - .set("groups", groups) - .set("algo", algo)); - - TensorShape input{ - batchSize, inputChannels, inputHeight, inputWidth}; - - TensorShape filter; - if (layerType == depthwiseConvolutionType) - filter = TensorShape({groups, - outputChannels / groups, - (size_t)1, - filterHeight, - filterWidth}); - else - filter = TensorShape({outputChannels, - inputChannels, - filterHeight, - filterWidth}); - TensorShape output{ - batchSize, outputChannels, outputHeight, outputWidth}; - - if (type == kForwardTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.run(); - } else if (type == kBackwardInputTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, input), ADD_TO); - test.run(); - } else if (type == kBackwardFilterTest) { - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); - test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); - test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, filter)); - test.run(); + for (size_t groups : {1, 7}) { + if (!useGroups && groups != 1 && + (inputChannels != groups || + outputChannels % groups != 0)) + continue; + if (!useGroups) groups = 1; + + size_t stride = 1; + size_t padding = 0; + size_t outputHeight = + (inputHeight - filterHeight + 2 * padding + stride) / + stride; + size_t outputWidth = + (inputWidth - filterWidth + 2 * padding + stride) / + stride; + VLOG(3) << " batchSize=" << batchSize + << " inputChannels=" << inputChannels + << " inputHeight=" << inputHeight + << " inputWidth=" << inputWidth + << " outputChannels=" << outputChannels + << " filterHeight=" << filterHeight + << " filterWidth=" << filterWidth + << " outputHeight=" << outputHeight + << " outputWidth=" << outputWidth + << " stride=" << stride << " padding=" << padding; + + std::vector paddings = {padding, padding}; + std::vector strides = {stride, stride}; + Compare2Function test( + conv1, + conv2, + FuncConfig() + .set("paddings", paddings) + .set("strides", strides) + .set("groups", groups) + .set("algo", algo)); + + TensorShape input{ + batchSize, inputChannels, inputHeight, inputWidth}; + + TensorShape filter; + if (groups > 1) + filter = TensorShape({groups, + outputChannels / groups, + inputChannels / groups, + filterHeight, + filterWidth}); + else + filter = TensorShape({outputChannels, + inputChannels, + filterHeight, + filterWidth}); + TensorShape output{ + batchSize, outputChannels, outputHeight, outputWidth}; + + if (type == kForwardTest) { + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); + test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, output)); + test.run(); + } else if (type == kBackwardInputTest) { + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, filter)); + test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, input), + ADD_TO); + test.run(); + } else if (type == kBackwardFilterTest) { + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, output)); + test.addInputs(BufferArg(VALUE_TYPE_FLOAT, input)); + test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, filter)); + test.run(); + } } } } @@ -225,107 +219,34 @@ public: } }; -// ======Start Convolution TEST====== TEST(Forward, GEMM) { ConvolutionTest test( - "NaiveConv-CPU", "GemmConv-CPU", convolutionType, kForwardTest); + "NaiveConv-CPU", "GemmConv-CPU", kForwardTest, false); ConvolutionTest2 test2( - "NaiveConv-CPU", "GemmConv-CPU", convolutionType, kForwardTest); + "NaiveConv-CPU", "GemmConv-CPU", kForwardTest, false); } #ifndef PADDLE_ONLY_CPU TEST(Forward, GEMM2) { ConvolutionTest test( - "GemmConv-CPU", "GemmConv-GPU", convolutionType, kForwardTest); + "GemmConv-CPU", "GemmConv-GPU", kForwardTest); ConvolutionTest2 test2( - "GemmConv-CPU", "GemmConv-GPU", convolutionType, kForwardTest); + "GemmConv-CPU", "GemmConv-GPU", kForwardTest); } TEST(BackwardInput, GEMM) { ConvolutionTest test( - "GemmConvGradInput-CPU", - "GemmConvGradInput-GPU", - convolutionType, - kBackwardInputTest); + "GemmConvGradInput-CPU", "GemmConvGradInput-GPU", kBackwardInputTest); ConvolutionTest2 test2( - "GemmConvGradInput-CPU", - "GemmConvGradInput-GPU", - convolutionType, - kBackwardInputTest); + "GemmConvGradInput-CPU", "GemmConvGradInput-GPU", kBackwardInputTest); } TEST(BackwardFilter, GEMM) { ConvolutionTest test( - "GemmConvGradFilter-CPU", - "GemmConvGradFilter-GPU", - convolutionType, - kBackwardFilterTest); - ConvolutionTest2 test2( - "GemmConvGradFilter-CPU", - "GemmConvGradFilter-GPU", - convolutionType, - kBackwardFilterTest); -} -#endif -// ======End Convolution TEST====== - -// ======Start DepthwiseConvolution TEST====== -// TODO(zhaolong) The depthwise convolution cpu test will be added when the cpu -// version of depthwiseConv is implemented. - -#ifndef PADDLE_ONLY_CPU -TEST(DepthwiseConvForward, GEMM) { - ConvolutionTest test( - "GemmConv-GPU", - "DepthwiseConv-GPU", - depthwiseConvolutionType, - kForwardTest); - ConvolutionTest2 test2( - "GemmConv-GPU", - "DepthwiseConv-GPU", - depthwiseConvolutionType, - kForwardTest); -} - -TEST(DepthwiseConvForward, GEMM2) { - ConvolutionTest test( - "DepthwiseConv-GPU", - "DepthwiseConv-GPU", - depthwiseConvolutionType, - kForwardTest); - ConvolutionTest2 test2( - "DepthwiseConv-GPU", - "DepthwiseConv-GPU", - depthwiseConvolutionType, - kForwardTest); -} - -TEST(DepthwiseConvBackwardInput, GEMM) { - ConvolutionTest test( - "DepthwiseConvGradInput-GPU", - "DepthwiseConvGradInput-GPU", - depthwiseConvolutionType, - kBackwardInputTest); - ConvolutionTest2 test2( - "DepthwiseConvGradInput-GPU", - "DepthwiseConvGradInput-GPU", - depthwiseConvolutionType, - kBackwardInputTest); -} - -TEST(DepthwiseConvBackwardFilter, GEMM) { - ConvolutionTest test( - "DepthwiseConvGradFilter-GPU", - "DepthwiseConvGradFilter-GPU", - depthwiseConvolutionType, - kBackwardFilterTest); + "GemmConvGradFilter-CPU", "GemmConvGradFilter-GPU", kBackwardFilterTest); ConvolutionTest2 test2( - "DepthwiseConvGradFilter-GPU", - "DepthwiseConvGradFilter-GPU", - depthwiseConvolutionType, - kBackwardFilterTest); + "GemmConvGradFilter-CPU", "GemmConvGradFilter-GPU", kBackwardFilterTest); } #endif -// ======End DepthwiseConvolution TEST====== } // namespace paddle diff --git a/paddle/gserver/layers/ExpandConvLayer.cpp b/paddle/gserver/layers/ExpandConvLayer.cpp index 224ef0d51b..783e02e47c 100644 --- a/paddle/gserver/layers/ExpandConvLayer.cpp +++ b/paddle/gserver/layers/ExpandConvLayer.cpp @@ -39,21 +39,22 @@ bool ExpandConvLayer::init(const LayerMap &layerMap, filterShape_.resize(numInputs); outputShape_.resize(numInputs); - string convType; - string convGradInputType; - string convGradFilterType; + std::string convType; + std::string convGradInputType; + std::string convGradFilterType; for (int i = 0; i < config_.inputs_size(); i++) { std::vector paddings = {(size_t)paddingY_[i], (size_t)padding_[i]}; std::vector strides = {(size_t)strideY_[i], (size_t)stride_[i]}; if (useGpu_ && (size_t)groups_[i] == (size_t)channels_[i] && !isDeconv_) { - convType = "DepthwiseConv" convGradInputType = - "DepthwiseConvGradInput" convGradFilterType = - "DepthwiseConvGradFilter" + convType = "DepthwiseConv"; + convGradInputType = "DepthwiseConvGradInput"; + convGradFilterType = "DepthwiseConvGradFilter"; } else { - convType = "GemmConv" convGradInputType = - "GemmConvGradInput" convGradFilterType = "GemmConvGradFilter" + convType = "GemmConv"; + convGradInputType = "GemmConvGradInput"; + convGradFilterType = "GemmConvGradFilter"; } if (FLAGS_use_nnpack) { diff --git a/paddle/gserver/tests/test_LayerGrad.cpp b/paddle/gserver/tests/test_LayerGrad.cpp index 2f28cec53e..2b45483bcc 100644 --- a/paddle/gserver/tests/test_LayerGrad.cpp +++ b/paddle/gserver/tests/test_LayerGrad.cpp @@ -349,13 +349,13 @@ TEST(Layer, CosSimVecMatLayer) { void testDepthwiseConvLayer(const string& type, bool useGpu) { TestConfig config; - config.biasSize = 16; + config.biasSize = 32; config.layerConfig.set_type(type); - config.layerConfig.set_num_filters(16); + config.layerConfig.set_num_filters(32); config.layerConfig.set_partial_sum(1); config.layerConfig.set_shared_biases(true); - config.inputDefs.push_back({INPUT_DATA, "layer_0", 2048, 192 / 2}); + config.inputDefs.push_back({INPUT_DATA, "layer_0", 2048, 192}); LayerInputConfig* input = config.layerConfig.add_inputs(); ConvConfig* conv = input->mutable_conv_conf(); conv->set_filter_size(2); @@ -388,8 +388,11 @@ void testDepthwiseConvLayer(const string& type, bool useGpu) { } TEST(Layer, depthwiseConvLayer) { + // 'depthwise_conv' is a sepecial case of 'exconv' whose + // groups size equals to the input channels size. + testDepthwiseConvLayer("exconv", /* useGpu= */ false); #ifndef PADDLE_ONLY_CPU - testDepthwiseConvLayer("depthwise_conv", /* useGpu= */ true); + testDepthwiseConvLayer("exconv", /* useGpu= */ true); #endif } -- GitLab