网站规划建设与管理维护,社交网站建设网,网站移动字幕要怎么做,wordpress中英文网站继续NLP的学习#xff0c;看完理论之后再看看实践#xff0c;然后就可以上手去kaggle做那个入门的project了orz。
参考#xff1a;
1810.04805.pdf (arxiv.org)
BERT 论文逐段精读【论文精读】_哔哩哔哩_bilibili
(强推!)2023李宏毅讲解大模型鼻祖BERT#xff0c;一小时…继续NLP的学习看完理论之后再看看实践然后就可以上手去kaggle做那个入门的project了orz。
参考
1810.04805.pdf (arxiv.org)
BERT 论文逐段精读【论文精读】_哔哩哔哩_bilibili
(强推!)2023李宏毅讲解大模型鼻祖BERT一小时带你读懂Bert顶级论文_哔哩哔哩_bilibili
BERT 论文逐段精读【论文精读】_哔哩哔哩_bilibili
在计算机视觉中很早的时候我们就可以在一个大的数据集上比如ImageNet上训练好一个CNN的模型这个模型可以用来帮助很多计算机视觉的任务提升性能但是NLP在BERT之前一直没有一个深的神经网络使得训练好之后能够帮助很多NLP任务-在NLP里面还是每个人构造自己的神经网络然后自己做训练。
BERT的出现使得我们可以在一个大的数据集上训练好一个比较深的神经网络然后英语在很多NLP的任务上面既简化了这些NLP任务的训练又提升了它的性能。所以BERT和它之后的一系列工作使得NLP有一个质的飞跃。
BERT是一个深的双向的transformer是用来做预训练的针对的是一般的语言理解的任务。
摘要
BERTBidirectional Encoder Representations from Transformerstransformer这个模型的双向的编码器表示注意到这里和标题内容是不一样的很可能这个名字是凑出来的李宏毅在NLP课程中提过这个表示就是凑出来的吐槽说论文也喜欢蹭热点比如有些用三个动词比如xxx is all you need这样还举例说后面的其他模型也凑热闹硬用芝麻街里的人名凑这篇论文的想法基于一个重要的工作ELMo这是一个基于RNN的架构来自于芝麻街的人物。不同于其他最近的论文指当时BERT设计用于在所有层中通过联合左右的这里与GPT不同GPT是基于左边的上下文上下文信息训练没有标记的文本深的双向表示。因为这一设计导致训练好的BERT可以只增加一个输出层就可以在很多NLP任务中比如问答、语言推理得到很多不错的结果并且不需要对仍无做很多特别的架构上的改动。
BERT在概念上更加简单在实验上也更好。
导言
在语言模型中预训练可以用来提升很多自然语言的任务。包括句子层面sentence-level的任务主要用来建模句子之间的关系比如对句子情绪的识别或者两个句子之间的关系词源层面token-level的任务比如实体命名的识别-指的是是不是人名街道名这种任务需要产生一些fine-grained的token层面的输出。
也就是说预训练在NLP中已经流行了一阵子了。
在使用预训练模型做特征表示的时候一般有两类策略feature-based基于特征的代表ELMo对每一个下游的任务构造一个跟这个任务相关的神经网络其实用的是RNN的架构在预训练好的这些表示作为一个额外的特征和输入一起输入到模型中-有一个统一的模型但是模型里面有不同的黑箱训练的任务不同会使用不同的黑箱和fine-tuning微调的。比如GPT把训练好的模型放到下一个任务的时候不需要改变很多只要改一点儿就行了。模型预训练好的参数会在新的数据上再进行微调。
这两个策略在与训练队时候都是使用一个相同的目标函数都是使用一个单向的语言模型来学习general的语言表示。
不过这里语言模型本身就是单向的给一些词预测下一个词是什么是属于预测模型既然是预测肯定是单向了。
这就导致了在预训练的时候存在一些限制比如在GPT里采用的事从左到右的结构只能从左读到右但是如果我们要做句子层面的一些分析的话从左看到右或者从右看到左都是合法的。另外就算是token-level上的一些任务比如QA其实也是可以看完整个句子去选答案的不用一个词一个词看。所以作者认为可以把两个方向的上下文都放进来的话应该可以提升任务的性能的。
BERT正是为了解决之前提到的语言模型是单向的问题的采用的是一个带掩码的语言模型masked language modelMLM。每一次从输入中随机选择一些token然后把他们盖住masked目标就是去预测那些被盖住的token就是完形填空orz。与标准的语言模型从左看到右不同的是MLM允许我们看左右的信息-就可以去预训练一个双向的深的Transformer。
除此之外还训练了一个“next sentence prediction”下一个句子的预测。核心思想是给定两个句子判断这两个句子在原文里是不是相邻的-让模型学习一些句子层面的信息。
贡献 1. 展示了双向信息的重要性 2. 不用对特定的任务做特定模型的改动BERT是基于微调的 3. 开源
结论
好。
最近一些实验表明使用非监督的预训练是许多语言理解系统language understanding system的必要组成部分。特别是即使是资源不多的任务也能够享受深度神经网络。
使得大量的NLP任务可以去使用同样的预训练模型。
双向ELMoTransformerGPT
BERT模型
BERT里面有两个步骤pre-training预训练和fine-tuning微调。
在pre-training中模型是在一个没有标号的数据上训练的。在微调的时候也是使用一个BERT模型但是这个模型的权重被初始化成我们在pre-training的时候得到的权重。所有的权重在微调的时候都会参与训练这个时候使用的就是有标号的数据了。每一个下游的任务都会创建一个新的BERT模型虽然都是使用pre-training的参数来初始化模型但是会各自对模型做fine-tuning。会根据自己的数据训练自己的模型。 在预训练的时候我们的输入是一些没有标号的句子对unlabeled sentence A and B pair训练一个BERT模型。对每一个下游的任务我们对每个任务创建一个同样的BERT模型他们的权重的初始化值来自于前面训练好的权重对每一个任务我们有自己的有标号的数据然后我们对BERT继续进行训练得到针对这个任务的BERT的版本。
模型架构
BERT模型是一个multi-layer bidirectional Transformer encoder多层的双向的Transformer的编码器。
三个参数L、H、A
LTransformer块的个数the number of layers, i.e., Transfomer blocks H隐藏层的大小the hidden size A在自注意力机制中multi-head的头的个数the number of self-attention heads
有两个模型BERT_BASEL12, H768, A12总共可以学习的参数是110M和BERT_LARGEL24, H1024, A16总共可以学习的参数是340M。这里LARGE比BASE层数翻了一倍宽度从768变成了1024为什么是1024因为BERT模型的复杂度和层数是线性关系和宽度是一个平方的关系因为深度变成BASE的两倍那么在宽度上也要使得增加的平方是之前的两倍 这里断一下这里没太听明白意思看了一下评论区的笔记BERT 论文逐段精读【论文精读】 - 哔哩哔哩 BERT 模型复杂度和层数 L 是 linear, 和宽度 H 是 平方关系。 因为 深度 变成了 以前的两倍在宽度上面也选择一个值使得这个增加的平方大概是之前的两倍。 大概这里计算了一下指的是1024^2≈2×768^2 头的数目变成了16每个头的维度都固定在644*16因为宽度增加了所以头的个数也增加了。 我看到这里也有疑问那么为什么增加之后的头的个数是16呢似乎也没有相关的信息。不过翻到两个比较有意思的论文考虑之后作为补充读物看看。 [1906.04341] What Does BERT Look At? An Analysis of BERTs Attention (arxiv.org) [2106.09650] Multi-head or Single-head? An Empirical Comparison for Transformer Training (arxiv.org) 题外话找到这张图了ELMo和他的小伙伴们 怎么把超参数换成可学习的参数的大小。模型中的可学习参数主要来源于两块一个是嵌入层另一个是Transformer块。
首先看一下嵌入层嵌入层就是一个矩阵输入是字典的大小这里字典的大小是30k弹幕30k是因为BERT用的是WordPiece embbeding一文读懂BERT中的WordPiece - hyc339408769 - 博客园 (cnblogs.com)vocabulary中有30k个token输出等于隐藏单元的个数即H输入会进入Transformer块。Transformer块中有两个东西一个是自注意力机制一个是后面的MLP。自注意力机制本身是没有可学习参数的但是对于multi-head attention mechanism的话会把所有进入的K(key), V(value), Q(query)分别做一次投影每一次投影的维度是等于64的A×64H。进来的K Q V都有自己的投影矩阵合并每个头的投影矩阵-得到H×H的矩阵。拿到输出之后还会做一次投影也是一个H×H的矩阵。所以对于Transformer块的自注意力可学习的参数是4×H²。
弹幕去看multi-head attention的示意图里面有4个Linear模块
4*H*H原因为QKV各一个投影阵h*h*3输出投影阵h*h
在往上是MLPMLP里面需要两个全连接层第一层的输入是H输出是4×H另一个全连接层的输入是4×H输出是H。所以每一个矩阵的大小是H×4H。所以两个就是8×H^2。(84)×H²就是一个Transformer块里的参数。还要乘以L有L个block
弹幕query, key和value投影的参数concat之后就是H*H*3了再加上concate之后的线性变换H*H就是4倍关系了
乘以4是因为全连接层的中间层维度是4倍H
最后一层里每个头都是H/A
所以最后的总的参数的个数就是30k×HL×H²×12 评论区给的解释 这里的参数就是各个W比如将keyvaluequery降为低维这三个维度矩阵都是(H, H/h),H就是我们字典输入embedding层后的特征数h是多头中头的数量。 对于一个头而言参数的总数是(H * (H / h) * 3),总共有h个头所以这一部分的参数是3(H²),然后我们需要把所有头拼接后又输出就又是一个H * H,相当于Attention层的参数个数是4H²在下面的前馈网络里隐藏层维度是(H,4*H)输出层是(4H,H所有这一部分就是8H² 感觉还不是很看得懂这里引用neural networks - How to account for the no:of parameters in the Multihead self-Attention layer of BERT - Cross Validated (stackexchange.com) The Illustrated Transformer – Jay Alammar – Visualizing machine learning one concept at a time. (jalammar.github.io) 这里仅仅对mult-headed self-attention部分进行讨论。 如图所示。在transformer块中输入向量先在multi-head里transform然后用在self-attention再串行再连入fully connected dense forward layer The input vector of dimension d_model (in X) gets multiplied by three matrices WQ, WK, WV, 12 (attention heads, or A) times to give (3A) pairs of vectors (Q, K, V). These vectors (Z0 to Z7 in the image) are each of length d_model/A. So dimension of each of these matrices is d_model * d_model/A and we have 3 * A such matrices. 维度为d_model的输入向量乘以三个矩阵WQ, WK, WV 12次12A# of attention heads得到3A个(Q, K, V)向量对pairs of vectors。这些向量图中的Z0到Z7每一个的长度都是d_model/A。所以每个矩阵的维度都是d_model * d_model/A。并且我们有3A个这样的矩阵。换句话说这里就是d_model * d_model/A * 3A前面是矩阵的sized_model * d_model/A后面是矩阵的个数 Including the bias for each of Q, K, V matrices, total weights till now d_model * d_model/A * 3A d_model * 3. By this point, we have Z0 to Zi vectors from above image. These are then concatenated, and passed through the dense layer W0 which would have dimension d_model * d_model d_model (with bias). 每个Q, K, V 矩阵都包含bias所以目前用到的权重是 d_model * d_model/A * 3A d_model * 3。现在我们就有了Zi向量把他们拼起来通过dense layer得到d_model * d_model d_model。 So total dimension of transformer cell: A * (d_model * d_model/A) * 3 3*d_model (d_model * d_model d_model). For BERT base, the values are A 12, d_model 786. So total parameters 12 * ( 768 * 768/12) * 3 3*768 768*768 768 2,362,368 还是觉得难以理解所以先拆开看multi-head attention。这一方法源自于Transformer。 多头注意力机制pytorch 多头注意力机制公式_轩辕的技术博客_51CTO博客 对于每个input首先经过一次变换得到K、Q、V一层K、Q、V就是3AA# of heads个权重比如这里一组K、Q、V因为A2所以个数为6因为要得到这6个向量所以理所当然要有6个权重参数。 注意力机制综述图解完整版附代码 - 知乎 自注意力机制的基本思想是在处理序列数据时每个元素都可以与序列中的其他元素建立关联而不仅仅是依赖于相邻位置的元素。它通过计算元素之间的相对重要性来自适应地捕捉元素之间的长程依赖关系。 具体而言对于序列中的每个元素自注意力机制计算其与其他元素之间的相似度并将这些相似度归一化为注意力权重。然后通过将每个元素与对应的注意力权重进行加权求和可以得到自注意力机制的输出。 首先对一句话x1 x2 x3 x4做embedding处理得到向量a1 a2 a3 a4 这里W表示的是embedding的参数矩阵。 经过embedding操作后向量a1 a2 a3 a4将会作为attention mechanism的输入。 紧接着每个a^i会乘以三个矩阵 q(Query) 的含义一般的解释是用来和其他单词进行匹配更准确地说是用来计算当前单词或字与其他的单词或字之间的关联或者关系 k(Key) 的含义则是被用来和q进行匹配也可理解为单词或者字的关键信息。 这里需要一个计算得到关联性。 对计算的关联性做softmax操作得到比较规整的关联性× v表示当前单词或字的重要信息重要特征将关联性和v^i分别相乘在求和group by。 以上是关于单头的介绍对于多头来说就不再满足于只使用一组kqv矩阵了 向量a^i再乘以三个矩阵之后还会被分配多个(K,Q,V)矩阵解释本段开始部分对3A的描述虽然都是同样的输入但是被放进不同的变换对中一个head就是3A个head就是3A 因为这里的例子是分成两个head所以之前得到的qkv就被破开了这里解释为什么是d_model/A也就是说最开始的dimension是d_model * d_model如果是单头的那么就不用变了但是这里是multi-head所以就被平均地切开了。 q^i1与其他标号有1的key比较相似度点乘用相似度作为权重乘以对应的value值。 输入和输出表示
下游任务有些是处理一个句子有些是处理两个句子所以为了使得BERT能处理所有这些任务所以输入既可以是一个句子也可以是一个句子对比如QA。这里的句子指的是一段连续的文字并不是语言学上定义的句子。输入称为一个“序列”sequence这里是sequence可以是一个句子也可以是两个句子。这里与Transformer有区别Transformer训练的时候的输入是一个序列对-encoder和decoder分别会输入一个序列。BERT这里只有encoder为了处理两个句子需要把两个句子变成一个序列。
BERT采用的切词的方法是WordPiece。核心思想是假设按照空格切词一个词作为一个token。因为数据量相对比较大会导致词典的size也特别大根据之前算模型参数的方法词典很大百万级别会导致整个可学习参数都在嵌入层上面。-用WordPiece如果一个词出现的概率不大应该切开看子序列如果某一个子序列很可能是词根出现的概率比较大的话就只保留这个子序列就好了不记得在哪篇博客里看到还提出另一个问题有些文字压根就不用空格作为词语的分割这样就可以把一个相对来说比较长的词切成很多一段一段的经常出现的片段。这样就可以用相对来说比较小的30k的词典就能够表示一个比较大的文本了。
弹幕这里的wordpiece应该和字节对编码是一个东西
切好之后看怎么把两个句子放到一起。序列的第一个词永远是一个特殊的记号“[CLS]”代表classification。BERT希望这个词最后的输出代表整个序列的信息比如整个句子层面的信息。因为BERT使用的是Transformer的encoder所以自注意力层会去看每一个词都会去看输入里面所有词的关系所以放第一个位置完全OK不影响读后面的内容。
弹幕既然每一次词都能看到序列的所有信息岂不是可以随便选一个词的输出来做分类
如果随便选一个词的输出作为分类结果那么就会让模型有了对应的偏好会让模型认为只要有那个选定的词就应该输出对应正确的分类结果。 选取一个与任意一个词都不直接相关的位置作为整个句子的语义向量对于所有单词来说都是公平的、没有偏爱的
虽然把两个句子合在一起但是因为要做的事句子层面的分类所以需要区分开来两个句子。有两个办法来区分第一个是在每个句子后面放一个特殊的词“[SEP]”表示separate第二个是学一个嵌入层来学习每一个token是属于哪个句子。 如图所示看下面sentence之间的[SEP]第一个位置[CLS]。每一个token进入句子得到这个token的embedding表示。最后一个transformer块的输出就代表这个token的BERT的表示再添加额外的输出层得到我们想要得到的结果。
对于每个给定的token其输入是通过将相应的token、段和位置嵌入相加来构建的token本身的embedding在哪一个句子的embedding位置的embedding。 给一个token的序列得到向量的序列。这里红色的是token。token embedding就是正常的embeddingsegment embedding就是表示是第一句话还是第二句话。position embedding是位置输入的大小是这个序列的长度输入就是每一个token在这个序列中的位置信息得到token位置的向量。在Transformer中位置信息是手动构造出来的矩阵但是在BERT中无论属于哪个句子、位置在哪里对应的向量的表示都是通过学习得来的。
弹幕SEP可以理解成每句话的句号用作分割句子所以第一个SEP是A的第二个是B的
高维语义空间的向量相加
Pre-training BERT
在pre-training的时候有两个东西比较关键一个是目标函数另一个是用来做预训练的数据。
Masked LM
对一个输入的token序列如果一个token是用WordPiece生成的话那么它有15%的概率会随机替换成一个掩码。但是对于一些比较特殊的 token第一个token[CLS]中间的分割token[SEP]就不做替换了。因此假设输入序列长度是1000的话我们就需要预测150个词。
这也有一些问题。因为我们在做掩码的时候会把词源替换成一个特殊的token [MASK]在训练的时候会看到有15%的token是[MASK]但是在微调的时候是没有这个东西的因为微调的时候不用这个目标函数导致在预训练和在微调的时候看到的数据是有一点不一样的。-解决方法是对于这15%的被选中的去做掩码的token有80%的概率是真的替换成特殊的掩码符号还有10%的概率是把它替换成一个随机的token还有10%的概率什么都不干。80% 10% 10%实验得到的如下图
弹幕这里的mismatch就是指输入数据的分布和后续finetune的分布不同 中间其实相当于给数据加噪音最后的使用的是和在做微调的时候一样的数据。
Next Sentence Prediction(NSP)
QA和自然语言推理都是基于理解两个句子的关系的但是这一关系并不能被语言模型直接找到。-所以让模型学习一些句子层面的信息
具体来说我们的一个输入序列中有两个句子A和BB在原文中间的概率是50%B就是A的下一个句子标记为IsNext还有50%的概率B就是从其他的地方随机拿来的句子标记为NotNext-50%的样本是正例50%的样本是负例。 注意在上面的例子中有一个“##”其实在原文中“flight ##less”是一个词“flightless”但是这个词出现的概率不高所以在WordPiece中把它砍成两个词##表示的意思就是后面那个词在原文中应该和前面的词在一起。
Fine-tuning BERT
BERT和一些基于encoder-decoder的架构的区别。
之前的transformer是encoder-decoder因为把整个句子对都一起输入进去所以self-attention能够看到两端但是在encoder-decoder的架构中encoder实际上一般是看不到decoder的信息的。因此BERT在这里会更好。但是代价是不能像transformer一样做机器翻译。
弹幕我的理解因为输入最好是一种语言机器翻译句子对是两种不同语言放进一个编码器处理上下文理解效果可能不好
ber能做机器翻译就是加一个解码器类似的比如说bart
--我猜他是想说输入有个最大的长度限制1024吧不像RNN可以无限长度尽管可能会遗忘
在做下游任务的时候会根据任务设计任务相关的输入和输出好处是模型其实不需要怎么变只要把输入改成需要的句子对就可以了。如果这个时候我们恰好就是有句子对A,B那么直接用就好了如果我们只有一个句子的话假设我们要做句子的分类就没有句子B了根据下游任务的要求要么是拿到第一个token对应的输出做分类或者是拿到对应的token的输出做输出。 a degenerate text-∅ pair in text classification or sequence tagging. At the output, the token representations are fed into an output layer for token-level tasks, such as sequence tagging or question answering, and the [CLS] representation is fed into an output layer for classification, such as entailment or sentiment analysis. 在输出端如果是token-level的任务token的表示被输入输出层。 弹幕其中对于前一类我们需要用到所有词元的表示, 后一类需要我们使用[CLS]的对应输出.
在预训练中我们的NSP对应后者, 而MLM代表前者.
就是文本对应一个空集
与预训练相比微调就比较便宜所有的结果都可以使用一个TPU跑一个小时就好了。
实验
BERT怎么用在下游任务上。
GLUE
是一个句子层面的任务。BERT是把第一个特殊token[CLS]的最后的向量拿出来记作C然后学习一个输出层W用softmax得到标号。
SQuAD
QA数据。阅读理解给一段话问一个问题找到答案所在的句子。-对每一个token判断是不是答案的开头/结尾。具体而言就是学两个向量S和E分别对应这个token是这个大难的开始的概率和这个token是这个答案的末尾的概率。具体而言对第二句话B的每一个token相乘再做softmax就会得到这个句子里面每一个token是答案开始/末尾的概率
SWAG
用来判断两个句子之间的关系。
Ablation Studies
看每一块对结果的贡献。
去掉下一个句子的预测/只是从左看到右的没有掩码/双向的LSTM
模型大小的影响
不用微调
评论区笔记
BERT 论文逐段精读【论文精读】 - 哔哩哔哩
BERT 论文逐段精读【论文精读】 - 哔哩哔哩 李宏毅-ELMO, BERT, GPT讲解_哔哩哔哩_bilibili
怎么让电脑看懂人类的文字
Introduction of ELMO, BERT, GPT
回顾 最早的做法是每一个不同的文字当做不同的符号每一个符号都用一个独特的编码表示。但是这样不太好词汇和词汇之间是完全没有任何关联的。比如这里cat和dog都是动物也许他们相较于cat和bag的关系会更近。但是从1-of-N encoding是看不出来的
因此出现了Word Class的概念把词汇做分类。但是这样分类显然太粗糙了比如图中class 1虽然cat dog和bird都是动物但是cat和dog是哺乳类动物但是鸟不是还是有区别直接这么归类太粗暴了。
因此就有了Word Embedding可以看做是一个soft的word class。每一个词汇都用一个向量来表示这个向量的某一个维度某一个维度可能就表示了这个词汇的某种意思。语音比较相近的词汇就会比较接近比如这里的dog和cat和rabbit就比较接近。但是跟birdtreeflower就比较有距离。所以从一个词汇的word embedding就可以知道这个词汇的意思。-怎么训练的呢根据词汇的上下文找到的。 在之前的RNN作业中指课程中的例子中我们希望训练一个sentiment analysis的classifier就不是使用1-of-N encoding来表示而是采用的embedding。用word embedding来表示某一个词汇的feature。 一个词汇可能有不同的意思。比如这里的bank这四个bank都是不同的token但是是同样的typetypebank。过去在做word embedding的时候是每一个type有一个embedding所以如果不同的token属于同样的type做embedding对应的那个vector就会是一样的也就是假设只要type是一样的语义就是一样的。但是事实上并非如此。 比如这里前两个句子中的bank指的都是银行前面有money后面两个bank指的都是河堤前面有river。过去传统的embedding每一个type都有一个embedding那么这四个bank就会有一模一样的embedding。 事实上我们希望机器可以给不同意思的token即使属于同一个type不同的embedding。过去的做法是去查一下词典bank这个type有两种不同的意思所以bank这个type应该要有两种不同的embedding。训练出来的结果我们希望是第一个和第二个的type是bank的token有一种embedding而第三个和第四个token有另一种embedding。 弹幕type就是spelling拼写token就是meaning意义 但是这么做显然是不够的因为人类的语言是很微妙的。比如同样是查词典有些词典会告诉我们bank有两个意思有些词典会告诉我们bank有三个意思。比如这里举例blood bank血库。 老师这里举的例子略二刺螈orz解释一下就是有些情况下我们很难分清两个名字/词的意思是不是一样的虽然我现在脑子里狂飙的也是二刺螈orz。我们可以说一些词汇是一样的也可以说是不一样的。 所以我们期待机器可以给每一个word token都有一个embedding。之前是每一个type都有一个embedding或者是每一个type都有固定多个embedding。现在是希望每一个token都有一个embedding。
看token的上下文越接近的token有越接近的embedding。比如图中三个bank都属于同一个word type但是这三个bank是不同的token。这些不同的token都会有不同的embedding。-contextualized word embedding。 不过在这个例子中下面两个bank的意思会比较接近所以vector比较近和上面那个bank的距离就会远一些。
ELMO 有一个技术可以做到这件事ELMO。ELMO是一个RNN-based的一个语言模型。做RNN-based的语言模型其实不需要做什么label只要收集一大堆句子。比如我们放进来一个句子“潮水退了 就知道谁没有穿裤子”现在我们就教我们的RNN-based language model加入看到BOSbegin of sentence就输出潮水假如给潮水就输出退了给潮水和退了就输出就……RNN-based language model训练的时候所学习的技能就是预测下一个token是什么学完以后就有一个contextualized word embedding。为什么说这个word embedding是contextualized的同样都是退了这个词汇上下文不同的话RNN输出来的embedding是不同的。 可能有人会提出这样只考虑了一个词汇的前文而没有考虑这个词汇的后文-再train一个反向的RNN从句尾读过来这个反向的RNN给吃知道就输出就给吃就就预测退了给吃退了就预测潮这样不仅考虑前文也考虑后文。
弹幕老师讲的这部分输入的是词向量还是one-hot编码 ELMo的输入是已经通过预训练的是One-hot通过字符卷积和highway层得到的token 应该是随机初始化one hot的向量size实在太大了 Embedding本身也在训练 应该有embedding层但是如果用这层就没上下文了用后面的隐层 输入【b, seq_len] 输出【b,seq_len,d_model] 比如这里就把“退了”这个词汇在正向的embedding和逆向的embedding都拿出来接起来同样的词汇上下文不一样得到的embedding就会不同。 现在我们train什么network都是要deep的RNN可以是deep的。但是我们train deep nn的时候会遇到问题因为有很多层每一层都有embedding到底用哪一层的embedding呢 ELMO的思路是全都要orz ELMO的做法是现在每一层都会给我们contextualized的word embedding每一个词汇丢进去都会有不止一个embedding吐出来每层RNN都会给一个embedding-把这些embedding都加起来一起用。
那么怎么加起来呢最简单的策略是直接直接拼起来。ELMO会做weighted sum加权和。假设我们这里的RNN有两层吐出了两个embeddingh1和h2ELMO会把第一层吐出的embedding乘α1第二层吐出来的embedding乘α2加起来得到蓝色的embedding再把蓝色的embedding做下游的任务。
那么这个α1和α2是什么来的呢learn出来的。怎么learn在还没有接下游任务之前在还没有使用ELMO token embedding之前是不知道这些α的值应该是多少的要先设定好接下来做什么application比如QA再把这些参数α1和α2和接下来的任务一起learn出来。
比如接下来要做QAQA的model里面也有一些参数会把α1和α2视为QA要学的参数的一部分跟着network的其他部分一起学出来。所以不同的任务要用的α1和α2就不一样。在原始的ELMO的论文中不同的任务学出来的α的结果如上图。
BERT BERT是transformer的encoder。在BERT里面只要收集一大堆句子这些句子不需要有annotation就可以把这个encoder train出来。
BERT实际上在做什么给一个句子给BERT每一个token都会吐一个embedding出来。input一串sequenceoutput一串embedding每一个embedding都对应到一个word。
虽然在例子中给的是中文的词但是实际上如果真的用于中文可能字的效果会更好。中文的词的数量太多了所以input的vector就太多了如果换成字的话因为常用的中文的字只有4000多个-可以穷举的。
如何训练BERT
方法一Masked LM 现在要交给BERT的任务是输入的句子的词汇以15%的概率置换成一个特殊的token [MASK]盖掉一个句子中15%的词汇BERT要做的就是猜测这些盖住的地方是哪个词汇。
那么BERT是怎么填回来的呢假设输入的句子的第二个词汇是盖住的接下来把输入都通过BERT每一个input token都会得到一个embedding接下来把盖住的地方的embedding丢到一个linear mult-class classifier里面要求这个classifier预测现在被mask的词汇是哪一个词汇。因为这个classifier是一个linear的classifier所以能力很弱所以想要能预测出被mask的词汇这个BERT就可能非常深-一定要能抽出来一个非常好的representation-如果两个词汇填在同一个地方不会有违和感那么这两个词汇就有类似的embedding
方法二Next Sentence Prediction 给两个句子BERT预测这两个句子是不是接在一起的。在两个句子之间加上[SEP]告诉BERT两个句子的交界在哪里。怎么判断两个句子是不是相接的还需要在加一个token在开头[CLS]代表在这个位置要做classification。从这个特殊的位置[CLS]输出的embedding丢到一个linear binary classifier里面让它output现在输入的这两个句子是不是接在一起的。
为什么放在句子的开头呢让BERT读完整个句子再决定这两个句子是不是接在一起的我先盲答是因为BERT是Bidirectional的所以不存在方向问题再加上attention mechanism本身就能看到整个句子
仔细想想BERT的架构如果BERT里面放的是RNN正向从左到右[CLS]放在句子的尾部比较合理。BERT的内部并不是RNNBERT的内部是一个Transformer是self-attention。self-attention的特色就是“天涯若比邻”两个相邻的word和两个距离很远的word对BERT来说是一样的。对self-attention来说假如不考虑position encoding的影响一个token放在句子的开头或结尾是没有差别的。
这个linear classifier和整个network架构是一起被训练的希望通过解决预测sentence的任务把BERT部分的参数学出来。
在文献中这两个方法是同时使用的。
怎么用BERT
假设我们现在输入一串wordPPT上的例子是word实际上应该是character每一个word都有一个contextualized的word embedding。怎么使用呢最简单的做法是把BERT当做一个抽feature的工具通过一种新的embedding做想做的任务。
在论文中给出的方法是把BERT和要做的任务一起训练。
case 1 假设现在是要输入一个句子输出一个类别。比如sentiment analysisdocument classification判断句子情绪文章分类。把现在要做分类的句子做一个分类不过要在开头的地方加一个[CLS]接下来把代表分类的符号的位置所输出的embedding丢到一个linear classifier里面去预测属于哪一类。
现在训练的时候linear classifier是随机初始化的只有这里需要重头学BERT的部分做fine-tuning只要微调就好。
case 2 假设现在要做的任务是输入一个句子决定句子中的每一个词汇属于哪一类。比如slot filling。把每一个embedding都丢到linear classifier里面决定embedding属于哪个类别。
case 3 假设现在要做的是输入两个句子输出一个类别。比如nature language inference给机器一个前提再给一个假设让机器判断根据这个前提这个假设对/错/不知道。
方法是先给model两个句子加上[CLS][SEP]把[CLS]的embedding丢到linear classifier里面让决定T/F/unknown
case 4 QA问题特别是里面的Extraction-based的QA问题。就是给model读一个文章问一个问题希望model给出答案但是答案肯定出现在文章里面了。
怎么做呢给model文章问题文章和问题都是用token sequence表示。model吃一个文章吃一个问题输出两个整数-这两个整数表示答案落在文章的第s个token和第e个token之间。 怎么用BERT解决刚刚的问题呢input问题[SEP]文章现在文章里面的每一个词汇都会有一个embedding接下来让machine去learn另外两个vector图中红色和蓝色的这两个vector 的dimension和黄色vector的dimension是一样的红色的vector拿去和文章中的每一个黄色的vector做点乘类似做attention的动作。 每一个算完点乘之后softmax得到分数然后看哪个分数最高。举例来说这里就是第二个词汇的分数最高。
-s2 同理蓝色的vector也做点乘softmax得到分数。
-e3
所以这里就是文章的第二个和第三个word就是答案。
但是如果出现s3,e2-没有答案了 为了适应中文的改动 ————————————————————————————————————
后面的内容都是GPT啦。介于我的motivation是完成kaggle nlp的Getting Started competitions所以就先读到这里了。后面等我做完这个project再来啦。 后面会参考
LeeMeng - 進擊的 BERTNLP 界的巨人之力與遷移學習
KerasNLP starter notebook Disaster Tweets | Kaggle 先容我吐槽一句看到小贝的头变成BERT我要应激啦脑海里面开始我铠他超×