collections

一些回顾性的经典总结

2019年盘点

Geoffrey Hinton 介绍了Stacked Capsule Autoencoders,即一种无监督版本的 Capsule 网络,这种神经编码器能查看所有的组成部分,并用于推断跟细节的特征; Yann LeCun 在《Self-Supervised Learning》中再次强调了自监督学习的重要性;(nlp那章里讲到了) Yoshua Bengio 在Deep Learning for System 2 Processing中回顾了深度学习,并讨论了当前的局限性以及前瞻性研究方向。

2019nlp

2021年盘点

google research总结

传统ML

PRML

传统ML库

数学相关

数据降维

孪生网络

聚类

树相关

xgb

XGBoost 是一项基于梯度提升可扩展集合技术,在解决机器学习难题方面是可靠和有效的。在本文中,研究者对这项新颖的技术如何在训练速度、泛化性能和参数设置方面发挥作用进行了实证分析。此外,通过精心调整模型和默认设置,研究者还对 XGBoost、随机森林和梯度提升展开了综合比较。结果表明,XGBoost 在所有情况下并不总是最佳选择。最后,他们还对 XGBoost 的参数调整过程进行了扩展分析。
推荐:通过对随机森林、梯度提升和 XGBoost 的综合比较,来自法国波尔多大学、匈牙利帕兹曼尼·彼得天主教大学以及马德里自治大学的三位研究者得出结论:从调查问题的数量看,梯度提升是最好的分类器,但默认参数设置下 XGBoost 和随机森林在平均排名(average rank)方面的差异不具备统计显著性。

深度森林

主题模型

CRF

DL基础研究

DL背后的原理

MIT 教授 Tomaso Poggio 曾在他的系列研究中 [1] 表示深度学习理论研究可以分为三大类:
  • 表征问题(Representation):为什么深层网络比浅层网络的表达能力更好?
  • 最优化问题(Optimization):为什么梯度下降能找到很好的极小值解,好的极小值有什么特点?
  • 泛化问题(Generalization):为什么过参数化仍然能拥有比较好的泛化性,不过拟合?
对于表征问题,我们想要知道深度神经网络这种「复合函数」,它的表达能力到底怎么确定,它的复合机制又是什么样的。我们不再满足于「能拟合任意函数」这样的定性描述,我们希望知道是不是有一种方法能描述 50 层 ResNet、12 层 Transformer 的拟合能力,能不能清楚地了解它们的理论性质与过程。
有了表征能力,那也只是具备了拟合潜力,深度学习还需要找到一组足够好的极值点,这就是模型的最优解。不同神经网络的「最优化 Landscape」是什么样的、怎样才能找到这种高维复杂函数的优秀极值点、极值点的各种属性都需要完善的理论支持。
最后就是泛化了,深度模型泛化到未知样本的能力直接决定了它的价值。那么深度模型的泛化边界该怎样确定、什么样的极值点又有更好的泛化性能,很多重要的特性都等我们确定一套理论基准。
neurips2019 杰出新方向论文奖颁给了Vaishnavh Nagarajan和J. Zico Kolter的《一致收敛理论可能无法解释深度学习中的泛化现象》(Uniform convergence may be unable to explain generalization in deep learning),其论点是一致收敛理论本身并不能解释深度学习泛化的能力。随着数据集大小的增加,泛化差距(模型对可见和不可见数据的性能差距)的理论界限也会增加,而经验泛化差距则会减小。
Shirin Jalali等人的论文《高斯混合模型的高效深度学习》(Efficient Deep Learning of Gaussian mix Models)从这个问题引入:“通用逼近定理指出,任何正则函数都可以使用单个隐藏层神经网络进行逼近。深度是否能让它更具效率?”他们指出,在高斯混合模型的最佳贝叶斯分类的情况下,这样的函数可以用具有一个隐藏层的神经网络中的O(exp(n))节点来近似,而在两层网络中只有O(n)节点。

NTK

神经正切核(neural tangent kernel, NTK)是近年来研究神经网络优化与泛化的一个新方向。它出现在数个spotlight报告和我在NeuIPS与许多人的对话中。Arthur Jacot等人基于完全连通神经网络在无限宽度限制下等同于高斯过程这一众所周知的概念,在函数空间而非参数空间中研究了其训练动力学。他们证明了“在神经网络参数的梯度下降过程中,网络函数(将输入向量映射到输出向量)遵循函数的核函数梯度成本,关于一个新的核:NTK。”他们还表明,当有限层版本的NTK经过梯度下降训练时,其性能会收敛到无限宽度限制NTK,然后在训练期间保持不变。
NeurIPS上关于NTK的论文有:
但是,许多人认为NTK不能完全解释深度学习。神经网络接近NTK状态所需要的超参数设置——低学习率、大的初始化、无权值衰减——在实践中通常不用于训练神经网络。NTK的观点还指出,神经网络只会像kernel方法一样泛化,但从经验上看,它们可以更好地泛化。
Colin Wei等人的论文“Regularization Matters: Generalization and Optimization of Neural Nets v.s. their Induced Kernel”从理论上证明了具有权值衰减的神经网络泛化效果要比NTK好得多,这表明研究 L2-regularized 神经网络可以更好的理解泛化。NeurIPS的以下论文也表明,传统的神经网络可以超越NTK:

优化算法

优化算法综述

复合函数最优化

nips2019快手,针对复合函数的最优化方法。这里复合指的是一个数学期望函数中复合了另一个数学期望,而常规的 ML 目标函数就只有最外面一个数学期望。这种最优化方法在风险管理或 RL 中非常有用,例如在 RL 中解贝尔曼方程,它本质上就是复合函数最优化问题。

adabound

AdaBound是一种优化程序,旨在提高不可见的数据的训练速度和性能,可用PyTorch实现。
AdaBound:一种基于PyTorch实现的优化器,训练速度堪比Adam,质量堪比SGD(ICLR 2019)

batchsize与学习率相关

《控制批大小和学习率以很好地泛化:理论和实证证据》(Control Batch Size and Learning Rate to Generalize Well: Theoretical and Empirical Evidence)中,Fengxiang He 的团队在CIFAR数据集上使用SGD训练了1600个ResNet-110和VGG-19模型,发现这些模型的泛化能力与 batch size负相关,与学习率正相关,与批大小/学习率之比负相关。

backpack框架

自动微分框架只在计算平均小批量(mini-batch)梯度时进行优化。但在理论上,小批量梯度方差或 Hessian 矩阵近似值等其他数量可以作为梯度实现高效的计算。研究人员对这些数量抱有极大的兴趣,但目前的深度学习软件不支持自动计算。此外,手动执行这些数量非常麻烦,效率低,生成代码的共享性也不高。这种情况阻碍了深度学习的进展,并且导致梯度下降及其变体的研究范围变窄。与此同时,这种情况还使得复现研究以及新提出需要这些数量的方法之间的比较更为复杂。因此,为了解决这个问题,来自图宾根大学的研究者在本文中提出一种基于 PyTorch 的高效框架 BackPACK,该框架可以扩展反向传播算法,进而从一阶和二阶导数中提取额外信息。研究者对深度神经网络上额外数量的计算进行了基准测试,并提供了一个测试最近几种曲率估算优化的示例应用,最终证实了 BackPACK 的性能。

Ranger

Shampoo

摘要:目前,无论是从理论还是应用层面来说,机器学习中的优化都是以随机梯度下降等一阶梯度方法为主。囊括二阶梯度和/或二阶数据统计的二阶优化方法虽然理论基础更强,但受限于计算量、内存和通信花销等因素,二阶梯度优化方法的普及度不高。然而在谷歌大脑与普林斯顿大学等研究者的努力下,二阶梯度优化终于在实战大模型上展现出独特的优势。
研究者表示,为了缩短理论和实际优化效果之间的差距,该论文提出了一种二阶优化的概念性验证,并通过一系列重要的算法与数值计算提升,证明它在实际深度模型中能有非常大的提升。具体而言,在训练深度模型过程中,二阶梯度优化 Shampoo 能高效利用由多核 CPU 和多加速器单元组成的异构硬件架构。并且在大规模机器翻译、图像识别等领域实现了非常优越的性能,要比现有的顶尖一阶梯度下降方法还要好。
推荐:本文的亮点在于研究者提出了真正应用的二阶梯度最优化器,在实战大模型上展现出独特的优势。

激活函数

激活函数汇总

GELU

Relu神经网络的记忆能力

Chulhee Yun等人发表“小型ReLU网络是强大的记忆器:对记忆能力的严格分析”,表明“具有Omega(sqrt(N))隐藏节点的3层ReLU网络可以完美地记忆具有N个点的大多数数据集。

梯度泄露

彩票假设

NLP中彩票假设的应用:
Frankle 和 Carbin 在 2018 年提出的彩票假说表明,一个随机初始化的网络包含一个小的子网络,这个子网络在进行单独地训练时,其性能能够与原始网络匹敌。在本文中,研究者证明了一个更有力的假说(正如 Ramanujan 等人在 2019 年所猜想的那样),即对于每个有界分布和每个带有有界权重的目标网络来说,一个具有随机权重的充分过参数化神经网络包含一个具有与目标网络几乎相同准确率的子网络,并且无需任何进一步的训练。
===>从根本上来说,剪枝随机初始化的神经网络与优化权重值一样重要。

知识蒸馏

生成模型

双下降问题

一些疑难杂症

度量学习

损失函数

mse vs cross-entropy

不一定回归就用mse,分类才用交叉熵
各种分布:

cross-entroy vs nllloss

CrossEntropyLoss就是把Softmax–Log–NLLLoss合并成一步

L_DMI

损失函数的pattern

softmax优化

Mixtape

自监督

机器学习+博弈论

normalization相关

BN

FRN

VAE

优化方法

摘要:优化器选择是当前深度学习管道的重要步骤。在本文中,研究者展示了优化器比较对元参数调优协议的灵敏度。研究结果表明,在解释文献中由最近实证比较得出的排名时,元参数搜索空间可能是唯一最重要的因素。但是,当元参数搜索空间改变时,这些结果会相互矛盾。随着调优工作的不断增加,更一般的优化器性能表现不会比近似于它们的那些优化器差,但最近比较优化器的尝试要么假设这些包含关系没有实际相关性,要么通过破坏包含的方式限制元参数。研究者在实验中发现,优化器之间的包含关系实际上很重要,并且通常可以对优化器比较做出预测。具体来说,流行的自适应梯度方法的性能表现绝不会差于动量或梯度下降法。
推荐:如何选择优化器?本文从数学角度论证了不同优化器的特性,可作为模型构建中的参考资料。

调参

表示学习

新的结构

NALU

摘要:神经算术逻辑单元(NALU)是一种神经网络层,可以学习精确的算术运算。NALU 的目标是能够进行完美的运算,这需要学习到精确的未知算术问题背后的底层逻辑。评价 NALU 性能是非常困难的,因为一个算术问题可能有许多种类的解法。因此,单实例的 MSE 被用于评价和比较模型之间的表现。然而,MSE 的大小并不能说明是否是一个正确的方法,也不能解释模型对初始化的敏感性。因此,研究者推出了一种「成功标准」,用来评价模型是否收敛。使用这种方法时,可以从很多初始化种子上总结成功率,并计算置信区间。通过使用这种方法总结 4800 个实验,研究者发现持续性的学习算术推导是具有挑战性的,特别是乘法。
推荐:尽管神经算术逻辑单元的出现说明了使用神经网络进行复杂运算推导是可行的,但是至今没有一种合适的评价神经网络是否能够成功收敛的标准。本文填补了这一遗憾,可供对本领域感兴趣的读者参考。

权重无关

on-lstm

其他相关理论

因果关系

由 Judea Pearl 倡导的图形因果推理(graphical causal inference)源于 AI 研究,并且在很长一段时间内,它与机器学习领域几乎没有任何联系。在本文中,研究者探讨了图形因果推理与机器学习之间已建立以及应该建立哪些联系,并介绍了一些关键概念。本文认为,机器学习和 AI 领域的未解决难题在本质上与因果关系有关,并解释了因果关系领域如何理解这些难题。

能量模型

贝叶斯深度学习

正如Emtiyaz Khan在他的受邀演讲《基于贝叶斯原理的深度学习》中所强调的那样,贝叶斯学习和深度学习是非常不同的。根据Khan的说法,深度学习使用“试错”(trial and error)的方法——看实验会把我们带向何方——而贝叶斯原理迫使你事先思考假设(先验)。
与常规的深度学习相比,贝叶斯深度学习主要有两个吸引人的点:不确定性估计和对小数据集的更好的泛化。在实际应用中,仅凭系统做出预测是不够的。知道每个预测的确定性很重要。在贝叶斯学习中,不确定性估计是一个内置特性。
传统的神经网络给出单点估计——使用一组权值在数据点上输出预测。另一方面,贝叶斯神经网络使用网络权值上的概率分布,并输出该分布中所有权值集的平均预测,其效果与许多神经网络上的平均预测相同。因此,贝叶斯神经网络是自然的集合体,它的作用类似于正则化,可以防止过拟合。
拥有数百万个参数的贝叶斯神经网络的训练在计算上仍然很昂贵。收敛到一个后验值可能需要数周时间,因此诸如变分推理之类的近似方法已经变得流行起来。Probabilistic Methods – Variational Inference类发表了10篇关于这种变分贝叶斯方法的论文。

可解释性

对于一个深度网络,网络通过多层神经层渐进的转换输入,这其中的几何解释应该是什么样的呢?本文的作者通过实验发现,以固有维度(ID:intrinsic dimensionality)为切入点,可以发现训练好的网络相比较未训练网络而言,其每层的固有维度数量级均小于每层单元数,而且 ID 的存在可以来衡量网络的泛化性能。
当人遇到图像判断的时候,总是会分解图片并解释分类的理由,而机器在判断的时候总是跟人的判断会有些差距。本文旨在缩小机器分类和人分类之间的差距,提出了一个 ProtoPNet,根据人判断的机理来分类图像。本文网络通过分解图像,得到不同的原型部分,通过组成这些信息最终得到正确的分类。
challenge sets,大部分是英文,中文比较少。构造方法:
  • 从已有数据集泛化:改下位词、同义词、反义词
  • 从已有数据集只抽出可用的部分
  • 使用模板建模具体语言特征
  • 对抗样本

子集选择

子集选择问题旨在从 n 个元素中,选择满足约束 c 的一个子集,以最大化目标函数 f。它有很多应用,包括影响力最大化,传感器放置等等。针对这类问题,现有的代表性算法有广义贪心算法和 POMC。广义贪心算法耗时较短,但是受限于它的贪心行为,其找到的解质量往往一般;POMC 作为随机优化算法,可以使用更多的时间来找到质量更好的解,但是其缺乏多项式的运行时间保证。因此,我们提出一个高效的演化算法 EAMC。通过优化一个整合了 f 和 c 的代理函数,它可以在多项式时间内找到目前已知最好的近似解,并且其在多类问题上的试验也显示出比广义贪心算法更好的性能。

计算机视觉

cv数据集

cv基础

cv历史

cnn相关

图像分割

图像分割综述

MoCo

PointRend

Graph-FCN

使用深度学习执行语义分割在图像像素分类方面取得了巨大进步。但是,深度学习提取高级特征时往往忽略了局部位置信息(local location information),而这对于图像语义分割而言非常重要。
为了避免上述问题,来自中科院自动化所、北京中医药大学的研究者们提出一个执行图像语义分割任务的图模型 Graph-FCN,该模型由全卷积网络(FCN)进行初始化。首先,通过卷积网络将图像网格数据扩展至图结构数据,这样就把语义分割问题转换成了图节点分类问题;然后,使用图卷积网络解决图节点分类问题。研究者称,这是首次将图卷积网络用于图像语义分割的尝试。该方法在 VOC 数据集上获得了有竞争力的 mIOU 性能,相比原始 FCN 模型有 1.34% 的性能提升。

目标检测

自然场景文字定位

EfficientDet

计算机视觉领域,模型效率已经变得越来越重要。在本文中,研究者系统地研究了用于目标检测的各种神经网络架构设计选择,并提出了一些关键的优化措施来提升效率。首先,他们提出了一种加权双向特征金字塔网络(weighted bi-directional feature pyramid network,BiFPN),该网络可以轻松快速地进行多尺度特征融合;其次,他们提出了一种复合缩放方法,该方法可以同时对所有骨干、特征网络和框/类预测网络的分辨率、深度和宽度进行统一缩放。基于这些优化,研究者开发了一类新的目标检测器,他们称之为EfficientDet。在广泛的资源限制条件下,该检测器始终比现有技术获得更高数量级的效率。具体而言,在没有附属条件的情况下,EfficientDet-D7在52M参数和326B FLOPS1的COCO数据集上实现了51.0 mAP的SOTA水平,体积缩小了4倍,使用的FLOPS减少了9.3倍,但仍比先前最佳的检测器还要准确(+0.3% mAP)。
推荐:本文探讨了计算机视觉领域的模型效率问题,分别提出了加权双向特征金字塔网络和复合缩放方法,进而开发了一种新的EfficientDet目标检测器,实现了新的 SOTA 水平。

YoloVxxx

图像识别

近年来,卷积神经网络(CNN)已经主宰了计算机视觉领域。自 AlexNet 诞生以来,计算机视觉社区已经找到了一些能够改进 CNN 的设计,让这种骨干网络变得更加强大和高效,其中比较出色的单个分支网络包括 Network in Network、VGGNet、ResNet、DenseNet、ResNext、MobileNet v1/v2/v3 和 ShuffleNet v1/v2。近年来同样吸引了研究社区关注的还有多分辨率骨干网络。作者认为目前实现高效卷积网络的工作流程可以分成两步:1)设计一种网络架构;2)对该网络中的连接进行剪枝。在第一步,作者研究了人类专家设计的架构与搜索得到的架构之间的共同模式:对于每种骨干网络,其架构都是由其普通模块和归约模块(reduction block)的设计所确定的。第二步会将某些连接剪枝去掉,这样就不能保证每个模块都有完整的信息交换了。Facebook AI 的研究者在这篇论文中通过在网络设计步骤中考虑剪枝,为图像识别任务设计了一种更高效的网络。他们创造了一种新的模块设计方法:Idle。

图像补全

文字检测与识别

图像合成

本论文要解决的问题是使用条件生成对抗网络(cGAN)生成合成图像。具体来说,本文要完成的具体任务是使用一个分割掩码控制所生成的图像的布局,该分割掩码的每个语义区域都具有标签,而网络可以根据这些标签为每个区域「添加」具有真实感的风格。尽管之前已经有一些针对该任务的框架了,但当前最佳的架构是 SPADE(也称为 GauGAN)。因此,本论文的研究也是以 SPADE 为起点的。具体来说,本文针对原始 SPADE 的两个缺陷提出了新的改进方案。本文在几个高难度的数据集(CelebAMaskHQ、CityScapes、ADE20K 和作者新建的 Facades 数据集)上对新提出的方法进行了广泛的实验评估。定量实验方面,作者基于 FID、PSNR、RMSE 和分割性能等多种指标对新方法进行了评估;定性实验方面,作者展示了可通过视觉观察进行评估的样本。
推荐:图像合成是近来非常热门的研究领域,世界各地的研究者为这一任务提出了许多不同的框架和算法,只为能合成出更具真实感的图像。阿卜杜拉国王科技大学和卡迪夫大学近日提出了一种新改进方案 SEAN,能够分区域对合成图像的内容进行控制和编辑(比如只更换眼睛或嘴),同时还能得到更灵活更具真实感的合成结果。有了这个技术,修图换眼睛时不用再担心风格不搭了。

人脸识别

CV相关比赛

3D模型相关

摘要:在本文中,来自 DeepMind 的研究者提出了一种直接建模网格的方法 PolyGen,该方法利用 Transformer 架构来循序地预测网格的顶点和表面。文中提出的 3D 网格深度生成模型 PolyGen 以对象类、三维像素和图像等一系列输入为条件,同时由于该模型是概率性的,因此它可以生成捕获模糊场景中不确定性的样本。
实验表明,该模型能够生成高质量、可用的网格,并为网格建模任务创建对数似然基准。研究者表示,PolyGen 模型能够生成连贯的、多样化的 3D 网格,并且相信可以扩展该模型在计算机视觉、机器人学和 3D 内容创建中的应用。
推荐:本文的亮点在于,研究者将网格生成问题作为自回归序列建模来处理,同时结合了 Transformers 和指针网络的优势,从而能够灵活地建模长度可变的网格序列。

GNN+CV

CV最新进展

半弱监督

Facebook将该方法称为“半弱监督”(semi-weak supervision),是结合了半监督学习和弱监督学习者两种不同训练方法的有点的一种新方法。通过使用teacher-student模型训练范式和十亿规模的弱监督数据集,它为创建更准确、更有效的分类模型打开了一扇门。如果弱监督数据集(例如与公开可用的照片相关联的hashtags)不能用于目标分类任务,该方法还可以利用未标记的数据集来生成高度准确的半监督模型。

advprop

对抗样本经常被认为是卷积神经网络的一个威胁。而研究者在这篇论文中提出了相反的论点:对抗网络可以被用来提升图像识别模型的准确率,只要使用正确的方式。研究者在这里提出了 AdvProp,这是一个增强对抗训练方法,能够将对抗样本视为额外样本,以方式过拟合。这一方法的关键在于对对抗样本使用了分离的辅助批归一化,因为它们和正常样本的隐藏分布不同。
研究说明,AdvProp 在很多图像识别任务上提升了一系列模型的性能,而且当模型变得更大的时候,性能也会更好。例如,通过将 AdvProp 用在最新的 EfficientNet-B7 模型上,使用 ImageNet 进行训练,研究者可以取得性能点的提升,如 ImageNet (+0.7%)、ImageNet-C (+6.5%)、ImageNet-A (+7.0%)、Stylized- ImageNet (+4.8%)。而在 增强的 EfficientNet-B8 上,这一方法在没有额外数据的情况下达到了 SOTA——85.5% 的 ImageNet top-1 精确度。这一结果超越了使用 3.5B Instagram 数据和 9.4 倍参数量的最佳模型。

稀疏性+cv

从历史发展的角度来看,对有效推理(efficient inference)的追求已经成为研究新的深度学习架构和构建块背后的驱动力之一。近来的一些示例包括:压缩和激发模块(squeeze-and-excitation module)、Xception 中的深度级可分离卷积(depthwise seperable convolution)和 MobileNet v2 中的倒置瓶颈(inverted bottleneck)。在所有这些示例中,生成的构建块不仅实现了更高的有效性和准确率,而且在领域内得到广泛采用。在本文中,来自 DeepMind 和 Google 的研究者们进一步扩展了神经网络架构的有效构建块,并且在没有结合标准基本体(standard primitive)的情况下,他们主张用稀疏对应(sparse counterpart)来替换这些密集基本体(dense primitive)。利用稀疏性来减少参数数量的想法并不新鲜,传统观点也认为理论浮点运算次数的减少不能转化为现实世界的效率增益。
研究者通过提出一类用于 ARM 和 WebAssembly 的有效稀疏核来纠正这种错误观点,并且进行开源作为 XNNPACK 库的组成部分。借助于稀疏标准体(sparse primitive)的有效实现,研究者表明,MobileNet v1、MobileNet v2 和 EfficientNet 架构的稀疏版本在有效性和准确率曲线(efficiency-accuracy curve)上显著优于强大的密集基线(dense baseline)。在骁龙 835 芯片上,他们提出的稀疏网络比同等的密集网络性能增强 1.3-2.4 倍,这几乎相当于 MobileNet-family 一整代的性能提升。研究者希望他们的研究成果可以促进稀疏性更广泛地用作创建有效和准确深度学习架构的工具。

自监督+半监督EnAET

无监督SimCLR

在这篇论文中,研究者发现:
  • 多个数据增强方法组合对于对比预测任务产生有效表示非常重要。此外,与有监督学习相比,数据增强对于无监督学习更加有用;
  • 在表示和对比损失之间引入一个可学习的非线性变换可以大幅提高模型学到的表示的质量;
  • 与监督学习相比,对比学习得益于更大的批量和更多的训练步骤。
基于这些发现,他们在 ImageNet ILSVRC-2012 数据集上实现了一种新的半监督、自监督学习 SOTA 方法——SimCLR。在线性评估方面,SimCLR 实现了 76.5% 的 top-1 准确率,比之前的 SOTA 提升了 7%。在仅使用 1% 的 ImageNet 标签进行微调时,SimCLR 实现了 85.8% 的 top-5 准确率,比之前的 SOTA 方法提升了 10%。在 12 个其他自然图像分类数据集上进行微调时,SimCLR 在 10 个数据集上表现出了与强监督学习基线相当或更好的性能。

图像对抗攻击

自然语言处理

nlp综述

LSTM相关

fasttext&word2vec

注:w2v训练时的内积不是2个emb-in的内积,而是emb-in和emb-out的内积
  • Dictionary::readWord:空格分割,一次读出来一个word
  • Dictionary::add:每个word求个hash,加进词典时,id就是从0开始的序号,同时记录一下词频
  • Dictionary::threshold:按词频排序,扔掉低频词
  • Dictionary::initNgrams:每个词,加上前缀BOW(<)和后缀(>),然后先扔进这个词的subwords里,然后再调用 Dictionary::computeSubwords把这个词的ngrams也扔进它的subwords里
整个词表,是word数+bucket这么大,其中bucket表示可容纳的subwords和wordNgrams的数量,默认200w

分词

语法解析

EMNLP 2019最佳论文
预训练词向量,如ELMo和BERT包括了丰富的句法和语义信息,使这些模型能够在各种任务上达到 SOTA 表现。在本文中,研究者则提出了一个非常快速的变分信息瓶颈方法,能够用非线性的方式压缩这些嵌入,仅保留能够帮助句法解析器的信息。研究者将每个词嵌入压缩成一个离散标签,或者一个连续向量。在离散的模式下,压缩的离散标签可以组成一种替代标签集。通过实验可以说明,这种标签集能够捕捉大部分传统 POS 标签标注的信息,而且这种标签序列在语法解析的过程中更为精确(在标签质量相似的情况下)。而在连续模式中,研究者通过实验说明,适当地压缩词嵌入可以在 8 种语言中产生更精确的语法解析器。这比简单的降维方法要好。

self-attention

文本匹配

机器翻译

  1. 1.
    Transformer Big + BT:回译
通过单语数据提升 NMT 模型最高效的方法之一是回译(back-translation)。如果我们的目标是训练一个英语到德语的翻译模型,那么可以首先训练一个从德语到英语的翻译模型,并利用该模型翻译所有的单语德语数据。然后基于原始的英语到德语数据,再加上新生成的数据,我们就能训练一个英语到德语的最终模型。
  1. 1.
    MASS:预训练
MASS 采用了编码器-解码器框架,并尝试在给定部分句子的情况下修复整个句子。如下所示为 MASS 的框架图,其输入句子包含了一些连续的 Token,并且中间会带有一些连续的 Mask,模型的任务是预测出被 Mask 掉的词是什么。相比 BERT 只有编码器,MASS 联合训练编码器与解码器,能获得更适合机器翻译的表征能力。

nlp标准&数据集

中文glue

中文阅读理解数据集

物理常识推理任务数据集

「在不使用刷子涂眼影的情况下,我应该用棉签还是牙签?」类似这种需要物理世界常识的问题对现今的自然语言理解系统提出了挑战。虽然最近的预训练模型 (如 BERT) 在更抽象的如新闻文章和百科词条这种具有丰富文本信息的领域问答方面取得了进展,但在更现实的领域,由于报导的偏差,文本本质上是有限的,类似于「用牙签涂眼影是一个坏主意」这样的事实很少得到直接报道。人工智能系统能够在不经历物理世界的情况下可靠地回答物理常识问题吗?是否能够捕获有关日常物品的常识知识,包括它们的物理特性、承受能力以及如何操纵它们。
在本文中,研究者介绍了一个关于物理常识推理任务和相应的基准数据集 PIQA(Physical Interaction:Question Answering)进行评估。虽然人类应对这一数据集很容易 (95% 的准确率),但是大型的预训模型很难 (77%)。作者分析了现有模型所缺乏的知识为未来的研究提供了重要的机遇。

常识推理数据集WinoGrande

研究者提出了 WINOGRANDE,一个有着 44k 个问题的大规模数据集。该数据集在规模和难度上较之前的数据集更大。该数据集的构建包括两个步骤:首先使用众包的方式设计问题,然后使用一个新的 AFLITE 算法缩减系统偏见(systematic bias),使得人类可以察觉到的词汇联想转换成机器可以检测到的嵌入联想(embedding association)。现在最好的 SOTA 模型可以达到的性能是 59.4 – 79.1%,比人脸性能水平(94%)低 15-35%(绝对值)。这种性能波动取决于训练数据量(2% 到 100%)。
本论文荣获了 AAAI 2020 最佳论文奖,文中提出的 WINOGRANDE 是一个很好的迁移学习资源;但同时也说明我们现在高估了模型的常识推理的能力。研究者希望通过这项研究能够让学界重视减少算法的偏见。

阅读理解

DCMN+

相关性模型

ULMFiT

归纳迁移学习(Inductive Transfer Learning)对计算机视觉(Compute Vision,CV)产生了巨大影响,但对自然语言处理(Natural Language Processing,NLP)一直没有突破性进展,现有的NLP方法,仍然需要根据特定任务进行修改,并且从零开始训练。我们提出了通用语言模型微调(Universal Language Model Fine-tuning for Text Classification,ULMFiT),这是一种有效的迁移学习方法,可以适用于任何NLP任务,另外,我们引入了语言模型微调的关键技术。我们的方法在6个文本分类任务上显著优于现有的最先进方法,在大部分数据集上将错误率降低了18-24%。此外,ULMFiT仅用100个标记样本训练出来的性能,可以媲美从零开始训练(Training From Scratch)使用100倍以上数据训练出来的性能。

bert/transformer相关总结

huggingface的nlp预训练模型库

用于NLP的预训练Transformer模型的开源库。它具有六种架构,分别是:
  • Google的BERT
  • OpenAI的GPT和GPT-2
  • Google / CMU的Transformer-XL和XLNet
  • Facebook的XLM

bert

主要讲了下面3篇:
bert的一些细节:
multi-head att 实现
输入原始的query(即from_tensor)之后, 把[batch, from_seq, emb]变成[?, emb],其中?=batch*from_seq
from_tensor_2d = reshape_to_matrix(from_tensor)
def reshape_to_matrix(input_tensor):
"""Reshapes a >= rank 2 tensor to a rank 2 tensor (i.e., a matrix)."""
ndims = input_tensor.shape.ndims
if ndims < 2:
raise ValueError("Input tensor must have at least rank 2. Shape = %s" %
(input_tensor.shape))
if ndims == 2:
return input_tensor
width = input_tensor.shape[-1]
output_tensor = tf.reshape(input_tensor, [-1, width])
return output_tensor
然后再接一个fc,把[?, emb]变成[?, head_num * per_head],一般head_num * per_head=emb
query_layer = tf.layers.dense(
from_tensor_2d,
num_attention_heads * size_per_head,
activation=query_act,
name="query",
kernel_initializer=create_initializer(initializer_range))
因为?=batch*from_seq,所以可以直接做如下变换
query_layer = transpose_for_scores(query_layer, batch_size,
num_attention_heads, from_seq_length,
size_per_head)
实际就是把?拆开成batch, from_seq,整个变成[batch, from_seq, head_num, per_head],然后做了个 transpose,把1和2互换了下,得到[batch, head_num, from_seq, per_head]
def transpose_for_scores(input_tensor, batch_size, num_attention_heads,
seq_length, width):
output_tensor = tf.reshape(
input_tensor, [batch_size, seq_length, num_attention_heads, width])
output_tensor = tf.transpose(output_tensor, [0, 2, 1, 3])
return output_tensor
然后key也做完全一样的操作(不过处理的是to_tensor,如果是self-attention,那to_tensor=from_tensor), 得到[batch, head_num, to_seq, per_head]
to_tensor_2d = reshape_to_matrix(to_tensor)
key_layer = tf.layers.dense(
to_tensor_2d,
num_attention_heads * size_per_head,
activation=key_act,
name="key",
kernel_initializer=create_initializer(initializer_range))
key_layer = transpose_for_scores(key_layer, batch_size, num_attention_heads,
to_seq_length, size_per_head)
然后就算
QKTQK^T
了,注意这里对key取了转置,也就是[batch, head_num, from_seq, per_head]乘以[batch, head_num, per_head, to_seq],得到的结果是[batch, head_num, from_seq, to_seq]
attention_scores = tf.matmul(query_layer, key_layer, transpose_b=True)
attention_scores = tf.multiply(attention_scores,
1.0 / math.sqrt(float(size_per_head)))
if attention_mask is not None:
# `attention_mask` = [B, 1, F, T]
attention_mask = tf.expand_dims(attention_mask, axis=[1])
# Since attention_mask is 1.0 for positions we want to attend and 0.0 for
# masked positions, this operation will create a tensor which is 0.0 for
# positions we want to attend and -10000.0 for masked positions.
adder = (1.0 - tf.cast(attention_mask, tf.float32)) * -10000.0
# Since we are adding it to the raw scores before the softmax, this is
# effectively the same as removing these entirely.
attention_scores += adder
attention_probs = tf.nn.softmax(attention_scores)
attention_probs = dropout(attention_probs, attention_probs_dropout_prob)
然后看下value的操作:
value_layer = tf.layers.dense(
to_tensor_2d,
num_attention_heads * size_per_head,
activation=value_act,
name="value",
kernel_initializer=create_initializer(initializer_range))
# `value_layer` = [batch, to_seq, head_num, per_head]
value_layer = tf.reshape(
value_layer,
[batch_size, to_seq_length, num_attention_heads, size_per_head])
# `value_layer` = [batch, head_num, to_seq, per_head]
value_layer = tf.transpose(value_layer, [0, 2, 1, 3])
# `context_layer` = [batch, head_num, from_seq, per_head]
context_layer = tf.matmul(attention_probs, value_layer)
# `context_layer` = [batch, from_seq, head_num, per_head]
context_layer = tf.transpose(context_layer, [0, 2, 1, 3])
再确认一点,
softmax(QKT)softmax(QK^T)
[batch, head_num, from_seq, to_seq],而
VV
[batch, head_num, to_seq, per_head],所以context_layer是[batch, head_num, from_seq, per_head]
最后,再搞一下,变回[batch, from_seq, head_num * per_head]
if do_return_2d_tensor:
# `context_layer` = [B*F, N*H]
context_layer = tf.reshape(
context_layer,
[batch_size * from_seq_length, num_attention_heads * size_per_head])
else:
# `context_layer` = [B, F, N*H]
context_layer = tf.reshape(
context_layer,
[batch_size, from_seq_length, num_attention_heads * size_per_head])
如上过程是
Concat(head1,...,headh)Concat(head_1, ..., head_h)
,其中
headi=Attention(QWiQ,KWiK,VWiV)head_i = Attention(QW_i^Q, KW_i^K, VW_i^V)
。包装在了函数attention_layer之中,我们注意到原文还有一个大小为
hdv×dmodelhd_v \times d_{model}
WOW^O
,也就是大小为
dmodel×dmodeld_{model}\times d_{model}
,再看看源码。。也就是说,正常的bert里,attention_heads就只有一个元素,然后接了个hidden_size的fc,而前面的代码里也提到了hidden_size正好就是
dmodeld_{model}
,所以这就是
WOW^O
attention_heads = []
with tf.variable_scope("self"):
attention_head = attention_layer(xxxxx)
attention_heads.append(attention_head)
attention_output = None
if len(attention_heads) == 1:
attention_output = attention_heads[0]
else:
# In the case where we have other sequences, we just concatenate
# them to the self-attention head before the projection.
attention_output = tf.concat(attention_heads, axis=-1)
# Run a linear projection of `hidden_size` then add a residual
# with `layer_input`.
with tf.variable_scope("output"):
attention_output = tf.layers.dense(
attention_output,
hidden_size,
kernel_initializer=create_initializer(initializer_range))
attention_output = dropout(attention_output, hidden_dropout_prob)
attention_output = layer_norm(attention_output + layer_input)
关于 mask,可以看看这个https://juejin.im/post/5b9f1af0e51d450e425eb32d
摘抄一下:
什么是padding mask呢?回想一下,我们的每个批次输入序列长度是不一样的!也就是说,我们要对输入序列进行对齐!具体来说,就是给在较短的序列后面填充0。因为这些填充的位置,其实是没什么意义的,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。 具体的做法是,把这些位置的值加上一个非常大的负数(可以是负无穷),这样的话,经过softmax,这些位置的概率就会接近0!
而sequence mask是为了使得decoder不能看见未来的信息。也就是对于一个序列,在time_step为t的时刻,我们的解码输出应该只能依赖于t时刻之前的输出,而不能依赖t之后的输出。因此我们需要想一个办法,把t之后的信息给隐藏起来。 那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为1,下三角的值权威0,对角线也是0。把这个矩阵作用在每一个序列上,就可以达到我们的目的啦。
masked-language-model的实现
如下,其中hidden_size就是是
dmodeld_{model}
def get_masked_lm_output(bert_config, input_tensor, output_weights, positions,
label_ids, label_weights):
"""Get loss and log probs for the masked LM."""
input_tensor = gather_indexes(input_tensor, positions)
with tf.variable_scope("cls/predictions"):
# We apply one more non-linear transformation before the output layer.
# This matrix is not used after pre-training.
with tf.variable_scope("transform"):
input_tensor = tf.layers.dense(
input_tensor,
units=bert_config.hidden_size,
activation=modeling.get_activation(bert_config.hidden_act),
kernel_initializer=modeling.create_initializer(
bert_config.initializer_range))
input_tensor = modeling.layer_norm(input_tensor)
# The output weights are the same as the input embeddings, but there is
# an output-only bias for each token.
output_bias = tf.get_variable(
"output_bias",
shape=[bert_config.vocab_size],
initializer=tf.zeros_initializer())
logits = tf.matmul(input_tensor, output_weights, transpose_b=True)
logits = tf.nn.bias_add(logits, output_bias)
log_probs = tf.nn.log_softmax(logits, axis=-1)
label_ids = tf.reshape(label_ids, [-1])
label_weights = tf.reshape(label_weights, [-1])
one_hot_labels = tf.one_hot(
label_ids, depth=bert_config.vocab_size, dtype=tf.float32)
# The `positions` tensor might be zero-padded (if the sequence is too
# short to have the maximum number of predictions). The `label_weights`
# tensor has a value of 1.0 for every real prediction and 0.0 for the
# padding predictions.
per_example_loss = -tf.reduce_sum(log_probs * one_hot_labels, axis=[-1])
numerator = tf.reduce_sum(label_weights * per_example_loss)
denominator = tf.reduce_sum(label_weights) + 1e-5
loss = numerator / denominator
return (loss, per_example_loss, log_probs)
其中的gather如下:
def gather_indexes(sequence_tensor, positions