using namespace caffe; // NOLINT(build/namespaces)
+using boost::python::dict;
using boost::python::extract;
using boost::python::len;
using boost::python::list;
// The pointer to the internal caffe::Net instant.
shared_ptr<Net<float> > net_;
+ // Input preprocessing configuration attributes.
+ dict mean_;
+ dict input_scale_;
+ dict channel_swap_;
// if taking input from an ndarray, we need to hold references
object input_data_;
object input_labels_;
boost::python::class_<CaffeNet, shared_ptr<CaffeNet> >(
"Net", boost::python::init<string, string>())
.def(boost::python::init<string>())
- .def("_forward", &CaffeNet::Forward)
- .def("_backward", &CaffeNet::Backward)
- .def("set_mode_cpu", &CaffeNet::set_mode_cpu)
- .def("set_mode_gpu", &CaffeNet::set_mode_gpu)
- .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)
- .add_property("layers", &CaffeNet::layers)
- .add_property("inputs", &CaffeNet::inputs)
- .add_property("outputs", &CaffeNet::outputs)
- .def("_set_input_arrays", &CaffeNet::set_input_arrays)
- .def("save", &CaffeNet::save);
+ .def("_forward", &CaffeNet::Forward)
+ .def("_backward", &CaffeNet::Backward)
+ .def("set_mode_cpu", &CaffeNet::set_mode_cpu)
+ .def("set_mode_gpu", &CaffeNet::set_mode_gpu)
+ .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)
+ .add_property("layers", &CaffeNet::layers)
+ .add_property("inputs", &CaffeNet::inputs)
+ .add_property("outputs", &CaffeNet::outputs)
+ .add_property("mean", &CaffeNet::mean_)
+ .add_property("input_scale", &CaffeNet::input_scale_)
+ .add_property("channel_swap", &CaffeNet::channel_swap_)
+ .def("_set_input_arrays", &CaffeNet::set_input_arrays)
+ .def("save", &CaffeNet::save);
boost::python::class_<CaffeBlob, CaffeBlobWrap>(
"Blob", boost::python::no_init)
mode: elementwise = use the whole mean (and check dimensions)
channel = channel constant (e.g. mean pixel instead of mean image)
"""
- if not hasattr(self, 'mean'):
- self.mean = {}
if input_ not in self.inputs:
raise Exception('Input not in {}'.format(self.inputs))
in_shape = self.blobs[input_].data.shape
input_: which input to assign this scale factor
scale: scale coefficient
"""
- if not hasattr(self, 'input_scale'):
- self.input_scale = {}
if input_ not in self.inputs:
raise Exception('Input not in {}'.format(self.inputs))
self.input_scale[input_] = scale
order: the order to take the channels.
(2,1,0) maps RGB to BGR for example.
"""
- if not hasattr(self, 'channel_swap'):
- self.channel_swap = {}
if input_ not in self.inputs:
raise Exception('Input not in {}'.format(self.inputs))
self.channel_swap[input_] = order
caffe_inputs: (K x H x W) ndarray
"""
caffe_in = input_.astype(np.float32)
+ mean = self.mean.get(input_name)
input_scale = self.input_scale.get(input_name)
channel_order = self.channel_swap.get(input_name)
in_size = self.blobs[input_name].data.shape[2:]
if channel_order is not None:
caffe_in = caffe_in[:, :, channel_order]
caffe_in = caffe_in.transpose((2, 0, 1))
- if hasattr(self, 'mean'):
- caffe_in -= self.mean.get(input_name, 0)
+ if mean is not None:
+ caffe_in -= mean
return caffe_in
Invert Caffe formatting; see Net.preprocess().
"""
decaf_in = input_.copy().squeeze()
+ mean = self.mean.get(input_name)
input_scale = self.input_scale.get(input_name)
channel_order = self.channel_swap.get(input_name)
- if hasattr(self, 'mean'):
- decaf_in += self.mean.get(input_name, 0)
+ if mean is not None:
+ decaf_in += mean
decaf_in = decaf_in.transpose((1,2,0))
if channel_order is not None:
channel_order_inverse = [channel_order.index(i)