caffe-tensorflow icon indicating copy to clipboard operation
caffe-tensorflow copied to clipboard

failed to convert mobilenet v2 weights

Open saeed68gm opened this issue 7 years ago • 8 comments

I tried this script to convert Mobilenet V2 weights provided here:

https://github.com/shicai/MobileNet-Caffe

The error I got was "unable to determine kernel parameters"

Any idea why or how to fix it?

saeed68gm avatar Feb 20 '18 19:02 saeed68gm

I am doing the same thing. I try the solution in #53 . The "kernel parameters" problem has been solved, but there are new bugs:

'fc7'; shape mismatch.  Source param shape is 1000 1024 1 1 (1024000); target param shape is 1000 1280 1 1 (1280000). To learn this layer's parameters from scratch rather than copying from a saved net, rename the layer.
*** Check failure stack trace: ***
Aborted (core dumped)

Do you face the same problems?

ginger0106 avatar Feb 27 '18 13:02 ginger0106

@ginger0106 I haven't tried the solution, but it seems strange as I don't see a fc7 layer in the prototxt file. There is only one fully connected layer with 1000 classes. Could it be because the difference in behavior of global averaging in tf vs caffe? I see the layer before FC is global averaging again.

saeed68gm avatar Feb 27 '18 15:02 saeed68gm

@saeed68gm I am trying to convert the same model mobilenet2 https://github.com/shicai/MobileNet-Caffe to tensorflow: 

./convert.py MobileNet2/mobilenet_v2_deploy.prototxt --caffemodel MobileNet2/mobilenet.caffemodel --code-output-path=mynet.py --data-output-path=m2tfdata.npy

I fix that problem by changing the layer name. But facing a new bug:

Traceback (most recent call last):
  File "./convert.py", line 60, in <module>
    main()
  File "./convert.py", line 56, in main
    args.phase)
  File "./convert.py", line 27, in convert
    transformer = TensorFlowTransformer(def_path, caffemodel_path, phase=phase)
  File "/home/heyhao/icme2018/ICME2018/kaffe/tensorflow/transformer.py", line 221, in __init__
    self.load(def_path, data_path, phase)
  File "/home/heyhao/icme2018/ICME2018/kaffe/tensorflow/transformer.py", line 254, in load
    print_stderr(self.graph)
  File "/home/heyhao/icme2018/ICME2018/kaffe/errors.py", line 7, in print_stderr
    sys.stderr.write('%s\n' % msg)
  File "/home/heyhao/icme2018/ICME2018/kaffe/graph.py", line 125, in __str__
    tuple(out_shape)))
TypeError: unsupported format string passed to tuple.__format__

ginger0106 avatar Feb 28 '18 08:02 ginger0106

@saeed68gm hi, I have fixed the bugs. These bugs are triggered by the difference of Python2 and Python3. p.s., I am using Python3.

  1. In graph.py:
def __str__(self):
       hdr = '{:<20} {:<30} {:>20} {:>20}'.format('Type', 'Name', 'Param', 'Output')
       s = [hdr, '-' * 94]
       for node in self.topologically_sorted():
           # If the node has learned parameters, display the first one's shape.
           # In case of convolutions, this corresponds to the weights.
           if node.data:#ginger
               node.data=list(node.data)#ginger
           data_shape = str(node.data[0].shape) if node.data else '--'
           out_shape = node.output_shape or '--'
           s.append('{:<20} {:<30} {:>20} {:>20}'.format(node.kind, node.name,data_shape, str(tuple(out_shape))) )#ginger
       return '\n'.join(s)
  1. In transformer.py and shapes.py, you should add list before map()
 def format(self, arg):
        '''Returns a string representation for the given value.'''
    #    return "'%s'" % arg if isinstance(arg, basestring) else str(arg)#ginger

        return "'%s'" % arg if isinstance(arg, str) else str(arg)

    def pair(self, key, value):
        '''Returns key=formatted(value).'''
        return '%s=%s' % (key, self.format(value))

    def emit(self):
        '''Emits the Python source for this node.'''
        # Format positional arguments
        args = list(map(self.format, self.args))#ginger
        # Format any keyword arguments
        if self.kwargs:
            args += [self.pair(k, v) for k, v in self.kwargs]
        # Set the node name
        args.append(self.pair('name', self.node.name))
        args = ', '.join(args)
        return '%s(%s)' % (self.op, args)

3.change all the basestring into str

  1. In transformer.py:
 def transform_source(self):
        if self.source is None:
            mapper = TensorFlowMapper(self.graph)
            chains = mapper.map()
            emitter = TensorFlowEmitter()
            self.source = emitter.emit(self.graph.name, chains)
        return self.source.encode(encoding="utf-8")#ginger

ginger0106 avatar Mar 01 '18 07:03 ginger0106

@ginger0106 Thank you for explaining, this is very helpful. I am going to try it and update here.

saeed68gm avatar Mar 01 '18 18:03 saeed68gm

@ginger0106 thank you for explaining, this is very helpful too. I met the same question before, and solved succeed with your method.

xiaoyaozzr avatar May 28 '18 11:05 xiaoyaozzr

@xiaoyaozzr Hi, I have finished converting caffe to tensorflow for mobilenetv1. But I am a little confused about conv function: conv(3,3,32,1,1,biased=False,group=32,relu=False,name='conv2_1_dw') Can you tell me how to write the conv function in network.py? Please! Thank you very much!

Ariel-JUAN avatar Jun 01 '18 06:06 Ariel-JUAN

How to implement mobilenetv2 based on network.py? Does it need to implement customed depthwise convolution in network.py according to mobilenet_v2_deploy.prototxt? @ginger0106 @xiaoyaozzr

ztwe avatar Jan 09 '19 14:01 ztwe