yolo v2记录

  这里主要从输入数据增量、新增层和检测层的处理三个方面来说下v2版本,文中使用的参数和数值为代码中默认值并以voc数据集为例来说明的。

一.输入数据处理

  V2版本处理具有前一个版本对数据增量处理方式外,还新增了对输入图像的色度、饱和度、曝光的处理,这三个分量都采用了和jitter类似的手段:产生一个指定范围的随机数,调整输入图像作为传播使用的数据。

  对truth的使用上相对v1发生了变化,一张图片最大能容纳30个目标(这30个目标是预定的,可以修改),超过30个的目标舍去,每个目标以(x,y,w,h,id)为顺序存储。每张图片对应的输出outpunum为5*30 = 150个。

二.新增层的处理

route layer

  它主要是将指定的某一层(当然指定的那一层在它之前)输出数据作为输入,copy过来,再做为输出使用,指定的层由layers参数确定,将不同大小的特征图连接到一块。其实这个操作在caffe里都不能算一层,只需要指针指向一下就可以了。这里主要说下copy的顺序,Layers参数可以有多个,即将多个层的数据拷贝过来做为输出。将每个batch中的各个层数据一次copy到output,即拷贝后的结果为:

       L1 L2…Ln, L1 L2…Ln, …, L1 L2…Ln

       batch1,    batch2,   …  batchm

reorg layer

       该层不是必须跟在route layer之后,它是否需要存在要看上面一层特征的大小是否需要变化,在voc的例子中,由于需要将26层的26*26*512的特征图转化成13*13*2048,使用stride为2的reorg layer。

  该层将512个通道分成了4部分,分别遍历了所有数据,结合reorg_cpu的代码来看

  第1部分 k∈(0-127),横向从0开始取偶数位w=26个,纵向间隔stride*w*stride(4行),则通道间隔为h*stride*w*stride(从这里可以看出通道变化范围必须为原来的1/4)

  第2部分 k∈(128-255),横向从1开始取奇数位w=26个,之后同上(c2与上一样但offset变化为从1开始,而h2起始值没变)

  第3部分 k∈(256-383),横向从52开始取偶数位w=26个(h2起始位1,则out_index起始位52,之后与1部分相同)

  第4部分 k∈(384-511)横向从53开始取奇数位w=26个(h2起始为1,w2起始为1,则out_index起始为53,后续规律相同)

  如此每部分循环取从头开始紧邻4行的1/4,恰好取完.

三.检测层的处理

  网络最后的输出,它没有像v1那样使用全连接的方法,而是使用1*1的卷积生成125个通道,输出尺寸为w*h*c = 13*13*125,即将每张图片划分为13*13个网格,每个网格预测5个目标,每个目标包含三个部分,依次为:目标位置4个点、包含目标置信度1个点、目标类别置信度20个点,总共25个点。为了更加方便的以偏移取数据,使用flatten方法将最后的网络输出做转置处理,这样网络变成了125*13*13,每次取数据都可以按各个网络的5个预测目标依次处理。也可以将flatten理解成将输出的三维矩阵压扁成125*169的二维矩阵,对之后的取数据来讲,是等效的。

  这个很好理解,按照作者的思路,如果不使用flatten,按顺序取数据(目标位置、置信度、坐标)为13行的每一行的列中分别取出,不符合上面的要求,转置后,变成了13*13的每个位置上取5组可能的预测信息。

  对于是否包含目标的置信度,输出取logistic激活,是为了将输出压缩到0-1之间,用于后续计算误差(有无目标)。

  对于目标类别置信度,仍然采用了softmax方法处理。然后就是计算回归的位置误差敏感项,根据误差求导生成。

  这里还要说下在使用v2版本的时候遇到的一个多gpu下训练不收敛的问题,或者出现nan,或者训练的时候收敛,但是是否有目标的置信度逐渐减小,直至为0,这样预测的目标置信度就都是0了。我是用的是tiny-yolo.cfg的配置,经过排查和各种尝试,发现刚开始训练时学习速率太大,在steps为-1,100,80000,100000的分段调整速率的划分中,使用小速率多学习一段时间,即可解决这个问题,比如改为-1,1000,80000,100000.分享出来,避免大家遇到相同的问题而纠结很久。

posted @ 2017-12-01 00:07  ILYISL  阅读(1556)  评论(0编辑  收藏  举报