论文简介:大幅减少训练迭代次数,提高泛化能力:Multi-Sample Dropout

论文标题:Multi-Sample Dropout for Accelerated Training and Bettehttps和http的区别r Generapplicationalization

论文链接:argithub打不开xiv.org/pdf/1905.09…

论文作者:{Hiroshi Inogit命令ue}

gitlab文简介

本文阐述的也是一种 dropout 技术的变形——gitimulti-sample dropout。传统 drappreciateopout 在每轮训练时会从输入中随机选择一组样本(称之为 dropout 样本),而 multi-sample dropout 会创建多个 dropouthttps域名 样本,然后appearance平均所有样本的损失,从而得到最终的损失。这种方法只要在 drappreciateopout 层后复github制部分训练网络,并在这些复制的全连接层之间共享权重就可以了,无需新运算符。通过综合 M 个https协议 dropout 样本的损失来更新网络参数,使得最终损失比任何一个 dropout 样本的损失都低。这样做的效果类似于对一个 minibatch 中的每个输入重复训练 M 次。因此,它大大减少了训练迭代次数。

Multi-Sample Dropout

图 1 是一个简单的 multi-sample dropout 实例,作图github开放私库为我们经常在炼丹中用到的“流水线”apple苹果官网Dropougiti轮胎t,在图片中这个 multi-sample dropout 使用了 2 个 dropgithub官网out 。该实例中只使用github开放私库了现有的深度学习框架和常见的操作符。如图所示,每个 dropgithubout 样本都复制了原网github打不开络中 dropout 层和 dropout 后的几层,图中实例复制了「dropout」、「fullygithub官网 connected」和「softmax +github打不开 loss func」层。在 dropout 层中,每个 dropout 样本使用不同的掩码来使其神经元子集不同,但复制的全连接层之间会共享参数giti(即连接权重),appstore然后利用相同的损失函数,github永久回家地址如交叉熵,计算每个 dropout 的损失,并对所有 dropout 样本的损失值进行平均,就可以得到最终的损失值。

训练更快,泛化更强的Dropout:Multi-Sample Dropout
该方法以最后的损失值作为优化训练github的目标函数,以最后一个全连接层输出中的最大值的类标签作为预测标签。当 dropout 应github汤姆用于网络尾段时,由于重复操作而增加的训练时间并不多。值https认证得注意的是,multi-sample dropout 中apple苹果官网 dropout 样本的数量可以是任意的,而图 1 中展示了有两个 dropout 样本的实例。

另外需要注意的是,神经元在推理过程中是不会被忽略的。只计算一个 drogiteepogithub中文官网网页ut 样本的损失是因为 dropout 样本在推理时是一样的,这样做可以对网络进行修剪以消除冗余计算。要注意的是,在推理时使用所有的 dropout 样本并不会严重影响预测性能,只是稍微增加了推理时间的计算成本。

Pytorch实现

github.com/lonePatient…

在初始化方法中,定义了一个ModuleList,包含多个Dropout, 在forward中,对样本进行多次dropout,最后对out求平均,对loss求平均。其中,dropout_num为超参数,表示Multi-Sample中,Multi的具体值,核心代码如下:

  self.dropouts = nn.ModuleList([nn.Dropout(dropout_p) for _ in range(dropout_num)])

完整ResNet模型结构:


class ResNet(nn.Module):
    def __init__(self, ResidualBlock, num_classes,dropout_num,dropout_p):
        super(ResNet, self).__init__()
        self.inchannel = 32
        self.conv1 = nn.Sequential(
            nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1, bias=False),
            nn.BatchNorm2d(32),
            nn.ReLU(),
        )
        self.layer1 = self.make_layer(ResidualBlock, 32,  2, stride=1)
        self.layer2 = self.make_layer(ResidualBlock, 64, 2, stride=2)
        self.layer3 = self.make_layer(ResidualBlock, 64, 2, stride=2)
        self.layer4 = self.make_layer(ResidualBlock, 128, 2, stride=2)
        self.fc = nn.Linear(128,num_classes)
        self.dropouts = nn.ModuleList([nn.Dropout(dropout_p) for _ in range(dropout_num)])
    def make_layer(self, block, channels, num_blocks, stride):
        strides = [stride] + [1] * (num_blocks - 1)   #strides=[1,1]
        layers = []
        for stride in strides:
            layers.append(block(self.inchannel, channels, stride))
            self.inchannel = channels
        return nn.Sequential(*layers)
    def forward(self, x,y = None,loss_fn = None):
        out = self.conv1(x)
        out = self.layer1(out)
        out = self.layer2(out)
        out = self.layer3(out)
        out = self.layer4(out)
        feature = F.avg_pool2d(out, 4)
        if len(self.dropouts) == 0:
            out = feature.view(feature.size(0), -1)
            out = self.fc(out)
            if loss_fn is not None:
                loss = loss_fn(out,y)
                return out,loss
            return out,None
        else:
            for i,dropout in enumerate(self.dropouts):
                if i== 0:
                    out = dropout(feature)
                    out = out.view(out.size(0),-1)
                    out = self.fc(out)
                    if loss_fn is not None:
                        loss = loss_fn(out, y)
                else:
                    temp_out = dropout(feature)
                    temp_out = temp_out.view(temp_out.size(0),-1)
                    out =out+ self.fc(temp_out)
                    if loss_fn is not None:
                        loss = loss+loss_fn(temp_out, y)
            if loss_fn is not None:
                return out / len(self.dropouts),loss / len(self.dropouts)
            return out,None

Bert如何使用Multi-Sample Dropout

于BERT家族模型使用了很多DGitHubropout,采用上述实现https安全问题过于复杂,一种更简单的实现:

for step, (input_ids, attention_mask, token_type_ids, y) in enumerate(tk):
    input_ids, attention_mask, token_type_ids, y = input_ids.to(device), attention_mask.to(
        device), token_type_ids.to(device), y.to(device).long()
    with autocast(): 
        for i in range(batch_n_iter):
            output = model(input_ids, attention_mask, token_type_ids).logits
            loss = criterion(output, y) / CFG['accum_iter']
            SCALER.scale(loss).backward()
        SCALER.step(optimizer)
        SCALER.update()
        optimizer.zero_grad()
  • 其中,batch_n_itgithub下载er为超参数,表示Mgithub永久回家地址ulti-Sample中,Multi的具体值。

如果大家用抱抱脸的话,可以按照下github直播平台永久回家面模板设置:

class multilabel_dropout():
    # Multisample Dropout 论文: https://arxiv.org/abs/1905.09788
    def __init__(self, HIGH_DROPOUT, HIDDEN_SIZE):
        self.high_dropout = torch.nn.Dropout(config.HIGH_DROPOUT)
        self.classifier = torch.nn.Linear(config.HIDDEN_SIZE * 2, 2)
    def forward(self, out):
        return torch.mean(torch.stack([
            self.classifier(self.high_dropout(p))
            for p in np.linspace(0.1,0.5, 5)
        ], dim=0), dim=0)

Multi-Sample Dropappearanceogithub开放私库ut作用

关于原gitee理的话,因为发现网上写的很github官网全了,这里偷懒了,大家可以看参考资料,这里主要给大家提供下代码了。

  • 大幅减少训练迭代次数
  • 提高泛化能力

参考资料

Multigithub中文官网网页-Sample DropHTTPSout for Accelerated Training and Better Generalizationapproach 大幅减少训练迭代次数,提高泛化能力:IBMgiti提出「新版Droapple苹果官网pout」