diff options
author | Jeff Donahue <jeff.donahue@gmail.com> | 2014-07-09 15:05:57 -0700 |
---|---|---|
committer | Jeff Donahue <jeff.donahue@gmail.com> | 2014-07-15 13:48:09 -0700 |
commit | d5351bc99eb40bcf2de750b5b3aeeb43cafce82f (patch) | |
tree | 95c75a64db93740fa35360cbff8dcaaaf3022836 /src/caffe | |
parent | b2a9a3c7fea3022cccecf1cd729b44db3fd9dffd (diff) | |
download | caffeonacl-d5351bc99eb40bcf2de750b5b3aeeb43cafce82f.tar.gz caffeonacl-d5351bc99eb40bcf2de750b5b3aeeb43cafce82f.tar.bz2 caffeonacl-d5351bc99eb40bcf2de750b5b3aeeb43cafce82f.zip |
Make ConvolutionLayer and InnerProductLayer abide by param_propagate_down_
Diffstat (limited to 'src/caffe')
-rw-r--r-- | src/caffe/layers/conv_layer.cpp | 76 | ||||
-rw-r--r-- | src/caffe/layers/conv_layer.cu | 78 | ||||
-rw-r--r-- | src/caffe/layers/inner_product_layer.cpp | 17 | ||||
-rw-r--r-- | src/caffe/layers/inner_product_layer.cu | 20 |
4 files changed, 112 insertions, 79 deletions
diff --git a/src/caffe/layers/conv_layer.cpp b/src/caffe/layers/conv_layer.cpp index 963dc688..0d6871d6 100644 --- a/src/caffe/layers/conv_layer.cpp +++ b/src/caffe/layers/conv_layer.cpp @@ -85,6 +85,7 @@ void ConvolutionLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom, bias_multiplier_data[i] = 1.; } } + this->param_propagate_down_.resize(this->blobs_.size(), true); } @@ -124,11 +125,15 @@ Dtype ConvolutionLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, template <typename Dtype> void ConvolutionLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) { - const Dtype* weight = this->blobs_[0]->cpu_data(); - Dtype* weight_diff = this->blobs_[0]->mutable_cpu_diff(); - caffe_set(this->blobs_[0]->count(), Dtype(0), weight_diff); + const Dtype* weight = NULL; + Dtype* weight_diff = NULL; + if (this->param_propagate_down_[0]) { + weight = this->blobs_[0]->cpu_data(); + weight_diff = this->blobs_[0]->mutable_cpu_diff(); + caffe_set(this->blobs_[0]->count(), Dtype(0), weight_diff); + } Dtype* bias_diff = NULL; - if (bias_term_) { + if (bias_term_ && this->param_propagate_down_[1]) { bias_diff = this->blobs_[1]->mutable_cpu_diff(); caffe_set(this->blobs_[1]->count(), Dtype(0), bias_diff); } @@ -136,14 +141,10 @@ void ConvolutionLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const int col_offset = K_ * N_; const int top_offset = M_ * N_; for (int i = 0; i < top.size(); ++i) { - const Dtype* top_diff = top[i]->cpu_diff(); - const Dtype* bottom_data = (*bottom)[i]->cpu_data(); - Dtype* bottom_diff = (*bottom)[i]->mutable_cpu_diff(); - Dtype* col_data = col_buffer_.mutable_cpu_data(); - Dtype* col_diff = col_buffer_.mutable_cpu_diff(); - + const Dtype* top_diff = NULL; // Bias gradient, if necessary. - if (bias_term_) { + if (bias_term_ && this->param_propagate_down_[1]) { + top_diff = top[i]->cpu_diff(); for (int n = 0; n < num_; ++n) { caffe_cpu_gemv<Dtype>(CblasNoTrans, num_output_, N_, 1., top_diff + top[0]->offset(n), @@ -151,29 +152,40 @@ void ConvolutionLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, bias_diff); } } - for (int n = 0; n < num_; ++n) { - // Since we saved memory in the forward pass by not storing all col data, - // we will need to recompute them. - im2col_cpu(bottom_data + (*bottom)[i]->offset(n), channels_, height_, - width_, kernel_size_, pad_, stride_, col_data); - // gradient w.r.t. weight. Note that we will accumulate diffs. - for (int g = 0; g < group_; ++g) { - caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasTrans, M_, K_, N_, - (Dtype)1., top_diff + top[i]->offset(n) + top_offset * g, - col_data + col_offset * g, (Dtype)1., - weight_diff + weight_offset * g); + if (this->param_propagate_down_[0] || propagate_down[i]) { + if (!top_diff) { + top_diff = top[i]->cpu_diff(); } - // gradient w.r.t. bottom data, if necessary - if (propagate_down[i]) { - for (int g = 0; g < group_; ++g) { - caffe_cpu_gemm<Dtype>(CblasTrans, CblasNoTrans, K_, N_, M_, - (Dtype)1., weight + weight_offset * g, - top_diff + top[i]->offset(n) + top_offset * g, - (Dtype)0., col_diff + col_offset * g); + Dtype* col_data = col_buffer_.mutable_cpu_data(); + Dtype* col_diff = col_buffer_.mutable_cpu_diff(); + const Dtype* bottom_data = (*bottom)[i]->cpu_data(); + Dtype* bottom_diff = (*bottom)[i]->mutable_cpu_diff(); + for (int n = 0; n < num_; ++n) { + // Since we saved memory in the forward pass by not storing all col + // data, we will need to recompute them. + im2col_cpu(bottom_data + (*bottom)[i]->offset(n), channels_, height_, + width_, kernel_size_, pad_, stride_, col_data); + // gradient w.r.t. weight. Note that we will accumulate diffs. + if (this->param_propagate_down_[0]) { + for (int g = 0; g < group_; ++g) { + caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasTrans, M_, K_, N_, + (Dtype)1., top_diff + top[i]->offset(n) + top_offset * g, + col_data + col_offset * g, (Dtype)1., + weight_diff + weight_offset * g); + } + } + // gradient w.r.t. bottom data, if necessary + if (propagate_down[i]) { + for (int g = 0; g < group_; ++g) { + caffe_cpu_gemm<Dtype>(CblasTrans, CblasNoTrans, K_, N_, M_, + (Dtype)1., weight + weight_offset * g, + top_diff + top[i]->offset(n) + top_offset * g, + (Dtype)0., col_diff + col_offset * g); + } + // col2im back to the data + col2im_cpu(col_diff, channels_, height_, width_, kernel_size_, pad_, + stride_, bottom_diff + (*bottom)[i]->offset(n)); } - // col2im back to the data - col2im_cpu(col_diff, channels_, height_, width_, kernel_size_, pad_, - stride_, bottom_diff + (*bottom)[i]->offset(n)); } } } diff --git a/src/caffe/layers/conv_layer.cu b/src/caffe/layers/conv_layer.cu index 59ec58df..74067886 100644 --- a/src/caffe/layers/conv_layer.cu +++ b/src/caffe/layers/conv_layer.cu @@ -46,13 +46,15 @@ Dtype ConvolutionLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom, template <typename Dtype> void ConvolutionLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) { - const Dtype* weight = this->blobs_[0]->gpu_data(); - Dtype* weight_diff = this->blobs_[0]->mutable_gpu_diff(); - caffe_gpu_set(this->blobs_[0]->count(), Dtype(0), weight_diff); - Dtype* col_data = col_buffer_.mutable_gpu_data(); - Dtype* col_diff = col_buffer_.mutable_gpu_diff(); + const Dtype* weight = NULL; + Dtype* weight_diff = NULL; + if (this->param_propagate_down_[0]) { + weight = this->blobs_[0]->gpu_data(); + weight_diff = this->blobs_[0]->mutable_gpu_diff(); + caffe_gpu_set(this->blobs_[0]->count(), Dtype(0), weight_diff); + } Dtype* bias_diff = NULL; - if (bias_term_) { + if (bias_term_ && this->param_propagate_down_[1]) { bias_diff = this->blobs_[1]->mutable_gpu_diff(); caffe_gpu_set(this->blobs_[1]->count(), Dtype(0), bias_diff); } @@ -60,41 +62,51 @@ void ConvolutionLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top, const int col_offset = K_ * N_; const int top_offset = M_ * N_; for (int i = 0; i < top.size(); ++i) { - const Dtype* top_diff = top[i]->gpu_diff(); - const Dtype* bottom_data = (*bottom)[i]->gpu_data(); - Dtype* bottom_diff = (*bottom)[i]->mutable_gpu_diff(); + const Dtype* top_diff = NULL; // Bias gradient, if necessary. - if (bias_term_) { + if (bias_term_ && this->param_propagate_down_[1]) { + top_diff = top[i]->gpu_diff(); for (int n = 0; n < num_; ++n) { caffe_gpu_gemv<Dtype>(CblasNoTrans, num_output_, N_, 1., top_diff + top[0]->offset(n), - static_cast<const Dtype*>(bias_multiplier_->gpu_data()), - 1., bias_diff); + static_cast<const Dtype*>(bias_multiplier_->gpu_data()), 1., + bias_diff); } } - for (int n = 0; n < num_; ++n) { - // since we saved memory in the forward pass by not storing all col data, - // we will need to recompute them. - im2col_gpu(bottom_data + (*bottom)[i]->offset(n), channels_, height_, - width_, kernel_size_, pad_, stride_, col_data); - // gradient w.r.t. weight. Note that we will accumulate diffs. - for (int g = 0; g < group_; ++g) { - caffe_gpu_gemm<Dtype>(CblasNoTrans, CblasTrans, M_, K_, N_, - (Dtype)1., top_diff + top[i]->offset(n) + top_offset * g, - col_data + col_offset * g, (Dtype)1., - weight_diff + weight_offset * g); + if (this->param_propagate_down_[0] || propagate_down[i]) { + if (!top_diff) { + top_diff = top[i]->gpu_diff(); } - // gradient w.r.t. bottom data, if necessary - if (propagate_down[i]) { - for (int g = 0; g < group_; ++g) { - caffe_gpu_gemm<Dtype>(CblasTrans, CblasNoTrans, K_, N_, M_, - (Dtype)1., weight + weight_offset * g, - top_diff + top[i]->offset(n) + top_offset * g, - (Dtype)0., col_diff + col_offset * g); + Dtype* col_data = col_buffer_.mutable_gpu_data(); + Dtype* col_diff = col_buffer_.mutable_gpu_diff(); + const Dtype* bottom_data = (*bottom)[i]->gpu_data(); + Dtype* bottom_diff = (*bottom)[i]->mutable_gpu_diff(); + for (int n = 0; n < num_; ++n) { + // Since we saved memory in the forward pass by not storing all col + // data, we will need to recompute them. + im2col_gpu(bottom_data + (*bottom)[i]->offset(n), channels_, height_, + width_, kernel_size_, pad_, stride_, col_data); + // gradient w.r.t. weight. Note that we will accumulate diffs. + if (this->param_propagate_down_[0]) { + for (int g = 0; g < group_; ++g) { + caffe_gpu_gemm<Dtype>(CblasNoTrans, CblasTrans, M_, K_, N_, + (Dtype)1., top_diff + top[i]->offset(n) + top_offset * g, + col_data + col_offset * g, (Dtype)1., + weight_diff + weight_offset * g); + } + } + // gradient w.r.t. bottom data, if necessary + if (propagate_down[i]) { + for (int g = 0; g < group_; ++g) { + caffe_gpu_gemm<Dtype>(CblasTrans, CblasNoTrans, K_, N_, M_, + (Dtype)1., weight + weight_offset * g, + top_diff + top[i]->offset(n) + top_offset * g, + (Dtype)0., col_diff + col_offset * g); + } + // col2im back to the data + col2im_gpu(col_diff, channels_, height_, width_, kernel_size_, pad_, + stride_, bottom_diff + (*bottom)[i]->offset(n)); } - // col2im back to the data - col2im_gpu(col_diff, channels_, height_, width_, kernel_size_, pad_, - stride_, bottom_diff + (*bottom)[i]->offset(n)); } } } diff --git a/src/caffe/layers/inner_product_layer.cpp b/src/caffe/layers/inner_product_layer.cpp index ddf55e49..29df6bf2 100644 --- a/src/caffe/layers/inner_product_layer.cpp +++ b/src/caffe/layers/inner_product_layer.cpp @@ -54,6 +54,7 @@ void InnerProductLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom, bias_multiplier_data[i] = 1.; } } + this->param_propagate_down_.resize(this->blobs_.size(), true); } template <typename Dtype> @@ -76,18 +77,22 @@ template <typename Dtype> void InnerProductLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) { - const Dtype* top_diff = top[0]->cpu_diff(); - const Dtype* bottom_data = (*bottom)[0]->cpu_data(); - // Gradient with respect to weight - caffe_cpu_gemm<Dtype>(CblasTrans, CblasNoTrans, N_, K_, M_, (Dtype)1., - top_diff, bottom_data, (Dtype)0., this->blobs_[0]->mutable_cpu_diff()); - if (bias_term_) { + if (this->param_propagate_down_[0]) { + const Dtype* top_diff = top[0]->cpu_diff(); + const Dtype* bottom_data = (*bottom)[0]->cpu_data(); + // Gradient with respect to weight + caffe_cpu_gemm<Dtype>(CblasTrans, CblasNoTrans, N_, K_, M_, (Dtype)1., + top_diff, bottom_data, (Dtype)0., this->blobs_[0]->mutable_cpu_diff()); + } + if (bias_term_ && this->param_propagate_down_[1]) { + const Dtype* top_diff = top[0]->cpu_diff(); // Gradient with respect to bias caffe_cpu_gemv<Dtype>(CblasTrans, M_, N_, (Dtype)1., top_diff, reinterpret_cast<const Dtype*>(bias_multiplier_->cpu_data()), (Dtype)0., this->blobs_[1]->mutable_cpu_diff()); } if (propagate_down[0]) { + const Dtype* top_diff = top[0]->cpu_diff(); // Gradient with respect to bottom data caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, M_, K_, N_, (Dtype)1., top_diff, this->blobs_[0]->cpu_data(), (Dtype)0., diff --git a/src/caffe/layers/inner_product_layer.cu b/src/caffe/layers/inner_product_layer.cu index 5b95a57b..f3e49467 100644 --- a/src/caffe/layers/inner_product_layer.cu +++ b/src/caffe/layers/inner_product_layer.cu @@ -33,18 +33,22 @@ template <typename Dtype> void InnerProductLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) { - const Dtype* top_diff = top[0]->gpu_diff(); - const Dtype* bottom_data = (*bottom)[0]->gpu_data(); - // Gradient with respect to weight - caffe_gpu_gemm<Dtype>(CblasTrans, CblasNoTrans, N_, K_, M_, (Dtype)1., - top_diff, bottom_data, (Dtype)0., this->blobs_[0]->mutable_gpu_diff()); - if (bias_term_) { + if (this->param_propagate_down_[0]) { + const Dtype* top_diff = top[0]->gpu_diff(); + const Dtype* bottom_data = (*bottom)[0]->gpu_data(); + // Gradient with respect to weight + caffe_gpu_gemm<Dtype>(CblasTrans, CblasNoTrans, N_, K_, M_, (Dtype)1., + top_diff, bottom_data, (Dtype)0., this->blobs_[0]->mutable_gpu_diff()); + } + if (bias_term_ && this->param_propagate_down_[1]) { + const Dtype* top_diff = top[0]->gpu_diff(); // Gradient with respect to bias caffe_gpu_gemv<Dtype>(CblasTrans, M_, N_, (Dtype)1., top_diff, - reinterpret_cast<const Dtype*>(bias_multiplier_->gpu_data()), - (Dtype)0., this->blobs_[1]->mutable_gpu_diff()); + reinterpret_cast<const Dtype*>(bias_multiplier_->gpu_data()), (Dtype)0., + this->blobs_[1]->mutable_gpu_diff()); } if (propagate_down[0]) { + const Dtype* top_diff = top[0]->gpu_diff(); // Gradient with respect to bottom data caffe_gpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, M_, K_, N_, (Dtype)1., top_diff, this->blobs_[0]->gpu_data(), (Dtype)0., |