public:
explicit SigmoidCrossEntropyLossLayer(const LayerParameter& param)
: LossLayer<Dtype>(param),
- sigmoid_layer_(new SigmoidLayer<Dtype>(param)),
+ sigmoid_layer_(new CaffeSigmoidLayer<Dtype>(param)),
sigmoid_output_(new Blob<Dtype>()) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
/// The internal SigmoidLayer used to map predictions to probabilities.
- shared_ptr<SigmoidLayer<Dtype> > sigmoid_layer_;
+ shared_ptr<CaffeSigmoidLayer<Dtype> > sigmoid_layer_;
/// sigmoid_output stores the output of the SigmoidLayer.
shared_ptr<Blob<Dtype> > sigmoid_output_;
/// bottom vector holder to call the underlying SigmoidLayer::Forward
* the computed outputs are @f$ y = \max(0, x) + \nu \min(0, x) @f$.
*/
virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top);
+ vector<Blob<Dtype>*>* top) = 0;
virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top);
+ vector<Blob<Dtype>*>* top) = 0;
/**
* @brief Computes the error gradient w.r.t. the ReLU inputs.
* @f$.
*/
virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
+ const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) = 0;
+ virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
+ const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) = 0;
+};
+
+/**
+ * @brief standard Caffe implementation of ReLULayer.
+ */
+template <typename Dtype>
+class CaffeReLULayer : public ReLULayer<Dtype> {
+ public:
+ explicit CaffeReLULayer(const LayerParameter& param)
+ : ReLULayer<Dtype>(param) {}
+
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_RELU;
+ }
+
+ protected:
+ virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
+ vector<Blob<Dtype>*>* top);
+ virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
+ vector<Blob<Dtype>*>* top);
+
+ virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
* @f$
*/
virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top);
+ vector<Blob<Dtype>*>* top) = 0;
virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top);
+ vector<Blob<Dtype>*>* top) = 0;
/**
* @brief Computes the error gradient w.r.t. the sigmoid inputs.
* @f$ if propagate_down[0]
*/
virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
+ const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) = 0;
+ virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
+ const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) = 0;
+};
+
+/**
+ * @brief standard Caffe implementation of SigmoidLayer.
+ */
+template <typename Dtype>
+class CaffeSigmoidLayer : public SigmoidLayer<Dtype> {
+ public:
+ explicit CaffeSigmoidLayer(const LayerParameter& param)
+ : SigmoidLayer<Dtype>(param) {}
+
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_SIGMOID;
+ }
+
+ protected:
+ virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
+ vector<Blob<Dtype>*>* top);
+ virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
+ vector<Blob<Dtype>*>* top);
+
+ virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
* @f$
*/
virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top);
+ vector<Blob<Dtype>*>* top) = 0;
virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top);
+ vector<Blob<Dtype>*>* top) = 0;
/**
* @brief Computes the error gradient w.r.t. the sigmoid inputs.
* @f$ if propagate_down[0]
*/
virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
+ const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) = 0;
+ virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
+ const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) = 0;
+};
+
+/**
+ * @brief standard Caffe implementation of TanHLayer.
+ */
+template <typename Dtype>
+class CaffeTanHLayer : public TanHLayer<Dtype> {
+ public:
+ explicit CaffeTanHLayer(const LayerParameter& param)
+ : TanHLayer<Dtype>(param) {}
+
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_TANH;
+ }
+
+ protected:
+ virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
+ vector<Blob<Dtype>*>* top);
+ virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
+ vector<Blob<Dtype>*>* top);
+
+ virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
template PoolingLayer<double>* GetPoolingLayer(const string& name,
const LayerParameter& param);
+// Get relu layer according to engine.
+template <typename Dtype>
+ReLULayer<Dtype>* GetReLULayer(const string& name,
+ const LayerParameter& param) {
+ ReLUParameter_Engine engine = param.relu_param().engine();
+ if (engine == ReLUParameter_Engine_CAFFE) {
+ return new CaffeReLULayer<Dtype>(param);
+ } else {
+ LOG(FATAL) << "Layer " << name << " has unknown engine.";
+ }
+}
+
+template ReLULayer<float>* GetReLULayer(const string& name,
+ const LayerParameter& param);
+template ReLULayer<double>* GetReLULayer(const string& name,
+ const LayerParameter& param);
+
+// Get sigmoid layer according to engine.
+template <typename Dtype>
+SigmoidLayer<Dtype>* GetSigmoidLayer(const string& name,
+ const LayerParameter& param) {
+ SigmoidParameter_Engine engine = param.sigmoid_param().engine();
+ if (engine == SigmoidParameter_Engine_CAFFE) {
+ return new CaffeSigmoidLayer<Dtype>(param);
+ } else {
+ LOG(FATAL) << "Layer " << name << " has unknown engine.";
+ }
+}
+
+template SigmoidLayer<float>* GetSigmoidLayer(const string& name,
+ const LayerParameter& param);
+template SigmoidLayer<double>* GetSigmoidLayer(const string& name,
+ const LayerParameter& param);
+
+// Get tanh layer according to engine.
+template <typename Dtype>
+TanHLayer<Dtype>* GetTanHLayer(const string& name,
+ const LayerParameter& param) {
+ TanHParameter_Engine engine = param.tanh_param().engine();
+ if (engine == TanHParameter_Engine_CAFFE) {
+ return new CaffeTanHLayer<Dtype>(param);
+ } else {
+ LOG(FATAL) << "Layer " << name << " has unknown engine.";
+ }
+}
+
+template TanHLayer<float>* GetTanHLayer(const string& name,
+ const LayerParameter& param);
+template TanHLayer<double>* GetTanHLayer(const string& name,
+ const LayerParameter& param);
+
// A function to get a specific layer from the specification given in
// LayerParameter. Ideally this would be replaced by a factory pattern,
// but we will leave it this way for now.
case LayerParameter_LayerType_POWER:
return new PowerLayer<Dtype>(param);
case LayerParameter_LayerType_RELU:
- return new ReLULayer<Dtype>(param);
+ return GetReLULayer<Dtype>(name, param);
case LayerParameter_LayerType_SILENCE:
return new SilenceLayer<Dtype>(param);
case LayerParameter_LayerType_SIGMOID:
- return new SigmoidLayer<Dtype>(param);
+ return GetSigmoidLayer<Dtype>(name, param);
case LayerParameter_LayerType_SIGMOID_CROSS_ENTROPY_LOSS:
return new SigmoidCrossEntropyLossLayer<Dtype>(param);
case LayerParameter_LayerType_SLICE:
case LayerParameter_LayerType_SPLIT:
return new SplitLayer<Dtype>(param);
case LayerParameter_LayerType_TANH:
- return new TanHLayer<Dtype>(param);
+ return GetTanHLayer<Dtype>(name, param);
case LayerParameter_LayerType_WINDOW_DATA:
return new WindowDataLayer<Dtype>(param);
case LayerParameter_LayerType_NONE:
namespace caffe {
template <typename Dtype>
-void ReLULayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
+void CaffeReLULayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
const Dtype* bottom_data = bottom[0]->cpu_data();
Dtype* top_data = (*top)[0]->mutable_cpu_data();
}
template <typename Dtype>
-void ReLULayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
+void CaffeReLULayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down,
vector<Blob<Dtype>*>* bottom) {
if (propagate_down[0]) {
}
}
-
#ifdef CPU_ONLY
-STUB_GPU(ReLULayer);
+STUB_GPU(CaffeReLULayer);
#endif
-INSTANTIATE_CLASS(ReLULayer);
-
+INSTANTIATE_CLASS(CaffeReLULayer);
} // namespace caffe
}
template <typename Dtype>
-void ReLULayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
+void CaffeReLULayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
const Dtype* bottom_data = bottom[0]->gpu_data();
Dtype* top_data = (*top)[0]->mutable_gpu_data();
}
template <typename Dtype>
-void ReLULayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
+void CaffeReLULayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down,
vector<Blob<Dtype>*>* bottom) {
if (propagate_down[0]) {
}
}
-
-INSTANTIATE_CLASS(ReLULayer);
-
+INSTANTIATE_CLASS(CaffeReLULayer);
} // namespace caffe
}
template <typename Dtype>
-void SigmoidLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
+void CaffeSigmoidLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
const Dtype* bottom_data = bottom[0]->cpu_data();
Dtype* top_data = (*top)[0]->mutable_cpu_data();
}
template <typename Dtype>
-void SigmoidLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
+void CaffeSigmoidLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down,
vector<Blob<Dtype>*>* bottom) {
if (propagate_down[0]) {
}
#ifdef CPU_ONLY
-STUB_GPU(SigmoidLayer);
+STUB_GPU(CaffeSigmoidLayer);
#endif
-INSTANTIATE_CLASS(SigmoidLayer);
+INSTANTIATE_CLASS(CaffeSigmoidLayer);
} // namespace caffe
}
template <typename Dtype>
-void SigmoidLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
+void CaffeSigmoidLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
const Dtype* bottom_data = bottom[0]->gpu_data();
Dtype* top_data = (*top)[0]->mutable_gpu_data();
}
template <typename Dtype>
-void SigmoidLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
+void CaffeSigmoidLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down,
vector<Blob<Dtype>*>* bottom) {
if (propagate_down[0]) {
}
}
-INSTANTIATE_CLASS(SigmoidLayer);
+INSTANTIATE_CLASS(CaffeSigmoidLayer);
} // namespace caffe
-// TanH neuron activation function layer.
-// Adapted from ReLU layer code written by Yangqing Jia
-
#include <algorithm>
#include <vector>
namespace caffe {
template <typename Dtype>
-void TanHLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
+void CaffeTanHLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
const Dtype* bottom_data = bottom[0]->cpu_data();
Dtype* top_data = (*top)[0]->mutable_cpu_data();
}
template <typename Dtype>
-void TanHLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
+void CaffeTanHLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down,
vector<Blob<Dtype>*>* bottom) {
if (propagate_down[0]) {
}
#ifdef CPU_ONLY
-STUB_GPU(TanHLayer);
+STUB_GPU(CaffeTanHLayer);
#endif
-INSTANTIATE_CLASS(TanHLayer);
+INSTANTIATE_CLASS(CaffeTanHLayer);
} // namespace caffe
-// TanH neuron activation function layer.
-// Adapted from ReLU layer code written by Yangqing Jia
-
#include <algorithm>
#include <vector>
}
template <typename Dtype>
-void TanHLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
+void CaffeTanHLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
const Dtype* bottom_data = bottom[0]->gpu_data();
Dtype* top_data = (*top)[0]->mutable_gpu_data();
}
template <typename Dtype>
-void TanHLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
+void CaffeTanHLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down,
vector<Blob<Dtype>*>* bottom) {
if (propagate_down[0]) {
}
}
-INSTANTIATE_CLASS(TanHLayer);
-
+INSTANTIATE_CLASS(CaffeTanHLayer);
} // namespace caffe
TYPED_TEST(NeuronLayerTest, TestReLU) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
- ReLULayer<Dtype> layer(layer_param);
+ CaffeReLULayer<Dtype> layer(layer_param);
layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
// Now, check values
TYPED_TEST(NeuronLayerTest, TestReLUGradient) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
- ReLULayer<Dtype> layer(layer_param);
+ CaffeReLULayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-3, 1701, 0., 0.01);
checker.CheckGradientEltwise(&layer, &(this->blob_bottom_vec_),
&(this->blob_top_vec_));
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
layer_param.ParseFromString("relu_param{negative_slope:0.01}");
- ReLULayer<Dtype> layer(layer_param);
+ CaffeReLULayer<Dtype> layer(layer_param);
layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
// Now, check values
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
layer_param.ParseFromString("relu_param{negative_slope:0.01}");
- ReLULayer<Dtype> layer(layer_param);
+ CaffeReLULayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-3, 1701, 0., 0.01);
checker.CheckGradientEltwise(&layer, &(this->blob_bottom_vec_),
&(this->blob_top_vec_));
TYPED_TEST(NeuronLayerTest, TestSigmoid) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
- SigmoidLayer<Dtype> layer(layer_param);
+ CaffeSigmoidLayer<Dtype> layer(layer_param);
layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
// Now, check values
TYPED_TEST(NeuronLayerTest, TestSigmoidGradient) {
typedef typename TypeParam::Dtype Dtype;
LayerParameter layer_param;
- SigmoidLayer<Dtype> layer(layer_param);
+ CaffeSigmoidLayer<Dtype> layer(layer_param);
GradientChecker<Dtype> checker(1e-2, 1e-3, 1701, 0., 0.01);
checker.CheckGradientEltwise(&layer, &(this->blob_bottom_vec_),
&(this->blob_top_vec_));
}
+TYPED_TEST(NeuronLayerTest, TestTanH) {
+ typedef typename TypeParam::Dtype Dtype;
+ LayerParameter layer_param;
+ CaffeTanHLayer<Dtype> layer(layer_param);
+ layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
+ layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
+ // Test exact values
+ for (int i = 0; i < this->blob_bottom_->num(); ++i) {
+ for (int j = 0; j < this->blob_bottom_->channels(); ++j) {
+ for (int k = 0; k < this->blob_bottom_->height(); ++k) {
+ for (int l = 0; l < this->blob_bottom_->width(); ++l) {
+ EXPECT_GE(this->blob_top_->data_at(i, j, k, l) + 1e-4,
+ (exp(2*this->blob_bottom_->data_at(i, j, k, l)) - 1) /
+ (exp(2*this->blob_bottom_->data_at(i, j, k, l)) + 1));
+ EXPECT_LE(this->blob_top_->data_at(i, j, k, l) - 1e-4,
+ (exp(2*this->blob_bottom_->data_at(i, j, k, l)) - 1) /
+ (exp(2*this->blob_bottom_->data_at(i, j, k, l)) + 1));
+ }
+ }
+ }
+ }
+}
+
+TYPED_TEST(NeuronLayerTest, TestTanHGradient) {
+ typedef typename TypeParam::Dtype Dtype;
+ LayerParameter layer_param;
+ CaffeTanHLayer<Dtype> layer(layer_param);
+ GradientChecker<Dtype> checker(1e-2, 1e-3);
+ checker.CheckGradientEltwise(&layer, &(this->blob_bottom_vec_),
+ &(this->blob_top_vec_));
+}
+
TYPED_TEST(NeuronLayerTest, TestDropoutHalf) {
const float kDropoutRatio = 0.5;
this->TestDropoutForward(kDropoutRatio);
+++ /dev/null
-// Adapted from other test files
-
-#include <cmath>
-#include <cstring>
-#include <vector>
-
-#include "gtest/gtest.h"
-
-#include "caffe/blob.hpp"
-#include "caffe/common.hpp"
-#include "caffe/filler.hpp"
-#include "caffe/vision_layers.hpp"
-
-#include "caffe/test/test_caffe_main.hpp"
-#include "caffe/test/test_gradient_check_util.hpp"
-
-namespace caffe {
-
-template <typename TypeParam>
-class TanHLayerTest : public MultiDeviceTest<TypeParam> {
- typedef typename TypeParam::Dtype Dtype;
- protected:
- TanHLayerTest()
- : blob_bottom_(new Blob<Dtype>(2, 10, 1, 1)),
- blob_top_(new Blob<Dtype>()) {
- // fill the values
- FillerParameter filler_param;
- GaussianFiller<Dtype> filler(filler_param);
- filler.Fill(this->blob_bottom_);
- blob_bottom_vec_.push_back(blob_bottom_);
- blob_top_vec_.push_back(blob_top_);
- }
- virtual ~TanHLayerTest() { delete blob_bottom_; delete blob_top_; }
- Blob<Dtype>* const blob_bottom_;
- Blob<Dtype>* const blob_top_;
- vector<Blob<Dtype>*> blob_bottom_vec_;
- vector<Blob<Dtype>*> blob_top_vec_;
-};
-
-TYPED_TEST_CASE(TanHLayerTest, TestDtypesAndDevices);
-
-TYPED_TEST(TanHLayerTest, TestForward) {
- typedef typename TypeParam::Dtype Dtype;
- LayerParameter layer_param;
- TanHLayer<Dtype> layer(layer_param);
- layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
- layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
- // Test exact values
- for (int i = 0; i < this->blob_bottom_->num(); ++i) {
- for (int j = 0; j < this->blob_bottom_->channels(); ++j) {
- for (int k = 0; k < this->blob_bottom_->height(); ++k) {
- for (int l = 0; l < this->blob_bottom_->width(); ++l) {
- EXPECT_GE(this->blob_top_->data_at(i, j, k, l) + 1e-4,
- (exp(2*this->blob_bottom_->data_at(i, j, k, l)) - 1) /
- (exp(2*this->blob_bottom_->data_at(i, j, k, l)) + 1));
- EXPECT_LE(this->blob_top_->data_at(i, j, k, l) - 1e-4,
- (exp(2*this->blob_bottom_->data_at(i, j, k, l)) - 1) /
- (exp(2*this->blob_bottom_->data_at(i, j, k, l)) + 1));
- }
- }
- }
- }
-}
-
-TYPED_TEST(TanHLayerTest, TestGradient) {
- typedef typename TypeParam::Dtype Dtype;
- LayerParameter layer_param;
- TanHLayer<Dtype> layer(layer_param);
- GradientChecker<Dtype> checker(1e-2, 1e-3);
- checker.CheckGradientEltwise(&layer, &(this->blob_bottom_vec_),
- &(this->blob_top_vec_));
-}
-
-} // namespace caffe