Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I don't understand which command I have to write to convert a model #8

Closed
cyrilgarcia009 opened this issue Jun 30, 2016 · 10 comments
Closed

Comments

@cyrilgarcia009
Copy link

I am really sorry but I just don't understand what I can use to convert a model from caffe to keras.

I have a folder with two files (prototxt and caffemodel), but I don't understand how to convert it. Can you help me please ?

@MarcBS
Copy link
Owner

MarcBS commented Jun 30, 2016

As it explained in the README file, you can use the caffe2keras.py as a command line tool the following way:

python caffe2keras.py -load_path <your_path> -prototxt <your_prototxt> -caffemodel <your_caffemodel>

where you just have to include the path to your model files (your_path) and the names of the prototxt (your_prototxt) and caffemodel (your_caffemodel) files included in that path.

The converted model will be stored by default in your_path.

I have just updated the README file for making this more clear.

@cyrilgarcia009
Copy link
Author

You mean I have to write this command line in the Terminal ?

@cyrilgarcia009
Copy link
Author

When I use this line in the terminal there is this error :

google.protobuf.text_format.ParseError: 37:2 : Message type "caffe.LayerParameter" has no field named "scale_param".

Do you understand why ?

Thank you very much for your help !

@MarcBS
Copy link
Owner

MarcBS commented Jul 1, 2016

This error is probably caused because the parameter 'scale_param' is relatively new in the .prototxt files. I have just updated the file caffe_pb2.py in the repo, which is in charge of controlling the valid .prototxt parameters.

Re-sync your cloned files with the new changes and try it again, it should work properly now.

@cyrilgarcia009
Copy link
Author

Hi,

I am really sorry but it still doesn't work. I'm getting this error even after the sync :

Traceback (most recent call last):
File "/Users/cyrilgarcia/keras/keras/caffe/caffe2keras.py", line 45, in
main(args)
File "/Users/cyrilgarcia/keras/keras/caffe/caffe2keras.py", line 34, in main
model = convert.caffe_to_keras(args.load_path+'/'+args.prototxt, args.load_path+'/'+args.caffemodel, debug=args.debug)
File "/Users/cyrilgarcia/keras/keras/caffe/convert.py", line 43, in caffe_to_keras
debug)
File "/Users/cyrilgarcia/keras/keras/caffe/convert.py", line 255, in create_model
raise RuntimeError('layer type', type_of_layer, 'used in this model is not currently supported')
RuntimeError: ('layer type', 'batchnorm', 'used in this model is not currently supported')
MacBook-Air-de-Cyril:~ cyrilgarcia$

May be this is because I don't know how to use caffe_pb2. py ?

@MarcBS
Copy link
Owner

MarcBS commented Jul 1, 2016

That error is thrown because the layer BatchNorm was not implemented in the converter yet.
I have just added it now. Try again and tell me if it worked.

@cyrilgarcia009
Copy link
Author

Still the same type of error :

Traceback (most recent call last):
File "/Users/cyrilgarcia/keras/keras/caffe/caffe2keras.py", line 45, in
main(args)
File "/Users/cyrilgarcia/keras/keras/caffe/caffe2keras.py", line 34, in main
model = convert.caffe_to_keras(args.load_path+'/'+args.prototxt, args.load_path+'/'+args.caffemodel, debug=args.debug)
File "/Users/cyrilgarcia/keras/keras/caffe/convert.py", line 43, in caffe_to_keras
debug)
File "/Users/cyrilgarcia/keras/keras/caffe/convert.py", line 260, in create_model
raise RuntimeError('layer type', type_of_layer, 'used in this model is not currently supported')
RuntimeError: ('layer type', 'scale', 'used in this model is not currently supported')

@ternaus
Copy link

ternaus commented Jul 2, 2016

Same error as @cyrilgarcia009 .

To add more context: I am trying to convert Resnet50 from https://github.com/KaimingHe/deep-residual-networks. Link to proto and weights: https://onedrive.live.com/?authkey=%21AAFW2-FVoxeVRck&id=4006CBB8476FF777%2117887&cid=4006CBB8476FF777

@MarcBS
Copy link
Owner

MarcBS commented Jul 4, 2016

Thanks for the context @ternaus.

I have applied some new changes to the converter and ResNets can be correctly transferred to Keras. As an example you can use the weights and prototxt provided by @ternaus.

Just as a reminder, don't forget to add the following layer as the first layer in your prototxt files:

layer {
name: "data"
type: "Data"
top: "data"
top: "label"
}

I have not checked the performance of the converted model, so please, if any of you apply some validation report the results comparison here for considering any possible modification. Thanks.

@MarcBS MarcBS closed this as completed Jul 4, 2016
@EpochalEngineer
Copy link

EpochalEngineer commented Jul 4, 2016

I was able to convert ResNet50 with the current commit and adding the data layer, but wasn't able to get inference working.

Exception: You are attempting to share a same BatchNormalization layer across different data flows. This is not possible. You should use mode=2 in BatchNormalization, which has a similar behavior but is shareable (see docs for a description of the behavior).

https://github.com/MarcBS/keras/blob/master/keras/layers/normalization.py#L193

Some debugging info that doesn't quite make sense:

ipdb> self.name
u'bn_conv1'
ipdb> self.called_with
Elemwise{add,no_inplace}.0
ipdb> x
Elemwise{add,no_inplace}.0
ipdb> x.name
ipdb>
ipdb> x.get_parents()[0]
Elemwise{add,no_inplace}(AbstractConv2d{border_mode='valid', subsample=(2, 2), filter_flip=True, imshp=(None, None, None, None), kshp=(64, 3, 7, 7)}.0, Reshape{4}.0)
ipdb> self.called_with.get_parents()[0]
Elemwise{add,no_inplace}(AbstractConv2d{border_mode='valid', subsample=(2, 2), filter_flip=True, imshp=(None, None, None, None), kshp=(64, 3, 7, 7)}.0, Reshape{4}.0)

I'm not all that familiar with keras/theano, but bn_conv1 has one input and output node and it's conv1 and caffe's separate batchnorm scale layer. It's not anywhere near a skip connection or addition (I searched the json and yaml files). Not sure how to get more information as to how x and self.called_with differ.

Here is a graphviz of the converted model:
https://i.imgur.com/PfMXhDw.png

Assuming it was accidentally getting recompiled , I removed the explicit compile step and got this error (same as if replacing mode=0 with mode=2 in the model files):

ValueError: GpuReshape: cannot reshape input of shape (2048) to shape (1, 1, 1, 7).
Apply node that caused the error: GpuReshape{4}(scale5a_branch1_gamma, TensorConstant{[1 1 1 7]})
Toposort index: 447
Inputs types: [CudaNdarrayType(float32, vector), TensorType(int64, vector)]
Inputs shapes: [(2048,), (4,)]
Inputs strides: [(1,), (8,)]
Inputs values: ['not shown', array([1, 1, 1, 7])]
Outputs clients: [[GpuElemwise{Composite{(((i0 * (i1 + i2)) + i3) + ((i4 * i5) + i6))},no_inplace}(GpuReshape{4}.0, GpuElemwise{Composite{(i0 * (i1 / i2))},no_inplace}.0, GpuReshape{4}.0, GpuReshape{4}.0, GpuReshape{4}.0, GpuElemwise{Composite{((i0 * (i1 / i2)) + i3)},no_inplace}.0, GpuReshape{4}.0)]]

only change to test_converted.py was replacing the 3 losses with one when compiling.

model.summary() looks reasonable around that area.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants