Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give the python layer parameter/weight blobs. #2944

Merged
merged 2 commits into from
Aug 27, 2015

Conversation

philkr
Copy link
Contributor

@philkr 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()

@longjon
Copy link
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.

@philkr
Copy link
Contributor Author

philkr commented Aug 25, 2015

Fixed the style and added some tests.

@longjon
Copy link
Contributor

longjon commented Aug 27, 2015

Looks good, thanks @philkr!

longjon added a commit that referenced this pull request Aug 27, 2015
Give the python layer parameter/weight blobs.
@longjon longjon merged commit f572eef into BVLC:master Aug 27, 2015
@longjon
Copy link
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 added a commit to Robotertechnik/caffe that referenced this pull request Aug 27, 2015
@peerajak
Copy link

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 philkr deleted the python_layer_param branch January 6, 2016 05:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants