之前基于yoloV2做过一段时间的物体检测,当时对yoloV2整个框架了如指掌。由于没有及时写笔记记录一下,现在回过头来很多东西都快忘光了。本篇博客不会记录如何使用darknet训练yoloV2,而更注重的的是整个yoloV2的算法,以及其中的一些细节。废话不多说,我们直接开始。
##物体检测训练主函数
yoloV2的训练函数主函数在examples/detector.c中的train_detector函数,这里就不贴代码了,太长了。我们主要看看整体的流程。
函数一开始为初始化网络,或者导入预训练参数,以及其他设置,如gpu,以及根据使用的gpu个数设置学习率。
接着就开始训练,具体的:
1、确定网络输入大小
yoloV2的训练过程有一个很重要的点,那就是多尺度图像训练。我们都知道yoloV2的输入图片大小是416416,但是在训练的时候并不是一直使用416416的图片进行训练,而是每隔一段时间就改变输入图像的大小,其策略为:
int dim = (rand() % 10 + 10) * 32;
if (get_current_batch(net)+200 > net.max_batches) dim = 608;//最后200批次训练都只用输入大小为608*608
2、训练样本读取
代码在src/data.c中的load_data_detection函数中。
yoloV2在读取样本的时候对数据进行了扩充,分别有随机抖动,镜像和亮度、饱和度、曝光度的调整。其中随机抖动和镜像需要对box也进行相应的调整。
3、训练
根据使用的gpu个数进行训练,调用的是train_networks函数。
如果gpu个数大于1,那么每隔100个训练批次就进行参数合并。
##region_layer
yoloV2的训练过程除了多尺度图片训练方式,以及数据扩充方式,另一个重点是最后的检测层region_layer。相应的代码在src/region_layrer.c中的forward_region_layer函数里面。
假设网络的输出是416416,那么yoloV2的输出是尺寸是1313;类别数为80,候选框的个数为5,那么通道数为(1+4+80)*5=425。每个候选框占85个通道,即第0到84通道属于第一个候选框,第85到169通道属于第二个候选框,以此类推。然后在每85个通道里面,存放顺序为:bbox(占4个通道)、是否