jasonlovescoding / YOLOv3-caffe

A YOLOv3 model in caffe
MIT License
42 stars 51 forks source link

how to transform yolov3 model to caffemodel #1

Open vvmex opened 6 years ago

vvmex commented 6 years ago

I have tested your yolov3 caffemodel successfully by modifying your detecting code a little. Change the type int into float, as fllows: new_w = int(img_w min(w 1.0 /img_w, h 1.0 /img_h)) new_h = int(img_h min(w 1.0 /img_w, h 1.0 /img_h)) ...... scaling_factor = min(1, float(args.resolution) / img_ori.shape[1])

Is there the python code that could transform yolov3 model to caffemodel? Thanks very much

jasonlovescoding commented 6 years ago

@vvmex Thanks for the info. The type issue may have something to do with the version of opencv (I also walked into it once in a python2 environment). The transformation was based on a project I developed during my internship, which I unfortunately cannot make public due to commercial rules. (This model was transformed as a test case to validate its correctness.) There are some open-source transform projects on github, if you need to try some :) good luck!

jasonlovescoding commented 6 years ago

feel free to ask if you need to know anything else :)

vvmex commented 6 years ago

Understand. Thanks for your advision. I will try it.

claudehang commented 6 years ago

Hi, I run the code and come across the errors as:

I0702 15:58:34.753731 17011 layer_factory.hpp:77] Creating layer Interp202 F0702 15:58:34.753783 17011 layer_factory.hpp:81] Check failed: registry.count(type) == 1 (0 vs. 1) Unknown layer type: Python (known types: AbsVal, Accuracy, ArgMax, BNLL, BatchNorm, BatchReindex, Bias, Concat, ContrastiveLoss, Convolution, Crop, Data, Deconvolution, Dropout, DummyData, ELU, Eltwise, Embed, EuclideanLoss, Exp, Filter, Flatten, HDF5Data, HDF5Output, HingeLoss, Im2col, ImageData, InfogainLoss, InnerProduct, Input, LRN, LSTM, LSTMUnit, Log, MVN, MemoryData, MultinomialLogisticLoss, PReLU, Parameter, Pooling, Power, RNN, ReLU, Reduction, Reshape, SPP, Scale, Sigmoid, SigmoidCrossEntropyLoss, Silence, Slice, Softmax, SoftmaxWithLoss, Split, Swish, TanH, Threshold, Tile, WindowData) Check failure stack trace: Aborted

I made no modification except as suggested by vvmex in the first post. Where might be wrong? Thx!

jasonlovescoding commented 6 years ago

Hi @claudehang Have you uncommented # WITH_PYTHON_LAYER := 1 before compiling caffe?

claudehang commented 6 years ago

Brilliant Bro!! It works amazingly!

claudehang commented 6 years ago

Another question. Where in Caffe can I see the source code of the implementation of UpsamplingBilinear2d Layer? Interested in this layer in your prototxt: layer { name: "Interp202" type: "Python" bottom: "688" top: "689" python_param {

the module name -- usually the filename -- that needs to be in $PYTHONPATH

module: 'interp'
# the layer name -- the class name in the module
layer: 'UpsamplingBilinear2d'
# the zoom factor
param_str: '{"zoom_factor":2}'

} } Could you give me some advice? Many thanks!!

jasonlovescoding commented 6 years ago

@claudehang In the offical BVLC caffe there is no interp layer corresponding to UpsamplingBilinear2d in pytorch. That's why I implemented it in interp.py within this project. There are some caffe forks that include interp layer though, such as deeplab caffe. You can look over its src/caffe/layers/interp_layer.cpp to see the logic, which is slightly different from pytorch as I pointed out in README

vvmex commented 6 years ago

@jasonlovescoding I have read your interp.py. You added a upsample layer by yourself with method of cv2.INTER_LINEAR. Actually , your upsample layer is not the same with darknet upsample layer which use the method of nearby value?

jasonlovescoding commented 6 years ago

@vvmex You're right! I've pushed some updates and fixed it.

claudehang commented 6 years ago

@jasonlovescoding Hi, another thing I want to consult you. In interp.py, the last line of def setup(self, bottom, top) function:

top[0].reshape(n_out, c_out, self.w_out, self.h_out)

is supposed to be called once at initialization. Any difference if instead this reshape operation is implemented in def reshape(...) function, which you now simply implement as pass? Many thanks!

jasonlovescoding commented 6 years ago

@claudehang Hi, reshape method is supposed to be called for every forward prop, which is unnecessary in this case since the output shape remains the same. Therefore it could be run once-for-all in the init method.

claudehang commented 6 years ago

@jasonlovescoding Thanks again and admire you much dude! @vvmex I have quite similar problem as you. However, in my case I go with this C++ repo: https://github.com/ChenYingpeng/caffe-yolov3 which contains the afterward process to get final actual loc and prob. I strongly recommend you have a try. Hopefully you get what you expect. If not, come back to our discussion here and we'd work out together!

jasonlovescoding commented 6 years ago

@claudehang You're welcome, dude. And thanks for your clarification!

shreyas0906 commented 6 years ago

Hey Jason,

Nice work on the scripts. However, I downloaded the models from https://github.com/ChenYingpeng/caffe-yolov3 and ran detect_one.py. I am not able to view any detection on the image. Can you please let me know the correct procedure to run your code? I am very new to Caffe.

Again, Nice work on the scripts.

jasonlovescoding commented 6 years ago

Hi @shreyas0906 Thanks! My guess is that the output blob name from its prototxt is not adapted to this project. Try modifying the three outputs into 'out0', 'out1' and 'out2' (ordered from small scale branch to large) and see if it works. There is a good website to visualize the network: http://ethereon.github.io/netscope/#/editor You will see the output names are now 'layer94-conv' and so on.

shreyas0906 commented 6 years ago

Hey @jasonlovescoding

I am very new to caffe and honestly did not understand how to solve the issue. Can you please shed some light on how to run your code. I could not find a better implementation of yolov3 out there.

Thanks

jasonlovescoding commented 6 years ago

@shreyas0906 Hi, take a look at 'rect_prepare' function of utils.py in this project. You will see that the three output blobs' names are assumed as 'out0', 'out1' and 'out2'. In the model you downloaded, the output blobs' names are set as 'layer82-conv', 'layer94-conv' and 'layer106-conv'. So the quick solution is to either change 'rect_prepare' to take these three names, or change the prototxt file to modify these three names into 'out0' 'out1' and 'out2'. As an aside, you can paste the content of 'yolov3.prototxt' from that model in baidu link to http://ethereon.github.io/netscope/#/editor and press shift+enter to visualize the network. You will see the three output layers in purple, and then free to check their output names.

PiyalGeorge commented 5 years ago

@jasonlovescoding , Awesome Bro!!! Its great to see you putting your efforts to help people.

buptlj commented 5 years ago

I converted my own model from darknet to caffe successfully(I add the upsample layer and re-compiled caffe). I tested the original darknet model and the converted caffe model following https://github.com/ChenYingpeng/caffe-yolov3, the results are the same. Then I tested the converted caffe model with detect_one.py, the detected boxes are not correct, they are smaller. I haven't found the reason. .

jasonlovescoding commented 5 years ago

@buptlj could you kindly share some examples in the thread?

buptlj commented 5 years ago

this is the darknet result: image this is the result of https://github.com/ChenYingpeng/caffe-yolov3 image the result of detect_one.py: image The whole image is too big, so i cut part of it.All the detected boxes are smaller.

jasonlovescoding commented 5 years ago

@buptlj It seems that ChenYingpeng/caffe-yolov3 repository is not accessible at this time, but what you observed is true - my guess is that there is some precision loss during the conversion of the model. If you are unhappy about the smaller boxes, you could try adding a margin.