这是卷积神经网络学习路线的第五篇文章,主要为大家介绍一下卷积神经网络的参数设置,调参技巧以及被广泛应用在了哪些领域,希望可以帮助到大家。
这个举个例子来说是最好的,因为直接说会抽象一些,我在网上找了一个caffe-ssd的参数设置配置文件solver.prototxt
,内容如下:
train_net:"train.prototxt"
test_net:"test.prototxt"
test_iter: 299
test_interval: 200
base_lr: 0.01
display: 20
max_iter: 6720
lr_policy: "step"
gamma: 0.1
power: 0.75
momentum: 0.9
weight_decay: 0.0001
snapshot: 224
snapshot_prefix: "snapshot"
solver_mode: GPU
device_id:0
debug_info:false
snapshot_after_train:true
test_initialization:false
average_loss:10
iter_size:1
stepsize:2000
type: SGD
eval_type:"detection"
ap_version:"11point"
show_per_class_result:true
我们就一个个来解析一下。
train_net
:训练的模型文件的路径。
test_net
:测试的模型文件的路径。
test_iter
:网络的迭代测试次数。网络一次测试batch_size
张图片,因为为了可以将验证集中所有图片都测试一次,这个参数乘以batch_size
应该等于验证集中的图片数。
test_interval
:网络迭代多少次进行一次测试。一次迭代即是将一个batch_size
的图片进行训练。这个文件中test_interval
设为了200
,也就是说每隔200
次对网络的准确率进行一次验证。一般来讲,我们是需要将训练集合中的所有图片都跑一次再对准确率进行测试,也就是test_interval
乘以batch_size
不小于训练集中的图片总数。
base_lr
:表示网络的基础学习率,学习率过高可能会无法梯度下降,loss保持不变,也可能loss不能收敛。而学习率过低会使网络收敛速度缓慢,也可能导致梯度消失。一般初始学习率设为0.01
。
display
:每隔多少次显示一次。也就是在屏幕上打印一次loss
和准确率。
max_iter
:网络的最大迭代次数。训练集中的图片需要训练多次,所以这个参数一般比较大。
lr_policy
:学习率变化策略,这里面又分为如下几类:
- fixed
: 保持base_lr
不变。
- step
:如果设置为step
,则还需要设置一个stepsize
, 返回 base_lr * gamma ^ (floor(iter / stepsize))
,其中iter
表示当前的迭代次数。
- exp
:返回base_lr * gamma^ iter
,iter
表示当前的迭代次数。
- inv
: 如果设置为inv
,还需要设置一个power
, 返回base_lr * (1 + gamma * iter) ^ (- power)
。
- multistep
:如果设置为multistep
,则还需要设置一个stepvalue
。这个参数和step
很相似,step
是均匀等间隔变化,而multistep
则是根据 stepvalue
值变化。
- poly
:学习率进行多项式误差, 返回 base_lr (1 - iter/max_iter) ^ (power)
- sigmoid
:学习率进行sigmod
衰减,返回 base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))
gamma
:因为这里学习率衰减策略为step
,所以需要设置gamma
和power
两个参数。
power
: 同上。
momentum
:上一次梯度更新的权重,一般取值在0.5--0.99
之间。通常设为0.9
,momentum
可以让使用SGD
的深度学习方法更加稳定以及快速。
weight_decay
: 权重衰减项,防止过拟合的一个参数。在损失函数中,weight decay
是放在正则项(regularization
)前面的一个系数,正则项一般指示模型的复杂度,所以weight decay
的作用是调节模型复杂度对损失函数的影响,若weight decay
很大,则复杂的模型损失函数的值也就大。
sanpshot
:每多少次保存一次学习的结果,在caffe框架下就是caffemodel
。
snapshot_prefix
:模型保存的路径。
solver_model
:设置使用GPU
还是CPU
进行学习训练。
device_id
:GPU序列号,默认从0
开始。
debug_info
:是否显示debug
信息。
snapshot_after_train
:是否在训练结束后保存一个snapshot文件。便于以后可以在此基础上继续训练。
test_initialization
:确保内存可以用并输出loss
的初始值。
average_loss
:显示loss
为之前average_loss
个loss
的平均值。
iter_size
:每处理ietr_size*batch_size
张图片后进行一次梯度计算。
stepsize
:每多少次学习率递减。这里是迭代2000
次学习率递减。
type
:优化算法的选择,一共有六种可选:SGD、AdaDelta、AdaGrad、Adam、Nesterov和RMSProp
。默认为SGD
。原理建议看看斯坦福大学的CS231N视频课程。
eval_type
:评价类型。
ap_version
:计算平均准确率(map值)的方法,有11point、MaxIntegral、Integral
三种,l1point
是SSD在VOC2007中计算AP的方法,使用了简单的均值计算。MaxInterral
是SSD在VOC2012中使用的最大值积分法。Integral
是普通积分方法。
show_per_class_result
:在终端输出每一类的AP(每一类的检测精度)信息。
在做工程的时候如何提高自己训练出来的模型的泛化能力是一项具有挑战性同时也是一件充满"玄学"的事情。回想我这一年半载训练的那么几个任务的调参来讲,大概可以总结为下面这几点。
batch_size
。在相同迭代次数和学习率的条件下,每批次采用更多的数据将有助于模型更好的学习到正确的模式,模型输出结果也会更加稳定。resnet
的残差结构以及bn
层。Dropout
策略,相当于对深度学习模型做了Ensemble
,有助于提高模型的泛化能力。本节建立在CV方向。
VGG16
吧。两个 3 × 3 3\times 3 3×3的卷积核堆叠能获得 5 × 5 5\times 5 5×5卷积核的感受野并且参数比 5 × 5 5\times 5 5×5卷积核少,所以是大量推荐使用的。fusion
到 3 × 3 3\times 3 3×3卷积核上,在许多经典CV任务上都可以获得大概1个点的提升。大家可以看看这篇文章解读,来自公众号AI科技评论。33卷积+13卷积+3*1卷积=白给的精度提升weight
的初始化我一般都是使用xavier
初始化。当然也可以可以尝试何凯明大神的He初始化。对于bias的初始化全置于0。Batch Normalization
。这是我一直在使用的技巧,可以很大程度的加快收敛速度。建议搭建自己网络的时候尽量加上BN
,如果有BN
了全连接层就没必要加Dropout
了。fpn
结构。在针对自己的数据调检测任务如yolov3
的时候不能盲目砍掉fpn
结构,尽管你分析出某个分支的Anchor基本不可能会对你预测的目标起作用,但如果你直接去掉分支很可能会带来漏检。SGD
。如果优化不动可以试试Adam
。ReLU
做一版,如果想再提升精度可以将ReLU
改成PReLU
试试。我更倾向于直接使用ReLU
。batch_size
:在不同类型的任务中,batch_size
的影响也不同,大家可以看看这篇batch_size
对模型性能影响的文章,来自公众号AI开发者。Batch_size是怎么影响模型性能的0.01
开始设置,我个人认为这个学习率和学习率衰减策略是相关的,但不宜设置的过大过小,0.01
和0.1
应该是比较常用的。学习率衰减策略我一般使用multistep
方式,step_size
的设置要看视你的的max_iter
而定。zero-center
。第一次见到这个词是在看cs231n的视频上。主要有2个步骤,第一个是减均值,第二个是除以方差。这样做下来最后的输入值域为[-1,1]
,一般减均值是最常用的,后面的除以方差用不用可能需要自己动手试验一下看看效果。resnet
的残差结构和dense net
密集连接结构,做工程的时候考虑到速度近乎不可能说完全使用完整版本的resnet
和densenet
的完整结构,但我们可以自己动手将我们网络的某些模块替换为残差结构和密集连接,替换的时候可以适当降低这俩结构的复杂度,类似于通道数减半,密集连接中只保留一半连接等等。这里需要做一些消融实验来验证改进后的精度。loss
一般是对模型的泛化性能有所改善的,但在用loss
的时候往往并不是直接替换loss
那么简单,需要仔细思考loss
背后的数学原理,要用对地方才可有提升。例如,如何将Focal Loss用到YOLOv3中提升map
,大家可以看看这个帖子。https://www.zhihu.com/question/293369755。map
值,miou
值等。并且在调参时建议将调整的参数和在测试集上的精度组合成一个字符串给模型重命令,方便之后快速review
。backbone
的网络,如训练VGG16-SSD
建议选择finetune
的方式,从头训练不仅费时费力,甚至难以收敛。VGG16
提取出的特征向量维度是[N,c1]
,ResNet50
提取的特征向量维度是[N,c2]
,Xception
提取的特征向量维度是[N, c3]
,那么我们可以使用三个系数a、b、c
将其组合为形状为[N, a*c1+b*c2+c*c3]
,其中a、b、c
三个参数的取值代表我们使用哪个模型的特征多一些,如果是分类回归比赛,我们在后面接特征处理网络就可以了。可以取不同的a、b、c
得到不同的特征,然后对结果做voting
,soft-voting
等多种处理,一般结果不会太差啦。batch_size
,优化器)训练出不同模型,然后做ensemble。因为我就做了一点点入门级比赛,上面介绍的方法取得了还不错的结果,所以我就在这里献丑啦,方法确实挺无脑的,大家笑一笑就好啦。
继续想了下,我好像除了这些有接触或者使用到,暂时没有什么其它的了,如果想起其他的了,之后补充下。
这篇文章为大家介绍了卷积神经网络的参数设置以及我这半年到一年间的的一些调参技巧,希望对大家有帮助。
卷积神经网络学习路线(一)| 卷积神经网络的组件以及卷积层是如何在图像中起作用的?
卷积神经网络学习路线(二)| 卷积层有哪些参数及常用卷积核类型盘点?
卷积神经网络学习路线(三)| 盘点不同类型的池化层、1*1卷积的作用和卷积核是否一定越大越好?
卷积神经网络学习路线(四)| 如何减少卷积层计算量,使用宽卷积的好处及转置卷积中的棋盘效应?
欢迎关注我的微信公众号GiantPandaCV,期待和你一起交流机器学习,深度学习,图像算法,优化技术,比赛及日常生活等。