Skip to content

Commit

Permalink
Merge pull request #479 from jeffdonahue/declare-layer-names-and-numb…
Browse files Browse the repository at this point in the history
…lobs

Layers declare their types and number of bottom/top blobs
  • Loading branch information
shelhamer committed Jun 9, 2014
2 parents 25aa129 + fe96991 commit cc06ab7
Show file tree
Hide file tree
Showing 26 changed files with 306 additions and 101 deletions.
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

0 comments on commit cc06ab7

Please sign in to comment.