Skip to content

Commit

Permalink
Merge pull request BVLC#594 from longjon/layer-reshaping
Browse files Browse the repository at this point in the history
On-the-fly net resizing, without reallocation (where possible)
  • Loading branch information
shelhamer committed Sep 18, 2014
2 parents 318cd96 + 167af0d commit 8789b23
Show file tree
Hide file tree
Showing 44 changed files with 575 additions and 210 deletions.
17 changes: 16 additions & 1 deletion include/caffe/blob.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,23 @@ class Blob {
public:
Blob()
: data_(), diff_(), num_(0), channels_(0), height_(0), width_(0),
count_(0) {}
count_(0), capacity_(0) {}
explicit Blob(const int num, const int channels, const int height,
const int width);
/**
* @brief Change the dimensions of the blob, allocating new memory if
* necessary.
*
* This function can be called both to create an initial allocation
* of memory, and to adjust the dimensions of a top blob during Layer::Reshape
* or Layer::Forward. When changing the size of blob, memory will only be
* reallocated if sufficient memory does not already exist, and excess memory
* will never be freed.
*
* Note that reshaping an input blob and immediately calling Net::Backward is
* an error; either Net::Forward or Net::Reshape need to be called to
* propagate the new input shape to higher layers.
*/
void Reshape(const int num, const int channels, const int height,
const int width);
void ReshapeLike(const Blob& other);
Expand Down Expand Up @@ -120,6 +134,7 @@ class Blob {
int height_;
int width_;
int count_;
int capacity_;

DISABLE_COPY_AND_ASSIGN(Blob);
}; // class Blob
Expand Down
24 changes: 18 additions & 6 deletions include/caffe/common_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class ArgMaxLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_ARGMAX;
Expand Down Expand Up @@ -81,6 +83,8 @@ class ConcatLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_CONCAT;
Expand Down Expand Up @@ -159,6 +163,8 @@ class EltwiseLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_ELTWISE;
Expand All @@ -178,7 +184,7 @@ class EltwiseLayer : public Layer<Dtype> {

EltwiseParameter_EltwiseOp op_;
vector<Dtype> coeffs_;
shared_ptr<Blob<int> > max_idx_;
Blob<int> max_idx_;

bool stable_prod_grad_;
};
Expand All @@ -198,7 +204,7 @@ class FlattenLayer : public Layer<Dtype> {
public:
explicit FlattenLayer(const LayerParameter& param)
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
Expand Down Expand Up @@ -251,6 +257,8 @@ class InnerProductLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_INNER_PRODUCT;
Expand Down Expand Up @@ -285,7 +293,7 @@ class MVNLayer : public Layer<Dtype> {
public:
explicit MVNLayer(const LayerParameter& param)
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
Expand Down Expand Up @@ -319,7 +327,7 @@ class SilenceLayer : public Layer<Dtype> {
public:
explicit SilenceLayer(const LayerParameter& param)
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {}

virtual inline LayerParameter_LayerType type() const {
Expand Down Expand Up @@ -351,7 +359,7 @@ class SoftmaxLayer : public Layer<Dtype> {
public:
explicit SoftmaxLayer(const LayerParameter& param)
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
Expand Down Expand Up @@ -388,6 +396,8 @@ class CuDNNSoftmaxLayer : public SoftmaxLayer<Dtype> {
: SoftmaxLayer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual ~CuDNNSoftmaxLayer();

protected:
Expand All @@ -413,7 +423,7 @@ class SplitLayer : public Layer<Dtype> {
public:
explicit SplitLayer(const LayerParameter& param)
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
Expand Down Expand Up @@ -448,6 +458,8 @@ class SliceLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_SLICE;
Expand Down
12 changes: 12 additions & 0 deletions include/caffe/data_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class BaseDataLayer : public Layer<Dtype> {
vector<Blob<Dtype>*>* top);
virtual void DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {}
// Data layers have no bottoms, so reshaping is trivial.
virtual void Reshape(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) {}
Expand Down Expand Up @@ -134,6 +137,9 @@ class DummyDataLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
// Data layers have no bottoms, so reshaping is trivial.
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {}

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_DUMMY_DATA;
Expand Down Expand Up @@ -166,6 +172,9 @@ class HDF5DataLayer : public Layer<Dtype> {
virtual ~HDF5DataLayer();
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
// Data layers have no bottoms, so reshaping is trivial.
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {}

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_HDF5_DATA;
Expand Down Expand Up @@ -204,6 +213,9 @@ class HDF5OutputLayer : public Layer<Dtype> {
virtual ~HDF5OutputLayer();
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {}
// Data layers have no bottoms, so reshaping is trivial.
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) {}

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_HDF5_OUTPUT;
Expand Down
37 changes: 28 additions & 9 deletions include/caffe/layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,54 @@ class Layer {
*
* @param bottom the preshaped input blobs
* @param top
* the allocated but unshaped output blobs, to be shaped by LayerSetUp
* the allocated but unshaped output blobs, to be shaped by Reshape
*
* Checks that the number of bottom and top blobs is correct.
* Calls LayerSetUp to do special layer setup for individual layer types.
* Calls LayerSetUp to do special layer setup for individual layer types,
* followed by Reshape to set up sizes of top blobs and internal buffers.
* Sets up the loss weight multiplier blobs for any non-zero loss weights.
* This method may not be overridden.
*/
void SetUp(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {
CheckBlobCounts(bottom, *top);
LayerSetUp(bottom, top);
Reshape(bottom, top);
SetLossWeights(top);
}

/**
* @brief Does layer-specific setup: your layer should implement this.
* @brief Does layer-specific setup: your layer should implement this function
* as well as Reshape.
*
* @param bottom
* the preshaped input blobs, whose data fields store the input data for
* this layer
* @param top
* the allocated but unshaped output blobs, to be initialized by LayerSetUp
* the allocated but unshaped output blobs
*
* This method should be used to do layer-specific setup. At a minimum, this
* includes reshaping the empty top blobs to the shape as dictated by the
* shapes of the bottom blobs and any relevant parameters from the
* <code>layer_param_</code>.
* This method should do one-time layer specific setup. This includes reading
* and processing relevent parameters from the <code>layer_param_</code>.
* Setting up the shapes of top blobs and internal buffers should be done in
* <code>Reshape</code>, which will be called before the forward pass to
* adjust the top blob sizes.
*/
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) { NOT_IMPLEMENTED; }
vector<Blob<Dtype>*>* top) {}

/**
* @brief Adjust the shapes of top blobs and internal buffers to accomodate
* the shapes of the bottom blobs.
*
* @param bottom the input blobs, with the requested input shapes
* @param top the top blobs, which should be reshaped as needed
*
* This method should reshape top blobs as needed according to the shapes
* of the bottom (input) blobs, as well as reshaping any internal buffers
* and making any other necessary adjustments so that the layer can
* accomodate the bottom blobs.
*/
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top) = 0;

/**
* @brief Given the bottom blobs, compute the top blobs and the loss.
Expand Down
14 changes: 12 additions & 2 deletions include/caffe/loss_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class AccuracyLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_ACCURACY;
Expand Down Expand Up @@ -97,6 +99,8 @@ class LossLayer : public Layer<Dtype> {
: Layer<Dtype>(param) {}
virtual void LayerSetUp(
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top);
virtual void Reshape(
const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top);

virtual inline int ExactNumBottomBlobs() const { return 2; }

Expand Down Expand Up @@ -148,7 +152,7 @@ class EuclideanLossLayer : public LossLayer<Dtype> {
public:
explicit EuclideanLossLayer(const LayerParameter& param)
: LossLayer<Dtype>(param), diff_() {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
Expand Down Expand Up @@ -339,6 +343,8 @@ class InfogainLossLayer : public LossLayer<Dtype> {
: LossLayer<Dtype>(param), infogain_() {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

// InfogainLossLayer takes 2-3 bottom Blobs; if there are 3 the third should
// be the infogain matrix. (Otherwise the infogain matrix is loaded from a
Expand Down Expand Up @@ -428,7 +434,7 @@ class MultinomialLogisticLossLayer : public LossLayer<Dtype> {
public:
explicit MultinomialLogisticLossLayer(const LayerParameter& param)
: LossLayer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
Expand Down Expand Up @@ -510,6 +516,8 @@ class SigmoidCrossEntropyLossLayer : public LossLayer<Dtype> {
sigmoid_output_(new Blob<Dtype>()) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_SIGMOID_CROSS_ENTROPY_LOSS;
Expand Down Expand Up @@ -606,6 +614,8 @@ class SoftmaxWithLossLayer : public LossLayer<Dtype> {
softmax_layer_(new SoftmaxLayer<Dtype>(param)) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_SOFTMAX_LOSS;
Expand Down
8 changes: 8 additions & 0 deletions include/caffe/net.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ class Net {
void BackwardFrom(int start);
void BackwardTo(int end);

/**
* @brief Reshape all layers from bottom to top.
*
* This is useful to propagate changes to layer sizes without running
* a forward pass, e.g. to compute output feature size.
*/
void Reshape();

Dtype ForwardBackward(const vector<Blob<Dtype>* > & bottom) {
Dtype loss;
Forward(bottom, &loss);
Expand Down
10 changes: 9 additions & 1 deletion include/caffe/neuron_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class NeuronLayer : public Layer<Dtype> {
public:
explicit NeuronLayer(const LayerParameter& param)
: Layer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
Expand Down Expand Up @@ -170,6 +170,8 @@ class DropoutLayer : public NeuronLayer<Dtype> {
: NeuronLayer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);

virtual inline LayerParameter_LayerType type() const {
return LayerParameter_LayerType_DROPOUT;
Expand Down Expand Up @@ -367,6 +369,8 @@ class CuDNNReLULayer : public ReLULayer<Dtype> {
: ReLULayer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual ~CuDNNReLULayer();

protected:
Expand Down Expand Up @@ -449,6 +453,8 @@ class CuDNNSigmoidLayer : public SigmoidLayer<Dtype> {
: SigmoidLayer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual ~CuDNNSigmoidLayer();

protected:
Expand Down Expand Up @@ -533,6 +539,8 @@ class CuDNNTanHLayer : public TanHLayer<Dtype> {
: TanHLayer<Dtype>(param) {}
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
vector<Blob<Dtype>*>* top);
virtual ~CuDNNTanHLayer();

protected:
Expand Down
Loading

0 comments on commit 8789b23

Please sign in to comment.