神经网络算法中,参数的设置或者调整,有什么方法可以采用

神经网络算法中,参数的设置或者调整,有什么方法可以采用,第1张

若果对你有帮助,请点赞。

神经网络的结构(例如2输入3隐节点1输出)建好后,一般就要求神经网络里的权值和阈值。现在一般求解权值和阈值,都是采用梯度下降之类的搜索算法(梯度下降法、牛顿法、列文伯格-马跨特法、狗腿法等等),这些算法会先初始化一个解,在这个解的基础上,确定一个搜索方向和一个移动步长(各种法算确定方向和步长的方法不同,也就使各种算法适用于解决不同的问题),使初始解根据这个方向和步长移动后,能使目标函数的输出(在神经网络中就是预测误差)下降。 然后将它更新为新的解,再继续寻找下一步的移动方向的步长,这样不断的迭代下去,目标函数(神经网络中的预测误差)也不断下降,最终就能找到一个解,使得目标函数(预测误差)比较小。

而在寻解过程中,步长太大,就会搜索得不仔细,可能跨过了优秀的解,而步长太小,又会使寻解过程进行得太慢。因此,步长设置适当非常重要。

学习率对原步长(在梯度下降法中就是梯度的长度)作调整,如果学习率lr = 0.1,那么梯度下降法中每次调整的步长就是0.1*梯度,

而在matlab神经网络工具箱里的lr,代表的是初始学习率。因为matlab工具箱为了在寻解不同阶段更智能的选择合适的步长,使用的是可变学习率,它会根据上一次解的调整对目标函数带来的效果来对学习率作调整,再根据学习率决定步长。

机制如下:

if newE2/E2 >maxE_inc %若果误差上升大于阈值

lr = lr * lr_dec %则降低学习率

else

if newE2 <E2%若果误差减少

lr = lr * lr_inc%则增加学习率

end

详细的可以看《神经网络之家》nnetinfo里的《[重要]写自己的BP神经网络(traingd)》一文,里面是matlab神经网络工具箱梯度下降法的简化代码

若果对你有帮助,请点赞。

祝学习愉快

我们到目前为止在神经网络中使用了好几个参数, 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的好坏,目前神经网络还有很多方面理论基础需要研究,为什么学习能力强,现在的一些实验表明结果比较好,但发展底层理论基础还有很长的路要走。

不一定,也可设置为[-1,1]之间。事实上,必须要有权值为负数,不然只有激活神经元,没有抑制的也不行。至于为什么在[-1,1]之间就足够了,这是因为归一化和Sigmoid函数输出区间限制这两个原因。一般在编程时,设置一个矩阵为bounds=ones(S,1)*[-1,1]%权值上下界。

在MATLAB中,可以直接使用net = init(net)来初始化。我们可以通过设定网络参数net.initFcn和net.layer{i}.initFcn这一技巧来初始化一个给定的网络。net.initFcn用来决定整个网络的初始化函数。前馈网络的缺省值为initlay,它允许每一层用单独的初始化函数。设定了net.initFcn ,那么参数net.layer{i}.initFcn 也要设定用来决定每一层的初始化函数。对前馈网络来说,有两种不同的初始化方式经常被用到:initwb和initnw。initwb函数根据每一层自己的初始化参数(net.inputWeights{i,j}.initFcn)初始化权重矩阵和偏置。前馈网络的初始化权重通常设为rands,它使权重在-1到1之间随机取值。这种方式经常用在转换函数是线性函数时。initnw通常用于转换函数是曲线函数。它根据Nguyen和Widrow[NgWi90]为层产生初始权重和偏置值,使得每层神经元的活动区域能大致平坦的分布在输入空间。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11267155.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存