Skip to content
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

Layers declare their types and number of bottom/top blobs #479

Merged
merged 2 commits into from
Jun 9, 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
77 changes: 76 additions & 1 deletion include/caffe/data_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,15 @@ class HDF5OutputLayer : public Layer<Dtype> {
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:
Expand Down Expand Up @@ -58,6 +66,12 @@ class HDF5DataLayer : public Layer<Dtype> {
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);
Expand Down Expand Up @@ -96,6 +110,13 @@ class DataLayer : public Layer<Dtype> {
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);
Expand Down Expand Up @@ -141,6 +162,12 @@ class ImageDataLayer : public Layer<Dtype> {
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);
Expand Down Expand Up @@ -171,6 +198,48 @@ class ImageDataLayer : public Layer<Dtype> {
Caffe::Phase phase_;
};

/* MemoryDataLayer
*/
template <typename Dtype>
class MemoryDataLayer : public Layer<Dtype> {
public:
explicit MemoryDataLayer(const LayerParameter& param)
: 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);
int datum_channels() { return datum_channels_; }
int datum_height() { return datum_height_; }
int datum_width() { return datum_width_; }
int batch_size() { return batch_size_; }

protected:
virtual Dtype Forward_cpu(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) { return; }
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
const bool propagate_down, vector<Blob<Dtype>*>* bottom) { return; }

Dtype* data_;
Dtype* labels_;
int datum_channels_;
int datum_height_;
int datum_width_;
int datum_size_;
int batch_size_;
int n_;
int pos_;
};

// This function is used to create a pthread that prefetches the window data.
template <typename Dtype>
Expand All @@ -188,6 +257,12 @@ class WindowDataLayer : public Layer<Dtype> {
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);
Expand Down
72 changes: 70 additions & 2 deletions include/caffe/layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
#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 {
Expand All @@ -30,9 +33,12 @@ class Layer {
}
}
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
Expand All @@ -53,6 +59,31 @@ class Layer {
// 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_;
Expand Down Expand Up @@ -82,6 +113,43 @@ class Layer {
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

Expand Down
27 changes: 27 additions & 0 deletions include/caffe/loss_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class LossLayer : public Layer<Dtype> {
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
Expand All @@ -49,6 +52,10 @@ class SigmoidCrossEntropyLossLayer : public LossLayer<Dtype> {
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);
Expand Down Expand Up @@ -81,6 +88,10 @@ class EuclideanLossLayer : public LossLayer<Dtype> {
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);
Expand All @@ -100,6 +111,10 @@ class InfogainLossLayer : public LossLayer<Dtype> {
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);
Expand All @@ -117,6 +132,10 @@ class HingeLossLayer : public LossLayer<Dtype> {
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);
Expand All @@ -134,6 +153,10 @@ class MultinomialLogisticLossLayer : public LossLayer<Dtype> {
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);
Expand All @@ -153,6 +176,10 @@ class AccuracyLayer : public Layer<Dtype> {
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);
Expand Down
34 changes: 34 additions & 0 deletions include/caffe/neuron_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ class NeuronLayer : 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_NONE;
}
virtual inline int ExactNumBottomBlobs() const { return 1; }
virtual inline int ExactNumTopBlobs() const { return 1; }
};

/* BNLLLayer
Expand All @@ -48,6 +54,10 @@ class BNLLLayer : public NeuronLayer<Dtype> {
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);
Expand Down Expand Up @@ -77,6 +87,10 @@ class DropoutLayer : public NeuronLayer<Dtype> {
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);
Expand Down Expand Up @@ -107,6 +121,10 @@ class PowerLayer : public NeuronLayer<Dtype> {
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);
Expand Down Expand Up @@ -138,6 +156,10 @@ class ReLULayer : public NeuronLayer<Dtype> {
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);
Expand Down Expand Up @@ -167,6 +189,10 @@ class SigmoidLayer : public NeuronLayer<Dtype> {
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);
Expand All @@ -191,6 +217,10 @@ class TanHLayer : public NeuronLayer<Dtype> {
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);
Expand Down Expand Up @@ -220,6 +250,10 @@ class ThresholdLayer : public NeuronLayer<Dtype> {
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);
Expand Down
Loading