8000 Within-channel LRN layer by jeffdonahue · Pull Request #273 · BVLC/caffe · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Within-channel LRN layer #273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Apr 8, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/cifar10/cifar10_full_test.prototxt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ layers {
bottom: "pool1"
top: "norm1"
lrn_param {
norm_region: WITHIN_CHANNEL
local_size: 3
alpha: 5e-05
beta: 0.75
Expand Down Expand Up @@ -103,6 +104,7 @@ layers {
bottom: "pool2"
top: "norm2"
lrn_param {
norm_region: WITHIN_CHANNEL
local_size: 3
alpha: 5e-05
beta: 0.75
Expand Down
2 changes: 2 additions & 0 deletions examples/cifar10/cifar10_full_train.prototxt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ layers {
bottom: "pool1"
top: "norm1"
lrn_param {
norm_region: WITHIN_CHANNEL
local_size: 3
alpha: 5e-05
beta: 0.75
Expand Down Expand Up @@ -103,6 +104,7 @@ layers {
bottom: "pool2"
top: "norm2"
lrn_param {
norm_region: WITHIN_CHANNEL
local_size: 3
alpha: 5e-05
beta: 0.75
Expand Down
11 changes: 8 additions & 3 deletions examples/cifar10/train_full.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

TOOLS=../../build/tools

GLOG_logtostderr=1 $TOOLS/train_net.bin cifar10_full_solver.prototxt
GLOG_logtostderr=1 $TOOLS/train_net.bin \
cifar10_full_solver.prototxt

#reduce learning rate by factor of 10
GLOG_logtostderr=1 $TOOLS/train_net.bin cifar10_full_solver_lr1.prototxt cifar10_full_iter_60000.solverstate
GLOG_logtostderr=1 $TOOLS/train_net.bin \
cifar10_full_solver_lr1.prototxt \
cifar10_full_iter_60000.solverstate

#reduce learning rate by factor of 10
GLOG_logtostderr=1 $TOOLS/train_net.bin cifar10_full_solver_lr2.prototxt cifar10_full_iter_65000.solverstate
GLOG_logtostderr=1 $TOOLS/train_net.bin \
cifar10_full_solver_lr2.prototxt \
cifar10_full_iter_65000.solverstate
18 changes: 18 additions & 0 deletions include/caffe/util/math_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,21 @@ void caffe_gpu_axpby(const int N, const Dtype alpha, const Dtype* X,
template <typename Dtype>
void caffe_copy(const int N, const Dtype *X, Dtype *Y);

template <typename Dtype>
void caffe_set(const int N, const Dtype alpha, Dtype *X);

template <typename Dtype>
void caffe_gpu_set(const int N, const Dtype alpha, Dtype *X);

template <typename Dtype>
void caffe_gpu_copy(const int N, const Dtype *X, Dtype *Y);

template <typename Dtype>
void caffe_add_scalar(const int N, const Dtype alpha, Dtype *X);

template <typename Dtype>
void caffe_gpu_add_scalar(const int N, const Dtype alpha, Dtype *X);

template <typename Dtype>
void caffe_scal(const int N, const Dtype alpha, Dtype *X);

Expand All @@ -84,9 +96,15 @@ void caffe_gpu_mul(const int N, const Dtype* a, const Dtype* b, Dtype* y);
template <typename Dtype>
void caffe_div(const int N, const Dtype* a, const Dtype* b, Dtype* y);

template <typename Dtype>
void caffe_gpu_div(const int N, const Dtype* a, const Dtype* b, Dtype* y);

template <typename Dtype>
void caffe_powx(const int n, const Dtype* a, const Dtype b, Dtype* y);

template <typename Dtype>
void caffe_gpu_powx(const int n, const Dtype* a, const Dtype b, Dtype* y);

template <typename Dtype>
Dtype caffe_nextafter(const Dtype b);

Expand Down
85 changes: 83 additions & 2 deletions include/caffe/vision_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,30 @@ class DropoutLayer : public NeuronLayer<Dtype> {
unsigned int uint_thres_;
};

template <typename Dtype>
class PowerLayer : public NeuronLayer<Dtype> {
public:
explicit PowerLayer(const LayerParameter& param)
: NeuronLayer<Dtype>(param) {}
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual Dtype Forward_gpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);

Dtype power_;
Dtype scale_;
Dtype shift_;
Dtype diff_scale_;
};

template <typename Dtype>
class ReLULayer : public NeuronLayer<Dtype> {
public:
Expand Down Expand Up @@ -246,6 +270,25 @@ class DataLayer : public Layer<Dtype> {
Blob<Dtype> data_mean_;
};

template <typename Dtype>
class EltwiseProductLayer : public Layer<Dtype> {
public:
explicit EltwiseProductLayer(const LayerParameter& param)
: Layer<Dtype>(param) {}
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual Dtype Forward_gpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);
};

template <typename Dtype>
class EuclideanLossLayer : public Layer<Dtype> {
public:
Expand Down Expand Up @@ -452,6 +495,10 @@ class InnerProductLayer : public Layer<Dtype> {
shared_ptr<SyncedMemory> bias_multiplier_;
};

// Forward declare PoolingLayer and SplitLayer for use in LRNLayer.
template <typename Dtype> class PoolingLayer;
template <typename Dtype> class SplitLayer;

template <typename Dtype>
class LRNLayer : public Layer<Dtype> {
public:
Expand All @@ -470,8 +517,19 @@ class LRNLayer : public Layer<Dtype> {
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);

// scale_ stores the intermediate summing results
Blob<Dtype> scale_;
virtual Dtype CrossChannelForward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual Dtype CrossChannelForward_gpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual Dtype WithinChannelForward(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void CrossChannelBackward_cpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);
virtual void CrossChannelBackward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);
virtual void WithinChannelBackward(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);

int size_;
int pre_pad_;
Dtype alpha_;
Expand All @@ -480,6 +538,28 @@ class LRNLayer : public Layer<Dtype> {
int channels_;
int height_;
int width_;

// Fields used for normalization ACROSS_CHANNELS
// scale_ stores the intermediate summing results
Blob<Dtype> scale_;

// Fields used for normalization WITHIN_CHANNEL
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_;
vector<Blob<Dtype>*> square_bottom_vec_;
vector<Blob<Dtype>*> square_top_vec_;
shared_ptr<PoolingLayer<Dtype> > pool_layer_;
Blob<Dtype> pool_output_;
vector<Blob<Dtype>*> pool_top_vec_;
shared_ptr<PowerLayer<Dtype> > power_layer_;
Blob<Dtype> power_output_;
vector<Blob<Dtype>*> power_top_vec_;
shared_ptr<EltwiseProductLayer<Dtype> > product_layer_;
Blob<Dtype> product_data_input_;
vector<Blob<Dtype>*> product_bottom_vec_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that both PowerLayer and EltwiseProductLayer are suitable to be refactored in #244.

};

template <typename Dtype>
Expand Down Expand Up @@ -521,6 +601,7 @@ class PoolingLayer : public Layer<Dtype> {

int kernel_size_;
int stride_;
int pad_;
int channels_;
int height_;
int width_;
Expand Down
4 changes: 4 additions & 0 deletions src/caffe/layer_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Layer<Dtype>* GetLayer(const LayerParameter& param) {
return new DropoutLayer<Dtype>(param);
case LayerParameter_LayerType_EUCLIDEAN_LOSS:
return new EuclideanLossLayer<Dtype>(param);
case LayerParameter_LayerType_ELTWISE_PRODUCT:
return new EltwiseProductLayer<Dtype>(param);
case LayerParameter_LayerType_FLATTEN:
return new FlattenLayer<Dtype>(param);
case LayerParameter_LayerType_HDF5_DATA:
Expand All @@ -56,6 +58,8 @@ Layer<Dtype>* GetLayer(const LayerParameter& param) {
return new MultinomialLogisticLossLayer<Dtype>(param);
case LayerParameter_LayerType_POOLING:
return new PoolingLayer<Dtype>(param);
case LayerParameter_LayerType_POWER:
return new PowerLayer<Dtype>(param);
case LayerParameter_LayerType_RELU:
return new ReLULayer<Dtype>(param);
case LayerParameter_LayerType_SIGMOID:
Expand Down
62 changes: 62 additions & 0 deletions src/caffe/layers/eltwise_product_layer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2014 BVLC and contributors.

#include <vector>

#include "caffe/layer.hpp"
#include "caffe/vision_layers.hpp"
#include "caffe/util/math_functions.hpp"

namespace caffe {

template <typename Dtype>
void EltwiseProductLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
CHECK_GE(bottom.size(), 2) <<
"Eltwise Product Layer takes at least 2 blobs as input.";
CHECK_EQ(top->size(), 1) <<
"Eltwise Product Layer takes a single blob as output.";
const int num = bottom[0]->num();
const int channels = bottom[0]->channels();
const int height = bottom[0]->height();
const int width = bottom[0]->width();
for (int i = 1; i < bottom.size(); ++i) {
CHECK_EQ(num, bottom[i]->num());
CHECK_EQ(channels, bottom[i]->channels());
CHECK_EQ(height, bottom[i]->height());
CHECK_EQ(width, bottom[i]->width());
}
(*top)[0]->Reshape(num, channels, height, width);
}

template <typename Dtype>
Dtype EltwiseProductLayer<Dtype>::Forward_cpu(
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {
const int count = (*top)[0]->count();
Dtype* top_data = (*top)[0]->mutable_cpu_data();
caffe_mul(count, bottom[0]->cpu_data(), bottom[1]->cpu_data(), top_data);
for (int i = 2; i < bottom.size(); ++i) {
caffe_mul(count, top_data, bottom[i]->cpu_data(), top_data);
}
return Dtype(0.);
}

template <typename Dtype>
void EltwiseProductLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
if (propagate_down) {
const int count = top[0]->count();
const Dtype* top_data = top[0]->cpu_data();
const Dtype* top_diff = top[0]->cpu_diff();
for (int i = 0; i < bottom->size(); ++i) {
const Dtype* bottom_data = (*bottom)[i]->cpu_data();
Dtype* bottom_diff = (*bottom)[i]->mutable_cpu_diff();
caffe_div(count, top_data, bottom_data, bottom_diff);
caffe_mul(count, bottom_diff, top_diff, bottom_diff);
}
}
}

INSTANTIATE_CLASS(EltwiseProductLayer);


} // namespace caffe
42 changes: 42 additions & 0 deletions
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2014 BVLC and contributors.

#include <vector>

#include "caffe/layer.hpp"
#include "caffe/vision_layers.hpp"
#include "caffe/util/math_functions.hpp"

namespace caffe {

template <typename Dtype>
Dtype EltwiseProductLayer<Dtype>::Forward_gpu(
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {
const int count = (*top)[0]->count();
Dtype* top_data = (*top)[0]->mutable_gpu_data();
caffe_gpu_mul(count, bottom[0]->gpu_data(), bottom[1]->gpu_data(), top_data);
for (int i = 2; i < bottom.size(); ++i) {
caffe_gpu_mul(count, top_data, bottom[i]->gpu_data(), top_data);
}
return Dtype(0.);
}

template <typename Dtype>
void EltwiseProductLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
if (propagate_down) {
const int count = top[0]->count();
const Dtype* top_data = top[0]->gpu_data();
const Dtype* top_diff = top[0]->gpu_diff();
for (int i = 0; i < bottom->size(); ++i) {
const Dtype* bottom_data = (*bottom)[i]->gpu_data();
Dtype* bottom_diff = (*bottom)[i]->mutable_gpu_diff();
caffe_gpu_div(count, top_data, bottom_data, bottom_diff);
caffe_gpu_mul(count, bottom_diff, top_diff, bottom_diff);
}
}
}

INSTANTIATE_CLASS(EltwiseProductLayer);


} // namespace caffe
Loading
0