【论文笔记】Multi-Sample Dropout for Accelerated Training and Better Generalization

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介: 【论文笔记】Multi-Sample Dropout for Accelerated Training and Better Generalization

论文简介:训练更快,泛化更强的Dropout:Multi-Sample Dropout

论文标题:Multi-Sample Dropout for Accelerated Training and Better Generalization

论文链接:https://arxiv.org/pdf/1905.09788.pdf

论文作者:{Hiroshi Inoue}


论文简介


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


Multi-Sample Dropout


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


14.png


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

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


Pytorch实现



https://github.com/lonePatient/multi-sample_dropout_pytorch

在初始化方法中,定义了一个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家族模型使用了很多Dropout,采用上述实现过于复杂,一种更简单的实现:

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_iter为超参数,表示Multi-Sample中,Multi的具体值。

如果大家用抱抱脸的话,可以按照下面模板设置:

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 Dropout作用


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


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


参考资料


Multi-Sample Dropout for Accelerated Training and Better Generalization

大幅减少训练迭代次数,提高泛化能力:IBM提出「新版Dropout」

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
6月前
|
机器学习/深度学习 资源调度 监控
PyTorch使用Tricks:Dropout,R-Dropout和Multi-Sample Dropout等 !!
PyTorch使用Tricks:Dropout,R-Dropout和Multi-Sample Dropout等 !!
98 0
|
6月前
|
机器学习/深度学习 自然语言处理 算法
【论文精读】ACL 2022:Graph Pre-training for AMR Parsing and Generation
【论文精读】ACL 2022:Graph Pre-training for AMR Parsing and Generation
|
5月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
MTCNN(Multi-task Cascaded Convolutional Networks)
MTCNN(Multi-task Cascaded Convolutional Networks)
74 0
|
机器学习/深度学习 编解码 自然语言处理
DeIT:Training data-efficient image transformers & distillation through attention论文解读
最近,基于注意力的神经网络被证明可以解决图像理解任务,如图像分类。这些高性能的vision transformer使用大量的计算资源来预训练了数亿张图像,从而限制了它们的应用。
522 0
|
机器学习/深度学习 编解码 自然语言处理
BEIT: BERT Pre-Training of Image Transformers论文解读
本文介绍了一种自监督视觉表示模型BEIT,即图像transformer的双向编码器表示。继自然语言处理领域开发的BERT之后
591 0
|
人工智能 自然语言处理 算法
【论文精读】AAAI 2022 - OneRel Joint Entity and Relation Extraction with One Module in One Step
联合实体和关系提取是自然语言处理和知识图构建中的一项重要任务。现有的方法通常将联合提取任务分解为几个基本模块或处理步骤,以使其易于执行
205 0
|
机器学习/深度学习 自然语言处理 算法
RNNsearch、Multi-task、attention-model...你都掌握了吗?一文总结机器翻译必备经典模型(1)
RNNsearch、Multi-task、attention-model...你都掌握了吗?一文总结机器翻译必备经典模型
118 0
|
机器学习/深度学习 人工智能 自然语言处理
RNNsearch、Multi-task、attention-model...你都掌握了吗?一文总结机器翻译必备经典模型(3)
RNNsearch、Multi-task、attention-model...你都掌握了吗?一文总结机器翻译必备经典模型
183 0
|
数据挖掘
【多标签文本分类】Initializing neural networks for hierarchical multi-label text classification
【多标签文本分类】Initializing neural networks for hierarchical multi-label text classification
115 0
【多标签文本分类】Initializing neural networks for hierarchical multi-label text classification
【多标签文本分类】Ensemble Application of Convolutional and Recurrent Neural Networks for Multi-label Text
【多标签文本分类】Ensemble Application of Convolutional and Recurrent Neural Networks for Multi-label Text
102 0
【多标签文本分类】Ensemble Application of Convolutional and Recurrent Neural Networks for Multi-label Text