我从零搭建自己的目标检测网络而不用现在流行的网络(YOLO,RCNN,SSD等)有以下几个原因:
- 看不懂源码,就算看懂了也不能保证自己注意到了所有的细节
- 我要完成的任务是识别任何我想识别的物体,换句话说就是没有公开的数据集(这说白了还是因为我没搞懂YOLO网络在训练方面的一些细节)
- 流行的网络都是针对的正方形或指定比例的图像分辨率输入,而我要用摄像头,分辨率固定,不需要resize,而且分辨率较高,想给每个网格分配更高的分辨率
- YOLO完全可以根据实际需求进行大量裁剪
- 自己从零开始设计更能加深理解
这些原因让我最终决定不如自己设计一个网络。我将按照YOLO系列的设计思想去搭建,使用自己的数据集训练,代码基于pytorch。
代码仓库
第一版 https://gitee.com/xd15zhn/SimpleNet
第二版 https://gitee.com/xd15zhn/ZhnNet
详情及权重加QQ 1076214993 或QQ群 1026512757 或微信 zhn1076214993
注:因为要识别任意物体,就要能够做到从零开始训练,所以权重文件不重要。我提供的权重文件是识别我自己的人脸(别人的没试过),第二版大小约4.3MB。如果有需要的话建议还是加一下群,群文件里有各个版本的代码,可以大致看出我如何从零开始的过程。也可以讨论相关技术问题。
简要介绍
因为是参考了YOLO,所以我的网络就是对YOLO的各种简化,比如:YOLO要检测多个类别,我只检测一个;YOLO使用了多个先验框,我只用一个;YOLO使用了多个特征层,我也只用一个(以后可能会加到3个);YOLO输出多个网格(grid),我只输出一个(特指第一版)。看这篇文章前建议先对YOLO有个大概的了解即可,后面我会对YOLO为什么进行某项设计的部分原因进行介绍。训练网络的大致思路是,在搭建网络的过程中分成两路,一路预测概率(也就是二分类),一路进行边界框回归。
第一版的主干网络使用resnet18,没有修改结构,把摄像头输入的图像resize成224x224,最终输出是7x7(每个网格的分辨率是32x32),然后分成两路。使用resnet可以加载预训练权重,这里提一下我虽然没有修改结构但我重写了代码,加载官方的预训练权重会出问题,将不匹配的地方依次修改即可。详见pytorch加载预训练模型与自己模型不匹配的解决方法。
第二版基于shufflenetV2网络进行修改,我使用的摄像头分辨率是640x480,由于我的任务中要识别的物体较大,所以我猜测使用更大的网格分辨率会更好(欢迎大佬对这一想法提出质疑),出于设计卷积核的考虑,我把输入图像的分辨率填充至640x512,以白色填充(因为墙是白色),输出为4x5,这样每个网格的分辨率是128x128。
系列文章目录
从零搭建自己的目标检测网络教程(一)网络结构
从零搭建自己的目标检测网络教程(二)边界框回归
从零搭建自己的目标检测网络教程(三)数据集处理
从零搭建自己的目标检测网络教程(四)损失函数
从零搭建自己的目标检测网络教程(五)训练
程序的运行
第一版程序中将分类和定位的训练分成两部分文件,第二版中将两部分合并,但原理都是:先训练分类部分,使特征提取主干网络能够提取到特征,再冻结主干网络的参数,使用定位数据集训练定位网络。这样做的原因很简单,就是自己拍摄得到的数据集必然很少,只能采用特殊的训练方法。
最后给大家打气的部分
经过这一设计网络的过程我感受到了神经网络惊人的拟合能力,只要遵循大概的设计模式使用大概的训练方法和超参数大概的训练一下就可以大概实现一个还算不错的结果(单隐层前馈网络求最小值就是我典型的一次随便尝试),如果想要进一步提高精度和速度才需要考虑那些流行的网络,也就是说人人都可以搭建自己的网络,只不过质量差一点而已。