Skip to content

Commit cc06ab7

Browse files
committed
Merge pull request #479 from jeffdonahue/declare-layer-names-and-numblobs
Layers declare their types and number of bottom/top blobs
2 parents 25aa129 + fe96991 commit cc06ab7

26 files changed

+306
-101
lines changed

include/caffe/data_layers.hpp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,15 @@ class HDF5OutputLayer : public Layer<Dtype> {
2828
explicit HDF5OutputLayer(const LayerParameter& param);
2929
virtual ~HDF5OutputLayer();
3030
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
31-
vector<Blob<Dtype>*>* top);
31+
vector<Blob<Dtype>*>* top) {}
32+
33+
virtual inline LayerParameter_LayerType type() const {
34+
return LayerParameter_LayerType_HDF5_OUTPUT;
35+
}
36+
// TODO: no limit on the number of blobs
37+
virtual inline int ExactNumBottomBlobs() const { return 2; }
38+
virtual inline int ExactNumTopBlobs() const { return 0; }
39+
3240
inline std::string file_name() const { return file_name_; }
3341

3442
protected:
@@ -58,6 +66,12 @@ class HDF5DataLayer : public Layer<Dtype> {
5866
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
5967
vector<Blob<Dtype>*>* top);
6068

69+
virtual inline LayerParameter_LayerType type() const {
70+
return LayerParameter_LayerType_HDF5_DATA;
71+
}
72+
virtual inline int ExactNumBottomBlobs() const { return 0; }
73+
virtual inline int ExactNumTopBlobs() const { return 2; }
74+
6175
protected:
6276
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
6377
vector<Blob<Dtype>*>* top);
@@ -96,6 +110,13 @@ class DataLayer : public Layer<Dtype> {
96110
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
97111
vector<Blob<Dtype>*>* top);
98112

113+
virtual inline LayerParameter_LayerType type() const {
114+
return LayerParameter_LayerType_DATA;
115+
}
116+
virtual inline int ExactNumBottomBlobs() const { return 0; }
117+
virtual inline int MinTopBlobs() const { return 1; }
118+
virtual inline int MaxTopBlobs() const { return 2; }
119+
99120
protected:
100121
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
101122
vector<Blob<Dtype>*>* top);
@@ -141,6 +162,12 @@ class ImageDataLayer : public Layer<Dtype> {
141162
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
142163
vector<Blob<Dtype>*>* top);
143164

165+
virtual inline LayerParameter_LayerType type() const {
166+
return LayerParameter_LayerType_IMAGE_DATA;
167+
}
168+
virtual inline int ExactNumBottomBlobs() const { return 0; }
169+
virtual inline int ExactNumTopBlobs() const { return 2; }
170+
144171
protected:
145172
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
146173
vector<Blob<Dtype>*>* top);
@@ -171,6 +198,48 @@ class ImageDataLayer : public Layer<Dtype> {
171198
Caffe::Phase phase_;
172199
};
173200

201+
/* MemoryDataLayer
202+
*/
203+
template <typename Dtype>
204+
class MemoryDataLayer : public Layer<Dtype> {
205+
public:
206+
explicit MemoryDataLayer(const LayerParameter& param)
207+
: Layer<Dtype>(param) {}
208+
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
209+
vector<Blob<Dtype>*>* top);
210+
211+
virtual inline LayerParameter_LayerType type() const {
212+
return LayerParameter_LayerType_MEMORY_DATA;
213+
}
214+
virtual inline int ExactNumBottomBlobs() { return 0; }
215+
virtual inline int ExactNumTopBlobs() { return 2; }
216+
217+
// Reset should accept const pointers, but can't, because the memory
218+
// will be given to Blob, which is mutable
219+
void Reset(Dtype* data, Dtype* label, int n);
220+
int datum_channels() { return datum_channels_; }
221+
int datum_height() { return datum_height_; }
222+
int datum_width() { return datum_width_; }
223+
int batch_size() { return batch_size_; }
224+
225+
protected:
226+
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
227+
vector<Blob<Dtype>*>* top);
228+
virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
229+
const bool propagate_down, vector<Blob<Dtype>*>* bottom) { return; }
230+
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
231+
const bool propagate_down, vector<Blob<Dtype>*>* bottom) { return; }
232+
233+
Dtype* data_;
234+
Dtype* labels_;
235+
int datum_channels_;
236+
int datum_height_;
237+
int datum_width_;
238+
int datum_size_;
239+
int batch_size_;
240+
int n_;
241+
int pos_;
242+
};
174243

175244
// This function is used to create a pthread that prefetches the window data.
176245
template <typename Dtype>
@@ -188,6 +257,12 @@ class WindowDataLayer : public Layer<Dtype> {
188257
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
189258
vector<Blob<Dtype>*>* top);
190259

260+
virtual inline LayerParameter_LayerType type() const {
261+
return LayerParameter_LayerType_WINDOW_DATA;
262+
}
263+
virtual inline int ExactNumBottomBlobs() const { return 0; }
264+
virtual inline int ExactNumTopBlobs() const { return 2; }
265+
191266
protected:
192267
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
193268
vector<Blob<Dtype>*>* top);

include/caffe/layer.hpp

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
#ifndef CAFFE_LAYER_H_
44
#define CAFFE_LAYER_H_
55

6+
#include <string>
67
#include <vector>
8+
79
#include "caffe/blob.hpp"
810
#include "caffe/common.hpp"
911
#include "caffe/proto/caffe.pb.h"
1012

13+
using std::string;
1114
using std::vector;
1215

1316
namespace caffe {
@@ -30,9 +33,12 @@ class Layer {
3033
}
3134
}
3235
virtual ~Layer() {}
33-
// SetUp: your function should implement this.
36+
// SetUp: your function should implement this, and call Layer::SetUp for
37+
// common SetUp functionality.
3438
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
35-
vector<Blob<Dtype>*>* top) = 0;
39+
vector<Blob<Dtype>*>* top) {
40+
CheckBlobCounts(bottom, *top);
41+
}
3642

3743
// Forward and backward wrappers. You should implement the cpu and
3844
// gpu specific implementations instead, and should not change these
@@ -53,6 +59,31 @@ class Layer {
5359
// Writes the layer parameter to a protocol buffer
5460
virtual void ToProto(LayerParameter* param, bool write_diff = false);
5561

62+
// Returns the layer type as an enum value.
63+
virtual inline LayerParameter_LayerType type() const {
64+
return LayerParameter_LayerType_NONE;
65+
}
66+
67+
// Returns the layer type name.
68+
virtual inline const string& type_name() const {
69+
return LayerParameter_LayerType_Name(type());
70+
}
71+
72+
// These methods can be overwritten to declare that this layer type expects
73+
// a certain number of blobs as input and output.
74+
//
75+
// ExactNum{Bottom,Top}Blobs return a non-negative number to require an exact
76+
// number of bottom/top blobs; the Min/Max versions return a non-negative
77+
// number to require a minimum and/or maximum number of blobs.
78+
// If Exact is specified, neither Min nor Max should be specified, and vice
79+
// versa. These methods may not rely on SetUp having been called.
80+
virtual inline int ExactNumBottomBlobs() const { return -1; }
81+
virtual inline int MinBottomBlobs() const { return -1; }
82+
virtual inline int MaxBottomBlobs() const { return -1; }
83+
virtual inline int ExactNumTopBlobs() const { return -1; }
84+
virtual inline int MinTopBlobs() const { return -1; }
85+
virtual inline int MaxTopBlobs() const { return -1; }
86+
5687
protected:
5788
// The protobuf that stores the layer parameters
5889
LayerParameter layer_param_;
@@ -82,6 +113,43 @@ class Layer {
82113
Backward_cpu(top, propagate_down, bottom);
83114
}
84115

116+
// CheckBlobCounts: called by the parent Layer's SetUp to check that the
117+
// number of bottom and top Blobs provided as input match the expected
118+
// numbers specified by the {ExactNum,Min,Max}{Bottom,Top}Blobs() functions.
119+
virtual void CheckBlobCounts(const vector<Blob<Dtype>*>& bottom,
120+
const vector<Blob<Dtype>*>& top) {
121+
if (ExactNumBottomBlobs() >= 0) {
122+
CHECK_EQ(ExactNumBottomBlobs(), bottom.size())
123+
<< type_name() << " Layer takes " << ExactNumBottomBlobs()
124+
<< " bottom blob(s) as input.";
125+
}
126+
if (MinBottomBlobs() >= 0) {
127+
CHECK_LE(MinBottomBlobs(), bottom.size())
128+
<< type_name() << " Layer takes at least " << MinBottomBlobs()
129+
<< " bottom blob(s) as input.";
130+
}
131+
if (MaxBottomBlobs() >= 0) {
132+
CHECK_GE(MaxBottomBlobs(), bottom.size())
133+
<< type_name() << " Layer takes at most " << MaxBottomBlobs()
134+
<< " bottom blob(s) as input.";
135+
}
136+
if (ExactNumTopBlobs() >= 0) {
137+
CHECK_EQ(ExactNumTopBlobs(), top.size())
138+
<< type_name() << " Layer produces " << ExactNumTopBlobs()
139+
<< " top blob(s) as output.";
140+
}
141+
if (MinTopBlobs() >= 0) {
142+
CHECK_LE(MinTopBlobs(), top.size())
143+
<< type_name() << " Layer produces at least " << MinTopBlobs()
144+
<< " top blob(s) as output.";
145+
}
146+
if (MaxTopBlobs() >= 0) {
147+
CHECK_GE(MaxTopBlobs(), top.size())
148+
<< type_name() << " Layer produces at most " << MaxTopBlobs()
149+
<< " top blob(s) as output.";
150+
}
151+
}
152+
85153
DISABLE_COPY_AND_ASSIGN(Layer);
86154
}; // class Layer
87155

include/caffe/loss_layers.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class LossLayer : public Layer<Dtype> {
3535
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top);
3636
virtual void FurtherSetUp(
3737
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {}
38+
39+
virtual inline int ExactNumBottomBlobs() const { return 2; }
40+
virtual inline int ExactNumTopBlobs() const { return 0; }
3841
};
3942

4043
/* SigmoidCrossEntropyLossLayer
@@ -49,6 +52,10 @@ class SigmoidCrossEntropyLossLayer : public LossLayer<Dtype> {
4952
virtual void FurtherSetUp(const vector<Blob<Dtype>*>& bottom,
5053
vector<Blob<Dtype>*>* top);
5154

55+
virtual inline LayerParameter_LayerType type() const {
56+
return LayerParameter_LayerType_SIGMOID_CROSS_ENTROPY_LOSS;
57+
}
58+
5259
protected:
5360
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
5461
vector<Blob<Dtype>*>* top);
@@ -81,6 +88,10 @@ class EuclideanLossLayer : public LossLayer<Dtype> {
8188
virtual void FurtherSetUp(const vector<Blob<Dtype>*>& bottom,
8289
vector<Blob<Dtype>*>* top);
8390

91+
virtual inline LayerParameter_LayerType type() const {
92+
return LayerParameter_LayerType_EUCLIDEAN_LOSS;
93+
}
94+
8495
protected:
8596
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
8697
vector<Blob<Dtype>*>* top);
@@ -100,6 +111,10 @@ class InfogainLossLayer : public LossLayer<Dtype> {
100111
virtual void FurtherSetUp(const vector<Blob<Dtype>*>& bottom,
101112
vector<Blob<Dtype>*>* top);
102113

114+
virtual inline LayerParameter_LayerType type() const {
115+
return LayerParameter_LayerType_INFOGAIN_LOSS;
116+
}
117+
103118
protected:
104119
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
105120
vector<Blob<Dtype>*>* top);
@@ -117,6 +132,10 @@ class HingeLossLayer : public LossLayer<Dtype> {
117132
explicit HingeLossLayer(const LayerParameter& param)
118133
: LossLayer<Dtype>(param) {}
119134

135+
virtual inline LayerParameter_LayerType type() const {
136+
return LayerParameter_LayerType_HINGE_LOSS;
137+
}
138+
120139
protected:
121140
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
122141
vector<Blob<Dtype>*>* top);
@@ -134,6 +153,10 @@ class MultinomialLogisticLossLayer : public LossLayer<Dtype> {
134153
virtual void FurtherSetUp(const vector<Blob<Dtype>*>& bottom,
135154
vector<Blob<Dtype>*>* top);
136155

156+
virtual inline LayerParameter_LayerType type() const {
157+
return LayerParameter_LayerType_MULTINOMIAL_LOGISTIC_LOSS;
158+
}
159+
137160
protected:
138161
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
139162
vector<Blob<Dtype>*>* top);
@@ -153,6 +176,10 @@ class AccuracyLayer : public Layer<Dtype> {
153176
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
154177
vector<Blob<Dtype>*>* top);
155178

179+
virtual inline LayerParameter_LayerType type() const {
180+
return LayerParameter_LayerType_ACCURACY;
181+
}
182+
156183
protected:
157184
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
158185
vector<Blob<Dtype>*>* top);

include/caffe/neuron_layers.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class NeuronLayer : public Layer<Dtype> {
3333
: Layer<Dtype>(param) {}
3434
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
3535
vector<Blob<Dtype>*>* top);
36+
37+
virtual inline LayerParameter_LayerType type() const {
38+
return LayerParameter_LayerType_NONE;
39+
}
40+
virtual inline int ExactNumBottomBlobs() const { return 1; }
41+
virtual inline int ExactNumTopBlobs() const { return 1; }
3642
};
3743

3844
/* BNLLLayer
@@ -48,6 +54,10 @@ class BNLLLayer : public NeuronLayer<Dtype> {
4854
explicit BNLLLayer(const LayerParameter& param)
4955
: NeuronLayer<Dtype>(param) {}
5056

57+
virtual inline LayerParameter_LayerType type() const {
58+
return LayerParameter_LayerType_BNLL;
59+
}
60+
5161
protected:
5262
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
5363
vector<Blob<Dtype>*>* top);
@@ -77,6 +87,10 @@ class DropoutLayer : public NeuronLayer<Dtype> {
7787
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
7888
vector<Blob<Dtype>*>* top);
7989

90+
virtual inline LayerParameter_LayerType type() const {
91+
return LayerParameter_LayerType_DROPOUT;
92+
}
93+
8094
protected:
8195
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
8296
vector<Blob<Dtype>*>* top);
@@ -107,6 +121,10 @@ class PowerLayer : public NeuronLayer<Dtype> {
107121
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
108122
vector<Blob<Dtype>*>* top);
109123

124+
virtual inline LayerParameter_LayerType type() const {
125+
return LayerParameter_LayerType_POWER;
126+
}
127+
110128
protected:
111129
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
112130
vector<Blob<Dtype>*>* top);
@@ -138,6 +156,10 @@ class ReLULayer : public NeuronLayer<Dtype> {
138156
explicit ReLULayer(const LayerParameter& param)
139157
: NeuronLayer<Dtype>(param) {}
140158

159+
virtual inline LayerParameter_LayerType type() const {
160+
return LayerParameter_LayerType_RELU;
161+
}
162+
141163
protected:
142164
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
143165
vector<Blob<Dtype>*>* top);
@@ -167,6 +189,10 @@ class SigmoidLayer : public NeuronLayer<Dtype> {
167189
explicit SigmoidLayer(const LayerParameter& param)
168190
: NeuronLayer<Dtype>(param) {}
169191

192+
virtual inline LayerParameter_LayerType type() const {
193+
return LayerParameter_LayerType_SIGMOID;
194+
}
195+
170196
protected:
171197
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
172198
vector<Blob<Dtype>*>* top);
@@ -191,6 +217,10 @@ class TanHLayer : public NeuronLayer<Dtype> {
191217
explicit TanHLayer(const LayerParameter& param)
192218
: NeuronLayer<Dtype>(param) {}
193219

220+
virtual inline LayerParameter_LayerType type() const {
221+
return LayerParameter_LayerType_TANH;
222+
}
223+
194224
protected:
195225
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
196226
vector<Blob<Dtype>*>* top);
@@ -220,6 +250,10 @@ class ThresholdLayer : public NeuronLayer<Dtype> {
220250
virtual void SetUp(const vector<Blob<Dtype>*>& bottom,
221251
vector<Blob<Dtype>*>* top);
222252

253+
virtual inline LayerParameter_LayerType type() const {
254+
return LayerParameter_LayerType_THRESHOLD;
255+
}
256+
223257
protected:
224258
virtual Dtype Forward_cpu(const vector<Blob<Dtype>*>& bottom,
225259
vector<Blob<Dtype>*>* top);

0 commit comments

Comments
 (0)