提交 bda259bb 编写于 作者: W wangyang59

added more test on convTrans layer and comments

上级 70e44732
......@@ -23,6 +23,17 @@ bool ConvTransBaseLayer::init(const LayerMap& layerMap,
Layer::init(layerMap, parameterMap);
/* Initialize the convolutional layer parameter */
/* Everything is the same as ConvBaseLayer.cpp except that the meaning of
* num_filters and channel is switched.
*
* In the config, num_filters refer to the number of feature maps in the
* output of convTransLayer, and channel refer to the number of feature maps
* in the input of convTransLayer.
*
* However, within the convTrans class, the channel is related to the output
* and num_filters is related to the input, so that it is consistent with the
* settings in convLayer.
* */
channel_ = config_.num_filters();
sharedBiases_ = config_.shared_biases();
for (auto& inputConfig : config_.inputs()) {
......
......@@ -96,6 +96,11 @@ public:
* - outputSize = 5;
*/
/*
* In order to be consistent with the convLayer, here the outputSize is
* actually the size of the input image of convTransLayer, and the image size
* is actually the size of the output image of convTransLayer
*/
int imageSize(int outputSize, int filterSize, int padding, int stride) {
int imageSize;
if (!caffeMode_) {
......
......@@ -17,6 +17,11 @@ limitations under the License. */
#include "paddle/utils/Stat.h"
#include "ExpandConvTransLayer.h"
/* The implementation of the convTransLayer is basically a swap of forward and
* backward of the original convLayer.
* The variable naming follows the convention of the convLayer.
* */
namespace paddle {
REGISTER_LAYER(exconvt, ExpandConvTransLayer);
......
......@@ -26,7 +26,7 @@ namespace paddle {
* This layer expands input and use matrix multiplication to
* calculate convolution operation.
*
* The config file api is img_conv_layer.
* The config file api is img_convTrans_layer.
*/
class ExpandConvTransLayer : public ConvTransBaseLayer {
protected:
......
......@@ -33,7 +33,9 @@ P_DECLARE_double(checkgrad_eps);
P_DECLARE_bool(thread_local_rand_use_global_seed);
P_DECLARE_bool(prev_batch_state);
// Test that the convTrans forward is the same as conv backward
TEST(Layer, convTransLayerFwd) {
// Setting up conv-trans layer
TestConfig configt;
configt.biasSize = 3;
configt.layerConfig.set_type("exconvt");
......@@ -68,7 +70,7 @@ TEST(Layer, convTransLayerFwd) {
LayerMap layerMap;
vector<Argument> datas;
initDataLayer(configt, &dataLayers, &datas, &layerMap, "convTrans",
100, false, useGpu);
100, false, false);
// test layer initialize
std::vector<ParameterPtr> parameters;
LayerPtr convtLayer;
......@@ -76,6 +78,7 @@ TEST(Layer, convTransLayerFwd) {
convtLayer->getBiasParameter()->zeroMem();
convtLayer->forward(PASS_GC);
// Setting up conv-layer config
TestConfig config;
config.biasSize = 16;
config.layerConfig.set_type("exconv");
......@@ -109,16 +112,18 @@ TEST(Layer, convTransLayerFwd) {
LayerMap layerMap2;
vector<Argument> datas2;
initDataLayer(config, &dataLayers2, &datas2, &layerMap2, "conv",
100, false, useGpu);
100, false, false);
// test layer initialize
std::vector<ParameterPtr> parameters2;
LayerPtr convLayer;
initTestLayer(config, &layerMap2, &parameters2, &convLayer);
// Sync convLayer and convtLayer parameter
convLayer->getBiasParameter()->zeroMem();
convLayer->getParameters()[0]->getBuf(PARAMETER_VALUE)->copyFrom(
*(convtLayer->getParameters()[0]->getBuf(PARAMETER_VALUE)));
// Set convLayer outputGrad as convTransLayer input value
convLayer->forward(PASS_GC);
convLayer->getOutput().grad->copyFrom(*(dataLayers[0]->getOutputValue()));
......@@ -126,10 +131,117 @@ TEST(Layer, convTransLayerFwd) {
auto callback = [&](Parameter* para) { ++callbackFlags[para->getID()]; };
convLayer->backward(callback);
// Check that the convLayer backward is the same as convTransLayer forward
checkMatrixEqual(convtLayer->getOutputValue(),
dataLayers2[0]->getOutputGrad());
}
// Do one forward pass of convTrans layer and check to see if its output
// matches the given result
void doOneConvtTest(size_t imgSize, size_t output_x, size_t stride,
size_t padding, size_t filter_size, MatrixPtr& result) {
TestConfig configt;
configt.biasSize = 1;
configt.layerConfig.set_type("exconvt");
configt.layerConfig.set_num_filters(1);
configt.layerConfig.set_partial_sum(1);
configt.layerConfig.set_shared_biases(true);
configt.inputDefs.push_back({INPUT_DATA, "layer_0", output_x * output_x,
filter_size * filter_size});
LayerInputConfig* input = configt.layerConfig.add_inputs();
ConvConfig* conv = input->mutable_conv_conf();
conv->set_filter_size(filter_size);
conv->set_filter_size_y(filter_size);
conv->set_channels(1);
conv->set_padding(padding);
conv->set_padding_y(padding);
conv->set_stride(stride);
conv->set_stride_y(stride);
conv->set_groups(1);
conv->set_filter_channels(1);
conv->set_img_size(imgSize);
conv->set_output_x(output_x);
configt.layerConfig.set_size(conv->img_size() * conv->img_size() *
configt.layerConfig.num_filters());
configt.layerConfig.set_name("convTrans");
std::vector<DataLayerPtr> dataLayers;
LayerMap layerMap;
vector<Argument> datas;
initDataLayer(configt, &dataLayers, &datas, &layerMap, "convTrans",
1, false, false);
dataLayers[0]->getOutputValue()->zeroMem();
dataLayers[0]->getOutputValue()->add(1.0);
// test layer initialize
std::vector<ParameterPtr> parameters;
LayerPtr convtLayer;
initTestLayer(configt, &layerMap, &parameters, &convtLayer);
convtLayer->getBiasParameter()->zeroMem();
convtLayer->getParameters()[0]->zeroMem();
convtLayer->getParameters()[0]->getBuf(PARAMETER_VALUE)->add(1.0);
convtLayer->forward(PASS_GC);
checkMatrixEqual(convtLayer->getOutputValue(), result);
}
TEST(Layer, convTransLayerFwd2) {
size_t imgSize, output_x, stride, padding, filter_size;
MatrixPtr result;
imgSize = 5;
output_x = 1;
stride = 1;
padding = 0;
filter_size = 5;
result = Matrix::create(1, imgSize * imgSize, false, false);
result->zeroMem();
result->add(1.0);
doOneConvtTest(imgSize, output_x, stride, padding, filter_size, result);
imgSize = 5;
output_x = 2;
stride = 1;
padding = 0;
filter_size = 4;
float resultData[] = {1, 2, 2, 2, 1,
2, 4, 4, 4, 2,
2, 4, 4, 4, 2,
2, 4, 4, 4, 2,
1, 2, 2, 2, 1};
result = Matrix::create(resultData, 1, imgSize * imgSize, false, false);
doOneConvtTest(imgSize, output_x, stride, padding, filter_size, result);
imgSize = 5;
output_x = 2;
stride = 2;
padding = 1;
filter_size = 5;
float resultData2[] = {1, 2, 2, 2, 1,
2, 4, 4, 4, 2,
2, 4, 4, 4, 2,
2, 4, 4, 4, 2,
1, 2, 2, 2, 1};
result = Matrix::create(resultData2, 1, imgSize * imgSize, false, false);
doOneConvtTest(imgSize, output_x, stride, padding, filter_size, result);
imgSize = 5;
output_x = 2;
stride = 2;
padding = 0;
filter_size = 3;
float resultData3[] = {1, 1, 2, 1, 1,
1, 1, 2, 1, 1,
2, 2, 4, 2, 2,
1, 1, 2, 1, 1,
1, 1, 2, 1, 1};
result = Matrix::create(resultData3, 1, imgSize * imgSize, false, false);
doOneConvtTest(imgSize, output_x, stride, padding, filter_size, result);
}
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
initMain(argc, argv);
......
......@@ -1107,7 +1107,7 @@ def parse_conv(conv, input_layer_name, conv_conf):
conv_conf.caffe_mode)
def parse_convt(conv, input_layer_name, conv_conf):
def parse_convt(conv, input_layer_name, conv_conf, num_filters):
conv_conf.filter_size = conv.filter_size
conv_conf.filter_size_y = conv.filter_size_y
conv_conf.channels = conv.channels
......@@ -1116,7 +1116,7 @@ def parse_convt(conv, input_layer_name, conv_conf):
conv_conf.stride = conv.stride
conv_conf.stride_y = conv.stride_y
conv_conf.groups = conv.groups
conv_conf.filter_channels = conv.channels / conv.groups
conv_conf.filter_channels = num_filters / conv.groups
conv_conf.caffe_mode = conv.caffe_mode
outputSize = g_layer_map[input_layer_name].size / conv.channels
......@@ -1126,14 +1126,14 @@ def parse_convt(conv, input_layer_name, conv_conf):
config_assert((conv_conf.output_x ** 2) == outputSize,
("Input layer %s: Incorrect input image size %d for input "
+ "image pixels %d")
% (input_layer_name, conv_conf.img_size, img_pixels))
% (input_layer_name, conv_conf.output_x, outputSize))
if conv.caffe_mode:
conv_conf.img_size = \
(conv_conf.output_x - 1) * conv.stride \
+ conv.filter_size - 2 * conv.padding
else:
conv_conf.img_size = \
(conv_conf.output_x - 1) * conv.stride \
(conv_conf.output_x - 2) * conv.stride \
+ conv.filter_size - 2 * conv.padding + 1
......@@ -1655,7 +1655,7 @@ class ConvTransLayerBase(LayerBase):
num_filters=None,
shared_biases=False,
**xargs):
super(ConvLayerBase, self).__init__(
super(ConvTransLayerBase, self).__init__(
name, self.layer_type, 0, inputs=inputs, **xargs)
if num_filters is not None:
......@@ -1686,7 +1686,7 @@ class ConvTransLayerBase(LayerBase):
parse_convt(
self.inputs[input_index].conv,
input_layer.name,
self.config.inputs[input_index].conv_conf)
self.config.inputs[input_index].conv_conf, num_filters)
conv_conf = self.config.inputs[input_index].conv_conf
psize = self.calc_parameter_size(conv_conf)
print("output size for %s is %d " % (name, conv_conf.output_x))
......@@ -1700,7 +1700,7 @@ class ConvTransLayerBase(LayerBase):
self.create_bias_parameter(bias, psize, [psize, 1])
def calc_parameter_size(self, conv_conf):
return conv_conf.channels() * conv_conf.filter_channels \
return conv_conf.channels * conv_conf.filter_channels \
* (conv_conf.filter_size * conv_conf.filter_size_y)
@config_layer('exconvt')
......
......@@ -36,7 +36,7 @@ __all__ = ["full_matrix_projection", "AggregateLevel", "ExpandLevel",
"pooling_layer", "lstmemory", "last_seq", "first_seq",
"cos_sim", "hsigmoid", "conv_projection",
"regression_cost", 'classification_cost', "LayerOutput",
'img_conv_layer', 'img_pool_layer', 'batch_norm_layer',
'img_conv_layer', 'img_convTrans_layer', 'img_pool_layer', 'batch_norm_layer',
'img_cmrnorm_layer', 'addto_layer',
'concat_layer', 'lstm_step_layer', 'recurrent_group',
'memory', 'StaticInput', 'expand_layer', 'scaling_layer',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册