LSTM调参经验
0、开始训练之前先要做些什么?
在开始调参之前,需要确定方向,所谓方向就是确定了之后,在调参过程中不再更改
1、根据任务需求,结合数据,确定网络结构。
例如对于RNN而言,你的数据是变长还是非变长;输入输出对应关系是many2one还是many2many等等,更多结构参考如下
非RNN的普通过程,从固定尺寸的输入到固定尺寸的输出(比如图像分类)
输出是序列(例如图像标注:输入是一张图像,输出是单词的序列)
输入是序列(例如情绪分析:输入是一个句子,输出是对句子属于正面还是负面情绪的分类)
输入输出都是序列(比如机器翻译:RNN输入一个英文句子输出一个法文句子)
同步的输入输出序列(比如视频分类中,我们将对视频的每一帧都打标签)
2、确定训练集、验证集和测试集,并尽可能的确保它们来自相同的分布,并且训练集与测试集的划分通常是7:3,然后在训练集中在进行验证集的划分,验证集的划分可以是交叉验证,也可以是固定比例。
一旦确定了数据集的划分,就能够专注于提高算法的性能。如果能够保证三者来自相同的分布,对于后续的问题定位也会有着极大的意义。
例如,某个模型在训练集上效果很好,但是在测试集上的结果并不如意,如果它们来自相同的分布,那么就可以肯定:模型在训练集上过拟合了(overfitting),那么对应的解决办法就是获取更多的训练集。
但是如果训练集和测试集来自不同的分布,那么造成上述结果的原因可能会是多种的:
(i).在训练集上过拟合;(ii).测试集数据比训练集数据更难区分,这时,有必要去进行模型结构,算法方面的修改;(iii).测试集并不一定更难区分,只是与训练集的分布差异比较大,那么此时如果我们去想方设法提高训练集上的性能,这些工作都将是白费努力。
3、确定单一的评估算法的指标。
这里需要注意的是,在进行调参之前,我们需要明确我们的目的是什么,是尽可能的分的准(查准率,precision)还是尽可能的找的全(查全率,recall)亦或者两者都要考虑(F1或者ROC曲线下面积);还或者说,我不仅要关注准确率还要考虑时间效率(此时可以将准确率与算法的运行时间做一个简单的加权,来构建出一个新的指标)。
我们需要确定使用的指标,并且在优化过程中不再更改,否者你会不知道究竟哪个参数好,因为两个不同的指标之间不容易比较。另外,需要明确使用一个指标,这样能够更加直观的观察不同参数之间的好坏。
4、对数据进行归一化/标准化处理。
归一化的原因:统一量纲、便于梯度的计算、加快收敛等
归一化之前
归一化之后
归一化:一般采用max-min归一化,使得数据缩放到大小为(-1,1)或者(0,1)之间。
标准化:z-scores标准化,使得数据整体的均值为0,方差为1。
对于图像数据的归一化可以采用除以255(如果图像像素在0-255之间)的方式。
数据归一化的方式是对训练集进行归一化,然后将这种归一化方式应用到验证集和测试集中。
5、打印你的网络参数个数,与你的数据量进行一个对比。网络越大,功能越强,但也更容易过拟合。不要尝试用10,000个样本来学习一百万个参数。
1、开始调参之前先要做些什么?
1、首先不使用Dropout以及正则化项,使用一个较小的数据集(从原始数据集中取出一小部分),让你的网络去训练拟合这个数据集,看看能否做到损失为0 / 准确率为1 (前提是这个小数据集不能只包含一类样本)。
2、在一轮epoch中,打印出输入、输出,检测数据的正确性(例如图像数据确保size,其他数据检查是否输入为0,以及检查是否每个batch都是相同的值,检查特征与标签是否对应)
3、去除正则化项,观察初始的loss值,并对loss进行预估。
例如,一个二分类问题,使用softmax分类器,那么当样本属于两个类的概率都为0.5的时候,此时的loss = -ln(0.5) = 0.69,后续当网络的loss不再变化时,看看那时候的loss与这个值的关系。如果最终不再变化的loss值等于这个值,那么也就是说网络完全不收敛。
4、可视化训练过程,在每一轮epoch训练完成后,计算验证集上的loss与准确率(你的评价指标),并记录下每一轮epoch后训练集与验证集的loss与评价指标。如果是图像数据,可以进行每一层的可视化。
5、如果可以的话,在开始训练之前,尝试用经典的数据集(网上公开数据集,经常在深度学习的网络中使用的数据集,例如MNIST,CIFAR10)先进行训练,因为这些经典数据集都有参考标准(baseline),而且没有数据方面的问题(如噪声、不平衡、随机性过大导致难以学习的问题等等,尤其是在你自己设计了一个新的网络结构时。
2、如何调参?
1、在确保了数据与网络的正确性之后,使用默认的超参数设置,观察loss的变化,初步定下各个超参数的范围,再进行调参。对于每个超参数,我们在每次的调整时,只去调整一个参数,然后观察loss变化,千万不要在一次改变多个超参数的值去观察loss。
2、对于loss的变化情况,主要有以下几种可能性:上升、下降、不变,对应的数据集有train与val(validation),那么进行组合有如下的可能:
train loss 不断下降,val loss 不断下降——网络仍在学习;
train loss 不断下降,val loss 不断上升——网络过拟合;
train loss 不断下降,val loss 趋于不变——网络欠拟合;
train loss 趋于不变,val loss 趋于不变——网络陷入瓶颈;
train loss 不断上升,val loss 不断上升——网络结构问题;
train loss 不断上升,val loss 不断下降——数据集有问题;
其余的情况,也是归于网络结构问题与数据集问题中。
3、当loss趋于不变时观察此时的loss值与1-3中计算的loss值是否相同,如果相同,那么应该是在梯度计算中出现了nan或者inf导致oftmax输出为0。
此时可以采取的方式是减小初始化权重、降低学习率。同时评估采用的loss是否合理。
3、解决方式
1、当网络过拟合时,可以采用的方式是正则化(regularization)与丢弃法(dropout)以及BN层(batch normalization),正则化中包括L1正则化与L2正则化,在LSTM中采用L2正则化。另外在使用dropout与BN层时,需要主要注意训练集和测试集上的设置方式不同,例如在训练集上dropout设置为0.5,在验证集和测试集上dropout要去除。
2、当网络欠拟合时,可以采用的方式是:去除 / 降低 正则化;增加网络深度(层数);增加神经元个数;增加训练集的数据量。
3、设置early stopping,根据验证集上的性能去评估何时应该提早停止。
4、对于LSTM,可使用softsign(而非softmax)激活函数替代tanh(更快且更不容易出现饱和(约0梯度))
5、尝试使用不同优化算法,合适的优化器可以是网络训练的更快,RMSProp、AdaGrad或momentum(Nesterovs)通常都是较好的选择。
6、使用梯度裁剪(gradient clipping),归一化梯度后将梯度限制在5或者15。
7、学习率(learning rate)是一个相当重要的超参数,对于学习率可以尝试使用余弦退火或者衰减学习率等方法。
7、可以进行网络的融合(网络快照)或者不同模型之间的融合。
参考文献:
2、Machine Learning Yearning,吴恩达
LSTM调参经验的更多相关文章
- 【新人赛】阿里云恶意程序检测 -- 实践记录11.10 - XGBoost学习 / 代码阅读、调参经验总结
XGBoost学习: 集成学习将多个弱学习器结合起来,优势互补,可以达到强学习器的效果.要想得到最好的集成效果,这些弱学习器应当"好而不同". 根据个体学习器的生成方法,集成学习方 ...
- pytorch调参经验(一)
个人博客:https://yifdu.github.io/2018/11/18/pytorch%E8%B0%83%E5%8F%82%E7%BB%8F%E9%AA%8C%EF%BC%88%E4%B8%8 ...
- 神经网络CNN训练心得--调参经验
1.样本要随机化,防止大数据淹没小数据 2.样本要做归一化.关于归一化的好处请参考:为何需要归一化处理3.激活函数要视样本输入选择(多层神经网络一般使用relu)4.mini batch很重要,几百是 ...
- DL 调参经验
2019-10-20 11:45:54 数据侧 1.在数据集很大的情况下,不要立马跑全量数据.可以现在小数据集上进行测试,估算一下运行时间. 2.数据shuffle和augmentation,训练之前 ...
- 漫谈PID——实现与调参
闲话: 作为一个控制专业的学生,说起PID,真是让我又爱又恨.甚至有时候会觉得我可能这辈子都学不会pid了,但是经过一段时间的反复琢磨,pid也不是很复杂.所以在看懂pid的基础上,写下这篇文章,方便 ...
- sklearn中SVM调参说明
写在前面 之前只停留在理论上,没有实际沉下心去调参,实际去做了后,发现调参是个大工程(玄学).于是这篇来总结一下sklearn中svm的参数说明以及调参经验.方便以后查询和回忆. 常用核函数 1.li ...
- LightGBM调参笔记
本文链接:https://blog.csdn.net/u012735708/article/details/837497031. 概述在竞赛题中,我们知道XGBoost算法非常热门,是很多的比赛的大杀 ...
- 基于pytorch的CNN、LSTM神经网络模型调参小结
(Demo) 这是最近两个月来的一个小总结,实现的demo已经上传github,里面包含了CNN.LSTM.BiLSTM.GRU以及CNN与LSTM.BiLSTM的结合还有多层多通道CNN.LSTM. ...
- [调参]CV炼丹技巧/经验
转自:https://www.zhihu.com/question/25097993 我和@杨军类似, 也是半路出家. 现在的工作内容主要就是使用CNN做CV任务. 干调参这种活也有两年时间了. 我的 ...
随机推荐
- Question20180106 Java环境变量的配置及为什么要配置环境变量
Question 1 Java环境变量的配置及为什么要配置环境变量 Q1.1为什么要配置环境变量 在学习JAVA的过程中,涉及到多个环境变量(environment variable)的概念,如PA ...
- 在Win7虚拟机下搭建Hadoop2.6.0+Spark1.4.0单机环境
Hadoop的安装和配置可以参考我之前的文章:在Win7虚拟机下搭建Hadoop2.6.0伪分布式环境. 本篇介绍如何在Hadoop2.6.0基础上搭建spark1.4.0单机环境. 1. 软件准备 ...
- Python基础—03-运算符与分支结构
运算符与分支结构 运算符 赋值运算符 用'='表示,左边只能是变量 算术运算符 +.-.*:加.减.乘 /:除法运算,结果是浮点型 //:除法运算,结果是整型 %:求余 **:求幂 复合运算符 +=. ...
- RPAD()和LPAD()函数进行字符串的填充
RPAD()函数从右边对字符串使用指定的字符进行填充. 格式:RPAD(string,padded_length,[pad_string]) string 表示:被填充的字符串. padded_len ...
- Linux-history的用法
history: history [-c] [-d 偏移量] [n] 或 history -anrw [文件名] 或 history -ps 参数 [参数...] history的作用是显示或操纵历史 ...
- 'sessionFactory' or 'hibernateTemplate' is required
网上都是说在dao中未注入 sessionFactory,然而我有 于是排除 @Autowired public FlightDaoImpl(@Qualifier(value = "ses ...
- js根据年份获取某月份有几天
function getNum(year, month) { var temp; month = parseInt(month, 10); temp = new Date(year, month, 0 ...
- mongodb的windows系统下安装
先下载安装包,地址有下面两个,按需选择吧. https://www.mongodb.com/download-center/v2/community https://www.mongodb.org/d ...
- 解决软件启动报error while loading shared libraries: libgd.so.2: cannot open shared object错误
解决软件启动报error while loading shared libraries: libgd.so.2: cannot open shared object错误 今天安装启动nginx的时候报 ...
- linux文件IO操作篇 (一) 非缓冲文件
文件IO操作分为 2 种 非缓冲文件IO 和 缓冲文件IO 它们的接口区别是 非缓冲 open() close() read() write() 缓冲 fopen() fclose() fread() ...