use split layer in LRNMapLayer
authorJeff Donahue <jeff.donahue@gmail.com>
Sat, 29 Mar 2014 04:25:15 +0000 (21:25 -0700)
committerJeff Donahue <jeff.donahue@gmail.com>
Tue, 8 Apr 2014 18:36:18 +0000 (11:36 -0700)
include/caffe/vision_layers.hpp
src/caffe/layers/lrn_map_layer.cpp
src/caffe/layers/lrn_map_layer.cu

index e82cd82..22c0fd0 100644 (file)
@@ -530,8 +530,8 @@ class LRNLayer : public Layer<Dtype> {
   int width_;
 };
 
-template <typename Dtype>
-class PoolingLayer;
+template <typename Dtype> class PoolingLayer;
+template <typename Dtype> class SplitLayer;
 
 template <typename Dtype>
 class LRNMapLayer : public Layer<Dtype> {
@@ -551,6 +551,8 @@ class LRNMapLayer : public Layer<Dtype> {
   virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
       const bool propagate_down, vector<Blob<Dtype>*>* bottom);
 
+  shared_ptr<SplitLayer<Dtype> > split_layer_;
+  vector<Blob<Dtype>*> split_top_vec_;
   shared_ptr<PowerLayer<Dtype> > square_layer_;
   Blob<Dtype> square_input_;
   Blob<Dtype> square_output_;
@@ -565,7 +567,6 @@ class LRNMapLayer : public Layer<Dtype> {
   shared_ptr<EltwiseProductLayer<Dtype> > product_layer_;
   Blob<Dtype> product_data_input_;
   vector<Blob<Dtype>*> product_bottom_vec_;
-  vector<Blob<Dtype>*> product_top_vec_;
 };
 
 template <typename Dtype>
index 3ae3e5f..15119ad 100644 (file)
@@ -24,6 +24,13 @@ void LRNMapLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
   const Dtype pre_pad = (size_ - 1) / 2;
   const Dtype alpha = this->layer_param_.lrn_map_param().alpha();
   const Dtype beta = this->layer_param_.lrn_map_param().beta();
+  // Set up split layer to use inputs in the numerator and denominator.
+  split_top_vec_.clear();
+  split_top_vec_.push_back(bottom[0]);
+  split_top_vec_.push_back(&square_input_);
+  LayerParameter split_param;
+  split_layer_.reset(new SplitLayer<Dtype>(split_param));
+  split_layer_->SetUp(bottom, &split_top_vec_);
   // Set up square layer to square the inputs.
   square_input_.Reshape(num, channels, height, width);
   square_bottom_vec_.clear();
@@ -65,15 +72,14 @@ void LRNMapLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
   CHECK_EQ(power_output_.channels(), channels);
   CHECK_EQ(power_output_.height(), height);
   CHECK_EQ(power_output_.width(), width);
-  // Set up a product layer to compute outputs by multiplying inputs by scale.
+  // Set up a product layer to compute outputs by multiplying inputs by the
+  // demoninator computed by the power layer.
   product_bottom_vec_.clear();
   product_bottom_vec_.push_back(bottom[0]);
   product_bottom_vec_.push_back(&power_output_);
-  product_top_vec_.clear();
-  product_top_vec_.push_back((*top)[0]);
   LayerParameter product_param;
   product_layer_.reset(new EltwiseProductLayer<Dtype>(product_param));
-  product_layer_->SetUp(product_bottom_vec_, &product_top_vec_);
+  product_layer_->SetUp(product_bottom_vec_, top);
   CHECK_EQ((*top)[0]->num(), num);
   CHECK_EQ((*top)[0]->channels(), channels);
   CHECK_EQ((*top)[0]->height(), height);
@@ -83,14 +89,11 @@ void LRNMapLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
 template <typename Dtype>
 Dtype LRNMapLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
     vector<Blob<Dtype>*>* top) {
-  const int count = bottom[0]->count();
-  const Dtype* bottom_data = bottom[0]->cpu_data();
-  Dtype* square_bottom_data = square_input_.mutable_cpu_data();
-  caffe_copy(count, bottom_data, square_bottom_data);
+  split_layer_->Forward(bottom, &split_top_vec_);
   square_layer_->Forward(square_bottom_vec_, &square_top_vec_);
   pool_layer_->Forward(square_top_vec_, &pool_top_vec_);
   power_layer_->Forward(pool_top_vec_, &power_top_vec_);
-  product_layer_->Forward(product_bottom_vec_, &product_top_vec_);
+  product_layer_->Forward(product_bottom_vec_, top);
   return Dtype(0.);
 }
 
@@ -98,14 +101,11 @@ template <typename Dtype>
 void LRNMapLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
     const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
   if (propagate_down) {
-    product_layer_->Backward(product_top_vec_, true, &product_bottom_vec_);
+    product_layer_->Backward(top, true, &product_bottom_vec_);
     power_layer_->Backward(power_top_vec_, true, &pool_top_vec_);
     pool_layer_->Backward(pool_top_vec_, true, &square_top_vec_);
     square_layer_->Backward(square_top_vec_, true, &square_bottom_vec_);
-    const int count = (*bottom)[0]->count();
-    const Dtype* scale_diff = square_input_.cpu_diff();
-    Dtype* bottom_diff = (*bottom)[0]->mutable_cpu_diff();
-    caffe_axpy(count, Dtype(1), scale_diff, bottom_diff);
+    split_layer_->Backward(split_top_vec_, true, bottom);
   }
 }
 
index 727728e..b41adfc 100644 (file)
@@ -11,14 +11,11 @@ namespace caffe {
 template <typename Dtype>
 Dtype LRNMapLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
     vector<Blob<Dtype>*>* top) {
-  const int count = bottom[0]->count();
-  const Dtype* bottom_data = bottom[0]->gpu_data();
-  Dtype* square_bottom_data = square_input_.mutable_gpu_data();
-  caffe_gpu_copy(count, bottom_data, square_bottom_data);
+  split_layer_->Forward(bottom, &split_top_vec_);
   square_layer_->Forward(square_bottom_vec_, &square_top_vec_);
   pool_layer_->Forward(square_top_vec_, &pool_top_vec_);
   power_layer_->Forward(pool_top_vec_, &power_top_vec_);
-  product_layer_->Forward(product_bottom_vec_, &product_top_vec_);
+  product_layer_->Forward(product_bottom_vec_, top);
   return Dtype(0.);
 }
 
@@ -26,14 +23,11 @@ template <typename Dtype>
 void LRNMapLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
     const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
   if (propagate_down) {
-    product_layer_->Backward(product_top_vec_, true, &product_bottom_vec_);
+    product_layer_->Backward(top, true, &product_bottom_vec_);
     power_layer_->Backward(power_top_vec_, true, &pool_top_vec_);
     pool_layer_->Backward(pool_top_vec_, true, &square_top_vec_);
     square_layer_->Backward(square_top_vec_, true, &square_bottom_vec_);
-    const int count = (*bottom)[0]->count();
-    const Dtype* scale_diff = square_input_.gpu_diff();
-    Dtype* bottom_diff = (*bottom)[0]->mutable_gpu_diff();
-    caffe_gpu_axpy(count, Dtype(1), scale_diff, bottom_diff);
+    split_layer_->Backward(split_top_vec_, true, bottom);
   }
 }