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、可以进行网络的融合(网络快照)或者不同模型之间的融合。

参考文献:

1、深度学习笔记(四):循环神经网络的概念,结构和代码注释

2、Machine Learning Yearning,吴恩达

3、神经网络为什么要归一化

4、LSTM超参数调试注意事项

LSTM调参经验的更多相关文章

  1. 【新人赛】阿里云恶意程序检测 -- 实践记录11.10 - XGBoost学习 / 代码阅读、调参经验总结

    XGBoost学习: 集成学习将多个弱学习器结合起来,优势互补,可以达到强学习器的效果.要想得到最好的集成效果,这些弱学习器应当"好而不同". 根据个体学习器的生成方法,集成学习方 ...

  2. 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 ...

  3. 神经网络CNN训练心得--调参经验

    1.样本要随机化,防止大数据淹没小数据 2.样本要做归一化.关于归一化的好处请参考:为何需要归一化处理3.激活函数要视样本输入选择(多层神经网络一般使用relu)4.mini batch很重要,几百是 ...

  4. DL 调参经验

    2019-10-20 11:45:54 数据侧 1.在数据集很大的情况下,不要立马跑全量数据.可以现在小数据集上进行测试,估算一下运行时间. 2.数据shuffle和augmentation,训练之前 ...

  5. 漫谈PID——实现与调参

    闲话: 作为一个控制专业的学生,说起PID,真是让我又爱又恨.甚至有时候会觉得我可能这辈子都学不会pid了,但是经过一段时间的反复琢磨,pid也不是很复杂.所以在看懂pid的基础上,写下这篇文章,方便 ...

  6. sklearn中SVM调参说明

    写在前面 之前只停留在理论上,没有实际沉下心去调参,实际去做了后,发现调参是个大工程(玄学).于是这篇来总结一下sklearn中svm的参数说明以及调参经验.方便以后查询和回忆. 常用核函数 1.li ...

  7. LightGBM调参笔记

    本文链接:https://blog.csdn.net/u012735708/article/details/837497031. 概述在竞赛题中,我们知道XGBoost算法非常热门,是很多的比赛的大杀 ...

  8. 基于pytorch的CNN、LSTM神经网络模型调参小结

    (Demo) 这是最近两个月来的一个小总结,实现的demo已经上传github,里面包含了CNN.LSTM.BiLSTM.GRU以及CNN与LSTM.BiLSTM的结合还有多层多通道CNN.LSTM. ...

  9. [调参]CV炼丹技巧/经验

    转自:https://www.zhihu.com/question/25097993 我和@杨军类似, 也是半路出家. 现在的工作内容主要就是使用CNN做CV任务. 干调参这种活也有两年时间了. 我的 ...

随机推荐

  1. Question20180106 Java环境变量的配置及为什么要配置环境变量

    Question 1  Java环境变量的配置及为什么要配置环境变量 Q1.1为什么要配置环境变量 在学习JAVA的过程中,涉及到多个环境变量(environment variable)的概念,如PA ...

  2. 在Win7虚拟机下搭建Hadoop2.6.0+Spark1.4.0单机环境

    Hadoop的安装和配置可以参考我之前的文章:在Win7虚拟机下搭建Hadoop2.6.0伪分布式环境. 本篇介绍如何在Hadoop2.6.0基础上搭建spark1.4.0单机环境. 1. 软件准备 ...

  3. Python基础—03-运算符与分支结构

    运算符与分支结构 运算符 赋值运算符 用'='表示,左边只能是变量 算术运算符 +.-.*:加.减.乘 /:除法运算,结果是浮点型 //:除法运算,结果是整型 %:求余 **:求幂 复合运算符 +=. ...

  4. RPAD()和LPAD()函数进行字符串的填充

    RPAD()函数从右边对字符串使用指定的字符进行填充. 格式:RPAD(string,padded_length,[pad_string]) string 表示:被填充的字符串. padded_len ...

  5. Linux-history的用法

    history: history [-c] [-d 偏移量] [n] 或 history -anrw [文件名] 或 history -ps 参数 [参数...] history的作用是显示或操纵历史 ...

  6. 'sessionFactory' or 'hibernateTemplate' is required

    网上都是说在dao中未注入  sessionFactory,然而我有 于是排除 @Autowired public FlightDaoImpl(@Qualifier(value = "ses ...

  7. js根据年份获取某月份有几天

    function getNum(year, month) { var temp; month = parseInt(month, 10); temp = new Date(year, month, 0 ...

  8. mongodb的windows系统下安装

    先下载安装包,地址有下面两个,按需选择吧. https://www.mongodb.com/download-center/v2/community https://www.mongodb.org/d ...

  9. 解决软件启动报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的时候报 ...

  10. linux文件IO操作篇 (一) 非缓冲文件

    文件IO操作分为 2 种 非缓冲文件IO 和 缓冲文件IO 它们的接口区别是 非缓冲 open() close() read() write() 缓冲 fopen() fclose() fread() ...