explicit HDF5OutputLayer(const LayerParameter& param);
virtual ~HDF5OutputLayer();
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top);
+ vector<Blob<Dtype>*>* top) {}
+
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_HDF5_OUTPUT;
+ }
+ // TODO: no limit on the number of blobs
+ virtual inline int ExactNumBottomBlobs() const { return 2; }
+ virtual inline int ExactNumTopBlobs() const { return 0; }
+
inline std::string file_name() const { return file_name_; }
protected:
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_HDF5_DATA;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 0; }
+ virtual inline int ExactNumTopBlobs() const { return 2; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_DATA;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 0; }
+ virtual inline int MinTopBlobs() const { return 1; }
+ virtual inline int MaxTopBlobs() const { return 2; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_IMAGE_DATA;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 0; }
+ virtual inline int ExactNumTopBlobs() const { return 2; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_WINDOW_DATA;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 0; }
+ virtual inline int ExactNumTopBlobs() const { return 2; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
#ifndef CAFFE_LAYER_H_
#define CAFFE_LAYER_H_
+#include <string>
#include <vector>
+
#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/proto/caffe.pb.h"
+using std::string;
using std::vector;
namespace caffe {
}
}
virtual ~Layer() {}
- // SetUp: your function should implement this.
+ // SetUp: your function should implement this, and call Layer::SetUp for
+ // common SetUp functionality.
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top) = 0;
+ vector<Blob<Dtype>*>* top) {
+ CheckBlobCounts(bottom, *top);
+ }
// Forward and backward wrappers. You should implement the cpu and
// gpu specific implementations instead, and should not change these
// Writes the layer parameter to a protocol buffer
virtual void ToProto(LayerParameter* param, bool write_diff = false);
+ // Returns the layer type as an enum value.
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_NONE;
+ }
+
+ // Returns the layer type name.
+ virtual inline const string& type_name() const {
+ return LayerParameter_LayerType_Name(type());
+ }
+
+ // These methods can be overwritten to declare that this layer type expects
+ // a certain number of blobs as input and output.
+ //
+ // ExactNum{Bottom,Top}Blobs return a non-negative number to require an exact
+ // number of bottom/top blobs; the Min/Max versions return a non-negative
+ // number to require a minimum and/or maximum number of blobs.
+ // If Exact is specified, neither Min nor Max should be specified, and vice
+ // versa. These methods may not rely on SetUp having been called.
+ virtual inline int ExactNumBottomBlobs() const { return -1; }
+ virtual inline int MinBottomBlobs() const { return -1; }
+ virtual inline int MaxBottomBlobs() const { return -1; }
+ virtual inline int ExactNumTopBlobs() const { return -1; }
+ virtual inline int MinTopBlobs() const { return -1; }
+ virtual inline int MaxTopBlobs() const { return -1; }
+
protected:
// The protobuf that stores the layer parameters
LayerParameter layer_param_;
Backward_cpu(top, propagate_down, bottom);
}
+ // CheckBlobCounts: called by the parent Layer's SetUp to check that the
+ // number of bottom and top Blobs provided as input match the expected
+ // numbers specified by the {ExactNum,Min,Max}{Bottom,Top}Blobs() functions.
+ virtual void CheckBlobCounts(const vector<Blob<Dtype>*>& bottom,
+ const vector<Blob<Dtype>*>& top) {
+ if (ExactNumBottomBlobs() >= 0) {
+ CHECK_EQ(ExactNumBottomBlobs(), bottom.size())
+ << type_name() << " Layer takes " << ExactNumBottomBlobs()
+ << " bottom blob(s) as input.";
+ }
+ if (MinBottomBlobs() >= 0) {
+ CHECK_LE(MinBottomBlobs(), bottom.size())
+ << type_name() << " Layer takes at least " << MinBottomBlobs()
+ << " bottom blob(s) as input.";
+ }
+ if (MaxBottomBlobs() >= 0) {
+ CHECK_GE(MaxBottomBlobs(), bottom.size())
+ << type_name() << " Layer takes at most " << MaxBottomBlobs()
+ << " bottom blob(s) as input.";
+ }
+ if (ExactNumTopBlobs() >= 0) {
+ CHECK_EQ(ExactNumTopBlobs(), top.size())
+ << type_name() << " Layer produces " << ExactNumTopBlobs()
+ << " top blob(s) as output.";
+ }
+ if (MinTopBlobs() >= 0) {
+ CHECK_LE(MinTopBlobs(), top.size())
+ << type_name() << " Layer produces at least " << MinTopBlobs()
+ << " top blob(s) as output.";
+ }
+ if (MaxTopBlobs() >= 0) {
+ CHECK_GE(MaxTopBlobs(), top.size())
+ << type_name() << " Layer produces at most " << MaxTopBlobs()
+ << " top blob(s) as output.";
+ }
+ }
+
DISABLE_COPY_AND_ASSIGN(Layer);
}; // class Layer
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top);
virtual void FurtherSetUp(
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {}
+
+ virtual inline int ExactNumBottomBlobs() const { return 2; }
+ virtual inline int ExactNumTopBlobs() const { return 0; }
};
/* SigmoidCrossEntropyLossLayer
virtual void FurtherSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_SIGMOID_CROSS_ENTROPY_LOSS;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void FurtherSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_EUCLIDEAN_LOSS;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void FurtherSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_INFOGAIN_LOSS;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
explicit HingeLossLayer(const LayerParameter& param)
: LossLayer<Dtype>(param) {}
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_HINGE_LOSS;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void FurtherSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_MULTINOMIAL_LOGISTIC_LOSS;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_ACCURACY;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
: Layer<Dtype>(param) {}
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_NONE;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
};
/* BNLLLayer
explicit BNLLLayer(const LayerParameter& param)
: NeuronLayer<Dtype>(param) {}
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_BNLL;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_DROPOUT;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_POWER;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
explicit ReLULayer(const LayerParameter& param)
: NeuronLayer<Dtype>(param) {}
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_RELU;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
explicit SigmoidLayer(const LayerParameter& param)
: NeuronLayer<Dtype>(param) {}
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_SIGMOID;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
explicit TanHLayer(const LayerParameter& param)
: NeuronLayer<Dtype>(param) {}
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_TANH;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_THRESHOLD;
+ }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_ARGMAX;
+ }
+ virtual inline int MinBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_CONCAT;
+ }
+ virtual inline int MinBottomBlobs() const { return 2; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_CONVOLUTION;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_ELTWISE;
+ }
+ virtual inline int MinBottomBlobs() const { return 2; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_FLATTEN;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_IM2COL;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_INNER_PRODUCT;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_LRN;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
vector<Blob<Dtype>*> product_bottom_vec_;
};
-/* PoolingLayer
+/* MemoryDataLayer
*/
template <typename Dtype>
class MemoryDataLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_MEMORY_DATA;
+ }
+ virtual inline int ExactNumBottomBlobs() { return 0; }
+ virtual inline int ExactNumTopBlobs() { return 2; }
+
// Reset should accept const pointers, but can't, because the memory
// will be given to Blob, which is mutable
void Reset(Dtype* data, Dtype* label, int n);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_POOLING;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int MinTopBlobs() const { return 1; }
+ virtual inline int MaxTopBlobs() const { return max_top_blobs_; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom);
+ int max_top_blobs_;
int kernel_size_;
int stride_;
int pad_;
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_SOFTMAX;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_SOFTMAX_LOSS;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 2; }
+ virtual inline int ExactNumTopBlobs() const { return 0; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
+ virtual inline LayerParameter_LayerType type() const {
+ return LayerParameter_LayerType_SPLIT;
+ }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int MinTopBlobs() const { return 1; }
+
protected:
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
template <typename Dtype>
void AccuracyLayer<Dtype>::SetUp(
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 2) << "Accuracy Layer takes two blobs as input.";
- CHECK_EQ(top->size(), 1) << "Accuracy Layer takes 1 output.";
+ Layer<Dtype>::SetUp(bottom, top);
CHECK_EQ(bottom[0]->num(), bottom[1]->num())
<< "The data and label should have the same number.";
CHECK_EQ(bottom[1]->channels(), 1);
template <typename Dtype>
void ArgMaxLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "ArgMaxLayer Layer takes 1 input.";
- CHECK_EQ(top->size(), 1) << "ArgMaxLayer Layer takes 1 output.";
+ Layer<Dtype>::SetUp(bottom, top);
out_max_val_ = this->layer_param_.argmax_param().out_max_val();
if (out_max_val_) {
// Produces max_ind and max_val
template <typename Dtype>
void ConcatLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_GT(bottom.size(), 1) <<
- "ConcatLayer takes at least two blobs as input.";
- CHECK_EQ(top->size(), 1) <<
- "ConcatLayer takes a single blob as output.";
-
+ Layer<Dtype>::SetUp(bottom, top);
concat_dim_ = this->layer_param_.concat_param().concat_dim();
CHECK_GE(concat_dim_, 0) <<
"concat_dim should be >= 0";
template <typename Dtype>
void ConvolutionLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "Conv Layer takes a single blob as input.";
- CHECK_EQ(top->size(), 1) << "Conv Layer takes a single blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
kernel_size_ = this->layer_param_.convolution_param().kernel_size();
stride_ = this->layer_param_.convolution_param().stride();
group_ = this->layer_param_.convolution_param().group();
template <typename Dtype>
void DataLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 0) << "Data Layer takes no input blobs.";
- CHECK_GE(top->size(), 1) << "Data Layer takes at least one blob as output.";
- CHECK_LE(top->size(), 2) << "Data Layer takes at most two blobs as output.";
+ Layer<Dtype>::SetUp(bottom, top);
if (top->size() == 1) {
output_labels_ = false;
} else {
template <typename Dtype>
void EltwiseLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_GE(bottom.size(), 2) <<
- "Eltwise Layer takes at least 2 blobs as input.";
- CHECK_EQ(top->size(), 1) <<
- "Eltwise Layer takes a single blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
CHECK(this->layer_param().eltwise_param().coeff_size() == 0
|| this->layer_param().eltwise_param().coeff_size() == bottom.size()) <<
"Eltwise Layer takes one coefficient per bottom blob.";
template <typename Dtype>
void FlattenLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "Flatten Layer takes a single blob as input.";
- CHECK_EQ(top->size(), 1) << "Flatten Layer takes a single blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
int channels_out = bottom[0]->channels() * bottom[0]->height()
* bottom[0]->width();
(*top)[0]->Reshape(bottom[0]->num(), channels_out, 1, 1);
template <typename Dtype>
void HDF5DataLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 0) << "HDF5DataLayer takes no input blobs.";
- CHECK_EQ(top->size(), 2) << "HDF5DataLayer takes two blobs as output.";
-
+ Layer<Dtype>::SetUp(bottom, top);
// Read the source to parse the filenames.
const string& source = this->layer_param_.hdf5_data_param().source();
LOG(INFO) << "Loading filename from " << source;
}
template <typename Dtype>
-void HDF5OutputLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
- vector<Blob<Dtype>*>* top) {
- // TODO: no limit on the number of blobs
- CHECK_EQ(bottom.size(), 2) << "HDF5OutputLayer takes two blobs as input.";
- CHECK_EQ(top->size(), 0) << "HDF5OutputLayer takes no output blobs.";
-}
-
-template <typename Dtype>
Dtype HDF5OutputLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
CHECK_GE(bottom.size(), 2);
template <typename Dtype>
void Im2colLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "Im2col Layer takes a single blob as input.";
- CHECK_EQ(top->size(), 1) << "Im2col Layer takes a single blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
kernel_size_ = this->layer_param_.convolution_param().kernel_size();
stride_ = this->layer_param_.convolution_param().stride();
pad_ = this->layer_param_.convolution_param().pad();
template <typename Dtype>
void ImageDataLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 0) << "Input Layer takes no input blobs.";
- CHECK_EQ(top->size(), 2) << "Input Layer takes two blobs as output.";
+ Layer<Dtype>::SetUp(bottom, top);
const int new_height = this->layer_param_.image_data_param().new_height();
const int new_width = this->layer_param_.image_data_param().new_height();
CHECK((new_height == 0 && new_width == 0) ||
template <typename Dtype>
void InnerProductLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "IP Layer takes a single blob as input.";
- CHECK_EQ(top->size(), 1) << "IP Layer takes a single blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
const int num_output = this->layer_param_.inner_product_param().num_output();
bias_term_ = this->layer_param_.inner_product_param().bias_term();
// Figure out the dimensions
template <typename Dtype>
void LossLayer<Dtype>::SetUp(
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 2) << "Loss Layer takes two blobs as input.";
- CHECK_EQ(top->size(), 0) << "Loss Layer takes no output.";
+ Layer<Dtype>::SetUp(bottom, top);
CHECK_EQ(bottom[0]->num(), bottom[1]->num())
<< "The data and label should have the same number.";
FurtherSetUp(bottom, top);
template <typename Dtype>
void LRNLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) <<
- "Local Response Normalization Layer takes a single blob as input.";
- CHECK_EQ(top->size(), 1) <<
- "Local Response Normalization Layer takes a single blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
num_ = bottom[0]->num();
channels_ = bottom[0]->channels();
height_ = bottom[0]->height();
template <typename Dtype>
void MemoryDataLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 0) << "Memory Data Layer takes no blobs as input.";
- CHECK_EQ(top->size(), 2) << "Memory Data Layer takes two blobs as output.";
+ Layer<Dtype>::SetUp(bottom, top);
batch_size_ = this->layer_param_.memory_data_param().batch_size();
datum_channels_ = this->layer_param_.memory_data_param().channels();
datum_height_ = this->layer_param_.memory_data_param().height();
template <typename Dtype>
void NeuronLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "Neuron Layer takes a single blob as input.";
- CHECK_EQ(top->size(), 1) << "Neuron Layer takes a single blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
// NeuronLayer allows in-place computations. If the computation is not
// in-place, we will need to initialize the top blob.
if ((*top)[0] != bottom[0]) {
template <typename Dtype>
void PoolingLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "PoolingLayer takes a single blob as input.";
+ // Set the max number of top blobs before calling base Layer::SetUp.
+ // If doing MAX pooling, we can optionally output an extra top Blob
+ // for the mask. Otherwise, we only have one top Blob.
if (this->layer_param_.pooling_param().pool() ==
PoolingParameter_PoolMethod_MAX) {
- CHECK_GE(top->size(), 1)
- << "MaxPoolingLayer takes at least one blob as output.";
- CHECK_LE(top->size(), 2)
- << "MaxPoolingLayer takes at most two blobs as output.";
+ max_top_blobs_ = 2;
} else {
- CHECK_EQ(top->size(), 1) << "PoolingLayer takes a single blob as output.";
+ max_top_blobs_ = 1;
}
+ Layer<Dtype>::SetUp(bottom, top);
kernel_size_ = this->layer_param_.pooling_param().kernel_size();
stride_ = this->layer_param_.pooling_param().stride();
pad_ = this->layer_param_.pooling_param().pad();
template <typename Dtype>
void SoftmaxLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "Softmax Layer takes a single blob as input.";
- CHECK_EQ(top->size(), 1) << "Softmax Layer takes a single blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
(*top)[0]->Reshape(bottom[0]->num(), bottom[0]->channels(),
bottom[0]->height(), bottom[0]->width());
sum_multiplier_.Reshape(1, bottom[0]->channels(),
template <typename Dtype>
void SoftmaxWithLossLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 2) << "SoftmaxLoss Layer takes two blobs as input.";
- CHECK_EQ(top->size(), 0) << "SoftmaxLoss Layer takes no blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
softmax_bottom_vec_.clear();
softmax_bottom_vec_.push_back(bottom[0]);
softmax_top_vec_.push_back(&prob_);
template <typename Dtype>
void SplitLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
- CHECK_EQ(bottom.size(), 1) << "Split Layer takes a single blob as input.";
- CHECK_GE(top->size(), 1) << "Split Layer takes at least one blob as output.";
+ Layer<Dtype>::SetUp(bottom, top);
count_ = bottom[0]->count();
for (int i = 0; i < top->size(); ++i) {
// Allow the 0th top blob to be 'in-place', but no others.
template <typename Dtype>
void WindowDataLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {
+ Layer<Dtype>::SetUp(bottom, top);
// SetUp runs through the window_file and creates two structures
// that hold windows: one for foreground (object) windows and one
// for background (non-object) windows. We use an overlap threshold
// to decide which is which.
- CHECK_EQ(bottom.size(), 0) << "Window data Layer takes no input blobs.";
- CHECK_EQ(top->size(), 2) << "Window data Layer prodcues two blobs as output.";
-
// window_file format
// repeated:
// # image_index