丢弃法(基于MXNet)

丢弃法

可以采用倒置丢弃法来应对过拟合问题。

1. 方法

⼀个单隐藏层的多层感知机。其中输⼊个数为4,隐藏单元个数为5,且隐藏单元 h i ( i = 1 , . . . , 5 ) h_i(i = 1, . . . , 5) hii=1,...,5的计算表达式为:
h i = ϕ ( x 1 w 1 i + x 2 w 2 i + x 3 w 3 i + x 4 w 4 i + b i ) (1) h_i=\phi(x_1w_{1i}+x_2w_{2i}+x_3w_{3i}+x_4w_{4i}+b_i) \tag 1 hi=ϕ(x1w1i+x2w2i+x3w3i+x4w4i+bi)(1)
这里 ϕ \phi ϕ是激活函数, x 1 , . . . , x 4 x_1,...,x_4 x1,...,x4是输入,隐藏单元 i i i的权重参数为 w 1 i , . . . , w 4 i w_{1i},...,w_{4i} w1i,...,w4i,偏差参数为 b i b_i bi。当对该隐藏层使用丢弃法时,该层的隐藏单元将有一定概率被丢弃掉。设丢弃概率为 p p p,那么有 p p p的概率 h i h_i hi会被清零,有 1 − p 1-p 1p的概率 h i h_i hi会除以 1 − p 1-p 1p做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量 ξ i \xi_i ξi为0和1的概率分别为 p p p 1 − p 1-p 1p。使用丢弃法时我们计算新的隐藏单元 h i ′ h_i^{'} hi
h i ′ = ξ i 1 − p h i (2) h_i^{'}=\frac{\xi_i}{1-p}h_i \tag 2 hi=1pξihi(2)
由于 E ( ξ i ) = 1 − p E(\xi_i)=1-p E(ξi)=1p,因此:
E ( h i ′ ) = E ( ξ i ) 1 − p h i = h i (3) E(h_i^{'})=\frac{E(\xi_i)}{1-p} h_i = h_i \tag 3 E(hi)=1pE(ξi)hi=hi(3)
即丢弃法不改变其输⼊的期望值。使⽤丢弃法,⼀种可能的结果如图所⽰,其中 h 2 h_2 h2 h 5 h_5 h5被清零。这时输出值的计算不再依赖 h 2 h_2 h2 h 5 h_5 h5,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即 h 1 , . . . , h 5 h_1, . . . , h_5 h1,...,h5都有可能被清零,输出层的计算无法过度依赖 h 1 , . . . , h 5 h_1, . . . , h_5 h1,...,h5中的任⼀个,从而在训练模型时起到正则化的作用,并可以用来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,⼀般不使⽤丢弃法。
在这里插入图片描述

2. diy实现

drop函数将以drop_prob的概率丢弃NDArray输入X中的元素

from mxnet import autograd, gluon, init, nd
from mxnet.gluon import loss as gloss, nn
def dropout(X, drop_prob):
    assert 0 <= drop_prob <=1 # 检查是否为合法输入
    keep_prob = 1 - drop_prob
    if keep_prob == 0:
        return X.zeros_like()
    mask = nd.random.uniform(0, 1, X.shape) < keep_prob
    return mask * X / keep_prob
# 测试dropout函数
X = nd.arange(16).reshape((2, 8))
dropout(X, 0)


[[ 0. 1. 2. 3. 4. 5. 6. 7.]
[ 8. 9. 10. 11. 12. 13. 14. 15.]]
<NDArray 2x8 @cpu(0)>

dropout(X, 0.5)


[[ 0. 2. 4. 6. 0. 0. 0. 14.]
[ 0. 18. 0. 0. 24. 26. 28. 0.]]
<NDArray 2x8 @cpu(0)>

dropout(X, 1)


[[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]]
<NDArray 2x8 @cpu(0)>

定义模型参数

我们将定义⼀个包含两个隐藏层的多层感知机,其中两个隐藏层的输出个数都是256。

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256
W1 = nd.random.normal(scale=0.01, shape=(num_inputs, num_hiddens1))
b1 = nd.zeros(num_hiddens1)
W2 = nd.random.normal(scale=0.01, shape=(num_hiddens1, num_hiddens2))
b2 = nd.zeros(num_hiddens2)
W3 = nd.random.normal(scale=0.01, shape=(num_hiddens2, num_outputs))
b3 = nd.zeros(num_outputs)

params = [W1, b1, W2, b2, W3, b3]
for param in params:
    param.attach_grad()

定义模型

全连接层和激活函数ReLU串起来,并对每个激活函数的输出使⽤丢弃法。我们可以分别设置各个层的丢弃概率。通常的建议是把靠近输⼊层的丢弃概率设得小⼀点。

drop_prob1, drop_prob2 = 0.2, 0.5
def net(X):
    X = X.reshape((-1, num_inputs))
    H1 = (nd.dot(X, W1) + b1).relu()
    if autograd.is_training():
        H1 = dropout(H1, drop_prob1)
    H2 = (nd.dot(H1, W2) + b2).relu()
    if autograd.is_training():
        H2 = dropout(H2, drop_prob2)
    return nd.dot(H2, W3) + b3
from utils import load_data_fashion_mnist, train_ch3
num_epochs, lr, batch_size = 5, 0.5, 256
loss = gloss.SoftmaxCrossEntropyLoss()
train_iter, test_iter = load_data_fashion_mnist(batch_size)
train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)
epoch 1, loss 1.2918, train acc 0.497, test acc 0.746
epoch 2, loss 0.6188, train acc 0.767, test acc 0.818
epoch 3, loss 0.5200, train acc 0.811, test acc 0.846
epoch 4, loss 0.4670, train acc 0.829, test acc 0.857
epoch 5, loss 0.4332, train acc 0.842, test acc 0.862

3. 简洁实现

在Gluon中,我们只需要在全连接层后添加Dropout层并指定丢弃概率。在训练模型时,Dropout层将以指定的丢弃概率随机丢弃上⼀层的输出元素;在测试模型时,Dropout层并不发挥作⽤。

net = nn.Sequential()
net.add(nn.Dense(256, activation="relu"), nn.Dropout(drop_prob1), nn.Dense(256, activation="relu"), nn.Dropout(drop_prob2), nn.Dense(10))
net.initialize(init.Normal(sigma=0.01))
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': lr})
train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, trainer)
epoch 1, loss 1.2261, train acc 0.533, test acc 0.766
epoch 2, loss 0.6071, train acc 0.774, test acc 0.828
epoch 3, loss 0.5046, train acc 0.813, test acc 0.845
epoch 4, loss 0.4563, train acc 0.833, test acc 0.853
epoch 5, loss 0.4259, train acc 0.843, test acc 0.859
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeeGLMath

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值