声明:本文使用的YOLOv3来自github中的AlexeyAB大神的代码。
系统环境:ubuntu18.04,GTX1660ti
github上有完整的实现步骤,博主只是记录一下。
准备好自定义的训练集/验证集/测试集,本文按照PASCAL VOC(COCO也可以)数据集格式进行存储数据,VOC格式如何存储百度一下即可。参考:制作自己的数据集
git clone https://github.com/AlexeyAB/darknet
打开终端运行上面代码,下载到本地(如果网络不好下载太慢,可以上传到码云然后git clone 码云链接)
cd darknet
切换到darknet(目录名)目录中,输入make进行编译
注意:在make之前,找到makefile文件,我们可以设置一些功能,根据自己的需求设置,GPU/CUDNN/OPENCV是必要的
编译完成后运行./build.sh
,用于查找已安装的可依赖项,例如:CUDA、cudnn、zed sdk等。(提提前安装好cmake)
超参数可以不用修改,分辨率可以提高一点,首次训练可以将max_batches调小一点,等跑通之后再调高。这里的subivisions表示将每个batch再分成32份然后输入到网络中进行训练。如果运行程序报错:out of mermory 内存溢出,则尝试将sub调大一点。
图中的anchors表示锚框尺寸,我们可以在自己的数据集上进行聚类,为了使锚框尺寸更适合我们的数据。
./darknet detector calc_anchors data/obj.data -num_of_clusters 9-width 512 -height 512
运行上面代码即可得到聚类结果,如果想要更高分辨率的聚类效果,修改width和height即可,一定要是32的整数倍。
在data目录下创建obj.data文件和obj.name文件
在obj.name中添加类名,例如:
dragon fruit
在obj.data中:
classes= 1
train = data/train.txt
valid = data/test.txt
names = data/obj.names
backup = backup/
classes取决于你的类别数量,train和vaild表示你的数据路径,.txt是之前创建数据集时生成好的,backup表示训练时的权重保存路径。
训练之前下载预训练权重darknet53.conv.74, 点击下载,提取码:ik6e
修改好cfg文件后,我们用以下代码进行训练
./darknet detector train data/obj.data cfg/yolov3.cfg darknet53.conv.74
如果想实时观察训练的情况(损失值和精度值),运行以下代码
./darknet detector train data/obj.data cfg/yolov3.cfg darknet53.conv.74 -map
训练时保存训练日志,运行以下代码
./darknet detector train data/obj.data cfg/yolov3.cfg darknet53.conv.74 >log.txt -map
完成训练后,我们可以用测试集进行测试,加载训练好的权重,运行以下代码。
./darknet detector test data/obj.data cfg/yolov3.cfg backup/yolov3_5000.weights data/fruit.jpg
确保data文件中有需要测试的图片
计算AP值,查看我们模型的训练效果,运行以下代码
./darknet detector map data/obj.data cfg/yolov3.cfg backup/yolov3_5000.weights
博主正好在用ZED相机,所以拿训练好的模型跑了一下,运行以下代码即可(要提前安装好ZED sdk,将makefile中的ZED_CAMERA设置为1,并在darknet目录下cmake)。
其他摄像头也可以实现,建议参考github中的教程。
LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH ./uselib data/obj.names cfg/yolov3.cfg backup/yolov3_5000.weights zed_camera
运行结果:
检测到目标后,可以直接实现对目标的定位,xyz坐标是以相机左目为原点建立的坐标系,深度值由相机计算得出,检测速度40fps左右,定位精度有待验证。
博主只是记录一下自己的实现过程,写的比较粗糙,想要训练自己数据集的同学,建议参考github中的教程