зеркало из https://github.com/microsoft/caffe.git
define caffe.Net input preprocessing members by boost::python
define `Net.{mean, input_scale, channel_swap}` on the boost::python side so that the members always exist. drop ugly initialization logic.
This commit is contained in:
Родитель
d1d499df53
Коммит
99f27fc082
|
@ -25,6 +25,7 @@
|
|||
|
||||
|
||||
using namespace caffe; // NOLINT(build/namespaces)
|
||||
using boost::python::dict;
|
||||
using boost::python::extract;
|
||||
using boost::python::len;
|
||||
using boost::python::list;
|
||||
|
@ -274,6 +275,10 @@ struct CaffeNet {
|
|||
|
||||
// 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_;
|
||||
|
@ -311,19 +316,22 @@ BOOST_PYTHON_MODULE(_caffe) {
|
|||
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)
|
||||
|
|
|
@ -211,8 +211,6 @@ def _Net_set_mean(self, input_, mean_f, mode='elementwise'):
|
|||
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
|
||||
|
@ -240,8 +238,6 @@ def _Net_set_input_scale(self, input_, scale):
|
|||
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
|
||||
|
@ -257,8 +253,6 @@ def _Net_set_channel_swap(self, input_, order):
|
|||
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
|
||||
|
@ -282,6 +276,7 @@ def _Net_preprocess(self, input_name, input_):
|
|||
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:]
|
||||
|
@ -292,8 +287,8 @@ def _Net_preprocess(self, input_name, input_):
|
|||
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
|
||||
|
||||
|
||||
|
@ -302,10 +297,11 @@ def _Net_deprocess(self, input_name, input_):
|
|||
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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче