动手学深度学习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)1−0.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)1−0.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