0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深度学习刷SOTA的一堆trick

深度学习自然语言处理 来源:包包算法笔记 作者:包包算法笔记 2022-09-07 15:13 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一般通用的trick都被写进论文和代码库里了

像优秀的优化器,学习率调度方法,数据增强,dropout,初始化,BN,LN,确实是调参大师的宝贵经验,大家平常用的也很多。

这里主要有几个,我们分成三部分,稳定有用型trick,场景受限型trick,性能加速型trick。

稳定有用型trick

0.模型融合

懂得都懂,打比赛必备,做文章没卵用的人人皆知trick,早年模型小的时候还用stacking,直接概率融合效果也不错。

  1. 对抗训练

对抗训练就是在输入的层次增加扰动,根据扰动产生的样本,来做一次反向传播。以FGM为例,在NLP上,扰动作用于embedding层。给个即插即用代码片段吧,引用了知乎id:Nicolas的代码,写的不错,带着看原理很容易就明白了。

#初始化
fgm=FGM(model)
forbatch_input,batch_labelindata:
#正常训练
loss=model(batch_input,batch_label)
loss.backward()#反向传播,得到正常的grad
#对抗训练
fgm.attack()#在embedding上添加对抗扰动
loss_adv=model(batch_input,batch_label)
loss_adv.backward()#反向传播,并在正常的grad基础上,累加对抗训练的梯度
fgm.restore()#恢复embedding参数
#梯度下降,更新参数
optimizer.step()
model.zero_grad()

具体FGM的实现

importtorch
classFGM():
def__init__(self,model):
self.model=model
self.backup={}

defattack(self,epsilon=1.,emb_name='emb.'):
#emb_name这个参数要换成你模型中embedding的参数名
forname,paraminself.model.named_parameters():
ifparam.requires_gradandemb_nameinname:
self.backup[name]=param.data.clone()
norm=torch.norm(param.grad)
ifnorm!=0andnottorch.isnan(norm):
r_at=epsilon*param.grad/norm
param.data.add_(r_at)

defrestore(self,emb_name='emb.'):
#emb_name这个参数要换成你模型中embedding的参数名
forname,paraminself.model.named_parameters():
ifparam.requires_gradandemb_nameinname:
assertnameinself.backup
param.data=self.backup[name]
self.backup={}

2.EMA/SWA

移动平均,保存历史的一份参数,在一定训练阶段后,拿历史的参数给目前学习的参数做一次平滑。这个东西,我之前在earhian的祖传代码里看到的。他喜欢这东西+衰减学习率。确实每次都有用。

#初始化
ema=EMA(model,0.999)
ema.register()

#训练过程中,更新完参数后,同步updateshadowweights
deftrain():
optimizer.step()
ema.update()

# eval前,apply shadow weights;eval之后,恢复原来模型的参数
defevaluate():
ema.apply_shadow()
#evaluate
ema.restore()

具体EMA实现,即插即用:

classEMA():
def__init__(self,model,decay):
self.model=model
self.decay=decay
self.shadow={}
self.backup={}

defregister(self):
forname,paraminself.model.named_parameters():
ifparam.requires_grad:
self.shadow[name]=param.data.clone()

defupdate(self):
forname,paraminself.model.named_parameters():
ifparam.requires_grad:
assertnameinself.shadow
new_average=(1.0-self.decay)*param.data+self.decay*self.shadow[name]
self.shadow[name]=new_average.clone()

defapply_shadow(self):
forname,paraminself.model.named_parameters():
ifparam.requires_grad:
assertnameinself.shadow
self.backup[name]=param.data
param.data=self.shadow[name]

defrestore(self):
forname,paraminself.model.named_parameters():
ifparam.requires_grad:
assertnameinself.backup
param.data=self.backup[name]
self.backup={}

这两个方法的问题就是跑起来会变慢,并且提分点都在前分位,不过可以是即插即用类型

3.Rdrop等对比学习方法

有点用,不会变差,实现起来也很简单

#训练过程上下文
ce=CrossEntropyLoss(reduction='none')
kld=nn.KLDivLoss(reduction='none')
logits1=model(input)
logits2=model(input)
#下面是训练过程中对比学习的核心实现!!!!
kl_weight=0.5#对比loss权重
ce_loss=(ce(logits1,target)+ce(logits2,target))/2
kl_1=kld(F.log_softmax(logits1,dim=-1),F.softmax(logits2,dim=-1)).sum(-1)
kl_2=kld(F.log_softmax(logits2,dim=-1),F.softmax(logits1,dim=-1)).sum(-1)
loss=ce_loss+kl_weight*(kl_1+kl_2)/2

大家都知道,在训练阶段。dropout是开启的,你多次推断dropout是有随机性的。

模型如果鲁棒的话,你同一个样本,即使推断时候,开着dropout,结果也应该差不多。好了,那么它的原理也呼之欲出了。用一张图来形容就是:

5d5ce4a6-2e61-11ed-ba43-dac502259ad0.gif

随便你怎么踹(dropout),本AI稳如老狗。

KLD loss是衡量两个分布的距离的,所以说他就是在原始的loss上,加了一个loss,这个loss刻画了模型经过两次推断,抵抗因dropout造成扰动的能力。

4.TTA

这个一句话说明白,测试时候构造靠谱的数据增强,简单一点的数据增强方式比较好,然后把预测结果加起来算个平均。

5.伪标签

代码和原理实现也不难,代价也是训练变慢,毕竟多了一些数据一句话说明白,就是用训练的模型,把测试数据,或者没有标签的数据,推断一遍。构成伪标签,然后拿回去训练。注意不要leak。

听起来挺离谱的,我们把步骤用伪代码实现一下。

model1.fit(train_set,label,val=validation_set)#step1
pseudo_label=model.pridict(test_set)#step2
new_label=concat(pseudo_label,label)#step3
new_train_set=concat(test_set,train_set)#step3
model2.fit(new_train_set,new_label,val=validation_set)#step4
final_predict=model2.predict(test_set)#step5

用网上一个经典的图来说就是。

5e04879c-2e61-11ed-ba43-dac502259ad0.jpg

6.神经网络自动填空值

表数据在NN上的trick,快被tabnet 集大成了,这个方法是把缺失值的位置之外的地方mask,本身当成1这样可以学习出一个参数,再加回这个feature的输入上。可以看看他文章的实现。

场景受限型trick

有用但场景受限或者不稳定

1.PET或者其他prompt的方案

在一些特定场景上有用,比如zeroshot,或者小样本的监督训练,在数据量充足情况下拿来做模型融合有点用,单模型不一定干的过硬怼。

2.Focalloss

偶尔有用,大部分时候用处不大,看指标,在一些对长尾,和稀有类别特别关注的任务和指标上有所作为。

3.mixup/cutmix等数据增强

挑数据,大部分数据和任务用处不大,局部特征比较敏感的任务有用,比如音频分类等

4人脸等一些改动softmax的方式

在数据量偏少的时候有用,在工业界数据量巨大的情况下用处不大

5.领域后预训练

把自己的数据集,在Bert base上用MLM任务再过一遍,代价也是变慢,得益于huggingface可用性极高的代码,实现起来也非常简单,适用于和预训练预料差别比较大的一些场景,比如中药,ai4code等,在一些普通的新闻文本分类数据集上用处不大。

6.分类变检索

这算是小样本分类问题的标准解法了,类似于人脸领域的baseline,在这上面有很多围绕类间可分,类内聚集的loss改进,像aa-softmax,arcface,am-softmax等

在文本分类,图像分类上效果都不错。

突破性能型trick

1.混合精度训练

AMP即插即用,立竿见影。

2.梯度累积

在优化器更新参数之前,用相同的模型参数进行几次前后向传播。在每次反向传播时计算的梯度被累积(加总)。不过这种方法会影响BN的计算,可以用来突破batchsize上限。

3.Queue或者memery bank

可以让batchsize突破天际,可以参考MoCo用来做对比学习的那个实现方式

4.非必要不同步

多卡ddp训练的时候,用到梯度累积时,可以使用no_sync减少不必要的梯度同步,加快速度


审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4976

    浏览量

    74370
  • 深度学习
    +关注

    关注

    73

    文章

    5604

    浏览量

    124615
  • nlp
    nlp
    +关注

    关注

    1

    文章

    491

    浏览量

    23341

原文标题:深度学习刷SOTA的一堆trick

文章出处:【微信号:zenRRan,微信公众号:深度学习自然语言处理】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    人工智能-Python深度学习进阶与应用技术:工程师高培解读

    深度学习的工程化落地,早已不是纸上谈兵的事。从卷积神经网络到Transformer,从目标检测到大模型私有化部署,技术栈不断延伸,工程师面临的知识体系也越来越庞杂。现根据中际赛威工程师培训老师的
    的头像 发表于 04-21 11:01 282次阅读
    人工智能-Python<b class='flag-5'>深度</b><b class='flag-5'>学习</b>进阶与应用技术:工程师高培解读

    从github上下载下来编译为什么有一堆报错哈?

    从github上下载下来编译为什么有一堆报错哈?
    发表于 03-27 06:17

    DRV8251:款优秀的有直流电机驱动器深度解析

    DRV8251:款优秀的有直流电机驱动器深度解析 在电机驱动领域,有直流电机驱动器直是非常关键的部件。今天我们要深入探讨的是德州仪器
    的头像 发表于 01-07 16:35 577次阅读

    机器学习深度学习中需避免的 7 个常见错误与局限性

    无论你是刚入门还是已经从事人工智能模型相关工作段时间,机器学习深度学习中都存在些我们需要时刻关注并铭记的常见错误。如果对这些错误置之不
    的头像 发表于 01-07 15:37 345次阅读
    机器<b class='flag-5'>学习</b>和<b class='flag-5'>深度</b><b class='flag-5'>学习</b>中需避免的 7 个常见错误与局限性

    穿孔机顶头检测仪 机器视觉深度学习

    顶头状态。 检测顶头算法 引入人工智深度学习技术,通过Keras实现卷积神经网络(CNN),用Numpy实现采集数据的训练,得到符合现场需求的模型,进步提升检测的准确性和现场的适应性。 应用范围
    发表于 12-22 14:33

    Amphenol ZTPD - 2210数字输出热电探测器深度解析

    Amphenol ZTPD - 2210数字输出热电探测器深度解析 在电子工程领域,传感器是获取环境信息的关键部件。今天,我们要深入探讨Amphenol Advanced Sensors的ZTPD
    的头像 发表于 12-10 11:35 578次阅读

    深度睡眠时为什么串口会发送一堆 \\0?

    RT,初始化串口,发送数据然后休眠,串口工具会收到CW32L010发送的一堆� ,AI统计了下 128个字节,是什么原因啊?
    发表于 11-28 07:25

    如何深度学习机器视觉的应用场景

    深度学习视觉应用场景大全 工业制造领域 复杂缺陷检测:处理传统算法难以描述的非标准化缺陷模式 非标产品分类:对形状、颜色、纹理多变的产品进行智能分类 外观质量评估:基于学习的外观质量标准判定 精密
    的头像 发表于 11-27 10:19 324次阅读

    如何在机器视觉中部署深度学习神经网络

    图 1:基于深度学习的目标检测可定位已训练的目标类别,并通过矩形框(边界框)对其进行标识。 在讨论人工智能(AI)或深度学习时,经常会出现“神经网络”、“黑箱”、“标注”等术语。这些概
    的头像 发表于 09-10 17:38 1047次阅读
    如何在机器视觉中部署<b class='flag-5'>深度</b><b class='flag-5'>学习</b>神经网络

    嵌入式 STM32 零基础入门:「降维打击式学习法」适配零基础,高效进阶全栈工程师

    嵌入式学习难吗?今天就为你揭秘颠覆传统的——“降维打击式嵌入式学习法”!初学嵌入式会感觉难,为什么?因为嵌入式是软硬件深度结合的技术,应用层开发所见即所得,效果直观,相对容易上手。但底层开发却像
    的头像 发表于 08-25 15:24 873次阅读
    嵌入式 STM32 零基础入门:「降维打击式<b class='flag-5'>学习</b>法」适配零基础,高效进阶全栈工程师

    学习D13的芯片配置,为什么我vscode,一堆爆红,看着好烦,有没有解决办法

    学习D13的芯片配置,为什么我vscode,一堆爆红,看着好烦,有没有解决办法
    发表于 08-22 20:02

    深度学习对工业物联网有哪些帮助

    、实施路径三个维度展开分析: 深度学习如何突破工业物联网的技术瓶颈? 1. 非结构化数据处理:解锁“沉睡数据”价值 传统困境 :工业物联网中70%以上的数据为非结构化数据(如设备振动波形、红外图像、日志文本),传统方法难以
    的头像 发表于 08-20 14:56 1198次阅读

    自动驾驶中Transformer大模型会取代深度学习吗?

    [首发于智驾最前沿微信公众号]近年来,随着ChatGPT、Claude、文心言等大语言模型在生成文本、对话交互等领域的惊艳表现,“Transformer架构是否正在取代传统深度学习”这
    的头像 发表于 08-13 09:15 4363次阅读
    自动驾驶中Transformer大模型会取代<b class='flag-5'>深度</b><b class='flag-5'>学习</b>吗?

    AURIX tc367通过 MCU SOTA 更新逻辑 IC 闪存是否可行?

    你好专家:我的用例是 MCU 通过 SPI 连接到逻辑 IC,逻辑 IC 连接到 8MB 闪存,但 MCU PFLASH 大小为 2MB,通过 MCU SOTA 更新逻辑 IC 闪存是否可行?
    发表于 08-11 06:36

    求助,关于TC387使能以及配置SOTA些问题求解

    你好, 之前我拿到贵司给个demo,里面有些使能以及配置SWAP的代码, 这里有些疑问 问题1. 判断SOTA功能是否生效,demo中使用的是 SCU_STMEM1中的bit位, 代码如下
    发表于 08-08 07:31