基于PyQt5的SSD目标检测软件(三)
续上节。。。。
2. 训练部分
2.1 真实框得处理
预测部分实际上是没有计算loss的向前传播,主要是通过模型进行预测结果,而训练过程主要通过反向传播来修正权重减小整体的成本loss和精度loss从而使模型更加准确。
在预测部分,每个特征层的预测结果,num_priors x 4 的卷积 用于预测 该特征层上 每一个网格点上 每一个先验框 的 微调 情况(bounding box regression(边界框回归 在训练中 微调边界框大小匹配真实框))。
所以说,我们直接利用SSD网络预测到的结果只是直接匹配相同类别所得到的原来初始化先验框的结果,而我们需要的是进行bounding box regression 回归后 调整过的准确预测框的位置。
而在训练的时候,我们需要计算loss(分类loss和边界框回归loss(IOU))函数,这个loss函数是相对于ssd网络的预测结果的。我们需要把图片输入到当前的ssd网络中,得到预测结果;同时还需要把真实框的信息,进行编码,这个编码是把真实框的位置信息格式转化为ssd预测结果的格式信息。
我们需要找到 每一张用于训练的图片的每一个真实框对应的先验框,并通过 回归预测的方法 让模型学会如何调整预测生成的先验框才能得到真实框对应的先验框。
从预测结果获得真实框的过程被称作解码,而从真实框获得预测结果的过程就是编码的过程。
因此我们只需要将解码过程逆过来就是编码过程了。
代码实现:
1 | def encode(matched, priors, variances): |
训练时选取 IOU最大的框 做为 预测生成的先验框。
因此我们还要经过一次筛选,将上述代码获得的真实框对应的所有的iou较大先验框的预测结果中,iou最大的那个筛选出来。
代码实现:
1 | def match(threshold, truths, priors, variances, labels, loc_t, conf_t, idx): |
2.2 利用处理完的真实框与对应图片的预测结果计算loss
loss的计算分为三个部分:
1、获取所有正标签的框的预测结果的回归loss。
2、获取所有正标签的种类的预测结果的交叉熵loss。
3、获取一定负标签的种类的预测结果的交叉熵loss。
由于在ssd的训练过程中,正负样本极其不平衡,即 存在对应真实框的先验框可能只有十来个,但是不存在对应真实框的负样本却有几千个,这就会导致负样本的loss值极大,因此我们可以考虑减少负样本的选取,对于ssd的训练来讲,常见的情况是取三倍正样本数量的负样本用于训练。这个三倍呢,也可以修改,调整成自己喜欢的数字。
代码实现:
1 | class MultiBoxLoss(nn.Module): |
四、数据集准备
本项目采用得是VOC数据集格式具体存放在 VOCdevkit
文件夹下,其中voc2ssd.py
为综合VOCdevkit/VOC2007/JPEGImages
文件夹下图像文件及VOCdevkit/VOC2007/Annotations
下标签文件生成索引文件并存放与VOCdevkit/VOC2007/ImageSets/Main
的txt文件中分别为训练集/测试集/验证集的索引,而uitils/voc_annotation.py
为生成索引绝对路径在2007_test.txt/2007_train.txt/2007_val.txt
中
对图像生成标签文件的软件使用labelimg进行目标检测数据集标注,labelimg是基于pyqt的一个软件,使用很方便,用以下命令即可安装:
1 | pip install labelimg |
运行直接在shell内运行命令:
1 | labelimg |