实现MobileNet-SSD网络并进行优化

主要目的:在移动端运行目标识别算法

选用网络mobilenet

选用平台 caffe

思路 选用github已有项目优化(优化方式主要参考网上博客和论文)

  1. 下载https://github.com/chuanqi305/MobileNet-SSD,git clonecaffe下的examples下;
  2. MobileNet-SSD项目内容简介:template 存放4个网络定义的公用模板,可以由gen.py脚本修改并生成;MobileNetSSD_deploy.prototxt 运行网络定义文件;solver_train.prototxt 网络训练超参数定义文件;solver_test.prototxt 网络测试超参数定义文件;train.sh 网络训练脚本;test.sh 网络测试脚本;gen_model.sh 生成自定义网络脚本(调用template文件夹内容);gen.py 生成公用模板脚本(暂不用);demo.py 实际检测脚本(图片存于images文件夹);merge_bn.py 合并bn层脚本,用于生成最终的caffemodel
  3. 用lableimg标记样本制作自己的VOC数据集(详细步骤见https://blog.csdn.net/liu_xiao_cheng/article/details/78563632
  4. 模型分析:通过分析Mobilenet的模型结构MobileNet-SSD的模型结构, 可以看出,conv13是骨干网络的最后一层,作者仿照VGG-SSD的结构,在Mobilenet的conv13后面添加了8个卷积层,然后总共抽取6层用作检测。
  5. 先修改demo.py中的变量路径,测试一下环境,
    caffe_root = '/home/system/caffe/caffe-master/'
    net_file= 'example/MobileNetSSD_deploy.prototxt'
    caffe_model='example/MobileNetSSD_deploy.caffemodel' 
    test_dir = "images"
    如果Linux环境没有配置支持opencv显示图像就把imshow相关的函数注释掉,把图片保存到指定文件夹
  6. 进入MobileNet-SSD目录,执行以下命令建立数据的软连接
    ln ‐s /home/its/data/KITTIdevkit/KITTI/lmdb/KITTI_trainval_lmdb trainval_lmdb
    ln ‐s /home/its/data/KITTIdevkit/KITTI/lmdb/KITTI_test_lmdb test_lmdb
  7. 修改labelmap.prototxt文件
    item {
    name: "none_of_the_above"
    label: 0
    display_name: "background"
    }
    item {
    name: "tongue"
    label: 1
    display_name: "LungOpacity"
    }
  8. 运行gen_model.sh脚本,usage: ./gen_model.sh CLASSNUM,我的训练CLASSNUM=2
  9. 执行之后,得到examples文件夹,里面的3个prototxt就是从模板生成的正式网络定义,根据作者设置,其中的deploy文件是已经合并过bn层的,需要后面配套使用。
  10. 修改训练超参数,根据实际情况,修改solver_train.prototxt和solver_test.prototxt,batch_size需要修改example/MobileNetSSD_train.prototxt,其中test_iter=测试集图片数量/batchsize;初始学习率不宜太高,否则基础权重破坏比较严重;优化算法是RMSProp,可能对收敛有好处,不要改成SGD,也是为了保护权重。
  11. 修改并运行train.sh脚本,中途可以不断调节参数。训练结束后,运行test.sh脚本,测试网络的精度值。
  12. 合并bn层,为了提高模型运行速度,作者在这里将bn层合并到了卷积层中,相当于bn的计算时间就被节省了,对检测速度可能有小幅度的帮助,打开merge_bn.py文件,然后注意修改其中的文件路径:
    caffe_root = '/home/system/caffe/caffe-master/'
     
    train_proto = 'example/MobileNetSSD_train.prototxt' 
    train_model = 'snapshot/mobilenet_iter_33000.caffemodel'  #should be your snapshot caffemodel
     
    deploy_proto = 'example/MobileNetSSD_deploy.prototxt' 
    save_model = 'example/MobileNetSSD_deploy.caffemodel'
    然后运行该脚本,就可以得到最终的检测模型,那这个模型由于合并了bn层,参数格式已经变化,就不能再用于训练了。如果想继续训练,应该用合并前的。对于得到的最终模型,可用demo.py脚本查看实际检测效果,也可以部署在其他地方。
  13. 用depthwise convolution layer代替普通convolution layer减少参数缩小模型加快运行速度,举例来说,假设输入通道数64,输出通道数64. 传统的Conv2D方法的参数数量为3*3*64*64;而SeparableConv2D的参数数量为3*3*64+1*1*64*64,参数数量减少了32192个。git clone https://github.com/yonghenglh6/DepthwiseConvolution.git。clone depthwise convolution layer项目代码到caffe源码目录外的地方(以防编译时报错),注意到项目中的caffe文件夹,将其中的depthwise_conv_layer.hpp,depthwise_conv_layer.cpp和depthwise_conv_layer.cu这三个文件放到caffe/src/caffe/layers/下,然后重新编译caffe,make pycaffe;make all;make test;make runtest。编译完修改demo.py测试运行时间
    import time
     
    def detect(imgfile):
        #
        #
        net.blobs['data'].data[...] = img
        start=time.time() # time begin
        out = net.forward() 
        use_time=time.time()-start # proc time 
        print("time="+str(use_time)+"s")
        #
            #
  14. 测试结果:经过优化后我的模型运行时间是200ms,mAP 99.94%,效果还是不错的。

猜你喜欢

转载自blog.csdn.net/liu_xiao_cheng/article/details/82781082
今日推荐