Dropout,顾名思义,就是丢弃,是在多层感知机(MLP)中经常用到的一种用于防止过拟合的一种训练技巧,如上图所示,就是在中间层将一些神经元变为0,然后输出
需要注意的是:在实作中并不会像上面这张图片这样直接删除神经元,而是通过生成一个含有0的Mask去和原来输入的结果作点积(维持输入形状不改变,被去掉的神经元对应的位置乘以0)
李沐老师还提到,Dropout也可以看成是另一种形式的正则化方法(Regulation),也可以用来防止模型过拟合
def dropout_layer(X, dropout):
# input, dropout rate
assert 0 <= dropout <= 1
if dropout == 1:
return torch.zeros_like(X) # 等于1变全0了 全丢了
if dropout == 0:
return X
# 比较得到布尔矩阵
mask = (torch.randn(X.shape) > dropout).float()
# 做矩阵乘法比使用数组索引index的运算速度快 X[mask] = 0
return mask * X /(1.0 - dropout)
net = nn.Sequential(nn.Flatten(),
nn.Linear(784, 256),
nn.ReLU(),
nn.Dropout(dropout1),
nn.Linear(256, 256),
nn.ReLU(),
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.0, inplace=False)
(4): Linear(in_features=256, out_features=256, bias=True)
(5): ReLU()
(6): Dropout(p=0.0, inplace=False)
(7): Linear(in_features=256, out_features=10, bias=True)
)
老师的代码主要用到了两个Dropout
层,因此在模型中对应两个dropout rate,👇下面我们主要对者两个参数进行调节并观察对应的实验结果。dropout rate 后面将简写为(DR)
??注意!!:在运行代码时候,记得修改loss = nn.CrossEntropyLoss(reduction='none')
,里面reduction,不然显示不出来loss!
两种版本的实现的训练效果都差不多(这里假设没有其他优化计算的因素影响模型最后的训练效果),接下来我们就用简洁Torch版本来讨论。
不用dropout的模型准确率反而上升了?
弹幕里面说是因为有可能模型是过拟合的,因为这里的Loss变的非常小
李沐老师说,现在256是一个很大的模型(对于我们这个小的MNIST数据集来说
报错🙅,这个是运行不了的
这个也会出现很问题
这里推测之前运行不了的原因也有可能是第一层的神经网络扔得太多了
综上所述,不管怎么调节dropout rate,还是比不过不用drop的策略,有可能模型还是不够大,应该出现overfitting的情况再使用dropout策略会好一点?
各位看官,都看到这里了,麻烦动动手指头给博主来个点赞8,您的支持作者最大的创作动力哟!
才疏学浅,若有纰漏,恳请斧正
本文章仅用于各位作为学习交流之用,不作任何商业用途,若涉及版权问题请速与作者联系,望悉知