From 4bed0ac9bab45246183184d84ff1b742e60574c7 Mon Sep 17 00:00:00 2001 From: Jeff Donahue Date: Mon, 24 Aug 2015 19:44:18 -0700 Subject: [PATCH 1/2] TestConcatLayer: add gradient check for bottom[1] only (to verify propagate_down[0] == false correctness) --- src/caffe/test/test_concat_layer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/caffe/test/test_concat_layer.cpp b/src/caffe/test/test_concat_layer.cpp index 662a50fa23b..088e0a41685 100644 --- a/src/caffe/test/test_concat_layer.cpp +++ b/src/caffe/test/test_concat_layer.cpp @@ -173,4 +173,13 @@ TYPED_TEST(ConcatLayerTest, TestGradientChannels) { this->blob_top_vec_); } +TYPED_TEST(ConcatLayerTest, TestGradientChannelsBottomOneOnly) { + typedef typename TypeParam::Dtype Dtype; + LayerParameter layer_param; + ConcatLayer layer(layer_param); + GradientChecker checker(1e-2, 1e-2); + checker.CheckGradient(&layer, this->blob_bottom_vec_0_, + this->blob_top_vec_, 1); +} + } // namespace caffe From 6a7d4d6652018245f7bde1499d5208996912f3fb Mon Sep 17 00:00:00 2001 From: Jeff Donahue Date: Mon, 24 Aug 2015 19:22:54 -0700 Subject: [PATCH 2/2] bugfix for ConcatLayer with propagate_down set if propagate_down[i] was set, offset_concat_axis was not correctly updated for subsequent bottoms i+1, i+2, ... --- src/caffe/layers/concat_layer.cpp | 13 +++++++------ src/caffe/layers/concat_layer.cu | 17 +++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/caffe/layers/concat_layer.cpp b/src/caffe/layers/concat_layer.cpp index 1cac8fc3387..95fba105b9a 100644 --- a/src/caffe/layers/concat_layer.cpp +++ b/src/caffe/layers/concat_layer.cpp @@ -76,13 +76,14 @@ void ConcatLayer::Backward_cpu(const vector*>& top, int offset_concat_axis = 0; const int top_concat_axis = top[0]->shape(concat_axis_); for (int i = 0; i < bottom.size(); ++i) { - if (!propagate_down[i]) { continue; } - Dtype* bottom_diff = bottom[i]->mutable_cpu_diff(); const int bottom_concat_axis = bottom[i]->shape(concat_axis_); - for (int n = 0; n < num_concats_; ++n) { - caffe_copy(bottom_concat_axis * concat_input_size_, top_diff + - (n * top_concat_axis + offset_concat_axis) * concat_input_size_, - bottom_diff + n * bottom_concat_axis * concat_input_size_); + if (propagate_down[i]) { + Dtype* bottom_diff = bottom[i]->mutable_cpu_diff(); + for (int n = 0; n < num_concats_; ++n) { + caffe_copy(bottom_concat_axis * concat_input_size_, top_diff + + (n * top_concat_axis + offset_concat_axis) * concat_input_size_, + bottom_diff + n * bottom_concat_axis * concat_input_size_); + } } offset_concat_axis += bottom_concat_axis; } diff --git a/src/caffe/layers/concat_layer.cu b/src/caffe/layers/concat_layer.cu index 8f2e85d8f52..3c64c7ef224 100644 --- a/src/caffe/layers/concat_layer.cu +++ b/src/caffe/layers/concat_layer.cu @@ -53,15 +53,16 @@ void ConcatLayer::Backward_gpu(const vector*>& top, const int top_concat_axis = top[0]->shape(concat_axis_); const bool kForward = false; for (int i = 0; i < bottom.size(); ++i) { - if (!propagate_down[i]) { continue; } - Dtype* bottom_diff = bottom[i]->mutable_gpu_diff(); const int bottom_concat_axis = bottom[i]->shape(concat_axis_); - const int bottom_concat_size = bottom_concat_axis * concat_input_size_; - const int nthreads = bottom_concat_size * num_concats_; - Concat // NOLINT_NEXT_LINE(whitespace/operators) - <<>>( - nthreads, top_diff, kForward, num_concats_, concat_input_size_, - top_concat_axis, bottom_concat_axis, offset_concat_axis, bottom_diff); + if (propagate_down[i]) { + Dtype* bottom_diff = bottom[i]->mutable_gpu_diff(); + const int bottom_concat_size = bottom_concat_axis * concat_input_size_; + const int nthreads = bottom_concat_size * num_concats_; + Concat // NOLINT_NEXT_LINE(whitespace/operators) + <<>>( + nthreads, top_diff, kForward, num_concats_, concat_input_size_, + top_concat_axis, bottom_concat_axis, offset_concat_axis, bottom_diff); + } offset_concat_axis += bottom_concat_axis; } }