Give the python layer parameter/weight blobs. #2944

Merged
merged 2 commits into from Aug 27, 2015

Conversation

Projects
None yet
4 participants
Contributor

philkr commented Aug 19, 2015

This PR allows the python layer to have its own parameter/weight blobs.
As any python layer inherits form caffe.Layer it already has a self.blobs variable that gets saved and loaded properly, however it wasn't possible to add a new blob to that BlobVec. This PR adds a function add_blob to the BlobVec which allows a python layer to extend the vector with a new blob. The arguments of the add_blob function are the dimensions of the blob to be added.

Here is a simple layer that demonstrates the use.

import caffe

class Param(caffe.Layer):
    def setup(self, bottom, top):
        self.blobs.add_blob(1,2,3)
        self.blobs[0].data[...] = 0

    def reshape(self, bottom, top):
        top[0].reshape(10)

    def forward(self, bottom, top):
        print(self.blobs[0].data)
        self.blobs[0].data[...] += 1

    def backward(self, top, propagate_down, bottom):
        pass


def main():
    from caffe import NetSpec, layers as L, params as P, to_proto
    from os import path
    ns = NetSpec()

    A = L.Python(module='test_phase', layer='Param', ntop=1, name='foo')
    open('/tmp/test.prototxt', 'w').write(str(to_proto(A)))
    net = caffe.Net('/tmp/test.prototxt', caffe.TRAIN )
    if path.exists('/tmp/test.caffemodel'):
        net.copy_from('/tmp/test.caffemodel')
    print( "Loaded" )
    net.forward()
    net.forward()
    net.save('/tmp/test.caffemodel')

if __name__ == "__main__":
    main()
Contributor

longjon commented Aug 24, 2015

Generally for this purpose I am using #2079, which ought to eventually in some way in accord with #1474 provide a more natural way to deal with parameters, esp. when using net spec.

But this seems like a reasonable exposure of the current state affairs. It would be nice if Layer.blobs was treated as a more Pythonic list-like thing, but that's understandably difficult with vector_indexing_suite, so this interface seems pretty reasonable and the code is unobtrusive.

For merge:

  • Could we provide a basic test of this functionality?
  • Please do follow the existing style (even where not checked by lint); in particular, one space between functions, and use explicit braces around blocks.
Contributor

philkr commented Aug 25, 2015

Fixed the style and added some tests.

Contributor

longjon commented Aug 27, 2015

Looks good, thanks @philkr!

@longjon longjon added a commit that referenced this pull request Aug 27, 2015

@longjon longjon Merge pull request #2944 from philkr/python_layer_param
Give the python layer parameter/weight blobs.
f572eef

@longjon longjon merged commit f572eef into BVLC:master Aug 27, 2015

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
Contributor

longjon commented Aug 27, 2015

Ah, I just merged this, so this comment is too late, but one more thing for the future: please squash style changes (here they appear in the test commit, which is confusing).

@ctrevino ctrevino added a commit to Robotertechnik/caffe that referenced this pull request Aug 27, 2015

@ctrevino ctrevino Give the python layer parameter/weight blobs. #2944 f8a0447

Thank you very much. Exactly what I have been looking for

It terns out that this is perfectly what I want! the solver do update the weights!. I tested it by setting initial weights to zeros and backward with ones. the result diff is with 0-base_lr*1.
the way to access this new blobvec is as follow
solver.net.params['loss'][0].data

philkr deleted the philkr:python_layer_param branch Jan 6, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment