神经网络参数hyper-parameters选择

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了神经网络参数hyper-parameters选择相关的知识,希望对你有一定的参考价值。

参考技术A 我们到目前为止在神经网络中使用了好几个参数, hyper-parameters包括:

学习率(learning rate):η

Regularization parameter:λ

之前只是设置了一些合适的值, 如何来选择合适的hyper-parameters呢?

例如:

我们设置如下参数:

隐藏层: 30个神经元, mini-batch size: 10, 训练30个epochs

η=10.0, λ=1000.0

>>>importmnist_loader>>>

training_data,validation_data,test_data=\...mnist_loader.load_data_wrapper()

>>>importnetwork2>>>net=network2.Network([784,30,10])     >>>net.SGD(training_data,30,10,10.0,lmbda=1000.0,...evaluation_data=validation_data,monitor_evaluation_accuracy=True)

结果:

结果: Epoch 0 training complete Accuracy on evaluation data: 1030 / 10000

Epoch 1 training complete Accuracy on evaluation data: 990 / 10000 

Epoch 2 training complete Accuracy on evaluation data: 1009 / 10000

差到跟随机猜测一样!

神经网络中可变化调整的因素很多:

神经网络结构::层数、每层神经元个数多少

初始化w和b的方法

Cost函数(目标定义的cost函数最小)

Regularization: L1、L2(减少overfitting的方式)

Sigmoid输出还是Softmax?

使用Droput?

训练集大小

mini-batch size()

学习率(learning rate):η

Regularization parameter:λ

总体策略: 

从简单的出发:开始实验,循环的个数减小

如:MNIST数据集, 开始不知如何设置, 可以先简化使用0,1两类图, 减少80%数据量, 用两层神经网络[784, 2] (比[784, 30, 2]快),取得设置是否合理?

更快的获取反馈: 之前每个epoch来检测准确率, 可以替换为每1000个图之后,或者减少validation set的量, 比如用100代替10000

重复实验:

>>> net = network2.Network([784, 10]) 

>>> net.SGD(training_data[:1000], 30, 10, 10.0, lmbda = 1000.0, \ ... evaluation_data=validation_data[:100], \ ... monitor_evaluation_accuracy=True) 

Epoch 0 training complete Accuracy on evaluation data: 10 / 100 

 Epoch 1 training complete Accuracy on evaluation data: 10 / 100 

 Epoch 2 training complete Accuracy on evaluation data: 10 / 100

更快得到反馈, 之前可能每轮要等10秒,现在不到1秒: λ之前设置为1000, 因为减少了训练集的数量, λ为了保证weight decay一样,对应的减少λ = 20.0

>>> net = network2.Network([784, 10]) 

>>> net.SGD(training_data[:1000], 30, 10, 10.0, lmbda = 20.0, \ ... evaluation_data=validation_data[:100], \ ... monitor_evaluation_accuracy=True)

结果:

Epoch0 training complete Accuracy one valuationdata:12/100

Epoch1 training complete Accuracy one valuationdata:14/100

Epoch2 training complete Accuracy one valuationdata:25/100

Epoch3 training complete Accuracy one valuationdata:18/100

也许学习率η=10.0太低? 应该更高?增大到100:

>>>net=network2.Network([784,10])

>>>net.SGD(training_data[:1000],30,10,100.0,lmbda=20.0,\...evaluation_data=validation_data[:100],\...monitor_evaluation_accuracy=True)

结果:

Epoch0 training complete Accuracy one valuationdata:10/100

Epoch1 training complete Accuracy one valuationdata:10/100

Epoch2 training complete Accuracy one valuationdata:10/100

Epoch3 training complete Accuracy one valuationdata:10/100

结果非常差, 也许结果学习率应该更低? =10

>>>net=network2.Network([784,10])

>>>net.SGD(training_data[:1000],30,10,1.0,lmbda=20.0,\...evaluation_data=validation_data[:100],\...monitor_evaluation_accuracy=True)

结果好很多:

Epoch0 training complete Accuracy one valuationdata:62/100

Epoch1 training complete Accuracy one valuationdata:42/100

Epoch2 training complete Accuracy one valuationdata:43/100

Epoch3 training complete Accuracy one valuationdata:61/100

假设保持其他参数不变: 30 epochs, mini-batch size: 10,λ=5.0

实验学习率=0.025, 0.25, 2.5

如果学习率太大,可能造成越走越高,跳过局部最低点 太小,学习可能太慢

对于学习率, 可以从0.001, 0.01, 0.1, 1, 10 开始尝试, 如果发现cost开始增大, 停止, 实验更小的微调 。

对于MNIST, 先找到0.1, 然后0.5, 然后0.25。

对于提前停止学习的条件设置, 如果accuracy在一段时间内变化很小 (不是一两次,5到10次变化很小)。

之前一直使用学习率是常数, 可以开始设置大一下, 后面逐渐减少: 比如开始设定常数, 直到在验证集上准确率开始下降, 减少学习率 (/2, /3)。

对于regularization parameterλ:

先不设定regularization, 把学习率调整好, 然后再开始实验λ, 1.0, 10, 100..., 找到合适的, 再微调。

对于mini-batch size:

太小: 没有充分利用矩阵计算的library和硬件的整合的快速计算。

太大: 更新权重和偏向不够频繁。

好在mini-batch size和其他参数变化相对独立, 所以不用重新尝试, 一旦选定。

自动搜索: 网格状搜索各种参数组合

 (grid search) 2012**Random search for hyper-parameter optimization, by James Bergstra and Yoshua Bengio (2012). by James Bergstra and Yoshua Bengio 1998 

paper**Efficient BackProp, by Yann LeCun, Léon Bottou, Genevieve Orr and Klaus-Robert Müller (1998) by Yann LeCun, Léon Bottou, Genevieve Orr and Klaus-Robert Müller. 

参数之前会互相影响 如何选择合适的hyper-parameters仍是一个正在研究的课题,

随机梯度下降有没有其他变种: Hessian 优化, Momentum-based gradient descent 

除了sigmoid,其他人工神经网络的模型? 

tanh

tanh(w⋅x+b)

要靠实验比较rectified、linear和sigmoid,tanh的好坏,目前神经网络还有很多方面理论基础需要研究,为什么学习能力强,现在的一些实验表明结果比较好,但发展底层理论基础还有很长的路要走。

深度学习调参策略

超参数(Hyper-Parameter)是困扰神经网络训练的问题之一,因为这些参数不可通过常规方法学习获得。

神经网络经典五大超参数:

学习率(Leraning Rate)、权值初始化(Weight Initialization)、网络层数(Layers)

单层神经元数(Units)、正则惩罚项(Regularizer|Normalization)

这五大超参数使得神经网络更像是一门实践课,而不是理论课。

懂神经网络可能只要一小时,但是调神经网络可能要几天。

https://zhuanlan.zhihu.com/p/24720954#!

 

英文介绍:]

http://lamda.nju.edu.cn/weixs/project/CNNTricks/CNNTricks.html

知乎上的一些比较好的解答:https://www.zhihu.com/question/41631631?from=profile_question_card

https://zhuanlan.zhihu.com/p/24720954#!

 

没做过CNN,RNN,调过连续值DNN,以下经验仅限于CTR
1.样本要足够随机,防止大数据淹没小数据
2.样本要做归一化
3.激活函数要视样本输入选择
4.minibatch很重要,几百到几千是比较合适的(很大数据量的情况下),无论是cnn还是rnn,batch normalization都有用,不一定结果提高几个点,收敛快多了
5.learning rate很重要,可以直接用adagrad or adadelta,省去一些麻烦,然后把冲量调到0.9以上
6.权重初始化,可用高斯分布乘上一个很小的数
7.loss不降了lr就除10


调了快1年的rnn, 深刻的感受到,深度学习是一门实验科学,下面是一些炼丹心得,后面会不断补充. 有问题的地方,也请大家指正.
  1. 参数初始化,下面几种方式,随便选一个,结果基本都差不多.

    1. uniform
      W = np.random.uniform(low=-scale, high=scale, size=shape)
    2. glorot_uniform
      scale = np.sqrt(6. / (shape[0] + shape[1]))
      np.random.uniform(low=-scale, high=scale, size=shape)
    3. 高斯初始化:
      w = np.random.randn(n) / sqrt(n),n为参数数目
      激活函数为relu的话,推荐
      w = np.random.randn(n) * sqrt(2.0/n)
    4. svd ,对RNN效果比较好,可以有效提高收敛速度.
  2. 数据预处理方式

    1. zero-center ,这个挺常用的.
      X -= np.mean(X, axis = 0) # zero-center
      X /= np.std(X, axis = 0) # normalize
    2. PCA whitening,这个用的比较少.
  3. 训练技巧

    1. 要做梯度归一化,即算出来的梯度除以minibatch size
    2. clip c(梯度裁剪): 限制最大梯度,其实是value = sqrt(w1^2+w2^2….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15
    3. dropout对小数据防止过拟合有很好的效果,值一般设为0.5,小数据上dropout+sgd效果更好. dropout的位置比较有讲究, 对于RNN,建议放到输入->RNN与RNN->输出的位置.关于RNN如何用dropout,可以参考这篇论文:arxiv.org/abs/1409.2329
    4. adam,adadelta等,在小数据上,我这里实验的效果不如sgd,如果使用sgd的话,可以选择从1.0或者0.1的学习率开始,隔一段时间,在验证集上检查一下,如果cost没有下降,就对学习率减半. 我看过很多论文都这么搞,我自己实验的结果也很好. 当然,也可以先用ada系列先跑,最后快收敛的时候,更换成sgd继续训练.同样也会有提升.
    5. 除了gate之类的地方,需要把输出限制成0-1之外,尽量不要用sigmoid,可以用tanh或者relu之类的激活函数.
    6. rnn的dim和embdding size,一般从128上下开始调整. batch size,一般从128左右开始调整.batch size合适最重要,并不是越大越好.
    7. word2vec初始化,在小数据上,不仅可以有效提高收敛速度,也可以可以提高结果.
    8. 尽量对数据做shuffle
    9. LSTM 的forget gate的bias,用1.0或者更大的值做初始化,可以取得更好的结果,来自这篇论文:jmlr.org/proceedings/pa, 我这里实验设成1.0,可以提高收敛速度.实际使用中,不同的任务,可能需要尝试不同的值.
  4. Ensemble: 论文刷结果的终极核武器,深度学习中一般有以下几种方式

    1. 同样的参数,不同的初始化方式
    2. 不同的参数,通过cross-validation,选取最好的几组
    3. 同样的参数,模型训练的不同阶段
    4. 不同的模型,进行线性融合. 例如RNN和传统模型.
下面的网站也有一些总结:
http://blog.csdn.net/chenzhi1992/article/details/52905569

 

以上是关于神经网络参数hyper-parameters选择的主要内容,如果未能解决你的问题,请参考以下文章

如何选取一个神经网络中的超参数hyper-parameters

深度学习调参策略

暗黑破坏神II中文版怎么在属性的路径后面添加参数

Docker成神之路——浅谈DockerOverlay网络

如何使用视觉输入训练人工神经网络玩暗黑破坏神 2?

机器学习脉络梳理