adds a parameter to the LRN layer (denoted as "k" in [Krizhevsky et al., NIPS 2012])
authorKaren Simonyan <karen@robots.ox.ac.uk>
Thu, 18 Sep 2014 00:08:56 +0000 (01:08 +0100)
committerKaren Simonyan <karen@robots.ox.ac.uk>
Mon, 22 Sep 2014 19:28:06 +0000 (20:28 +0100)
include/caffe/vision_layers.hpp
src/caffe/layers/lrn_layer.cpp
src/caffe/layers/lrn_layer.cu
src/caffe/proto/caffe.proto

index fa51614..a3c8bc0 100644 (file)
@@ -246,6 +246,7 @@ class LRNLayer : public Layer<Dtype> {
   int pre_pad_;
   Dtype alpha_;
   Dtype beta_;
+  Dtype k_;
   int num_;
   int channels_;
   int height_;
index fb74b03..a09a479 100644 (file)
@@ -14,6 +14,7 @@ void LRNLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
   pre_pad_ = (size_ - 1) / 2;
   alpha_ = this->layer_param_.lrn_param().alpha();
   beta_ = this->layer_param_.lrn_param().beta();
+  k_ = this->layer_param_.lrn_param().k();
   if (this->layer_param_.lrn_param().norm_region() ==
       LRNParameter_NormRegion_WITHIN_CHANNEL) {
     // Set up split_layer_ to use inputs in the numerator and denominator.
@@ -110,7 +111,7 @@ void LRNLayer<Dtype>::CrossChannelForward_cpu(
   Dtype* scale_data = scale_.mutable_cpu_data();
   // start with the constant value
   for (int i = 0; i < scale_.count(); ++i) {
-    scale_data[i] = 1.;
+    scale_data[i] = k_;
   }
   Blob<Dtype> padded_square(1, channels_ + size_ - 1, height_, width_);
   Dtype* padded_square_data = padded_square.mutable_cpu_data();
index ee5e359..47b003b 100644 (file)
@@ -10,7 +10,7 @@ template <typename Dtype>
 __global__ void LRNFillScale(const int nthreads, const Dtype* in,
     const int num, const int channels, const int height,
     const int width, const int size, const Dtype alpha_over_size,
-    Dtype* scale) {
+    const Dtype k, Dtype* scale) {
   CUDA_KERNEL_LOOP(index, nthreads) {
     // find out the local offset
     int w = index % width;
@@ -33,20 +33,20 @@ __global__ void LRNFillScale(const int nthreads, const Dtype* in,
     // until we reach size, nothing needs to be subtracted
     while (head < size) {
       accum_scale += in[head * step] * in[head * step];
-      scale[(head - post_pad) * step] = 1. + accum_scale * alpha_over_size;
+      scale[(head - post_pad) * step] = k + accum_scale * alpha_over_size;
       ++head;
     }
     // both add and subtract
     while (head < channels) {
       accum_scale += in[head * step] * in[head * step];
       accum_scale -= in[(head - size) * step] * in[(head - size) * step];
-      scale[(head - post_pad) * step] = 1. + accum_scale * alpha_over_size;
+      scale[(head - post_pad) * step] = k + accum_scale * alpha_over_size;
       ++head;
     }
     // subtract only
     while (head < channels + post_pad) {
       accum_scale -= in[(head - size) * step] * in[(head - size) * step];
-      scale[(head - post_pad) * step] = 1. + accum_scale * alpha_over_size;
+      scale[(head - post_pad) * step] = k + accum_scale * alpha_over_size;
       ++head;
     }
   }
@@ -90,7 +90,7 @@ void LRNLayer<Dtype>::CrossChannelForward_gpu(
   // NOLINT_NEXT_LINE(whitespace/operators)
   LRNFillScale<<<CAFFE_GET_BLOCKS(n_threads), CAFFE_CUDA_NUM_THREADS>>>(
       n_threads, bottom_data, num_, channels_, height_, width_, size_,
-      alpha_ / size_, scale_data);
+      alpha_ / size_, k_, scale_data);
   CUDA_POST_KERNEL_CHECK;
   n_threads = bottom[0]->count();
   // NOLINT_NEXT_LINE(whitespace/operators)
index 9395c38..b9712fa 100644 (file)
@@ -548,6 +548,7 @@ message LRNParameter {
     WITHIN_CHANNEL = 1;
   }
   optional NormRegion norm_region = 4 [default = ACROSS_CHANNELS];
+  optional float k = 5 [default = 1.];
 }
 
 // Message that stores parameters used by MemoryDataLayer