-
Notifications
You must be signed in to change notification settings - Fork 877
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
CoreML conversion fails due to Lambda layer #80
Comments
So, this seems like a hack (not a real solution), but since it solved my problem I'll post it and close the issue. Out of the full yolo v2 configuration documented here: If you simply delete the reorg section it seems to work. Not sure what damage this does to the algorithm, but the model I recently trained was really accurate so it can't be that bad. |
Hi @seantempesta , I'm facing the exact same problem. When you say "delete the reorg section", I first naively tried to delete the [reorg] section in the yolo.cfg file. But then, of course there is a size mismatch between layers. Can you please point me toward a list of steps to remove the reorg layer ? |
Actually, it looks like I did delete more than just the reorg section:
So the route layers above and below it too? Keep in mind I have no idea what I'm doing and this could potentially be bad, but I got a working model that seemed pretty accurate. |
Also, in case you decide the Full Yolo V2 model is too slow and want to use the Tiny model, you need to train using the Tiny weights. I found quite a bit of misinformation on this (other guides saying to use Instead I trained with the And then this tutorial is amazing: I pretty much had to do everything exactly as he did (including using his modified version of YAD2K) to get the model to convert to Keras and then to CoreML. |
Thanks for your quick answer! I don't necessarily need the speed of tiny YOLO for my case, so I can stay with the full YOLO v2 for accuracy. I have few questions about your modifications: 1/ when you say "pretty accurate", did you run the model over the COCO dataset and check the exact value of mAP ? Or do you mean it predicts something "reasonable"? |
If you want to reuse the existing Yolo 2 network and weights without retraining, another option that I just got working, but is a bit involved, is roughly:
That last part is the tricky part and will take some experimenting and re-running your coreml conversion script. https://apple.github.io/coremltools/generated/coremltools.models.neural_network.html |
@ldocao: Regarding your questions:
I trained it for a new object class and found it to work well for my application. I believe it had a 99% Recall rate and an IOU=88%.
The config I'm using was based on
Yeah, I probably didn't do this right. Just reporting what worked for me. |
@pchensoftware Hi Peter, |
@pcmanik Did you eventually manage to solve the issue? |
@eirikhollis No progress here. Waiting for response from @pchensoftware |
A quick and dirty solution can be applied directly on the cfg file to remove the reorg layer. The reorg layer in the keras_yolo.py code uses the space_to_depth function of tensorflow. It moves extra data in height and width into the depth. It reduces the height and width dimensions without lossing information. In the cfg file, the part to modify is the following:
It resizes the convolutional layer just above in the code with the space_to_depth function (from 38x38x64 to 19x19x256) and concatenates it with a previous convolutional layer (19x19x1024) to produce an output of size 19x19x1280. It is possible to replace these 4 lines of code with:
It will transform the output of the convolutional layer (38x38x64) into a smaller one (19x19x64). This output is duplicated 4 times and they are concatenated to match the correct shape (19x19x256). Thus the final route concatenates the stacked features maps with the previous convolutional layer to produce an output with the correct shape (19x19x1280). If you don't match the correct shapes, the trained weights won't be at the corresponding layers and it will produce wrong results. Using the specific postprocessing presented here with a classification confidence threshold of 0.3 and an IoU threshold of 0.4, the results are not as good as before but they look correct over the images. Using the 2017 COCO validation dataset and the Python COCO API to compute the mAP scores, we obtain the following results before removing the reorg layer: The results after the quick and dirty solution: Few points are lost because we should not use duplicates of the maxpooling layer, it needs to be the entire 38x38x64 layer but reshaped as 19x19x256. A longer solution is to construct the entire graph in Tensorflow (or another framework) with a reshape tensor at the needed place (between batch_normalization_20 and conv2d_22). Then you load the weights to perfectly match the graph and you export it as a protobuf file. Finally you convert the protobuf file as a keras model to convert it into a CoreML model. |
Thank you @ArthurOuaknine I have succesfully converted YOLO to Keras with your instructions. Am I doing anything wrong? Here is the code for converting the model. |
I had the same problem than you @pcmanik.
CoreML doesn't allow to have the same name for multiple inputs. I think that the converter understand that there is a single input. |
@ArthurOuaknine Thank you. You did an amazing job there. Finally after your edit I get it working. The resulting CoreML model is working and its big improvement over the TinyYOLO so your "quick and dirty solution" is really good. My really big thanks to you! :) |
@ArthurOuaknine Much appreciation from me as well. Finally got it to work! |
I'm a programmer but a newb at ML, so after seeing how inaccurate TinyYOLO was on a phone I wanted to find a pre-made YOLOv2 .mlmodel >.< Has anyone put their resulting .mlmodel of their YOLOv2 anywhere that is accessible? |
@keless Write me email. |
Just contact me on mail I will send you the .mlmodel. |
In general @pchensoftware described everything correctly, but I would make a bit more detailed explanation for those who want to convert the network theirselves. I made it all on Linux, maybe there are some corrections needed for mac or windows. There are a lot of dirty hacks. I assume you want it to just Darknet to KerasSo you have trained a full yolo and want to run it on coreml. First, convert it to Keras format using
The name If you trained your own network it's possible that it has slightly different header format for the In the end it writes Replace In my case as you can see the numbers equal and nothing has to be done. In the end you should have your
In the Keras to CoreMlFirst of all get the source of coremltools, you will need to patch it. Create a file convert.py in the directory where you cloned the source with this content:
This is needed just to run the conversion. Maybe there is some other way, who knows. So finally, you will run all of this with this command:
The But before you can run it first let's correct something. First of all coremltools are available only for python2. If you know how to run it with python3 don't do what I describe in the Patching Keras chapter, for me it was easier to kludge the code so it just works. Patching CoremltoolsMake a virtualenv Activate it Install some libs
Then patch the main code. Here is the diff:
Patching KerasDon't do it if you have coremltools running in python3, only if you have out of box version with python 2. You also need to patch the Keras code a bit. Edit
and instead of put
It's possible that len is different in your case, maybe not, remember this is a very dirty hack that works only on one PC. In general this code is executed twice and for the first time you have to pass Enjoy!
After that I can run my full YOLO on iphone. |
@ArthurOuaknine I tried your solution and have a keras .h5 model. However, when I try to convert it to coreml I get the following error:
Do I have to add a custom layer? How do I avoid this problem? |
@tkreiman I am sorry but I never had this error. Obviously CoreML doesn't support the Merge layer, so you have to modify the structure of your model to only have supported layers. I think you should replace the Merge layer with a Concatenate layer. |
@ArthurOuaknine OK, I replaced the merge layer with Concatenate and it works now, thanks. |
I'm trying to convert a Darknet Yolo v2 model to Keras and then to CoreML using Apple's
coremltools
:https://github.com/apple/coremltools/
This procedure apparently used to work according to this tutorial:
https://github.com/hollance/YOLO-CoreML-MPSNNGraph
I'm kind of a noob, but from what I understand Lambda layers just allow you to run arbitrary code (which is unsurprisingly not supported by Apple's API). It looks like this is where this is happening:
yad2k.py
Is there a way to do
space_to_depth
with thekeras
API so the conversion is supported? I'm really out of my depth (pun intended) here and don't really understand what's going on. Any help would be appreciated. :)The text was updated successfully, but these errors were encountered: