专栏 | 卷积神经网络学习路线(五)| 卷积神经网络参数设置,提高泛化能力?

来自:AI开发者 2020-01-05

点击上方“蓝字”关注“AI开发者”

本文来自  @BBuf  的社区专栏  GiantPandaCV ,文末扫码即可订阅专栏。

前言

这是卷积神经网络学习路线的第五篇文章,主要为大家介绍一下卷积神经网络的参数设置,调参技巧以及被广泛应用在了哪些领域,希望可以帮助到大家。

卷积神经网络的参数设置

这个举个例子来说是最好的,因为直接说会抽象一些,我在网上找了一个caffe-ssd的参数设置配置文件 ,内容如下:

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

我们就一个个来解析一下。

:训练的模型文件的路径。

:测试的模型文件的路径。

:网络的迭代测试次数。网络一次测试 张图片,因为为了可以将验证集中所有图片都测试一次,这个参数乘以 应该等于验证集中的图片数。

:网络迭代多少次进行一次测试。一次迭代即是将一个 的图片进行训练。这个文件中 设为了 ,也就是说每隔 次对网络的准确率进行一次验证。一般来讲,我们是需要将训练集合中的所有图片都跑一次再对准确率进行测试,也就是 乘以 不小于训练集中的图片总数。

:表示网络的基础学习率,学习率过高可能会无法梯度下降,loss保持不变,也可能loss不能收敛。而学习率过低会使网络收敛速度缓慢,也可能导致梯度消失。一般初始学习率设为

:每隔多少次显示一次。也就是在屏幕上打印一次 和准确率。

:网络的最大迭代次数。训练集中的图片需要训练多次,所以这个参数一般比较大。

:学习率变化策略,这里面又分为如下几类:- :保持 不变。- :如果设置为 ,则还需要设置一个 ,  返回 ,其中 表示当前的迭代次数。- :返回 表示当前的迭代次数。- : 如果设置为 ,还需要设置一个 , 返回 。- :如果设置为 ,则还需要设置一个 。这个参数和 很相似, 是均匀等间隔变化,而 则是根据 值变化。- :学习率进行多项式误差, 返回 - :学习率进行 衰减,返回

:因为这里学习率衰减策略为 ,所以需要设置 两个参数。

:同上。

:上一次梯度更新的权重,一般取值在 之间。通常设为 可以让使用 的深度学习方法更加稳定以及快速。

:权重衰减项,防止过拟合的一个参数。在损失函数中, 是放在正则项( )前面的一个系数,正则项一般指示模型的复杂度,所以 的作用是调节模型复杂度对损失函数的影响,若 很大,则复杂的模型损失函数的值也就大。

:每多少次保存一次学习的结果,在caffe框架下就是

:模型保存的路径。

:设置使用 还是 进行学习训练。

:GPU序列号,默认从 开始。

:是否显示 信息。

:是否在训练结束后保存一个snapshot文件。便于以后可以在此基础上继续训练。

:确保内存可以用并输出 的初始值。

:显示 为之前 的平均值。

:每处理 张图片后进行一次梯度计算。

:每多少次学习率递减。这里是迭代 次学习率递减。

:优化算法的选择,一共有六种可选: 。默认为 。原理建议看看斯坦福大学的CS231N视频课程。

:评价类型。

:计算平均准确率(map值)的方法,有 三种, 是SSD在VOC2007中计算AP的方法,使用了简单的均值计算。 是SSD在VOC2012中使用的最大值积分法。 是普通积分方法。

:在终端输出每一类的AP(每一类的检测精度)信息。

提高卷积神经网络的泛化能力

在做工程的时候如何提高自己训练出来的模型的泛化能力是一项具有挑战性同时也是一件充满"玄学"的事情。回想我这一年半载训练的那么几个任务的调参来讲,大概可以总结为下面这几点。

使用更多的数据。竟可能标注更多的训练数据,这是提高泛化能力最理想的方法,更多的数据让模型得到更充分的学习,自然提高了泛化能力,但实际场景中考虑到标注成本的问题,可能并不能无脑加数据。

使用更大的 。在相同迭代次数和学习率的条件下,每批次采用更多的数据将有助于模型更好的学习到正确的模式,模型输出结果也会更加稳定。

数据过采样。很多情况下我们拿到手的数据都存在类别不均匀的情况,模型这个时候过多的拟合某类数量多的数据导致其输出结果偏向于该类数据,此时如果我们过采样其他类别的数据,使得数据量比较均衡可以一定程度提高泛化能力。

数据增强。数据增强是指在数据有限的情况通过一些几何操作对图像进行变换,使得同类数据的表现形式更加丰富,以此提高模型的泛化能力。数据增强是一门比较大的学问,在分类,检测,分割中数据增强的方式都有区别,我们可以通过研究优秀的开源代码实现的数据增强策略来应用到我们自己的任务中。

修改损失函数。这方面有大量的工作,如目标检测中的Focal Loss, GHM Loss,IOU Loss等都是为了提升模型的泛化能力。

修改网络。如果网络过浅并且参数量过少往往会使得模型的泛化能力不足导致欠拟合,此时一般考虑使用简单的堆叠卷积层增加网络的参数,提高模型的特征提取能力。而如果网络过深且训练数据量比较少,那么就容易导致模型过拟合,此时一般需要简化网络结构减少网络层数或者使用 的残差结构以及 层。

权重惩罚。权重惩罚也即是正则化操作,一般是在损失函数中添加一项权重矩阵的正则项作为惩罚项,用来惩罚损失值较小时网络权重过大的情况,此时往往是网络权值过拟合了数据样本。

Dropout策略。如果网络最后有全连接层可以使用 策略,相当于对深度学习模型做了 ,有助于提高模型的泛化能力。

一些调参技巧

本节建立在CV方向。

做工程

卷积是CNN的主流组件。平时有设计一些解决分类,回归任务的网络,里面的卷积核基本都设置为 ,要说原因的话应该去问问 吧。两个 的卷积核堆叠能获得 卷积核的感受野并且参数比 卷积核少,所以是大量推荐使用的。

可以适当使用 卷积。为什么要提这一点呢,这是因为 卷积可以减少计算量,并且 卷积可以在某个方向强调感受野,也就是说假如如果你要对一个长方形形状的目标进行分类,你可以使用 的卷积核搭配 的卷积核对长边方向设定更大的感受野,或许可以获得泛化性能的提升。

ACNet结构。这个研究来自于ICCV2019,可以在 卷积的基础上加上 的旁路卷积核,最后在推理阶段把三个卷积核都 卷积核上,在许多经典CV任务上都可以获得大概1个点的提升。大家可以看看这篇文章解读,来自公众号AI科技评论。 3 3卷积+1 3卷积+3*1卷积=白给的精度提升 卷积核权重初始化方式。对于 的初始化我一般都是使用 初始化。当然也可以可以尝试何凯明大神的He初始化。对于bias的初始化全置于0。 。这是我一直在使用的技巧,可以很大程度的加快收敛速度。建议搭建自己网络的时候尽量加上 ,如果有 了全连接层就没必要加 了。 目标检测不能盲目去掉 结构。在针对自己的数据调检测任务如 的时候不能盲目砍掉 结构,尽管你分析出某个分支的Anchor基本不可能会对你预测的目标起作用,但如果你直接去掉分支很可能会带来漏检。 优化器的选择。我基本都是带动量的 。如果优化不动可以试试 。 激活函数。可以先用 做一版,如果想再提升精度可以将 改成 试试。我更倾向于直接使用 :在不同类型的任务中, 的影响也不同,大家可以看看这篇 对模型性能影响的文章,来自公众号AI开发者。 Batch_size是怎么影响模型性能的 初始学习率。一般我是从 开始设置,我个人认为这个学习率和学习率衰减策略是相关的,但不宜设置的过大过小, 应该是比较常用的。学习率衰减策略我一般使用 方式, 的设置要看视你的的 而定。 数据与处理之 。第一次见到这个词是在看cs231n的视频上。主要有2个步骤,第一个是减均值,第二个是除以方差。这样做下来最后的输入值域为 ,一般减均值是最常用的,后面的除以方差用不用可能需要自己动手试验一下看看效果。 残差结构和密集连接。 的残差结构和 密集连接结构,做工程的时候考虑到速度近乎不可能说完全使用完整版本的 的完整结构,但我们可以自己动手将我们网络的某些模块替换为残差结构和密集连接,替换的时候可以适当降低这俩结构的复杂度,类似于通道数减半,密集连接中只保留一半连接等等。这里需要做一些消融实验来验证改进后的精度。 关于loss。优秀的 一般是对模型的泛化性能有所改善的,但在用 的时候往往并不是直接替换 那么简单,需要仔细思考 背后的数学原理,要用对地方才可有提升。例如,如何将Focal Loss用到YOLOv3中提升 ,大家可以看看这个帖子。https://www.zhihu.com/question/293369755。 找到模型调参时的可靠评价指标。在调整参数训练模型时一定要找到正确的评价指标,没调整一个参数就要记录一下模型的评价指标如准确率, 值, 值等。并且在调参时建议将调整的参数和在测试集上的精度组合成一个字符串给模型重命令,方便之后快速 。 使用了带 的网络,如训练 建议选择 的方式,从头训练不仅费时费力,甚至难以收敛。

做比赛

特征提取。VGG16,VGG19,ResNet50,Xception是非常好用的几个特征提取模型。建议使用训练好的经典模型对数据集提取特征向量存储到本地,更方便使用,同时可以大幅度降低显存消耗。

ensemle:

将不同的经典网络提取出的特征向量,假设 提取出的特征向量维度是 , 提取的特征向量维度是 , 提取的特征向量维度是 ,那么我们可以使用三个系数 将其组合为形状为 ,其中 三个参数的取值代表我们使用哪个模型的特征多一些,如果是分类回归比赛,我们在后面接特征处理网络就可以了。可以取不同的 得到不同的特征,然后对结果做 等多种处理,一般结果不会太差啦。

可以使用不同的初始化方式训练出模型,然后做ensemble。

可以使用用不同超参数(如学习率, ,优化器)训练出不同模型,然后做ensemble。

因为我就做了一点点入门级比赛,上面介绍的方法取得了还不错的结果,所以我就在这里献丑啦,方法确实挺无脑的,大家笑一笑就好啦。继续想了下,我好像除了这些有接触或者使用到,暂时没有什么其它的了,如果想起其他的了,之后补充下。

后记

这篇文章为大家介绍了卷积神经网络的参数设置以及我这半年到一年间的的一些调参技巧,希望对大家有帮助。

扫码订阅专栏

关于专栏

AI 研习社专栏旨在满足有持续创作能力的的知名学者、技术专家、优秀博主、讲师和人工智能人才文字创作和打造专属个人IP的需求。 AI 研习社希望能够帮助大咖见证求知,分享洞见~

欢迎大家来AI研习社订阅/开通专栏: https://www.yanxishe.com/column

  点击 阅读原文 ,查看专栏更多内容