神经网络中Dropout和Padding

1、Padding

Padding有两种方式,same和valid,其中same比较常见,因为是进行了填充,对图像的每一个像素点都进行了卷积操作,而valid有可能扔到一些边缘信息。两种的计算方式不同:

计算

2、Dropout

Dropout有意思的是每次训练都会随机扔到一些节点不进行训练,已达到防止过拟合的效果。当然在预测的时候是所有的节点都参加进行的预测,但是在预测的时候所有节点的权重要乘以一个系数,也就是我们之前所设定的dropout比率进行“缩放”。

Dropout中的参数设置:rate 、noise_shape

一般我们会将dropout理解为“一种低成本的集成策略”,这是对的。具体过程大概可以这样理解。
经过上述置零操作后,我们可以认为0的那部分是被丢弃了,丢失了一部分信息。然而虽然信息丢失了,但生活还得继续呀,不对,是训练还得继续,所以就逼着模型用剩下的信息去拟合目标了。然而每次dropout是随机的,我们就不能侧重于某些节点了。所以总的来说就是——每次逼着模型用少量的特征学习,每次被学习的特征有不同,那么就是说,每个特征都应该对模型的预测有所贡献(而不是侧重部分特征,导致过拟合)。
最后预测的时候,就不dropout了,所以就等价于所有局部特征的平均(这次终于用上所有的信息了),理论上效果就变好了,过拟合也不严重了(因为风险平摊到了每个特征而不是部分特征上面)。

更灵活些的用法

#有时候我们希望对dropout的方式做一些约束,比如,同一个batch内所有样本我想要同样的方式dropout,而不是第一个样本只dropout了第一个节点,第二个样本则只dropout第二个节点;又比如,用LSTM做文本分类时,我希望按照词向量来dropout,也就是每次要不把整个词向量都dropout掉,要不就整个词向量都保留,而不是只dropout掉一个词向量的某些节点;再再比如,用CNN多RGB图像分类时,我希望按照通道来dropout,每幅图像要dropout掉R、G、B三通道的任意一个通道(有点像颜色变换,或者RGB扰动),而不是只dropout掉图像上的某些像素(这个等价于图像加噪音)。
为了实现这些需求,需要用到dropout中的noise_shape参数,这个参数在Keras的Dropout层以及tf.nn.dropout都有(我只会这两个框架),两者的含义是一样的。然而,网上对dropout的这个参数鲜有提及,就算说了也含糊不清。下面以tf.nn.dropout(x, 0.5, noise_shape)为例。首先noise_shape是一个一维张量,说白了,就是一个一维数组(可以是list或者tuple),长度必须跟x.shape一样。而且,noise_shape里边的元素,只能是1或者是x.shape里边对应的元素。比如,x.shape=(3,4,5),那么noise_shape就只有下面8种允许情况:
(3,4,5)、(1,4,5)、(3,1,5)、(3,4,1)、(1,1,5)、(1,4,1)、(3,1,1)、(1,1,1)

那每一种的含义是什么呢?可以这样理解:**哪个轴为1,哪个轴就会被一致地dropout。**比如(3,4,5)时就是普通的dropout,没任何约束,(1,4,5)就是说batch中的每个样本要按同样的方式dropout(可以理解为,加在每个样本的噪音都是一样的),如果(3,4,5)是代表(句子数,每个句子的词数,每个词向量的维度),那么(3,4,1)就表示按照词向量来dropout(可以理解为随机跳过某些词)。对于有些读者来说,可能用numpy的代码来理解可能会直观一些,那就是:

def Dropout(x, drop_proba, noise_shape):
    return x*np.random.choice(
                              [0,1], 
                              noise_shape, 
                              p=[drop_proba,1-drop_proba]
                             )/(1.-drop_proba)

参考:https://spaces.ac.cn/archives/4521

Dropout可以解决过拟合

(1)取平均的作用: 先回到标准的模型即没有dropout,我们用相同的训练数据去训练5个不同的神经网络,一般会得到5个不同的结果,此时我们可以采用 “5个结果取均值”或者“多数取胜的投票策略”去决定最终结果。例如3个网络判断结果为数字9,那么很有可能真正的结果就是数字9,其它两个网络给出了错误结果。这种“综合起来取平均”的策略通常可以有效防止过拟合问题。因为不同的网络可能产生不同的过拟合,取平均则有可能让一些“相反的”拟合互相抵消。dropout掉不同的隐藏神经元就类似在训练不同的网络,随机删掉一半隐藏神经元导致网络结构已经不同,整个dropout过程就相当于对很多个不同的神经网络取平均。而不同的网络产生不同的过拟合,一些互为“反向”的拟合相互抵消就可以达到整体上减少过拟合。
(2)减少神经元之间复杂的共适应关系: 因为dropout程序导致两个神经元不一定每次都在一个dropout网络中出现。这样权值的更新不再依赖于有固定关系的隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况 。迫使网络去学习更加鲁棒的特征 ,这些特征在其它的神经元的随机子集中也存在。换句话说假如我们的神经网络是在做出某种预测,它不应该对一些特定的线索片段太过敏感,即使丢失特定的线索,它也应该可以从众多其它线索中学习一些共同的特征。从这个角度看dropout就有点像L1,L2正则,减少权重使得网络对丢失特定神经元连接的鲁棒性提高。
(3)Dropout类似于性别在生物进化中的角色:物种为了生存往往会倾向于适应这种环境,环境突变则会导致物种难以做出及时反应,性别的出现可以繁衍出适应新环境的变种,有效的阻止过拟合,即避免环境改变时物种可能面临的灭绝。

一般的在训练过程中使用dropout层就不需要再测试的时候做过多的操作了,但是需要注意的是dropout层会改变整体的方差,使得训练时候的方差大于测试时候的方差,那么怎么解决,一个最好的方式就是,冻结dropout层,然后重新对模型训练一两个批次便可以了,通过验证可得该种方式可以对最终的准确度有多提高。
Using batch normalization after dropout has a small problem. During training, dropout zeros some outputs, but scales up the remaining ones to maintain the output average. However, the output variance is not preserved. The variance is larger during training than it is during inference.
Batch normalization also behaves differently during training and inference. During training batches are normalized, but at the same time a running average of batch mean and variance is computed. This running average is used as a sample estimate during inference. It should be immediately obvious that the running average value is not a good approximation of the sample variance during inference, because dropout behavior changes the variance. See Xiang Li, Shuo Chen, Xiaolin Hu, Jian Yang, “Understanding the Disharmony between Dropout and Batch Normalization by Variance Shift”, arXiv:1801.05134.
One of the proposed solutions is to recompute the batch normalization running average without dropout, while freezing other layers. The resulting accuracy is expected to be slightly better.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 PyTorch ,可以通过 `torch.nn.Dropout` 模块来实现卷积神经网络Dropout 操作。下面是一个简单的示例代码: ```python import torch import torch.nn as nn class ConvNet(nn.Module): def __init__(self): super(ConvNet, self).__init__() self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1) self.relu = nn.ReLU() self.dropout = nn.Dropout(p=0.5) self.fc = nn.Linear(16 * 28 * 28, 10) def forward(self, x): out = self.conv1(x) out = self.relu(out) out = self.dropout(out) out = out.view(out.size(0), -1) out = self.fc(out) return out # 创建模型实例 model = ConvNet() # 使用 Dropout 模块进行训练 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9) # 在训练循环使用 Dropout for epoch in range(num_epochs): # ... model.train() for images, labels in train_loader: # ... outputs = model(images) loss = criterion(outputs, labels) # ... # ... model.eval() with torch.no_grad(): for images, labels in test_loader: # ... outputs = model(images) # ... ``` 在上面的示例,我们创建了一个简单的卷积神经网络 (`ConvNet`),其包含一个 Dropout 模块 (`nn.Dropout`)。在模型的 `forward` 方法,我们将 Dropout 应用于卷积层之后的激活函数之前。 在训练循环,我们使用 `model.train()` 将模型设置为训练模式,这会启用 Dropout 模块的随机失活。而在测试循环,我们使用 `model.eval()` 将模型设置为评估模式,这会禁用 Dropout 模块的随机失活。 请注意,`p` 参数是 Dropout 的丢弃概率,即每个神经元被丢弃的概率。在上面的示例,我们将丢弃概率设置为 0.5。你可以根据自己的需求调整这个值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值