阅读 175

动手学深度学习4.6 dropout简洁实现

import torch from torch import nn from d2l import torch as d2l 复制代码

dropout1, dropout2 = 0.2, 0.5 net = nn.Sequential(nn.Flatten(),         nn.Linear(784, 256),         nn.ReLU(),         # 在第一个全连接层之后添加一个dropout层         nn.Dropout(dropout1),         nn.Linear(256, 256),         nn.ReLU(),         # 在第二个全连接层之后添加一个dropout层         nn.Dropout(dropout2),         nn.Linear(256, 10)) def init_weights(m):     if type(m) == nn.Linear:         nn.init.normal_(m.weight, std=0.01) net.apply(init_weights) 复制代码

这个模型长这样:

Sequential(   (0): Flatten(start_dim=1, end_dim=-1)   (1): Linear(in_features=784, out_features=256, bias=True)   (2): ReLU()   (3): Dropout(p=0.2, inplace=False)   (4): Linear(in_features=256, out_features=256, bias=True)   (5): ReLU()   (6): Dropout(p=0.5, inplace=False)   (7): Linear(in_features=256, out_features=10, bias=True) ) 复制代码

  • (0):对输入进行处理,即28*28的扁平化为784的向量

  • (1):第一层是输入层

  • (2): 对第一层加激活函数ReLU()

  • (3): 对第一层进行Dropout,其中p=0.2

  • (4): 隐藏层1是256的向量

  • (5): 对隐藏层1加激活函数ReLU()

  • (6): 对隐藏层1进行Dropout,其中p=0.5

  • (7): 隐藏层2是256的向量,输出层是10分类

对于这个隐藏层的p,就是服从这个公式:

E[xi′]=p⋅0+(1−p)xi1−p=xi\begin{aligned} E\left[x_{i}'\right] &=p \cdot 0+(1-p) \frac{x_{i}}{1-p} =x_{i} \end{aligned}E[xi]=p⋅0+(1−p)1−pxi=xi

对于输入层到隐藏层1就是:

E(h11′)=0.2×0+(1−0.2)h111−0.2=h11E\left(h_{11}^{\prime}\right)=0.2 \times 0+(1-0.2) \frac{h_{11}}{1-0.2}=h_{11}E(h11)=0.2×0+(1−0.2)10.2h11=h11

对于隐藏层1到隐藏层2就是:

E(h21′)=0.5×0+(1−0.5)h211−0.5=h11E\left(h_{21}^{\prime}\right)=0.5 \times 0+(1-0.5) \frac{h_{21}}{1-0.5}=h_{11}E(h21)=0.5×0+(1−0.5)10.5h21=h11

num_epochs, lr, batch_size = 10, 0.5, 256 loss = nn.CrossEntropyLoss() train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) trainer = torch.optim.SGD(net.parameters(), lr=lr) trainer = torch.optim.SGD(net.parameters(), lr=lr) d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer) 复制代码

这段代码和动手学深度学习4.6 dropout手动实现里边的一模一样。

  • 设置训练迭代次数、学习率、批量大小

  • loss使用交叉熵

  • 读取数据集

  • 训练

再次重申,可能看起来手动实现和这个的区别不大,不就是自己弄个Sequential吗,但是当处理海量数据的时候,调库就是比你自己手写的速度更快效率更高。

手动实现是为了明白原理,简洁实现是为了提高效率。


作者:LolitaAnn
链接:https://juejin.cn/post/7031111339531567118

文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐