目录
一. 通过数据提升性能
1、获取更多数据
深度学习基于大量的学习数据,数据的质量直接影响到模型的表现,数据量越多,学习的特征越多
2、创造更多数据
为了提高模型的泛化能力,当找不到更多样本但确实需要更多更全的样本的时,可以考虑自己创造样本
在图像处理方面,常用的方法包括:图片的平移、缩放、旋转、翻转、裁剪、添加噪声等方式
如果是一维的波形数据,可以考虑在原有样本上添加一小段范围内(如:-2到2之间)的随机数,这种做法可以在一定程度上弥补自己冒然造出的数据的不准确性,不会改变原有波形的正常走势。
注意:一般情况下自己基于原有样本创造出的样本,不超过原有样本的5倍
3、重放缩数据
此处和所使用的激活函数密切相关,当输出层使用的激活函数是sigmoid函数时将数据缩放到(0, 1)之间,当使用tanh函数时将数据缩放到(-1, 1)之间。后者是都数据进行标准化使其符合0均值,单位标准差。
4、重新架构问题
不同的问题从不同的角度去理解会有不同解法,当遇到瓶颈是可通过重新观察数据,寻求更优的解决方式,比如原本理解的回归问题是否可以从分类的角度理解。
二. 通过算法提升性能
根据不通的问题划分,有时可以从机器学习算法入手,也可以从深度学习来考虑,通过在不同算法间的比较总会得到最优的那一个。
几种常见的重采样方法:
深度学习的过程通常较为漫长如何更快得到想要的结果?
1.在进行大量样本训练之前先使用少量的较为简单的样本进行训练,如果实验结果和预期相差不大,可进行大量样本训练。
2.使用的较好的硬件
3.早停法(停止标准详见文末参考资料)
图一 理想训练集误差和验证集误差
图二 实际训练集误差和验证集误差
三. 通过调参提升性能
1、分清问题
1.首先需要弄清楚模型效果不好的原因是过拟合还是欠拟合:
类型 | 常见情况 | 对策 |
过拟合 | 训练集表现较好,验证集表现较差 | 正则化、dropout方法...... |
欠拟合 | 训练集和验证集表现都较差 | 提升网络模型复杂度,增长训练时间..... |
| 同上图中的图二 | 早停法 |
2、网络超参数调整
1、输入像素:
为便于GPU并行计算,一般将图像大小设置为到 2的次幂。
2、卷积层参数的设定:
卷积核大小一般使用 1x1、3x3 或 5x5
使用 zero padding,可以充分利用边缘信息、使输入大小保持不变
卷积核的个数通常设置为 2的次幂,如 64, 128, 256, 512, 1024 等
3、池化层参数的设定:
一般采用卷积核大小 2x2 ,步长为 2
也可采用 stride convolutional layer 来代替池化层实现下采样
4、全连接层(可使用 Global Average Pooling 来代替):
Global Average Pooling 和 Average Pooling(Local
) 的差别就在 “Global”
这个字眼上。Global 和 Local 在字面上都是用来形容 pooling 窗口区域的。Local 是取 Feature Map 的一个子区域求平均值,然后滑动
;Global 显然就是对整个 Feature Map 求均值
了(kernel 的大小设置成和 Feature Map 的相同)
所以,有多少个 Feature Map 就可以输出多少个节点。一般可将输出的结果直接喂给 softmax 层
5、卷积的选取:
1.卷积核尺寸方面:
大卷积核用多个小卷积核代替(如一个5x5的卷积核可以用两个3x3的卷积核代替)
使用1×1卷积核
2.卷积层通道方面:
标准卷积用 depthwise 卷积代替
使用分组卷积groups(注意groups的值要为输入通道核输出通道的公约数)
分组卷积前使用 channel shuffle
通道加权计算
3.卷积层连接方面:
使用 skip connection,让模型更深
densely connection,使每一层都融合上其它层的特征输出(DenseNet)
4.启发:
类比到通道加权操作,卷积层跨层连接能否也进行加权处理?
bottleneck + Group conv + channel shuffle + depthwise
的结合会不会成为以后降低参数量的标准配置?
3训练超参数调整
- learning-rate 的选择
-
- 固定学习率时,
0.01,0.001
等都是比较好的选择,另外我们可以通过 validation error 来判断学习率的好坏,如下图所示。 - 自动调整学习率时,可使用 learning rate decay 算法(step decay,exponential decay)或一些自适应优化算法(Adam,Adadelta)。
- 固定学习率时,
- mini-batch 的选择
-
- batch size 太小会使训练速度很慢;太大会加快训练速度,但同时会导致内存占用过高,并有可能降低准确率。
- 所以 32 至 256 是不错的初始值选择,尤其是
64 和 128
,选择2的指数倍
的原因是:计算机内存一般为 2 的指数倍,采用 2 进制编码。
- dropout
-
- 在输入层和隐藏层同时使用
- 取20%-50%为佳。
4.使用更大的网络
-
- 在更大的网络上使用dropout可以有效提升模型的性能
小结
1:准备数据:务必保证有大量、高质量并且带有干净标签的数据
2:预处理:0均值和1方差化
3:minibatch:建议值128,1最好,但是效率不高,但过大容易过拟合
4:梯度归一化:计算出来梯度之后,要除以minibatch的数量。
5:学习率
5.1:用一个一般的学习率开始,逐渐减小
5.2:一个建议值是0.1,适用于很多NN的问题,一般倾向于小一点。
5.3:关于学习率:如果在验证集上性能不再增加就让学习率除以2或者5,然后继续,学习率会一直变得很小,到最后就可以停止训练了。
5.4:很多人用的一个设计学习率的原则就是监测一个比率(每次更新梯度的norm除以当前weight的norm),如果这个比率在10-3附近,如果小于这个值,学习会很慢,如果大于这个值,那么学习很不稳定,由此会带来失败。
6:使用验证集可以知道什么时候该开始降低学习率,什么时候该停止训练。
7:关于对weight初始化的选择的一些建议:
7.1:如果你很懒,直接用0.02*randn(num_params)来初始化,当然别的值你也可以去尝试
7.2:如果上面那个不太好使,那么就依次初始化每一个weight矩阵用init_scale / sqrt(layer_width) * randn,init_scale可以被设置为0.1或者1
7.3:初始化参数对结果的影响至关重要,要引起重视。
7.4:在深度网络中,随机初始化权重,使用SGD的话一般处理的都不好,这是因为初始化的权重太小了。这种情况下对于浅层网络有效,但是当足够深的时候就不行了,因为weight更新的时候,是靠很多weight相乘的,越乘越小,有点类似梯度消失的意思(这句话是我加的)
8:如果训练RNN或者LSTM,务必保证gradient的norm被约束在15或者5(前提还是要先归一化gradient),这一点在RNN和LSTM中很重要。
9:如果是自己算的梯度,需要检查梯度 。
10:如果使用长短期记忆人工神经网络(LSTM)来解决长时依赖的问题,记得初始化bias的时候要大一点
12:尽可能想办法多的扩增训练数据,如果使用的是图像数据,不妨对图像做一点扭转啊之类的,来扩充数据训练集合。
13:使用dropout
14:评价最终结果的时候,多做几次,平均一下所有的结果
参阅资料:
How To Improve Deep Learning Performance(https://machinelearningmastery.com/improve-deep-learning-performance/)
深度学习技巧之Early Stopping(早停法)(https://www.datalearner.com/blog/1051537860479157)
深度学习技巧之Early Stopping(早停法)(https://blog.csdn.net/df19900725/article/details/82973049)
深度学习训练的小技巧,调参经验。总结与记录(https://blog.csdn.net/chenzhi1992/article/details/52905569/?utm_medium=distribute.pc_relevant.none-task-blog-title-7&spm=1001.2101.3001.4242)