大家好,又见面了,我是你们的朋友全栈君。
1.dropout解决的问题
深度神经网络的训练是一件非常困难的事,涉及到很多因素,比如损失函数的非凸性导致的局部最优值、计算过程中的数值稳定性、训练过程中的过拟合等。
过拟合是指模型训练到一定程度后,在测试集上得到的测试误差远大于在训练集上得到的误差。
导致过拟合的主要原因有:
1. 训练数据集太小
2. 模型太复杂
3. 过度训练
2.dropout
dropout是指在训练一个很大的神经网络时,它在每次迭代的过程中随机“关闭”一些神经元,被关闭的神经元在前向和反向传播中都不贡献作用,英文即是“dropout”的意思。如下图所示:
我们看到图中打叉的神经元就是被“dropout”掉的神经元,和这些个神经元相连接的权重值也一并被“抹去”,不参与本次训练。不参与本次训练是说在当前的batch中,不参与训练,每个batch都会随机挑选神经元做dropout。
dropout为什么可以防止过拟合
dropout的解决方案,在每一次迭代的过程中,我们会随机dropout掉一些神经元(至于在那一层做dropout,需要看不同的情况),如果设置的dropout的值为0.8,则表示每个神经元有80%的概率被留下来,20%的概率被”抹去“。这就相当于我们从原来的神经网络中随机采样了80%的节点,组成了一个新的神经网络,这个是原来的神经网络的一个子网络,但是规模要比原来的神经网络小很多,并且训练代价也比较小。我们多次迭代优化,每次迭代优化都会做这样的”随机采样“,从原来的网络中构造一个子网络(sub-network),而每次构造的网络也都不尽相同,这样每个神经元对另一个特定神经元的激活很不敏感。这样参数就不会过分依赖于训练数据,增加了模型的泛化能力。
只在训练过程中使用dropout,在测试期间不使用dropout。因为在测试阶段,我们不期望输出结果是随机的,如果测试阶段应用了dropout,预测会受到干扰。
inverted dropout函数做法:举例神经网络 训练阶段前向传播第一层dropout
Z1=np.dot(W1,X)+b1
A1=relu(Z1)
D1=np.random.rand(A1.shape[0],A2.shape[1])
D1=D1<keep_prop
A1=np.multiply(A1,D1)
A1=A1/keep_prop #确保A1期望不变,这样测试阶段,没有dropout也没有影响
Z2=np.dot(A1,X)+b2
import numpy as np
def relu(x):
s = np.maximum(0,x)
return s
w1=[[1,2,3],[1,2,3],[4,5,6],[4,5,6]]
x=[[1,2],[1,2],[1,2]]
b=1
z1=np.dot(w1,x)+b
print(z1)
[[ 7 13]
[ 7 13]
[16 31]
[16 31]]
a1=relu(z1)
d1=np.random.rand(a1.shape[0],a1.shape[1])
print(d1)
[[0.58695556 0.41508454]
[0.16031604 0.24994934]
[0.10260241 0.8237806 ]
[0.28117361 0.8992166 ]]
d1=d1<0.8
print(d1)
[[ True True]
[ True True]
[ True False]
[ True False]]
a1=np.multiply(a1,d1)
print(a1)
[[ 7 13]
[ 7 13]
[16 0]
[16 0]]
a1=a1/0.8
print(a1)
[[ 8.75 16.25]
[ 8.75 16.25]
[20. 0. ]
[20. 0. ]]
train 和 test 的时候,dropout的概率怎么设置:按照原始的论文中,假设dropout的值是 p%,原始神经网络的神经元个数是N,因为在训练的过程中只有 p% 的神经元被保留下来,相应也只有p%的需要被优化的权值保留下来,这导致dropout后sub-network的输出也是整个原始神经网络的输出值的p%。所以,在测试的是时候使用的整个神经网络,我们只需要将每一层的权值矩阵乘以p%就可以保证测试网络的输出期望和训练网络的输出期望值大小一致了。
注意,如果你使用了tensorflow,则在测试的时候要保持dropout的值为1,即不”抹去“任何神经元。
为什么很少见CNN层加dropout: 这种情况确实不多见,典型的TextCNN模型,就是没有在卷积层加dropout。但是原始论文中确实又指出可以在卷积层做dropout ,只是收益并不是太明显。另外,dropout对于具有大量参数的全连接效果最好,而CNN的卷积层不是全连接,参数不是很多,所以效果不明显。论文还建议如果在CNN中加,最好是在开始的层加dropout,越往后的层,越是要小心加dropout。
神经网络加上dropout后,test loss 比 train loss还要小:正常,在不考虑测试集采样偏差的情况下,这种情况的解释是:每次train loss是在一个batch上计算的,而单个batch又是在一个通过dropout得到的sub-network计算得到的,即相当于在单颗树上得到的train loss;而测试的时候,用的整个神经网络,即相当于在整个”森林“上做预测,结果当然会好一下。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/133117.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...