NLP炼丹技巧合集

原创:郑佳伟

在NLP任务中,会有很多为了提升模型效果而提出的优化,为了方便记忆,所以就把这些方法都整理出来,也有助于大家学习。为了理解,文章并没有引入公式推导,只是介绍这些方法是怎么回事,如何使用。

一、对抗训练

近几年,随着深度学习的发展,对抗样本得到了越来越多的关注。通常,我们通过对模型的对抗攻击和防御来增强模型的稳健性,比如自动驾驶系统中的红绿灯识别,要防止模型因为一些随机噪声就将红灯识别为绿灯。在NLP领域,类似的对抗训练也是存在的。

简单来说,”对抗样本” 是指对于人类来说”看起来”几乎一样、但对于模型来说预测结果却完全不一样的样本,比如图中的例子,一只熊猫的图片在加了一点扰动之后被识别成了长臂猿。

NLP炼丹技巧合集

“对抗攻击”,就是生成更多的对抗样本,而”对抗防御”,就是让模型能正确识别更多的对抗样本。对抗训练,最初由 Goodfellow 等人提出,是对抗防御的一种,其思路是将生成的对抗样本加入到原数据集中用来增强模型对对抗样本的鲁棒性,Goodfellow还总结了对抗训练的除了提高模型应对恶意对抗样本的鲁棒性之外,还可以作为一种正则化,减少过拟合,提高模型泛化能力。

在CV任务中,输入是连续的RGB的值,而NLP问题中,输入是离散的单词序列,一般以one-hot向量的形式呈现,如果直接在raw text上进行扰动,那么扰动的大小和方向可能都没什么意义。Goodfellow在17年的ICLR中 提出了可以在连续的Embedding上做扰动,但对比图像领域中直接在原始输入加扰动的做法,扰动后的Embedding向量不一定能匹配上原来的Embedding向量表,这样一来对Embedding层的扰动就无法对应上真实的文本输入,这就不是真正意义上的对抗样本了,因为对抗样本依然能对应一个合理的原始输入。那么,在Embedding层做对抗扰动还有没有意义呢?有!实验结果显示,在很多任务中,在Embedding层进行对抗扰动能有效提高模型的性能。之所以能提高性能,主要是因为对抗训练可以作为正则化,一定程度上等价于在loss里加入了梯度惩罚,提升了模型泛化能力。

接下来看一下NLP对抗训练中常用的两个方法和具体实现代码。

第一种是FGM, Goodfellow在17年的ICLR中对他自己在15年提出的FGSM方法进行了优化,主要是在计算扰动的部分做了一点简单的修改。其伪代码如下:

对于每个样本x:

1.计算x的前向loss、反向传播得到梯度

2.根据Embedding矩阵的梯度计算出扰动项r,并加到当前Embedding上,相当于x+r

3.计算x+r的前向loss,反向传播得到对抗的梯度,累加到(1)的梯度上

4.将embedding恢复为(1)时的值

5.根据(3)的梯度对参数进行更新

具体pytorch代码如下:

1.  import torch
2.  class FGM():
3.      def __init__(self, model):
4.          self.model = model
5.          self.backup = {}
6.
7.      def attack(self, epsilon=1., emb_name='embedding'):
8.
9.          for name, param in self.model.named_parameters():
10.             if param.requires_grad and emb_name in name:
11.                 self.backup[name] = param.data.clone()
12.                 norm = torch.norm(param.grad)
13.                 if norm != 0 and not torch.isnan(norm):
14.                     r_at = epsilon * param.grad / norm
15.                     param.data.add_(r_at)
16.
17. def restore(self, emb_name='embedding'):
18.
19.     for name, param in self.model.named_parameters():
20.         if param.requires_grad and emb_name in name:
21.             assert name in self.backup
22.             param.data = self.backup[name]
23.     self.backup = {}

需要使用对抗训练的时候,只需要添加五行代码:

需要使用对抗训练的时候,只需要添加五行代码:
1.
2.  fgm = FGM(model)
3.  for batch_input, batch_label in data:
4.
5.      loss = model(batch_input, batch_label)
6.      loss.backward()
7.
8.      fgm.attack()
9.      loss_adv = model(batch_input, batch_label)
10.     loss_adv.backward()
11.     fgm.restore()
12.
13.     optimizer.step()
14.     model.zero_grad()

第二种是PGD, FGM直接通过epsilon参数一下算出了对抗扰动,这样得到的对抗扰动可能不是最优的。因此PGD进行了改进,多迭代几次,”小步走,多走几步”,慢慢找到最优的扰动。伪代码如下

对于每个样本x:

1.计算x的前向loss、反向传播得到梯度并备份

对于每步t:

2.根据Embedding矩阵的梯度计算出扰动项r,并加到当前Embedding上,相当于x+r(超出范围则投影回epsilon内)

3.t不是最后一步: 将梯度归0,根据1的x+r计算前后向并得到梯度

4.t是最后一步: 恢复(1)的梯度,计算最后的x+r并将梯度累加到(1)上

5.将Embedding恢复为(1)时的值

6.根据(4)的梯度对参数进行更新

可以看到,在循环中r是逐渐累加的,要注意的是最后更新参数只使用最后一个x+r算出来的梯度。具体代码如下:

1.  import torch
2.  class PGD():
3.      def __init__(self, model):
4.          self.model = model
5.          self.emb_backup = {}
6.          self.grad_backup = {}
7.
8.      def attack(self, epsilon=1., alpha=0.3, emb_name='emb.', is_first_attack=False):
9.
10.         for name, param in self.model.named_parameters():
11.             if param.requires_grad and emb_name in name:
12.                 if is_first_attack:
13.                     self.emb_backup[name] = param.data.clone()
14.                 norm = torch.norm(param.grad)
15.                 if norm != 0 and not torch.isnan(norm):
16.                     r_at = alpha * param.grad / norm
17.                     param.data.add_(r_at)
18.                     param.data = self.project(name, param.data, epsilon)
19.
20.     def restore(self, emb_name='emb.'):
21.
22.         for name, param in self.model.named_parameters():
23.             if param.requires_grad and emb_name in name:
24.                 assert name in self.emb_backup
25.                 param.data = self.emb_backup[name]
26.         self.emb_backup = {}
27.
28.     def project(self, param_name, param_data, epsilon):
29.         r = param_data - self.emb_backup[param_name]
30.         if torch.norm(r) > epsilon:
31.             r = epsilon * r / torch.norm(r)
32.         return self.emb_backup[param_name] + r
33.
34.     def backup_grad(self):
35.         for name, param in self.model.named_parameters():
36.             if param.requires_grad:
37.                 self.grad_backup[name] = param.grad.clone()
38.
39.     def restore_grad(self):
40.         for name, param in self.model.named_parameters():
41.             if param.requires_grad:
42.                 param.grad = self.grad_backup[name]

使用的时候,步骤要多一点:

1.  pgd = PGD(model)
2.  K = 3
3.  for batch_input, batch_label in data:
4.
5.      loss = model(batch_input, batch_label)
6.      loss.backward()
7.      pgd.backup_grad()
8.
9.      for t in range(K):
10.         pgd.attack(is_first_attack=(t==0))
11.         if t != K-1:
12.             model.zero_grad()
13.         else:
14.             pgd.restore_grad()
15.         loss_adv = model(batch_input, batch_label)
16.         loss_adv.backward()
17.     pgd.restore()
18.
19.     optimizer.step()
20.     model.zero_grad()

二、 Lookahead

Lookahead是近几年新多伦多大学向量学院的研究者提出的一种优化器,它与已有的方法完全不同,它迭代更新两组权重。直观来说,Lookahead 算法通过提前观察另一个优化器生成的「fast weights」序列,来选择搜索方向。该研究发现, Lookahead 算法能够提升学习稳定性,不仅降低了调参需要的时间,同时还能提升收敛速度与效果。此外,我们可以使用 Lookahead 加强已有最优化方法的性能。 Lookahead 的直观过程如图所示,它维护两组权重。Lookahead 首先使用SGD 等标准优化器,更新 k 次「Fast weights」,然后以最后一个 Fast weights 的方向更新「slow weights」。如下 Fast Weights 每更新 5 次,slow weights 就会更新一次。

NLP炼丹技巧合集

这种更新机制不仅能够有效地降低方差,而且Lookahead 对次优超参数没那么敏感,以至于它对大规模调参的需求没有那么强。此外,使用 Lookahead 及其内部优化器(如 SGD 或 Adam),还能实现更快的收敛速度,计算开销也比较小。 Lookahead的思路比较简答,准确来说它并不是一个优化器,而是一个使用现有优化器的方案。简单来说它就是下面三个步骤的循环执行:

1)、备份模型现有的权重θ;

2)、从θ出发,用指定优化器更新k步,得到新权重θ̃ ;

3)、更新模型权重为θ←θ+α(θ̃ −θ)。

NLP炼丹技巧合集

; 三、 Warmup

warm up是一种学习率优化方法。一般情况下,我们在训练模型过程中,学习率是不会变化的,而warm up是在不同阶段采用不同的学习策略。比如 在模型训练之初选用较小的学习率,训练一段时间之后(如10 epoches或10000steps)使用预设的学习率进行训练。 warm up的意义在于,在模型训练的初始阶段:模型对数据很陌生,需要使用较小的学习率学习,不断修正权重分布,如果开始阶段,使用很大的学习率,训练出现偏差后,后续需要很多个epoch才能修正过来,或者修正不过来,导致训练过拟合。

在模型训练的中间阶段,当使用较小的学习率学习一段时间后,模型已经根据之前的数据形成了先验知识,这时使用较大的学习率加速学习,前面学习到的先验知识可以使模型的方向正确,加速收敛速度。

在模型训练的学习率衰减阶段:模型参数在学习到一定阶段,参数分布已经在小范围内波动,整体分布变化不大,这时如果继续沿用较大的学习率,可能会破坏模型权值分布的稳定性。

常用的warm up策略介绍三种 (1)constant warm up:学习率从比较小的数值线性增加到预设值之后保持不变 (2)linear warm up:学习率从非常小的数值线性增加到预设值之后,然后再线性减小 (3)Cosine Warmup:学习率先从很小的数值线性增加到预设学习率,然后按照cos函数值进行衰减。

四、 混合精度训练

使用混合精度训练并不能提高模型效果,而是为了提高训练速度。混合精度训练时一种在尽可能减少精度损失的情况下利用半精度浮点数加速训练的方法。它使用FP16即半精度浮点数存储权重和梯度。在减少占用内存的同时起到了加速训练的效果。 通常训练神经网络模型的时候默认使用的数据类型为单精度FP32,混合精度训练是指在训练的过程中,同时使用单精度(FP32)和半精度(FP16)。

IEEE标准中的FP16和FP32格式如图所示,float16表示FP6,float表示FP32:

NLP炼丹技巧合集

从图中可以看出,与FP32相比,FP16的存储空间是FP32的一半。因此使用FP16训练神经网络可以使权重等参数所占用的内存是原来的一半,节省下来的内存可以放更大的网络模型或者使用更多的数据进行训练。并且在分布式训练,特别是大模型的训练过程中,半精度可以加快数据的流通。但使用FP16同样会带来一些问题,其中最重要的是1)精度溢出和2)舍入误差。

精度溢出:Float16的有效的动态范围约为 [5.96×10^-8,65504], 而Float32的范围是[1.4×10^-45, 1.7×10^38]。可以看到FP16相比FP32的有效范围要小很多,使用FP16替换FP32会出现上溢和下溢的情况。而在神经网络中,由于激活函数的梯度通常要比权重的梯度小,更容易出现下溢的情况。

舍入误差:0.00006666666在FP32中能正常表示,转换到FP16后会表示成为0.000067,不满足FP16最小间隔的数会强制舍入。

为了让深度学习训练,可以使用FP16的好处,并且避免精度溢出和舍入误差,FP16和FP32混合精度训练采用了三种有效的方法:

1.权重备份:权重备份主要是为了解决舍入误差的问题。其主要思路是把神经网络训练过程中产生的激活函数、梯度、以及中间变量等数据,在训练中都利用FP16来存储,同时复制一份FP32的权重参数,用于训练时候的更新。

NLP炼丹技巧合集

从图中可以看到,前向传播过程中产生的权重,激活函数,以及梯度都是用FP16进行存储和计算的。参数更新的公式为:
w e i g h t = w e i g h t + l r ∗ g r a d i e n t weight=weight+lrgradient w e i g h t =w e i g h t +l r ∗g r a d i e n t
lr表示学习率,gradient表示梯度,在深度模型中,l r ∗ g r a d i e n t lr
gradient l r ∗g r a d i e n t的值可能会很小,如果利用FP16的权重进行更新,可能会导致误差问题,以至于权重更新无效。因此要使用FP32的权重参数进行更新,即:
w e i g h t 32 = w e i g h t 32 + l r ∗ g r a d i e n t 16 weight_{32}=weight_{32}+lr*gradient_{16}w e i g h t 3 2 ​=w e i g h t 3 2 ​+l r ∗g r a d i e n t 1 6 ​

在这里需要注意的是,虽然对权重用FP32格式拷贝增加了内存,但是对于整体的内存占用还是很小的。训练内存的消耗主要是激活,这是因为每一层的批量或激活会保存下来用于重复使用。激活也使用半精度存储,整体的内存基本减半。

2.损失缩放:仅使用FP32进行训练,模型可以收敛的很好,但是如果使用FP32和FP16混合进行训练,会存在模型不收敛。主要原因是梯度的太小,使用FP16表示之后会造成数据下溢的问题,导致模型不收敛,

NLP炼丹技巧合集

所以神经网络模型为了匹配FP32的准确性,对前向传播计算出来的Loss值进行放大,例如:对FP32的参数乘以一个因子系数,把可能溢出的数据,转换到FP16可表示的范围。根据链式求导法则,放大Loss后会作用在反向传播的每一层梯度,这样比在每一层梯度上进行放大更加高效。

损失缩放实现的主要过程:

(1)在神经网络模型在前向传播之后,将得到loss增大2^K倍。

(2)在反向传播之后,将权重梯度缩小2^K倍,使用FP32进行表示。 这种损失缩放是使用一个默认值对损失进行缩放,是静态的。动态损失缩放算法是在梯度溢出的时候减少损失缩放规模,并且阶段性的尝试增加损失规模,从而实现在不引起溢出的情况下使用最高损失缩放因子,更好地恢复精度。

具体实现过程如下:

(1)动态损失缩放会在开始的时候使用较高的缩放因子(如2^24),然后在训练迭代中检测数值是否存在溢出;

(2)如果没有数值溢出,则不进行缩放,继续进行迭代,如果检测到数值溢出,则缩放因子会减半,重新确认数值更新情况,直到数值不会溢出;

(3)在训练的后期,loss已经趋近收敛,梯度更新的幅度往往小了,这个时候使用更高的损失缩放因子来防止数据下溢。

3.运算精度:为了有效减少计算过程中的舍入误差,混合精度训练在训练过程中,使用FP16进行矩阵乘法运算,使用FP32来进行矩阵乘法中间的累加部分,然后将FP32格式的值转换成FP16格式的数值。

NLP炼丹技巧合集

混合精度训练是减少内存占用、运算时间和运算量的方法。现在已经证明了很多深度模型都可以用这个方法训练,并且在不修改模型参数的情况下,准确率不会下降。Pytorch1.6版本已经实现了NVIDIA的APEX混合精度训练的功能,看一下具体代码:

1.  from apex import amp
2.  model, optimizer = amp.initialize(model, optimizer, opt_level="o1")
3.  with amp.scale_loss(loss, optimizer) as scaled_loss:
4.      scaled_loss.backward()

opt_level有4种选择,分别为”o0″,”o1″,”o2″,”o3″,是APEX混合精度库支持的4种混合精度训练策略。”o0″和”o3″策略分别表示FP32和FP16的纯精度方式。”o1″策略表示使用混合精度训练,但会根据实际Tensor和操作之间的关系建立黑白名单来决定是否使用FP16。例如使用FP16进行GEMM和CNN卷积运算会特别友好,则会把输入的数据和权重转换成FP16进行运算,而使用FP32计算Softmax、Batchnorm等标量和向量。此外,默认使用动态损失缩放。而”o2″策略也是混合精度训练,但没有黑白名单,它是将模型权重参数以及输入模型的参数都转换为FP16,Batch norm使用FP32,另外模型权重文件复制一份FP32,用于跟优化器更新梯度保持一致。同样提供了动态损失缩放。使用权重备份是为了减少舍入误差,使用损失缩放是为了避免数据溢出。

五、Label smoothing

1)使用cross-entropy的问题

传统one-hot编码标签的网络学习过程中,鼓励模型预测为目标类别的概率趋近1,非目标类别的概率趋近0,即最终预测的logits向量(logits向量经过softmax后输出的就是预测的所有类别的概率分布)中目标类别𝑧𝑖zi的值会趋于无穷大,使得模型向预测正确与错误标签的logit差值无限增大的方向学习,而过大的logit差值会使模型缺乏适应性,对它的预测过于自信。在训练数据不足以覆盖所有情况下,这就会导致网络过拟合,泛化能力差,而且实际上有些标注数据不一定准确,这时候使用交叉熵损失函数作为目标函数也不一定是最优的了。

2)计算公式

y k L S = y k ( 1 − α ) + α / K y_{k}^{L S}=y_{k}(1-\alpha)+\alpha / K y k L S ​=y k ​(1 −α)+α/K

3) 举例说明

p(cat) = 1

p(pig) = 0

p(dog) = 0

三分类k=3,假设smoothing parameter α = 0.1 \alpha=0.1 α=0 .1

Cat = (1-0.1)[1,0,0]+0.1/3

=[0.9,0,0]+0.03

=[0.933,0.03,0.03]

Label smoothing就是使用[0.933,0.03,0.03]代替[1,0,0]

六、Focal loss

focal loss 定义

F L ( p t ) = − ( 1 − p t ) γ log ⁡ ( p t ) \mathrm{FL}\left(p_{\mathrm{t}}\right)=-\left(1-p_{\mathrm{t}}\right)^{\gamma} \log \left(p_{\mathrm{t}}\right)F L (p t ​)=−(1 −p t ​)γlo g (p t ​)

在交叉熵的基础上添加了一个可调节因子( 1 − p t ) γ (1-p_{t})^\gamma (1 −p t ​)γ, 且γ > 0 {\gamma > 0}γ>0

1)、当一个样本被误分类并且pt很小时,调节因子接近1,F L = − l o g ( p t ) FL=−log \left(p_{\mathrm{t}}\right)F L =−l o g (p t ​), 并且loss不受影响。

2)、当p𝑡->1 ,调节因子变为0,FL=0, 降低分类良好样本的权重。 焦点参数γ平滑的调整了简单样本被降权的概率。当γ=0是,FL=CE。 简单样本:可以理解为正确分类的样本

3)、 alpha-focal loss

F L ( p t ) = − α t ( 1 − p t ) γ log ⁡ ( p t ) \mathrm{FL}\left(p_{\mathrm{t}}\right)=-\alpha_{\mathrm{t}}\left(1-p_{\mathrm{t}}\right)^{\gamma} \log \left(p_{\mathrm{t}}\right)F L (p t ​)=−αt ​(1 −p t ​)γlo g (p t ​)

𝛼调整正负样本的权重。

七、梯度累加(加快训练速度)

如果只有单卡,且可以加载模型,但batch受限的话可以使用梯度累加,进行N次前向后反向更新一次参数,相当于扩大了N倍的batch size。

正常的训练代码是这样的:

for i, (inputs, labels) in enumerate(training_set):
    loss = model(inputs, labels)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

加入梯度累加后:

for i, (inputs, labels) in enumerate(training_set):
    loss = model(inputs, labels)
    loss = loss / accumulation_steps

    loss.backward()
    if (i+1) % accumulation_steps == 0:
        optimizer.step()
        model.zero_grad()

要注意的是,batch扩大后,如果想保持样本权重相等, 学习率也要线性扩大或者适当调整 。另外 batchnorm也会受到影响,小batch下的均值和方差肯定不如大batch的精准,可以调整BN中的momentum参数解决。

八、LAMB(Layer-wise Adaptive Moments optimizer for Batch training)

LAMB:模型在进行大批量数据训练时,能够维持梯度更新的精度。

LAMB主要是综合了Adam和LARS(Layerwise Adaptive Rate Scaling),对学习率进行调整。上文提到当batch变大时学习率也需要变大,这样会导致收敛不稳定,LARS通过给LR乘上权重与梯度的norm比值来解决这个问题:

8.1)WarmUp

模型刚开始训练的时候,先使用一个较小的学习率,训练一些epochs,等模型稳定时再修改为预先设置的学习率。

为什么使用Warmup? 模型随机初始化,若选择一个较大的学习率,可能会带来模型的不稳定,选择Warmup先训练几个epochs, 之后,模型趋于稳定,等模型稳定之后在选择预先设置的学习率可以加快模型的收敛速度,模型效果最佳。

NLP炼丹技巧合集

; 九、文本数据增强

  1. 基础的文本数据增强(EDA)[同义词替换!]
  2. 闭包数据增强
  3. 无监督数据增强(UDA)
  4. 对偶数据增强

EDA对于训练集中的给定句子,随机选择并执行以下操作之一:

  • 同义词替换(SR):从句子中随机选择 n 个不是停用词的词。 用随机选择的同义词之一替换这些单词中的每一个。
  • 随机插入 (RI):在句子中随机找到一个词,并找出其同义词,且该同义词不是停用词。 将该同义词插入句子中的随机位置。 这样做n次。
  • 随机交换(RS):随机选择句子中的两个单词并交换它们的位置。 这样做n次。
  • 随机删除(RD):以概率 p 随机删除句子中的每个单词

闭包数据增强

数据集中每条数据有两个句子 a, b, 1 a, c, 1 a, d, 0 a~b, a~c => b~c a~b, ad不相似 => bd不相

UDA(Unsupervised Data Augmentation for Consistency Training)用于一致性训练的无监督数据增

NLP炼丹技巧合集

十、sharpen

让预测标签更接近真实标签,增大概率大的值,减小概率小的值)

import torch.nn as nn
logits = torch.randn(2,3)
print(logits)
t_softmax = torch.softmax(logits, dim=1)
print(t_softmax)
t_sharpen = torch.softmax(logits/0.4, dim=1)
print(t_sharpen)

十一、EMA

EMA在深度学习的优化过程中,θ t \theta_{t}θt ​是t时刻的模型权重weights,v t v_{t}v t ​是t时刻的影子权重(shadow weights)。在梯度下降的过程中,会一直维护着这个影子权重,但是这个影子权重并不会参与训练。基本的假设是,模型权重在最后的n步内,会在实际的最优点处抖动,所以我们取最后n步的平均,能使得模型更加的鲁棒。

在保存模型或者评估模型时,会利用影子权重进行评估,如果效果比当前效果好,则保存影子权重的参数,但是之后在继续训练的时候会还原之前的参数进行训练。

class EMA():
    def __init__(self, model, decay):
        self.model = model
        self.decay = decay
        self.shadow = {}
        self.backup = {}

    def register(self):
        for name, param in self.model.named_parameters():
            if param.requires_grad:
                self.shadow[name] = param.data.clone()

    def update(self):
        for name, param in self.model.named_parameters():
            if param.requires_grad:
                assert name in self.shadow
                new_average = (1.0 - self.decay) * param.data + self.decay * self.shadow[name]
                self.shadow[name] = new_average.clone()

    def apply_shadow(self):
        for name, param in self.model.named_parameters():
            if param.requires_grad:
                assert name in self.shadow
                self.backup[name] = param.data
                param.data = self.shadow[name]

    def restore(self):
        for name, param in self.model.named_parameters():
            if param.requires_grad:
                assert name in self.backup
                param.data = self.backup[name]
        self.backup = {}

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

训练过程中,更新完参数后,同步update shadow weights
def train():
    optimizer.step()
    ema.update()

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

参考

[1]Explaining and Harnessing Adversarial Examples(https://arxiv.org/pdf/1412.6572.pdf)

[2]【炼丹技巧】功守道:NLP中的对抗训练 + PyTorch实现(https://zhuanlan.zhihu.com/p/91269728)

[3]苏剑林. (Mar. 01, 2020). 《对抗训练浅谈:意义、方法和思考(附Keras实现) 》[Blog post]. Retrieved from https://spaces.ac.cn/archives/7234

[4]Mixed Precision Training(https://arxiv.org/pdf/1710.03740.pdf)

[5]When Does Label Smoothing Help?(https://arxiv.org/pdf/1906.02629.pdf)

[6]Label Smoothing分析(https://zhuanlan.zhihu.com/p/302843504)

[7]Focal Loss for Dense Object Detection(https://arxiv.org/pdf/1708.02002.pdf)

[8]【炼丹技巧】指数移动平均(EMA)的原理及PyTorch实现https://zhuanlan.zhihu.com/p/68748778

Original: https://blog.csdn.net/KaikebaAI/article/details/123256262
Author: 笑傲NLP江湖
Title: NLP炼丹技巧合集

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/545285/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【python数据分析】数据的分组,遍历,统计

    数据的分组,遍历,统计 俗话说:”人与类聚,物以群分”,到这里我们将学习数据的分组以及分组后统计。Pandas的分组相对于Excel会更加简单和灵活。 1️…

    人工智能 2023年6月19日
    085
  • YOLO算法之YOLOv5

    目录 一、什么是YOLOv5? 二、YOLO目标检测技术发展史 * 1、发展历程一览 2、各版本差异 三、YOLOv5网络结构和组件 一、什么是YOLOv5? 参考学习: 了解YO…

    人工智能 2023年6月16日
    080
  • YOLO算法v1-v3原理通俗理解

    YOLO算法v1-v3原理通俗理解 深度学习检测方法简述 我们所使用的目标检测,其实就是让机器在图片找到对应的目标,然后给图片上的目标套上一个框框,并贴上标签。比如如果图片上有人,…

    人工智能 2023年7月10日
    076
  • 推荐系统之协同过滤算法

    1、介绍 协同过滤算法(Collaborative Filtering) 是比较经典常用的推荐算法,从1992年一直延续至今。所谓协同过滤算法,基本思想是根据用户的历史行为数据的挖…

    人工智能 2023年6月12日
    0112
  • python评分卡3_woe与IV分箱实现

    本系列分以下章节:python评分卡1_woe与IV值python评分卡2_woe与IV分箱方法python评分卡3_woe与IV分箱实现python评分卡4_logistics原…

    人工智能 2023年6月16日
    0102
  • 集成学习笔记

    民主协商:Ensemble 集成学习:为了更好的解决某个特定机器学习的问题把多个模型有策略性的组合的过程,不是某种算法而是一大门类算法包括bagging和boosting 目的:改…

    人工智能 2023年5月31日
    0105
  • 基于Tensorflow的环境声音分类

    本章我们来介绍如何使用Tensorflow训练一个区分不同音频的分类模型,例如你有这样一个需求,需要根据不同的鸟叫声识别是什么种类的鸟,或者识别环境中的声音类型(空调声、汽车鸣笛声…

    人工智能 2023年7月2日
    069
  • 11-包装类

    您可以使用pybind 库为C++代码添加Python接口。 Pybind 是一个轻量级的头文件库,使得Python可以直接调用C++函数和类。要使用pybind ,您需要按照以下…

    人工智能 2023年6月26日
    064
  • 【机器学习】吴恩达作业6.0,python实现SVM支持向量机

    6.0支持向量机使用支持向量机(SVM)处理各种两维的样本数据集,了解支持向量机如何工作,以及如何使用带高斯核函数的SVM。 SVM(鲁棒性,大间距分类器)支持向量机(suppor…

    人工智能 2023年6月17日
    057
  • yolov5 部署jetson nano(通用) 保姆级教学

    Jetson nano从配置环境到yolov5成功推理检测全过程 文章目录 * – Jetson nano从配置环境到yolov5成功推理检测全过程* 一、烧录镜像* …

    人工智能 2023年5月26日
    074
  • 【OpenCV】 红绿灯识别检测

    目录 一:红绿灯识别检测效果展示 二:红绿灯识别检测具体步骤 1.初始化设置,对亮度设置 视频路径 进行初始化设置 2.帧处理,调整视频亮度,分解YCrCb的三个成分,拆分红和绿,…

    人工智能 2023年6月23日
    0121
  • LaTeX常用的希腊字符、数学符号、矩阵、公式、排版、中括号、大括号以及插入图片等操作手册

    背景 因为在写周报或者论文时需要使用LaTeX,但是因为对其上手时间不长,导致很多操作不熟悉,特别是针对许多特殊字符和排版样式都不了解,每次使用都需要现查,效率十分低下,故萌生了攥…

    人工智能 2023年6月17日
    0131
  • 计算机视觉项目实战-目标检测与识别

    😊😊😊 欢迎来到本博客😊😊😊本次博客内容将继续讲解关于OpenCV的相关知识🎉 作者简介:⭐️⭐️⭐️ 目前计算机研究生在读。主要研究方向是人工智能和群智能算法方向。目前熟悉深度学…

    人工智能 2023年6月17日
    070
  • 【论文阅读】注意力综述(软注意力)

    以下内容来自:综述:图像处理中的注意力机制 – 知乎 目录 概述 软注意力 Spatial Transformer Networks(空间域注意力)—2015 nips…

    人工智能 2023年7月12日
    072
  • 如何通过梯度下降法优化逻辑回归模型的参数

    问题介绍 优化逻辑回归模型的参数是机器学习中的一个重要问题。梯度下降法是一种常用的优化方法,在逻辑回归中也可以使用此方法来最小化损失函数,从而得到最优的模型参数。在本文中,我们将通…

    人工智能 2023年12月31日
    036
  • 注意力机制

    1.直观认知注意力机制 假设你想在淘宝上买一件价格便宜、黑白相间的格子衬衫,而淘宝每件衣服都有不同的用料、尺寸、类型、价格、颜色、款式、风格等等,这时你就会根据你的需求更关注如款式…

    人工智能 2023年5月28日
    068
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球