BVLC/caffe — pull request #594 by longjon (2014-07-03 03:41:25+00:00)
Title: On-the-fly net resizing, without reallocation (where possible)

This PR allows nets to change their input sizes in-place, reusing allocated memory for blobs and buffers. This allows, for example:
* building a net with a large batch size, and using it for batches of any smaller size, without memory or significant computational cost, and
* building a large convolutional net, and using it for inputs of any smaller size, again at no cost.

`Net` gets a new method `Reshape` that provides this functionality. One first resizes input blobs manually, then calls `Net::Reshape` with no arguments. (This has the unfortunate property that one has to momentarily "break" the net before calling `Reshape`, but it avoids the awkwardness of typing `Reshape` to accept a vector of 4-tuples.)

`Net::Reshape` just calls `Layer::Reshape` for each layer in turn, bottom-up. Since reshaping doesn't make sense for all layers, and layers may constrain acceptable new sizes, `Layer::Reshape` is opt-in; only layers that implement it can be reshaped. (Neuron layers can all be reshaped, most of them in a trivial way, so an implementation of `NeuronLayer::Reshape` is provided.)

Note that reshaping is intended only for cases where the existing parameters can continue to be used with modification. Reshaping is not intended for use with data layers. This PR provides reshapability for essentially only the layers needed for a Krizhevsky-style net.

Many layers use internal buffers, which are sometimes implemented as `Blob`s, sometimes `shared_ptr`s, and sometimes `SyncedMemory`s. This PR uniformizes some of these to be just `Blob`s in order to simplify implementation. As far as I can tell, no `shared_ptr`s were removed that needed to be `shared_ptr`s; someone let me know if this is not true (@jeffdonahue?)

This PR includes a simple implementation of part of #355 in 33959e5f9a4c4342ee797fca71d607d74f792483. Unlike #355, the implementation is entirely within `Blob::Reshape`, and does not touch `SyncedMemory`. The disadvantage is that it doesn't call `realloc` when enlarging blobs; this could be added in a later patch if desired. (This PR does not address sharing blobs between train and test nets.)

Although I haven't used it a lot yet, this PR is fully-baked: tests are included, it's usable from Python, it builds everything with `-Wall -Werror`, and passes tests and lint. There is a clean, linear history; if the reader feels overwhelmed by the changes, I suggest reading it one commit at a time.