From a8a0191089a94887db60ffa8be834e27b327a60b Mon Sep 17 00:00:00 2001 From: Jonathan L Long Date: Thu, 3 Apr 2014 22:21:13 -0700 Subject: [PATCH] switch from inheritance to directly overriding methods for caffe.Net Also, internally drop the "Caffe" prefix for classes exported by the internal _caffe module. This change means that SGDSolver will automatically return a Net with the "nice" Python interface rather than the internal one, (and avoids the extra layer of method wrapping that results from switching to composition). --- python/caffe/_caffe.cpp | 9 +++++---- python/caffe/pycaffe.py | 41 +++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/python/caffe/_caffe.cpp b/python/caffe/_caffe.cpp index c3bd704..11813f6 100644 --- a/python/caffe/_caffe.cpp +++ b/python/caffe/_caffe.cpp @@ -305,7 +305,7 @@ class CaffeSGDSolver { // The boost python module definition. BOOST_PYTHON_MODULE(_caffe) { boost::python::class_( - "CaffeNet", boost::python::init()) + "Net", boost::python::init()) .def("Forward", &CaffeNet::Forward) .def("ForwardPrefilled", &CaffeNet::ForwardPrefilled) .def("Backward", &CaffeNet::Backward) @@ -314,11 +314,12 @@ BOOST_PYTHON_MODULE(_caffe) { .def("set_phase_train", &CaffeNet::set_phase_train) .def("set_phase_test", &CaffeNet::set_phase_test) .def("set_device", &CaffeNet::set_device) - .add_property("blobs", &CaffeNet::blobs) + // rename blobs here since the pycaffe.py wrapper will replace it + .add_property("_blobs", &CaffeNet::blobs) .add_property("layers", &CaffeNet::layers); boost::python::class_( - "CaffeBlob", boost::python::no_init) + "Blob", boost::python::no_init) .add_property("name", &CaffeBlob::name) .add_property("num", &CaffeBlob::num) .add_property("channels", &CaffeBlob::channels) @@ -329,7 +330,7 @@ BOOST_PYTHON_MODULE(_caffe) { .add_property("diff", &CaffeBlobWrap::get_diff); boost::python::class_( - "CaffeLayer", boost::python::no_init) + "Layer", boost::python::no_init) .add_property("name", &CaffeLayer::name) .add_property("blobs", &CaffeLayer::blobs); diff --git a/python/caffe/pycaffe.py b/python/caffe/pycaffe.py index 367ad4f..863d315 100644 --- a/python/caffe/pycaffe.py +++ b/python/caffe/pycaffe.py @@ -3,26 +3,31 @@ Wrap the internal caffe C++ module (_caffe.so) with a clean, Pythonic interface. """ -from ._caffe import CaffeNet, SGDSolver +from ._caffe import Net, SGDSolver from collections import OrderedDict -class Net(CaffeNet): +# we directly update methods from Net here (rather than using composition or +# inheritance) so that nets created by caffe (e.g., by SGDSolver) will +# automatically have the improved interface + +@property +def _Net_blobs(self): + """ + An OrderedDict (bottom to top, i.e., input to output) of network + blobs indexed by name + """ + return OrderedDict([(bl.name, bl) for bl in self._blobs]) + +Net.blobs = _Net_blobs + +@property +def _Net_params(self): """ - The direct Python interface to caffe, exposing Forward and Backward - passes, data, gradients, and layer parameters + An OrderedDict (bottom to top, i.e., input to output) of network + parameters indexed by name; each is a list of multiple blobs (e.g., + weights and biases) """ - def __init__(self, param_file, pretrained_param_file): - super(Net, self).__init__(param_file, pretrained_param_file) - self._blobs = OrderedDict([(bl.name, bl) - for bl in super(Net, self).blobs]) - self.params = OrderedDict([(lr.name, lr.blobs) - for lr in super(Net, self).layers - if len(lr.blobs) > 0]) + return OrderedDict([(lr.name, lr.blobs) for lr in self.layers + if len(lr.blobs) > 0]) - @property - def blobs(self): - """ - An OrderedDict (bottom to top, i.e., input to output) of network - blobs indexed by name - """ - return self._blobs +Net.params = _Net_params -- 2.7.4