https://blog.csdn.net/watermelon1123/article/details/82083522
下面这部分将着重讲一下如何实现从darknet向yolov3的转换,首先这一过程要感谢chenyingpeng提供的代码,博客在这里。
1.加入upsample层并编译Caffe
upsample层的代码在这里,密码bwrd。
其中的upsample_layer.hpp放入include/caffe/layers下面;upsample_layer.cpp与upsample_layer.cu放在src/caffe/layers下面。
修改相应的caffe.proto文件,src/caffe/proto/caffe.proto中的LayerParameter的最后一行加入加入:
message LayerParameter {
.....
optional UpsampleParameter upsample_param = 149;
}
注意149为新层的ID号,该ID号请根据个人的caffe.proto文件指定即可。
然后再caffe.proto中添加upsample层的参数:
message UpsampleParameter{
optional int32 scale = 1 [default = 1];
}
紧接着重新编译Caffe,这样就完成了在Caffe中添加upsample层。更多信息请参考caffe中添加新层教程。
上面说过转换到Caffe后只包含推理过程,因此我们需要将训练好的模型(.cfg)和权重文件(.weights)转换到对应Caffe下的.proto和.caffemodel,代码可以借鉴github上的模型转换工具。注意该工具需要pytorch支持请自行安装。且该工具应用于Yolov2,因为我们在Caffe中加入了相应的upsample层并且yolov3和v2的网络结构有变化,因此需要替换相应的darknet2caffe.py,代码在这里,密码:i6y2。
至此我们的准备工作就结束了,这样通过Caffe我们就能得到相应的blobs,这些blobs里包含的信息和darknet输入给yolo层的信息是一样的。我们只需要通过yolo layer将blobs的信息进行解析就能够得到目标的位置和类别信息。因为私人原因,这部分代码不能开放,但是可以参考chenyingpeng的代码,在这里。经测试是同样可用的,只需要注意因为我们的yolo layer的检测过程是在Caffe外部实现的,因此yolo layer层的相应信息作者以硬编码的形式加入到代码中,使用的时候需要根据个人yolo layer的参数进行修改(比如我测试的时候yolo_layer.cpp中的函数get_detections中的类别数目没有修改就发生了难以言表的结果...)。
yolov3从darknet转Caffe的整个过程就结束了,其中关于yolov3的原理并没有详细解释特别多,本文主要着重于和转到Caffe框架相关的内容,具体yolov3的原理性文章推荐大家看这篇,里面关于yolov1~v3讲解的很详细(来自一群还在上大一的学生的论文解读,不禁让人感叹长江后浪推前浪,前浪我已GG)。关于yolov3的训练代码,推荐大家去看darknet的源码,尤其是关于Yolo layer的代码,里面有许多作者文章里没有讲清楚的内容,感兴趣的可以仔细钻研一下。
yolov3的caffe使用
1)转成caffe模型
前提:刚刚训练得到了相应的weights,准备好yolo需要的layer--upsample_layer.cpp,upsample_layer.cu,upsample_layer.h
参考:https://blog.csdn.net/watermelon1123/article/details/82083522
将新的layer添加进去,完成caffe的准备工作。然后还要安装好pytorch。
clone 转换工具:
git clone https://github.com/marvis/pytorch-caffe-darknet-convert
开始转换:最后会得到 yolov3.prototxt yolov3.caffemodel
python2.7 darknet2caffe.py cfg/yolov3-voc.cfg yolov3-voc.weights yolov3.prototxt yolov3.caffemodel
将yolov3-voc.weights放在文件夹下
然后将yolov3-voc.cfg放在./cfg文件夹下面
yolov3.prototxt yolov3.caffemodel是要生成的caffe模型和pro文件命名
2)使用caffe模型:
clone使用工具:
git clone https://github.com/ChenYingpeng/caffe-yolov3
cd caffe-yolov3
将生成的caffemodel和prototxt放在./caffemodel和./prototxt文件下【没有就建一个】
修改cmakelist.txt
"""全部都要改成自己的caffe路径"""
# build C/C++ interface
include_directories(${PROJECT_INCLUDE_DIR} ${GIE_PATH}/include)
include_directories(${PROJECT_INCLUDE_DIR}
/home/ubuntu247/liliang/caffe-ssd/include
/home/ubuntu247/liliang/caffe-ssd/build/include
)
file(GLOB inferenceSources *.cpp *.cu )
file(GLOB inferenceIncludes *.h )
cuda_add_library(yolov3-plugin SHARED ${inferenceSources})
target_link_libraries(yolov3-plugin
/home/ubuntu247/liliang/caffe-ssd/build/lib/libcaffe.so
/usr/lib/x86_64-linux-gnu/libglog.so
/usr/lib/x86_64-linux-gnu/libgflags.so.2
/usr/lib/x86_64-linux-gnu/libboost_system.so
/usr/lib/x86_64-linux-gnu/libGLEW.so.1.13
)
如果你在训练中使用的是自己的anchors值,要修改anchors的值(yolo.cpp中),再进行编译;还有yolo.h中的classes数
/*
* Company: Synthesis
* Author: Chen
* Date: 2018/06/04
*/
#include "yolo_layer.h"
#include "blas.h"
#include "cuda.h"
#include "activations.h"
#include "box.h"
#include
#include
//yolov3
//float biases[18] = {10,13,16,30,33,23,30,61,62,45,59,119,116,90,156,198,373,326};
float biases[18] = {7, 15, 16, 18, 22, 32, 9, 40, 20, 71, 37, 39, 52, 65, 70, 110, 105, 208};
/*
* Company: Synthesis
* Author: Chen
* Date: 2018/06/04
*/
#ifndef __YOLO_LAYER_H_
#define __YOLO_LAYER_H_
#include
#include
#include
using namespace caffe;
const int classes = 3;
const float thresh = 0.5;
const float hier_thresh = 0.5;
const float nms_thresh = 0.5;
const int num_bboxes = 3;
const int relative = 1;
编译
mkdir build
cd build
cmake ..
make -j12
运行:
./x86_64/bin/detectnet ../prototxt/yolov3.prototxt ../caffemodel/yolov3.caffemodel ../images/dog.jpg