目录

  • 一、摘要
  • 二、Token Cutoff介绍、公式
    • 2-1、背景介绍
    • 2-2、Cutoff介绍、架构示意图、公式详解
  • 三、Bi-SimCut介绍、公式
    • 3-0、Bi-SimCut完整概要
    • 3-1、Bi-SimCut介绍
    • 3-2、Bi-SimCut公式
    • 3-3、Bi-SimCut训练策略:双向预训练和单向微调
  • 四、代码阅读(损失函数部分)
  • 五、使用到的环境
  • 附录一:熵以及信息熵
  • 附录二:KL散度(相对熵)
  • 附录三:JS散度
  • 附录四:互信息
  • 总结

一、摘要

摘要:Bi-SimCut是一种简单但有效的训练策略,以提高神经机器翻译(NMT)的性能,它包括两个过程:双向预训练和单向微调,这两个过程都使用了SimCut, 这是一种简单的正则化方法,强调原始语句和经过Cutoff的语句的输出分布之间的一致性。SimCut并不是一种新的方法,而是Cutoff的简化版本。

二、Token Cutoff介绍、公式

2-1、背景介绍

背景:SimCut并不是一种新的方法,而是Shen等人在论文《A simple but tough to-beat data augmentation approach for natural language understanding and generation》提出的Token Cutoff的简化版本。Shen等人介绍了一套cutoff数据增强方法,并且利用JS散度损失在训练过程中使得原始样本和经过Cutoff之后的样本的输出分布一致。虽然性能可观,但是消耗资源巨大(为其中的四个超参数寻找合适的值耗时并且耗费资源),而Bi-SImCut可以解决这个问题(简单且有效)。

此外:文章还展示了

  • Simcut与预训练语言模型例如mBART的兼容性。
  • 结果表明:使用Bi-SimCut的NMT训练在不同量级上的数据都比Transformer取得了显著的改进,并且在几个基准上优于当前的SOTA方法BIBERT。

2-2、Cutoff介绍、架构示意图、公式详解

Cutoff介绍:Shen等人在论文《A simple but tough to-beat data augmentation approach for natural language understanding and generation》提出的Token Cutoff,介绍了一套简单而有效的数据增强策略,建议在一个训练实例中删除部分信息以产生多个扰动样本。为了确保模型完全不能利用已删除输入中的信息,删除过程发生在输入的嵌入层中。

CutOff架构示意图(图示来源于论文):Cutoff示意图,包含

  • Token Cutoff(令牌截断):从句子中删除几个单词的情况下,鼓励模型使用其余单词来得到正确的结果。
  • feature Cutoff(特征切断):每个输入维度都包含一定的语义信息,某些输入维度被删掉后,模型为了正确预测,就需要给与其余维度封装更加丰富的信息,增加了模型的鲁棒性。
  • span cutoff(跨度截断):删除了连续的文本块,鼓励模型利用其余特征来进行预测而不仅仅只是依赖于一小部分显著特征。

(公式详解)
Token Cutoff的交叉熵损失函数为:由三部分组成(原交叉熵损失 L c e ( θ ) L_{ce}(θ) Lce(θ)、使用cutoff的交叉熵损失、kl散度,α和β是平衡他们的标量超参数)

L t o k c u t ( θ ) = L c e ( θ ) + α L c u t ( θ ) + β L k l ( θ ) L_{tokcut}(θ) = L_{ce}(θ)+αL_{cut}(θ)+βL_{kl}(θ) Ltokcut(θ)=Lce(θ)+αLcut(θ)+βLkl(θ)

其中:不使用数据增强的交叉熵损失 L c e ( θ ) L_{ce}(θ) Lce(θ)可以表示为,其中θ是一组模型参数,x,y 代表的是平行语料库, f ( x , y ; θ ) f(x,y;θ) f(x,y;θ)是一系列的预测概率,ÿ是y的一系列独热码向量。
L c e ( θ ) = l ( f ( x , y ; θ ) , y ¨ ) L_{ce}(θ)= l(f(x,y;θ),ÿ) Lce(θ)=l(f(x,y;θ),y¨)

L c u t ( θ ) = 1 N ∑ i = 1 N l ( f ( x c u t i , y c u t i ; θ ) , y ¨ ) L_{cut}(θ) =\frac{1}{N}\sum_{i=1}^N l(f(x_{cut}^i,y_{cut}^i;θ),ÿ) Lcut(θ)=N1i=1Nl(f(xcuti,ycuti;θ),y¨)

这里:KL(·|·)表示两个分布的KL散度。有关于KL散度的更多信息请详见附录(有熵到KL散度、JS散度的说明)L k l ( θ ) L_{kl}(θ) Lkl(θ) 是为了保证原始样本和N个不同的cutoff样本的输出分布的一致性。

L k l ( θ ) = 1 N + 1 { ∑ i = 1 N K L ( f ( x c u t i , y c u t i ; θ ) ∣ ∣ p a v g ) + K L ( f ( x , y ; θ ) ∣ ∣ p a v g ) } L_{kl}(θ) = \frac{1}{N+1}\{\sum_{i=1}^N KL(f(x_{cut}^i,y_{cut}^i;θ)||p_{avg})+KL(f(x,y;θ)||p_{avg})\} Lkl(θ)=N+11{i=1NKL(f(xcuti,ycuti;θ)∣∣pavg)+KL(f(x,y;θ)∣∣pavg)}

p a v g = 1 N + 1 { ∑ i = 1 N f ( x c u t i , y c u t i ; θ ) + f ( x , y ; θ ) } p_{avg} = \frac{1}{N+1}\{\sum_{i=1}^N f(x_{cut}^i,y_{cut}^i;θ) + f(x,y;θ)\} pavg=N+11{i=1Nf(xcuti,ycuti;θ)+f(x,y;θ)}

三、Bi-SimCut介绍、公式

3-0、Bi-SimCut完整概要

Bi-SimCut:是一种用于提高神经机器翻译(NMT)性能的简单而有效的训练策略。 它包括两个步骤:双向预训练和单向微调。两个步骤都利用了SimCut,这是一种简单的正则化方法,可以强制原始句子和截断句子对应的输出分布之间的一致性。 Bi-SimCut在不通过回译或整合大规模预训练模型的情况下,在五个翻译基准测试中取得了强大的翻译性能。SimCut不是一种新方法,而是针对NMT简化和调整的Cutoff的一个版本,可以被认为是一种扰动-based方法。我们相信,由于SimCut和Bi-SimCut的普适性和简单性,它们可以成为未来NMT研究的强大基线。

为了更好地理解Bi-SimCut,以下是其主要特点

  • 双向预训练和单向微调两个步骤
  • 利用SimCut实现正则化,强制输出分布的一致性
  • 不需要回译或大规模预训练模型
  • 在五个翻译基准测试中取得强大的翻译性能
  • 为了更好地理解Bi-SimCut,以下是每个步骤的更详细的说明:

双向预训练:Bi-SimCut使用双向LSTM进行预训练。这个步骤的目的是为了让模型更好地理解输入序列的上下文信息,从而提高翻译性能。在预训练期间,模型首先从左到右处理输入序列,然后再从右到左处理输入序列。每个方向的训练都会在完整的输入序列上进行,而不是在截断的序列上进行。预训练期间使用的损失函数是交叉熵损失函数。

单向微调:在预训练之后,Bi-SimCut使用单向LSTM进行微调,以进一步提高翻译性能。微调期间,模型只从左到右处理输入序列。与预训练期间一样,微调期间也会在完整的输入序列上进行训练,而不是在截断的序列上进行。微调期间使用的损失函数是交叉熵损失函数。

为了更好地理解SimCut的作用,以下是一个例子

假设有两个句子,一个是原始句子,另一个是对原始句子进行截断后的句子。在使用SimCut时,模型将被要求在这两个句子上产生相同的输出分布。这可以通过将原始句子和截断句子对应的输出分布之间的KL散度最小化来实现。这种正则化方法可以帮助模型避免过度拟合,并提高模型的泛化能力。同时,这种正则化方法有助于防止模型在处理截断句子时出现错误。

总之,Bi-SimCut是一种简单而有效的训练策略,可以提高神经机器翻译的性能。它利用了SimCut这种简单的正则化方法,可以强制原始句子和截断句子对应的输出分布之间的一致性。通过双向预训练和单向微调两个步骤,Bi-SimCut可以在不使用回译或大规模预训练模型的

3-1、Bi-SimCut介绍

Bi-SimCut定义:Bi-SimCut是一种简单但有效的训练策略,以提高神经机器翻译(NMT)的性能,它包括两个过程:双向预训练和单向微调,这两个过程都使用了SimCut, 这是一种简单的正则化方法,强调原始语句和经过Cutoff的语句的输出分布之间的一致性。

提出Bi-SimCut的必要性:尽管Shen等人提出的Token Cutoff令人印象深刻,但是在资源有限的情况下,找到合适的超参数(pcut、α、β、N)是十分耗费时间和资源的,为了减少超参数搜索负担,我们提出了SimCut,一个简单的正则化方法使得原始句子和经过cutoff的样本输出分布保持一致。

使用到的数据集介绍: 使用到的详细数据集如下所示。

  • 低资源IWSLT14: en-de
  • 标准资源WMT14: en-de
  • 高资源WMT17: zh-en

3-2、Bi-SimCut公式

公式:公式是由受虚拟对抗训练(VAT,Sato 等人介绍的一种基于KL的的对抗正则化)启发产生的。对于每个句子对(x,y),我们只生成一个cutoff样本。并且与Token Cutoff论文中使用的策略相同,对于每对句子,SImCut的训练目标为:
L s i m c u t ( θ ) = L c e ( θ ) + α L s i m k l ( θ ) L_{simcut}(θ) = L_{ce}(θ)+αL_{simkl}(θ) Lsimcut(θ)=Lce(θ)+αLsimkl(θ)

其中
L s i m k l ( θ ) = K L ( f ( x , y ; θ ) ∣ ∣ f ( x c u t , y c u t ; θ ) ) L_{simkl}(θ) = KL(f(x,y;θ)||f(x_{cut},y_{cut};θ)) Lsimkl(θ)=KL(f(x,y;θ)∣∣f(xcut,ycut;θ))

Bi-SimCut优点:SimCut中只有两个超参数α和 p c u t p_{cut} pcut,大大简化了Token Cutoff中的超参数搜索步骤。注意:VAT只允许梯度通过KL发散项的右侧反向传播,而梯度在SimCut中被设计为通过KL正则化的的两侧反向传播。

α和 p c u t p_{cut} pcut的影响:α是我们优化问题中控制正则化强度的惩罚参数, p c u t p_{cut} pcut控制在SimCut中cutoff的百分比。α=3, p c u t p_{cut} pcut=0.05时表现最佳。实验表明,太小或者太大的α和 p c u t p_{cut} pcut都不利于模型训练。

总结L s i m k l ( θ ) L_{simkl}(θ) Lsimkl(θ)保证了原始样本和Cutoff样本的一致性。

3-3、Bi-SimCut训练策略:双向预训练和单向微调

双向预训练和单向微调:首先预训练一个双向NMT模型,并且将其作为初始化来微调一个单向NMT模型,假设我们要训练一个英语-》德语的NMT模型,我们首先将训练句对重构为英语+德语-》德语+英语,其中训练数据集翻倍。然后,我们用新的训练句对训练一个新的双向NMT模型,

四、代码阅读(损失函数部分)

代码解释
主要用于实现一种名为label_smoothed_cross_entropy_with_simcut的损失函数,它基于Fairseq库,用于训练神经网络模型。这个损失函数结合了标签平滑交叉熵损失(Label Smoothed Cross Entropy)和相似度裁剪损失(SimCut)。

  • 首先,代码导入了所需的库,如math、torch、fairseq等。然后,使用Python的dataclass装饰器定义了一个名为LabelSmoothedCrossEntropyCriterionWithSimCutConfig的数据类,用于存储模型训练过程中的配置参数,包括标签平滑系数(label_smoothing)、正则化项系数(alpha)、相似度裁剪方法中的概率参数(p)、是否报告准确性指标(report_accuracy)等。

  • 接下来,使用fairseq库中的@register_criterion装饰器将LabelSmoothedCrossEntropyCriterionWithSimCutConfig类注册为label_smoothed_cross_entropy_with_simcut。这意味着在训练模型时可以使用label_smoothed_cross_entropy_with_simcut作为损失函数。

  • LabelSmoothedCrossEntropyWithSimCutCriterion类继承自FairseqCriterion。它的__init__方法接收一系列参数,如任务对象、是否进行句子级别的平均等。该类实现了simcut方法,用于计算相似度裁剪损失。

  • forward方法用于计算给定样本的损失。它首先计算标签平滑交叉熵损失,然后在训练阶段将其与相似度裁剪损失结合起来。此外,该方法还计算了准确性指标(如果需要)。

  • compute_loss方法用于计算标签平滑交叉熵损失,compute_accuracy方法用于计算准确性指标。最后,reduce_metrics方法用于汇总分布式训练过程中的日志输出。

总之,这段代码实现了一种名为label_smoothed_cross_entropy_with_simcut的损失函数,用于训练神经网络模型。这个损失函数结合了标签平滑交叉熵损失和相似度裁剪损失,可以在训练过程中使用。

# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.import math
from dataclasses import dataclass, fieldimport torch
from fairseq import metrics, utils
from fairseq.criterions import FairseqCriterion, register_criterion
from fairseq.criterions.label_smoothed_cross_entropy import label_smoothed_nll_loss
from fairseq.dataclass import FairseqDataclass
from omegaconf import II# 这段代码是用 Python 的 dataclass 装饰器定义了一个名为 LabelSmoothedCrossEntropyCriterionWithSimCutConfig 的数据类,用于存储模型训练过程中的配置参数。@dataclass
class LabelSmoothedCrossEntropyCriterionWithSimCutConfig(FairseqDataclass):label_smoothing: float = field(# 表示平滑系数,为0则表示没有平滑。default=0.0,metadata={"help": "epsilon for label smoothing, 0 means no label smoothing"},)alpha: float = field(#  表示α参数,为0则表示不进行simcut  (正则化系数)default=0.0,metadata={"help": "alpha for simcut, 0 means no simcut"},)p: float = field(# cutoff的概率参数,为0则表示不进行simcut中的cutoff操作default=0.0,metadata={"help": "probability for cutoff in simcut, 0 means no cutoff in simcut"},)report_accuracy: bool = field(# 表示是否需要报告准确性指标。default=False,metadata={"help": "report accuracy metric"},)ignore_prefix_size: int = field(# 忽略token的数量。default=0,metadata={"help": "Ignore first N tokens"},)# 布尔值,即是否进行句子级别的平均,具体作用是用于计算loss值时,是否对每个句子的loss求平均,如果为True,则对整个batch的所有句子的loss值求平均。sentence_avg: bool = II("optimization.sentence_avg")# 这段代码是使用fairseq库中的@register_criterion装饰器将LabelSmoothedCrossEntropyCriterionWithSimCutConfig类注册为label_smoothed_cross_entropy_with_simcut
# 这意味着在训练模型时可以使用label_smoothed_cross_entropy_with_simcut作为损失函数。# @register_criterion装饰器提供了一种方便的方式,使用户可以自定义和注册新的损失函数。
@register_criterion("label_smoothed_cross_entropy_with_simcut", dataclass=LabelSmoothedCrossEntropyCriterionWithSimCutConfig
)
# 该类实现了'simcut'方法,用于计算相似度裁剪损失。
class LabelSmoothedCrossEntropyWithSimCutCriterion(FairseqCriterion):def __init__(# 该类接受一下参数self,# 任务对象task,# 一个布尔值,表示损失是否以句子为单位进行平均。如果为True,则每个句子的损失将被平均,否则将对所有标记的损失进行平均。sentence_avg,# 平滑label_smoothing,# 正则化项系数alpha=0.0,# 表示simcut方法中的p值p=0.0,# 一个整数,表示需要忽略的前缀的长度。ignore_prefix_size=0,# 是否需要报告准确性指标report_accuracy=False,):super().__init__(task)self.sentence_avg = sentence_avgself.eps = label_smoothingself.ignore_prefix_size = ignore_prefix_sizeself.report_accuracy = report_accuracyself.alpha = alphaself.p = 1 - pdef simcut(self, model, omega, sample, reduce):"""这段代码定义了一个名为simcut的方法,接受四个参数:self,model,omega,sample和reduce。"""# 计算omega矩阵在最后一维的softmax,得到一个概率分布,保存在变量prob中。prob = torch.nn.functional.softmax(omega, dim=-1)# 判断target序列中是否有padding字符,并生成一个与target同样形状的张量,其中为True的位置代表# 原来target中非padding字符的位置。valid_indices = (sample["target"] != self.padding_idx)# 调用模型中的encoder模块对输入进行编码,生成编码器输出。encoder_out = model.encoder(src_tokens=sample["net_input"]["src_tokens"],src_lengths=sample["net_input"]["src_lengths"],simcut_p=self.p)# 调用模型中的decoder模块对输入进行解码,生成解码器输出。 decoder_out = model.decoder(prev_output_tokens=sample["net_input"]["prev_output_tokens"],encoder_out=encoder_out,simcut_p=self.p)# 使用KL散度来计算解码器输出分布与目标分布之间的差异,并将结果保存在loss变量之中。loss = torch.nn.functional.kl_div(input=torch.nn.functional.log_softmax(decoder_out[0], dim=-1),target=prob, reduction='none')# 将每个位置的KL散度相加,得到总的散度。loss = loss.sum(dim=-1)# 将padding位置的kl散度值置为0。loss = loss * valid_indices.float()# if reduce:loss = loss.sum()return lossdef forward(self, model, sample, reduce=True):"""Compute the loss for the given sample.用于计算给定样本的损失。Returns a tuple with three elements:1) the loss2) the sample size, which is used as the denominator for the gradient3) logging outputs to display while training"""# 调用模型对输入进行前向传播,得到模型的输出net_output = model(**sample["net_input"])# 计算模型输出的损失,同时也计算了负对数似然损失,并将结果保存在loss和nll_loss中去。loss, nll_loss = self.compute_loss(model, net_output, sample, reduce=reduce)# if model.training:# 调用simcut方法,计算基于KL散度的相似度正则项,并将其加到总的损失函数中去。loss += self.alpha * self.simcut(model, net_output[0], sample, reduce)# 计算样本的大小,用于作为梯度的分母。sample_size = (sample["target"].size(0) if self.sentence_avg else sample["ntokens"])# 将损失函数的值、负对数似然损失的值、样本中的token数,句子数和样本大小等信息保存在一个字典中。logging_output = {"loss": loss.data,"nll_loss": nll_loss.data,"ntokens": sample["ntokens"],"nsentences": sample["target"].size(0),"sample_size": sample_size,}# 如果设置了报告准确率的标志,则执行下面的操作。if self.report_accuracy:# 计算模型的准确率,并将正确预测的数量和总数分别保存在n_correct和total变量中。n_correct, total = self.compute_accuracy(model, net_output, sample)logging_output["n_correct"] = utils.item(n_correct.data)logging_output["total"] = utils.item(total.data)return loss, sample_size, logging_outputdef get_lprobs_and_target(self, model, net_output, sample):# 获取归一化的对数概率,net_output代表输出,log_probs代表需要返回对数概率而非原始概率。lprobs = model.get_normalized_probs(net_output, log_probs=True)# 获取目标序列,其中sample是模型的输入,net_output是输出。target = model.get_targets(sample, net_output)# 如果ignore_prefix_size 大于0,则会忽略输出序列的前缀部分。if self.ignore_prefix_size > 0:# lprobs: B x T x Clprobs = lprobs[:, self.ignore_prefix_size :, :].contiguous()target = target[:, self.ignore_prefix_size :].contiguous()# 函数返回对数概率和目标序列,return lprobs.view(-1, lprobs.size(-1)), target.view(-1)def compute_loss(self, model, net_output, sample, reduce=True):"""用于计算给定模型在某个输入样本上的损失值。"""# self 是指代类实例本身,model 是正在评估的模型,net_output 是给定输入样本时模型的输出,sample 是输入样本本身。# 用于计算预测对数概率值和目标值lprobs, target = self.get_lprobs_and_target(model, net_output, sample)# 用label_smoothed_nll_loss函数来计算损失值,该函数返回两个值,总损失值loss和负对数似然值。loss, nll_loss = label_smoothed_nll_loss(lprobs,target,self.eps,ignore_index=self.padding_idx,# reduce 是一个布尔型标志,用于指示损失是否应该被缩减为一个标量值(例如,是否应该在批次上进行平均)。reduce=reduce,)return loss, nll_lossdef compute_accuracy(self, model, net_output, sample):"""计算神经网络模型在给定输入样本上预测准确率的方法。"""# lprobs, target = self.get_lprobs_and_target(model, net_output, sample)# 通过target.ne(self.padding_idx)创建一个掩码张量。这会创建一个二进制掩码张量,其中每个元素为1,如果target中对应的元素不等于填充索引。mask = target.ne(self.padding_idx)n_correct = torch.sum(lprobs.argmax(1).masked_select(mask).eq(target.masked_select(mask)))total = torch.sum(mask)return n_correct, total@classmethoddef reduce_metrics(cls, logging_outputs) -> None:"""Aggregate logging outputs from data parallel training."""# 用于在数据并行训练时聚合日志输出。# logging_outputs:这个参数包含了多个日志输出的列表# 循环遍历logging_outputs列表,对于每个日志输出,统计它的loss,nll_loss、ntokens和sample_size指标的总和。loss_sum = sum(log.get("loss", 0) for log in logging_outputs)nll_loss_sum = sum(log.get("nll_loss", 0) for log in logging_outputs)ntokens = sum(log.get("ntokens", 0) for log in logging_outputs)sample_size = sum(log.get("sample_size", 0) for log in logging_outputs)# 调用metrics.log_scalar和log_derived方法,将聚合后的指标值记录下来,其中log_scalar方法记录标量指标,如loss和nll_loss, log_derived()方法记录的是可以从已记录的指标派生出来的新指标,如ppl和accuracy。metrics.log_scalar("loss", loss_sum / sample_size / math.log(2), sample_size, round=3)metrics.log_scalar("nll_loss", nll_loss_sum / ntokens / math.log(2), ntokens, round=3)metrics.log_derived("ppl", lambda meters: utils.get_perplexity(meters["nll_loss"].avg))total = utils.item(sum(log.get("total", 0) for log in logging_outputs))if total > 0:metrics.log_scalar("total", total)n_correct = utils.item(sum(log.get("n_correct", 0) for log in logging_outputs))metrics.log_scalar("n_correct", n_correct)metrics.log_derived("accuracy",lambda meters: round(meters["n_correct"].sum * 100.0 / meters["total"].sum, 3)if meters["total"].sum > 0else float("nan"),)@staticmethoddef logging_outputs_can_be_summed() -> bool:"""Whether the logging outputs returned by `forward` can be summedacross workers prior to calling `reduce_metrics`. Setting thisto True will improves distributed training speed."""return True

五、使用到的环境

absl-py==1.0.0
antlr4-python3-runtime==4.8
anyio==3.4.0
argon2-cffi==21.1.0
attrs==21.2.0
Babel==2.9.1
backcall==0.2.0
bitarray==2.7.3
bleach==4.1.0
brotlipy==0.7.0
cachetools==4.2.4
certifi==2021.5.30
cffi @ file:///tmp/build/80754af9/cffi_1625807838443/work
chardet @ file:///tmp/build/80754af9/chardet_1607706746162/work
cmake==3.26.0
colorama==0.4.6
conda==4.10.3
conda-package-handling @ file:///tmp/build/80754af9/conda-package-handling_1618262148928/work
cryptography @ file:///tmp/build/80754af9/cryptography_1616769286105/work
cycler==0.11.0
Cython==0.29.33
debugpy==1.5.1
decorator==5.1.0
defusedxml==0.7.1
entrypoints==0.3
-e git+https://github.com/gpengzhi/Bi-SimCut@ab38d206413f32da45b6c0e0f9ee7f15d0d48a0f#egg=fairseq&subdirectory=fairseq
filelock==3.10.0
fonttools==4.28.2
google-auth==2.3.3
google-auth-oauthlib==0.4.6
grpcio==1.42.0
hydra-core==1.0.7
idna @ file:///home/linux1/recipes/ci/idna_1610986105248/work
importlib-metadata==4.8.2
importlib-resources==5.4.0
ipykernel==6.5.1
ipython==7.29.0
ipython-genutils==0.2.0
ipywidgets==7.6.5
jedi==0.18.1
Jinja2==3.0.3
json5==0.9.6
jsonschema==4.2.1
jupyter-client==7.1.0
jupyter-core==4.9.1
jupyter-server==1.12.0
jupyterlab==3.2.4
jupyterlab-language-pack-zh-CN==3.2.post2
jupyterlab-pygments==0.1.2
jupyterlab-server==2.8.2
jupyterlab-widgets==1.0.2
kiwisolver==1.3.2
lightseq==3.0.1
lit==15.0.7
lxml==4.9.2
Markdown==3.3.6
MarkupSafe==2.0.1
matplotlib==3.5.0
matplotlib-inline==0.1.3
mistune==0.8.4
mpmath==1.3.0
nbclassic==0.3.4
nbclient==0.5.9
nbconvert==6.3.0
nbformat==5.1.3
nest-asyncio==1.5.1
networkx==3.0
ninja==1.11.1
notebook==6.4.6
numpy==1.21.4
nvidia-cublas-cu11==11.10.3.66
nvidia-cuda-cupti-cu11==11.7.101
nvidia-cuda-nvrtc-cu11==11.7.99
nvidia-cuda-runtime-cu11==11.7.99
nvidia-cudnn-cu11==8.5.0.96
nvidia-cufft-cu11==10.9.0.58
nvidia-curand-cu11==10.2.10.91
nvidia-cusolver-cu11==11.4.0.1
nvidia-cusparse-cu11==11.7.4.91
nvidia-nccl-cu11==2.14.3
nvidia-nvtx-cu11==11.7.91
oauthlib==3.1.1
omegaconf==2.0.6
packaging==21.3
pandocfilters==1.5.0
parso==0.8.2
pexpect==4.8.0
pickleshare==0.7.5
Pillow==8.4.0
portalocker==2.7.0
prometheus-client==0.12.0
prompt-toolkit==3.0.22
protobuf==3.19.1
ptyprocess==0.7.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycosat==0.6.3
pycparser @ file:///tmp/build/80754af9/pycparser_1594388511720/work
Pygments==2.10.0
pyOpenSSL @ file:///tmp/build/80754af9/pyopenssl_1608057966937/work
pyparsing==3.0.6
pyrsistent==0.18.0
PySocks @ file:///tmp/build/80754af9/pysocks_1605305779399/work
python-dateutil==2.8.2
pytz==2021.3
PyYAML==6.0
pyzmq==22.3.0
regex==2022.10.31
requests @ file:///tmp/build/80754af9/requests_1608241421344/work
requests-oauthlib==1.3.0
rsa==4.8
ruamel-yaml-conda @ file:///tmp/build/80754af9/ruamel_yaml_1616016699510/work
sacrebleu==2.3.1
scipy==1.9.3
Send2Trash==1.8.0
setuptools-scm==6.3.2
six @ file:///tmp/build/80754af9/six_1623709665295/work
sniffio==1.2.0
supervisor==4.2.2
sympy==1.11.1
tabulate==0.9.0
tensorboard==2.7.0
tensorboard-data-server==0.6.1
tensorboard-plugin-wit==1.8.0
tensorboardX==2.6
terminado==0.12.1
testpath==0.5.0
tomli==1.2.2
torch==1.10.1+cu113
torchaudio==0.10.1+cu113
torchvision==0.11.2+cu113
tornado==6.1
tqdm @ file:///tmp/build/80754af9/tqdm_1625563689033/work
traitlets==5.1.1
triton==2.0.0
typing-extensions==4.0.0
urllib3 @ file:///tmp/build/80754af9/urllib3_1625084269274/work
wcwidth==0.2.5
webencodings==0.5.1
websocket-client==1.2.1
Werkzeug==2.0.2
widgetsnbextension==3.5.2
zipp==3.6.0

您可以在Ubuntu上使用以下命令将当前Python环境中所有已安装的包及其版本信息导出到名为"requirements.txt"的文件中:

  • pip freeze > requirements.txt

请注意,您需要在命令前加上pip关键字以使用pip命令。此命令将当前Python环境中所有已安装的包及其版本信息写入名为"requirements.txt"的文件中。

然后,您可以使用以下命令在另一个Python环境中安装这些依赖项:

  • pip install -r requirements.txt

该命令将读取名为"requirements.txt"的文件中列出的所有依赖项并安装它们。请注意,您需要在执行此命令之前确保已安装Python和pip。

需要注意的是,如果您的Python应用程序依赖于系统级软件包,则建议您使用操作系统特定的包管理器来管理这些依赖项。

附录一:熵以及信息熵

:用于描述不确定性,表示系统混乱的程度,越整齐熵也就越小,越混乱不确定的程度越大,熵也就越大,因此整个环境会自发的朝着混乱的方向发展,也就是熵增原理。

信息熵含义:信息熵表示随机变量不确定的程度。一件事情发生的概率越高,那么他的确定性也就越大,那么它的熵也就越小。信息熵常常被作为一个系统的信息含量的量化指标。

性质:信息熵非负。当一件事发生的概率为1时,信息就没有不确定,那么它的熵就是0。
公式:p(x)代表的是事件x发生的概率。
H ( X ) = − ∑ x ∈ X p ( x ) l o g p ( x ) H(X)=- \sum_{x∈X} p(x)logp(x) H(X)=xXp(x)logp(x)

总结:那些接近确定性的分布(输出几乎可以确定)具有较低的熵,那些接近均匀分布的概率分布具有较高的熵。

附录二:KL散度(相对熵)

定义:在机器学习领域,KL散度用来度量两个函数(概率分布)的相似程度或者相近程度,是用来描述两个概率分布差异的一种方法,也叫做相对熵。也就是说KL散度可以作为一种损失,来计算两者之间的概率差异。
公式
K L ( p ∣ ∣ q ) = ∑ p ( x ) l o g p ( x ) q ( x ) = ∑ p ( x ) ( l o g p ( x ) − l o g q ( x ) ) KL(p||q)= \sum p(x)log\frac{p(x)}{q(x)} = \sum p(x)(logp(x)-logq(x)) KL(p∣∣q)=p(x)logq(x)p(x)=p(x)(logp(x)logq(x))

性质

  • KL散度的值始终>=0,当且仅当P(x)=Q(x)时等号成立。
  • KL散度并不是一个对称量,KL(p||q)不等于KL(q||p)

双向KL散度定义:通过交换这两种分布的位置以间接使用整体对称的KL散度。

双向 K L 散度 = 0.5 ∗ K L ( A ∣ B ) + 0.5 ∗ K L ( B ∣ A ) 双向KL散度 = 0.5*KL(A|B) + 0.5*KL(B|A) 双向KL散度=0.5KL(AB)+0.5KL(BA)

附录三:JS散度

定义:KL散度是不对称的,训练神经网络会因为不同的顺序造成不一样的训练结果,为了克服这个问题,提出了JS散度。

J S ( P 1 ∣ ∣ P 2 ) = 1 2 K L ( P 1 ∣ ∣ P 1 + P 2 2 ) + 1 2 K L ( P 2 ∣ ∣ P 1 + P 2 2 ) JS(P1||P2)= \frac{1}{2}KL(P1||\frac{P1+P2}{2}) + \frac{1}{2}KL(P2||\frac{P1+P2}{2}) JS(P1∣∣P2)=21KL(P1∣∣2P1+P2)+21KL(P2∣∣2P1+P2)

性质

  • JS散度的值域范围是[0,1],相同为0,相反则为1,相比于KL,对相似度的判断更加准确了。
  • JS散度是一个对称量,JS(p||q)等于JS(q||p), 对称可以让散度度量更加准确,下边是证明代码。
import numpy as np
import math# 离散随机变量的KL散度和JS散度的计算方法def KL(p, q):# p,q为两个list,里面存着对应的取值的概率,整个list相加为1if 0 in q:raise ValueErrorreturn sum(_p * math.log(_p / _q) for (_p, _q) in zip(p, q) if _p != 0)def JS(p, q):M = [0.5 * (_p + _q) for (_p, _q) in zip(p, q)]return 0.5 * (KL(p, M) + KL(q, M))def exp(a, b):a = np.array(a, dtype=np.float32)b = np.array(b, dtype=np.float32)a /= a.sum()b /= b.sum()print(a)print(b)print(KL(a, b))print(JS(a, b))if __name__ == '__main__':# exp1print('exp1: Start')print(exp([1, 2, 3, 4, 5], [5, 4, 3, 2, 1]))print('exp1: End')# exp2# 把公式中的第二个分布做修改,假设这个分布中有某个值的取值非常小,就有可能增加两个分布的散度值print('exp2: Start')print(exp([1, 2, 3, 4, 5], [1e-12, 4, 3, 2, 1]))print(exp([1, 2, 3, 4, 5], [5, 4, 3, 2, 1e-12]))print('exp2: End')# exp3print('exp3: Start')print(exp([1e-12,2,3,4,5],[5,4,3,2,1]))print(exp([1,2,3,4,1e-12],[5,4,3,2,1]))print('exp3: End')

输出
exp1: Start
[0.06666667 0.13333334 0.2 0.26666668 0.33333334]
[0.33333334 0.26666668 0.2 0.13333334 0.06666667]
0.5216030835963031
0.11968758856917597
None
exp1: End
exp2: Start
[0.06666667 0.13333334 0.2 0.26666668 0.33333334]
[1.e-13 4.e-01 3.e-01 2.e-01 1.e-01]
2.065502018456509
0.0985487692550548
None
[0.06666667 0.13333334 0.2 0.26666668 0.33333334]
[3.5714287e-01 2.8571430e-01 2.1428572e-01 1.4285715e-01 7.1428574e-14]
9.662950847122168
0.19399530008415986
None
exp2: End
exp3: Start
[7.1428574e-14 1.4285715e-01 2.1428572e-01 2.8571430e-01 3.5714287e-01]
[0.33333334 0.26666668 0.2 0.13333334 0.06666667]
0.7428131560123377
0.19399530008415986
None
[1.e-01 2.e-01 3.e-01 4.e-01 1.e-13]
[0.33333334 0.26666668 0.2 0.13333334 0.06666667]
0.38315075574389773
0.0985487692550548
None
exp3: End

  • 将第一个实验与第二个实验做对比,可以看出KL散度的波动比较大,而JS的波动相对小。
  • 如果将第二个实验和第三个实验做对比,可以发现KL散度在衡量两个分布的差异时具有很大的不对称性。如果后面的分布在某一个值上缺失,就会得到很大的散度值;但是如果前面的分布在某一个值上缺失,最终的KL散度并没有太大的波动。这个demo可以清楚地看出KL不对称性带来的一些小问题,而JS具有对称性,所以第二个实验和第三个实验的JS散度实际上是距离相等的分布组。

附录四:互信息

定义:互信息衡量的是两种度量间相互关联的程度,极端一点来理解,如果X,Y相互独立,那么互信息为0,因为两者不相关;而如果X,Y相互的关系确定(比如Y是X的函数),那么此时X,Y是“完全关联的”。
公式
I ( X ; Y ) = ∑ x , y p ( x , y ) l o g p ( x , y ) p ( x ) p ( y ) = H ( X ) − H ( X ∣ Y ) = H ( Y ) − H ( Y ∣ X ) I(X;Y)= \sum_{x,y} p(x,y)log\frac{p(x,y)}{p(x)p(y)} = H(X) - H(X | Y) = H(Y) - H(Y | X) I(XY)=xyp(xy)logp(x)p(y)p(xy)=H(X)H(XY)=H(Y)H(YX)

总结

好烦,又想到了被论文支配的恐惧

Bi-SimCut: A Simple Strategy for Boosting Neural Machine Translation 论文笔记相关推荐

  1. Vocabulary Learning via Optimal Transport for Neural Machine Translation论文解读

    abstract token vocabulary的选择对机器翻译结果的影响比较大 本文研究什么样才是好的词表,并且能不能不通过训练直接找到最优的词表 首先提供一种从信息理论的角度来分析词表的作用 通 ...

  2. ACL 2016 | Modeling Coverage for Neural Machine Translation

    ACL 2016 | Modeling Coverage for Neural Machine Translation 原创2016-08-03小S程序媛的日常程序媛的日常 今天的 ACL 2016 ...

  3. 【Paper】Effective Approaches to Attention-based Neural Machine Translation

    论文原文:PDF 论文年份:2015 论文被引:4675(2020/11/08) 7232(2022/03/26) 论文作者:Minh-Thang Luong et.al. 文章目录 Abstract ...

  4. 【论文笔记】Effective Approaches to Attention-based Neural Machine Translation

    这篇文章发布2015年,关于Attention的应用. 现在看来可能价值没那么大了,但是由于没读过还是要读一遍. 简介 Introduce In parallel, the concept of &q ...

  5. 论文解读:On The Alignment Problem In Multi-Head Attention-Based Neural Machine Translation

    论文解读:On The Alignment Problem In Multi-Head Attention-Based Neural Machine Translation   机器翻译是自然语言处理 ...

  6. 《Effective Approaches to Attention-based Neural Machine Translation》—— 基于注意力机制的有效神经机器翻译方法

    目录 <Effective Approaches to Attention-based Neural Machine Translation> 一.论文结构总览 二.论文背景知识 2.1 ...

  7. nlp论文-《Neural Machine Translation by Jointly Learning to Align and Translate》-基于联合学习对齐和翻译的神经机器翻译(一)

    <Neural Machine Translation by Jointly Learning to Align and Translate>--基于联合学习对齐和翻译的神经机器翻译 作者 ...

  8. 神经机器翻译(Neural machine translation, NMT)学习笔记

    神经机器翻译(Neural machine translation, NMT)是最近提出的机器翻译方法.与传统的统计机器翻译不同,NMT的目标是建立一个单一的神经网络,可以共同调整以最大化翻译性能.最 ...

  9. 复现有道NLPCC-2018 CGEC:A Neural Machine Translation Approach to Chinese Grammatical Error Correction

    有道NLPCC-2018 CGEC任务论文:A Neural Machine Translation Approach to Chinese Grammatical Error Correction ...

最新文章

  1. 第四篇 Gallery控件
  2. C#程序实现动态调用DLL的研究(转)
  3. 光流 | 特征光流之视频中物体检测一(论文分享)
  4. SAP Commerce Cloud,通过 ycommercewebservices OCC APIs 进行结账的一个技术限制
  5. HDU 2897 (博弈 找规律) 邂逅明下
  6. python无限锁屏_定时锁屏程序,Python祝你原理猝死!
  7. EXCEL vba 易失性函数
  8. 解决Chrome 的右键谷歌网页翻译失效 20221107更新
  9. drop与delete的区别
  10. mac 远程连接 Windows 桌面
  11. 基于linux嵌入式浏览,基于LINUX的嵌入式浏览器的设计与 - 嵌入式操作系统 - 电子发烧友网...
  12. 数学建模学习心得--建模教程
  13. 加入云上江湖—蚂蚁 SOFAStack
  14. 海康威视监控下载下来的mp4格式的视频,小类别MPEG-PS格式
  15. github国内镜像站
  16. java计算机毕业设计临大新生入学指导系统源代码+数据库+系统+lw文档
  17. NOIP2012 提高组 Day 2
  18. Web自动化测试模式page object的小利器:gizmo
  19. Cyber_monitor的使用
  20. C++ 实现对选手、评委的计分

热门文章

  1. arima基本原理_1 arima 模型理论.pdf
  2. 君弘号《大白话讲炒股》笔记(第三部分):均线知识
  3. reaver使用相关
  4. 安利一个非常优秀的开源后台管理系统项目,开箱即用,极大提高效率
  5. 120分钟吃掉DIEN深度兴趣演化网络
  6. leaflet加载多种形式谷歌地图(120)
  7. 【曙光试题】恺撒的规划(difficult)
  8. OSChina 清明节乱弹 ——老乡不要害怕,我们不糟蹋你
  9. How to fix corrupt HDFS FIles
  10. 【XLPNet车牌识别算法】第二章 检测部分-算法篇1