diff --git a/mmdnn/conversion/caffe/mapper.py b/mmdnn/conversion/caffe/mapper.py index a83dbfcd..73d47451 100644 --- a/mmdnn/conversion/caffe/mapper.py +++ b/mmdnn/conversion/caffe/mapper.py @@ -259,11 +259,15 @@ def map_scale(cls, node): # TODO: The gamma parameter has to be set (in node.data?) and this should work. # Also, mean should be set to 0, and var to 1, just to be safe. if node.data: - raise NotImplementedError scale_value = float(node.parameters.filler.value) - kwargs = {'scale' : False, 'bias' : False, 'gamma' : scale_value, 'epsilon': 0} + if node.parameters.bias_term: + bias_value = float(node.parameters.bias_filler.value) + kwargs = {'use_scale' : True, 'use_bias' : node.parameters.bias_term, 'gamma' : scale_value, 'beta': bias_value, 'epsilon': 0} + else: + kwargs = {'use_scale' : True, 'use_bias' : node.parameters.bias_term, 'gamma' : scale_value, 'epsilon': 0} + cls._convert_output_shape(kwargs, node) - return Node.create('Scale', **kwargs) + return Node.create('Affine', **kwargs) else: return Node.create('Mul') diff --git a/mmdnn/conversion/examples/caffe/extractor.py b/mmdnn/conversion/examples/caffe/extractor.py index 106a9c0f..5d5953b1 100644 --- a/mmdnn/conversion/examples/caffe/extractor.py +++ b/mmdnn/conversion/examples/caffe/extractor.py @@ -44,6 +44,8 @@ class caffe_extractor(base_extractor): 'caffemodel' : 'http://dl.caffe.berkeleyvision.org/fcn16s-heavy-pascal.caffemodel'}, 'voc-fcn32s' : {'prototxt' : MMDNN_BASE_URL + "caffe/voc-fcn32s_deploy.prototxt", 'caffemodel' : 'http://dl.caffe.berkeleyvision.org/fcn32s-heavy-pascal.caffemodel'}, + 'trailnet_sresnet': {'prototxt': 'https://raw.githubusercontent.com/NVIDIA-AI-IOT/redtail/master/models/pretrained/TrailNet_SResNet-18.prototxt', + 'caffemodel': 'https://raw.githubusercontent.com/NVIDIA-AI-IOT/redtail/master/models/pretrained/TrailNet_SResNet-18.caffemodel'} } @@ -80,7 +82,7 @@ def inference(cls, architecture_name, architecture, path, image_path): img = np.transpose(img, (2, 0, 1)) img = np.expand_dims(img, 0) net.blobs['data'].data[...] = img - predict = np.squeeze(net.forward()[net._layer_names[-1]][0]) + predict = np.squeeze(net.forward()[net._output_list[-1]][0]) predict = np.squeeze(predict) return predict diff --git a/mmdnn/conversion/examples/imagenet_test.py b/mmdnn/conversion/examples/imagenet_test.py index 1f6fffed..0971d01f 100644 --- a/mmdnn/conversion/examples/imagenet_test.py +++ b/mmdnn/conversion/examples/imagenet_test.py @@ -88,6 +88,7 @@ class TestKit(object): 'voc-fcn8s' : lambda path : TestKit.ZeroCenter(path, 500, True), 'voc-fcn16s' : lambda path : TestKit.ZeroCenter(path, 500, True), 'voc-fcn32s' : lambda path : TestKit.ZeroCenter(path, 500, True), + 'trailnet_sresnet': lambda path: TestKit.ZeroCenter(path, (320, 180), True) }, 'tensorflow' : { @@ -246,7 +247,11 @@ def __init__(self): @staticmethod def ZeroCenter(path, size, BGRTranspose=False): img = Image.open(path) - img = img.resize((size, size)) + if isinstance(size, tuple): + h, w = size[0], size[1] + else: + h, w = size, size + img = img.resize((h, w)) x = np.array(img, dtype=np.float32) # Reference: 1) Keras image preprocess: https://github.com/keras-team/keras/blob/master/keras/applications/imagenet_utils.py diff --git a/mmdnn/conversion/keras/keras2_emitter.py b/mmdnn/conversion/keras/keras2_emitter.py index b96cc502..d7fe4a05 100644 --- a/mmdnn/conversion/keras/keras2_emitter.py +++ b/mmdnn/conversion/keras/keras2_emitter.py @@ -862,6 +862,23 @@ def emit_PRelu(self, IR_node, in_scope=False): ) return code + def emit_Affine(self, IR_node, in_scope=False): + if in_scope: + raise NotImplementedError + else: + self.used_layers.add('Affine') + if IR_node.layer.attr.get('beta', None) is None: + bias = None + else: + bias = IR_node.layer.attr['beta'].f + code = "{:<15} = Affine(name='{}', scale={}, bias={})({})".format( + IR_node.variable_name, + IR_node.name, + IR_node.layer.attr['gamma'].f, + bias, + self.parent_variable_name(IR_node)) + return code + def emit_yolo(self, IR_node, in_scope=False): self.used_layers.add('Yolo') self.yolo_parameter = [IR_node.get_attr('anchors'), @@ -1183,6 +1200,28 @@ def compute_output_shape(self, input_shape): return input_shape""") + def _layer_Affine(self): + self.add_body(0, ''' +from keras.engine import Layer, InputSpec +from keras import initializers +from keras import backend as K + +class Affine(Layer): + def __init__(self, scale, bias=None, **kwargs): + super(Affine, self).__init__(**kwargs) + self.gamma = scale + self.beta = bias + + def call(self, inputs, training=None): + input_shape = K.int_shape(inputs) + # Prepare broadcasting shape. + return self.gamma * inputs + self.beta + + def compute_output_shape(self, input_shape): + return input_shape + ''') + + def _layer_Split(self): self.add_body(0, ''' def __split(input, split_num, axis):