训练网络的一些trick(1):pre_train与逐层拷贝网络
来源:互联网 发布:mac rar解压软件下载 编辑:程序博客网 时间:2024/06/16 12:21
最近做detection方面的工作,在实际训练方面做了一些尝试,这一篇主要记录对于网络pre_train的理解。
首先说pre_train,目前几乎所有做detection的网络都会用到这个技巧,相比于ImageNet数据集里张百万甚至千万的图片量,detection数据集几万张的图片量实在有些少(Pascal VOC、COCO),单纯用这些图片去训练一个比较深的随机初始化的cnn然后得到一个比较好的结果几乎是不可能的事情,基本一开始就是loss=NaN。这时候就用到pre_train的技巧,先构建一个分类网络(比如VGG16)并且用ImageNet来训练,这样得到一个能提取较好特征的卷积网络,然后把后面几层用来分类的fc层去掉,换成做detection的rpn、roi或者其他的层,相当于detection训练的一开始就能得到一个比较好的卷积特征(虽然是用来分类的),这样就解决了网络难训练的问题(或者数据量不够的问题?)。
在做的项目里,比如我要检测非自然图像里的一个特定形状(比如在七龙珠动画片里检测龙珠。。或者其他什么奇怪的东西),那么有两个问题,1)我做检测的domain和正常检测的domain是不一样的,是在非自然图像中的(而不是一张照片),这样分类任务训练好的特征提取器(pre_train model)可能不会很好的适用,或许应该在相同domain下训练一个提取器会比较好,这样就引出另一个问题,2)数据量不够。没有一个大型的动画片的分类数据库,而且用作detection的训练数据也并不很多(大概3000张)。然后我自己做了一些探索和猜想。
首先domain的问题几乎没办法解决,除非有一个大的数据集;而数据量的问题(或者说优化detection的问题更合适),可以参考pre_train的过程。博主认为pre_train的过程从梯度下降的角度来考虑,相当于随机初始化等于把参数坐标随机设置到一个位置,这样距离高维空间中的最优解坐标相差非常远,而分类任务的最优解和detection最优解是有一些共通之处的,比如前面conv层提取的特征对于两个任务都有效,两个任务最优解在高维空间的位置可能相对比较接近(当然这两的维度都不一样,这是一个不是很恰当的比喻),而pretrain相当于把最开始随机初始化的参数坐标向着最优位置移动了一大步,这样利用有限的detection训练数据就有可能达到比较好的结果(比随机初始化要好)。
那么,对于要做的detection任务,在voc07或其他数据集上训好的model是不是比分类的pretrain model更接近最优解呢?要知道分类的model最后不会保留fc层,那pvanet来说,最后两层fc6、fc7共有2*4096*4096几千万的参数量,很大的数量级,更不用提还有rpn的一些层。基于这个猜想做了一些实验。
SSD的实验:用在Pascal voc上训练好的ssd300去初始化新任务的网络,base网络是VGG16,除了输出类别数目不同的层其它层全部复制(主要多了fc层),分类网络初始化map在17%左右,新的方法map提升到30%左右。数值整体比较差我认为是数据量和标注质量的问题。
pvanet的实验:几乎同样的做法,map从31%提高到35%,base网络是论文作者release出代码中的默认网络。
以上的实验和猜想都并不严格,还存在很多改进空间甚至是错误之处,欢迎指正。
附逐层拷贝网络的方法:
1.利用pycaffe的接口,初始化net之后会有一些给出的接口来操作net的param,这个在net_surgery里面有很好地例子。这里贴一些其他接口的代码。
if (net.layers[i].type == 'Convolution') or (net.layers[i].type == 'Scale'): net.layers[i].blobs[0].data.flat = net_.layers[i].blobs[0].data.flat #net.layers[i].blobs[1].data.flat = net_.layers[i].blobs[1].data.flat
主要给出了layer、blobs、data的接口,conv层blob有两个,bn层一般有3个。
2.拆分caffemodel成prototxt。拆分后的结果如下:
layer { name: "conv1" type: "Convolution" bottom: "data" top: "conv1" param { lr_mult: 1.0 } param { lr_mult: 2.0 } blobs { data: 0.264199763536 data: -0.220321893692 data: -0.251213937998 data: 0.150178313255 ... data: -0.05886515975 data: 0.0170712769032 data: -0.185302212834 shape { dim: 70 dim: 3 dim: 3 dim: 3 } } blobs { data: 0.0 data: 0.0 data: 0.0 ... data: 0.0 data: 0.0 shape { dim: 70 } } phase: TEST convolution_param { num_output: 70 kernel_size: 3 stride: 1 weight_filler { type: "xavier" } bias_filler { type: "constant" } }}这是一个conv层的形式。这种方法解析出来的prototxt文件太大,非常难操作,虽然比较直观,但还是不建议这样做。
附拆分代码:
import caffe.proto.caffe_pb2 as caffe_pb2caffemodel_filename = 'deploy.caffemodel'model = caffe_pb2.NetParameter()f = open(caffemodel_filename, 'rb')model.ParseFromString(f.read())f.close()proto_file = open('deploy.prototxt', 'w')proto_file.write(str(model.__str__))proto_file.close()print 'all done'
- 训练网络的一些trick(1):pre_train与逐层拷贝网络
- 网络层的一些协议
- 网络层的一些协议
- 用卷积神经网络检测脸部关键点的教程(一)环境配置与浅层网络训练
- 网络层与传输层的区别
- 网络层(1)
- 七层网络模型与四层网络模型及每层的网络协议?
- 网络层与路由器
- activeMQ的网络层1
- 网络层的拥塞控制与服务质量
- pvanet训练网络时的一些小技巧
- 应用层编码与网络接口层的数据发送
- iOS中一种网络层与业务层的设计方案
- 网络五层协议-与每层对应的协议
- 网络层-1、网络层功能概述
- 南京邮电大学的网络攻防训练平台(1)
- 网络层的协议
- Android的一些trick
- 各种变量的定义规则和使用规则?
- linux下安装docker
- JAVA基础(六)之Servlet
- 接口测试--postman interceptor插件
- D3D9函数(持续添加)
- 训练网络的一些trick(1):pre_train与逐层拷贝网络
- spark sql 处理时间类型
- [YTU]_2443( C++习题 复数类--重载运算符3+)
- MFC 操作 excel
- git学习0
- Android 自定义View(一)原理
- BS结构浏览器网页读写IC卡技术汇总
- day-18 paramiko 实现sftp功能
- BZOJ 1202: [HNOI2005]狡猾的商人