$\vec{a} \cdot \vec{b}=0$
\( x_i \)
$x^{y^z}=(1+{\rm e}^x)^{-2xy^w}$
]]>在 上一篇文章 中, 我们了解到 CRF 能够从训练数据中学习到有关 Labels 序列的约束,进而可以确保最终的实体标注序列是合理有效的。
这些约束可以是:
“B-label1 I-label2 I-label3 I-…”,在这个模式中, label1, label2, label3 … 应该是同一实体的 Label。譬如,“B-Person I-Person” 是合理有效的,但是 “B-Person I-Organization” 便是无效的。
“O I-label” 是无效的。命名实体的第一个起始标注应该是 “B-“ 开头的,而不是 “I-“。换一句话说,合理有效的模式应该是 “O B-label”
…
在读完这篇文章后,你将会知道为什么 CRF 能够学习到这些约束。
在 CRF 层的 Loss Function 中,我们有两种 Score ,Emission Score 和 Transition Score 它们是 CRF 层的关键。
第一个便是 Emission Score 。这里的 Emission Scores 来自于 BiLSTM 层,如下图所示,$w_0$ 被标记为 B-Person 的 score 是 1.5
为了方便理解,在这里给每个 label 一个索引标签:
我们使用 $x{i,y_j}$ 表示 Emission Score,$i$ 是 word 的 index, $y_j$ 是 label 的 index。譬如,依据上面的图可以得到,$x{i=1,yj=2} = x{w1, B-Organization} = 0.1$, 意思就是 $w_1$ 被标注为 B-Organization 的 score 为 0.1。
对于 Transition Score ,我们使用 $t{y_jy_j}$ 表示。譬如,$t{B-Persion, I-Person} = 0.9$,意思就是标签 B-Persion 转移到 I-Person 的 score 为 0.9。这样的话,我们便拥有了一个 转移矩阵,其中存储着所有标签之间的 Transition Score。
为了使得转移分数矩阵更加具有鲁棒性,我们得添加一些标签,START 和 END。START 表示句子的起始,并不是句子的第一个 word;END 表示句子的结束。
这里就是一个 transition matrix score 的例子,其中包含了我们额外添加的START 和 END 标签。
如上表所示,我们能够发现这个状态转移举证已经学习到了某些约束了。
句子中的第一个单词的标记应该是以“B-“ 或者 “O”开头, 并不会是 “I-”形式的标记。(可以从表中发现, “START” 到 “I-Person or I-Organization” 的转移值非常的小。)
在“B-label1 I-label2 I-label3 I-…”这样形式的标注序列中, label1, label2, label3 … 应该是同种实体的标签。比如,“B-Person I-Person” 是合理有效的标注序列,而 “B-Person I-Organization” 则不是。(譬如, the score from “B-Organization” to “I-Person” is only 0.0003 which is much lower than the others.)
“O I-label” is invalid. The first label of one named entity should start with “B-“ not “I-“, in other words, the valid pattern should be “O B-label” (表中 $t_{O, I-Person}$ 的值非常的小。)
好了,这时候你脑子里该满是黑人问号了,这个矩阵从哪里来的??
确切的说,这个矩阵是 BiLSTM-CRF 模型的一个参数。在你训练模型之前,你可以随机地初始化矩阵中所有的 transition score。在之后的训练过程中,这些随机初始化的 score 将会被自动更新。换句话说,CRF 层可以自己学习到这些约束。我们并不需要手动创建这样一个矩阵。这些分数值会随着训练的迭代次数的增加,变得越来越 “合理”。
CRF 的损失函数由 真实转移路径值 和 所有可能转移路径值两部分组成。真实路径表示在所有可能转移路径中具有最高 score 的路径。
假如我们的数据集中有这样一些标记:
我们也有一个由 5 个单词组成的句子,那么标签的可能转移路径有:
1.START B-Person B-Person B-Person B-Person B-Person END
2.START B-Person I-Person B-Person B-Person B-Person END
…
10.START B-Person I-Person O B-Organization O END
…
N.O O O O O O O
假定每一个可能的路径有一个分数值 $Pi$, 那么对于所有 N 条可能的路径的总分数值为 $P{total} = P_1 + P_2 + P_3 + … + P_N = e^{S_1} + e^{S_2} + e^{S_3} + … + e^{S_N}$,e 是数学常量 e。(在 2.4 节,我们会讨论如何计算 $S_i$,你也可以将它直接作为该路径的分数值。)
假如这里的第十条路径是真实的路径,换句话说,第十条路径是训练集提供的“黄金准则”。那么, $P_{10} $ 就应该在所有的路径分数值之和中占据最大的比例。
下面给出方程便是我们一直讨论的 Loss Function,在训练阶段,BiLSTM-CRF 模型的参数值将会一直不停的被更新,来提高真实路径的分数值所占的比重。
现在,问题来了:
今天就到这里吧~
参考文献
[1] Lample, G., Ballesteros, M., Subramanian, S., Kawakami, K. and Dyer, C., 2016. Neural architectures for named entity recognition. arXiv preprint arXiv:1603.01360.
[2] https://createmomo.github.io/2017/09/23/CRF_Layer_on_the_Top_of_BiLSTM_2/
注:本文翻译自 CreateMoMo 个人博客,暂未取得作者授权,仅做学习交流使用,如若侵权,立即删除。点击底部阅读原文可直达原博客。
该系列文章将会涉及以下几个方面:
Idea 概述 - 在命名实体识别任务中,为什么要在 BiLSTM模型上添加CRF层?
案例解读 - 通过一个简单的实现来揭示:CRF 层是怎样工作的?
Chainer 实现 BiLSTM+CRF 模型(翻译者会努力用 TensorFlow or PyTorch 来实现一番!)
谁适合阅读本系列文章?
本系列文章适合 NLP 或其他 AI 相关领域的初学者或者在校学生,希望你们在我的文章中能有所收获。期待有建设性的意见和建议!
如果你不知道神经网络、CRF 或者其他相关的知识,别担心,我会尽量从直觉上来帮助你来理解它们。唯一需要你知道的是命名实体识别的概念!
对于命名实体识别任务来说,基于神经网络和深度学习的方法越来越流行了。比如在这篇Paper中,作者就提出了 BiLSTM-CRF 模型用于命名实体识别任务,文中使用了 word level 和 character level 的 embedding。我将使用这篇文章中的模型来解释模型中 CRF层 是如何工作的 :) 。
如果你还不了解有关 BiLSTM 和 CRF 的细节的话,只要记住它们不过是命名实体识别模型中两种不同的 Layer 罢了!
首先,假设我们的数据集中有两种不同的实体类型:Person(人物) 和 Organization(组织)。那么,实际上,我们便有了五种实体的类别 Label :
这样的话,假如我们使用 $x$ 代表包含五个单词的句子,$w_0,w_1,w_2,w_3,w_4$。那么,在句子 $x$ 中,$[w_0,w_1]$ 是一个 Person 实体,$[w_3]$ 是一个 Organization 实体,其他的单词我们用 $O$ 表示。
在这里我会简要介绍一下 BiLSTM-CRF 模型。
如下图所示:
首先,在句子 $x$ 中的每一个词 $w_i$都对应着一个向量表示,这个向量由字符级别的词嵌入(character embedding)和单词级别的词嵌入(word embedding)共同组成(concat 操作?)。其中,字符级别的词嵌入(character embedding)由随机初始化得到,而单词级别的词嵌入(word embedding)一般来自于预先训练好的 word embedding 文件(word2vec 或者 GloVe)。所有的 embeddings 在训练过程中将会被 fine-tuned。
其次,BiLSTM-CRF 模型的输入便是这些词向量,模型的输出是对句子 $x$ 中单词对应的标签类别的预测。尽管了解 BiLSTM 层的细节对于我们来说并不必要,但是为了更加容易的理解 CRF 层,还是有必要知道一下 BiLSTM 层输出结果表示什么意思。
如上所示, BiLSTM 层的输出是每个类别的预测分数值。譬如,对于词 $w_0$ 来说,BiLSTM 层的输出为:1.5 (B-Person), 0.9 (I-Person), 0.1 (B-Organization), 0.08 (I-Organization) 和 0.05 (O)。这些分数值将会作为 CRF 层的输入。
之后,在所有由 BiLSTM 层预测的分数值输入到 CRF 层之后,CRF 便会选择具有最高预测分数值的类别标记序列作为最佳的答案。
你可能已经注意到了,假使没有 CRF 层,我们一样可以只训练 LSTM 来进行命名实体识别,流程如下:
因为 BiLSTM 层输出的正是每个单词的在各个类标上的分数值,我们完全可以选择具有最高分数的类标作为单词的命名实体类别标注。
譬如,对于 $w_0$ 来说, “B-Person” 具有最高的得分(1.5),因而我们可以选择 “B-Person”作为最佳的预测。同理,对于$w_1$,我们可以选择 “I-Person”;对于 $w_2$,我们可以选择 “O”;对于 $w_3$,我们可以选择 “B-Org”;对于 $w_2$,我们可以选择 “O”。
在这个例子中,尽管我们可以得到句子$x$中各个单词的正确类别标记。但是,有些情况下并不总是如此,看一看这个例子:
很显然,沿用上面的方法,我们得到的输出(“I-Organization I-Person” 和 “B-Organization I-Person” )便显得非常的不合理了,I-Organization 之后竟然会出现 I-Person 的标注!
The CRF layer could add some constrains to the final predicted labels to ensure they are valid. These constrains can be learned by the CRF layer automatically from the training dataset during the training process.
CRF 层能够给最终的预测 Labels 添加一些约束来确保其合理有效。在训练过程中,这些约束会被 CRF 层自动学习到。
这些约束可以是:
“B-label1 I-label2 I-label3 I-…”,在这个模式中, label1, label2, label3 … 应该是同一实体的 Label。譬如,“B-Person I-Person” 是合理有效的,但是 “B-Person I-Organization” 便是无效的。
“O I-label” 是无效的。命名实体的第一个起始标注应该是 “B-“ 开头的,而不是 “I-“。换一句话说,合理有效的模式应该是 “O B-label”
有了这些必要的约束,出现不合理标注序列的数量将会显著下降!
接下来,我将通过分析 CRF 的 Loss Function 来解释 CRF 层如何从训练数据集中学习到上述约束,以及为什么 CRF 能够学习到它们。
别走开,后续更加精彩!
参考文献
[1] CRF_Layer_on_the_Top_of_BiLSTM_1
[2] Lample, G., Ballesteros, M., Subramanian, S., Kawakami, K. and Dyer, C., 2016. Neural architectures for named entity recognition. arXiv preprint arXiv:1603.01360.)
2.初始化链表,带不带头节点
头指针
尾指针
首节点
尾节点
With 头节点
操作同一
Without 头节点
链表合并方便
头插法
尾插法
实现两个带头节点的链表 L1 和 L2进行连接,L2 连接到 L2 末尾。
将两个有序链表合并为一个有序链表。
]]>C++ 定义了一套包括 算数类型 和 空类型 在内点基本数据类型。其中 算术类型 包括 字符、整数型、布尔值和 浮点数。空类型不对应具体的值,仅用于一些特殊点场合,例如最常见点是,当函数不返回任何值时使用空类型作为返回类型。
在 C++ 中初始化是一个异常复杂的问题。
在 C++ 中 初始化 和 赋值 是两种完全不同的操作。
1 | int unit_num = 0; |
作为 C++11 新标准的一部分,用花括号初始化变量的到来全面的应用。
引用和指针
确保头文件多次包含仍然能正常工作的常用技术是预处理器(Preprocessor),它由 C++ 语言从 C语言中继承而来。
]]>类的定义一般放在头文件中,通常使用.h
作为头文件的后缀。标准库头文件一般不带后缀。
对于 #include
指令,包含来自标准库的头文件时,用尖括号 (<>)
包围头文件名。对于不属于标准库的头文件,则用双引号 ("")
包围。
文件重定向:将标准输入和标准输出与命名文件相关联起来。1
addItem <input_file >output_file
成员函数(member function)定义为类的一部分的函数,有时候也被称为方法(Method)。
点运算符 .
调用运算符 ()
https://github.com/spro/practical-pytorch
https://github.com/jadore801120/attention-is-all-you-need-pytorch
https://github.com/rguthrie3/DeepLearningForNLPInPytorch
https://github.com/yunjey/pytorch-tutorial
https://github.com/aaron-xichen/pytorch-playground
https://zhuanlan.zhihu.com/p/28448135
现在假设你有三个训练数据的样本。你的神经网络在输出层使用 softmax 激活函数将输出值转换为概率。假设神经网络的输出值和样本的实际值如下所示:1
2
3
4
5| computed | targets | correct? |
| -------------- |----------------------|----------|
| 0.3 0.3 0.4 | 0 0 1 (democrat) | yes |
| 0.3 0.4 0.3 | 0 1 0 (republican) | yes |
| 0.1 0.2 0.7 | 1 0 0 (other) | no |
这个神经网络的分类误差为 $\frac{1}{3} = 0.33$ ,其对应的分类准确率为 $\frac{2}{3}=0.67$ 。注意到这个神经网络仅仅将前两个样本分类正确,在第三个样本上却错的离谱。现在来看看另外一个神经网络:1
2
3
4
5computed | targets | correct?
-----------------------------------------------
0.1 0.2 0.7 | 0 0 1 (democrat) | yes
0.1 0.7 0.2 | 0 1 0 (republican) | yes
0.3 0.4 0.3 | 1 0 0 (other) | no
这个神经网络的分类误差也是 $\frac{1}{3} = 0.33$ 。但是这个神经网络的表现要比第一个要好,因为它预测正确分类的概率值要大,且对于第三个样本也仅仅是差一点就预测对了,不像第一个预测的那么离谱。由此看来,分类误差是一个很“粗暴”的误差度量指标。
现在我们看看 cross-entropy error。第一个神经网络对于第一个样本的交叉熵误差为:
注意到在这个神经网络分类中,计算有一点“怪异”,因为除了一项以外都是 0 。(网络上几个讲如何计算交叉熵的解释还不错。)所以,第一个神经网络的平均交叉熵误差计算如下:
第二个神经网络的平均交叉熵误差为:
Notice that the average cross-entropy error for the second, superior neural network is smaller than the ACE error for the first neural network. The ln() function in cross-entropy takes into account the closeness of a prediction and is a more granular way to compute error.
]]>梯度爆炸
]]>One-Hot Encoding 可以将 类别特征
转换为分类和回归算法更易于处理的格式。
这一节课将会深入了解 NLP 中分类问题。
根据传统的机器学习的“套路”,我们一般使用简单的模型(比如 Logistic Regression
)来定义和学习分类问题的决策边界(Decision Boundary
),使得模型能够通过这个决策边界区分两个或多个类别。在一般的机器学习流程中,我们一般假定输入是固定的(Fixed),然后只需要训练 $W$ 参数(即 SoftMax 权重),通过给定的输入 $X$ 来计算 $Y$ 的概率。
" You are uniformly charming ! " cried he, with a smile of associating and now and then I bowed and they perceived a chaise and for to wish for.
]]>“You are uniformly charming!” cried he, with a smile of associating and now and then I bowed and they perceived a chaise and for to wish for. —— Random sentence generated from Jane Austen trigram model
32 \( \times \) 32\(\times\)3 image \(\to\) stretch to 3072\(\times\)1
卷积层与全连接层的主要差别在于前者可以保全 空间结构 (Spatial Structure)。处理一张 32 \( \times \) 32\(\times\)3 的图片,不同于全连接层中将其展开为一维的长向量作为输入,我们在卷积层直接将图片的三维的结构输入,这样我们就可以保持图片的结构。
接下来,我们的权重是一些小的卷积核,例如 5 \( \times \) 5 \(\times\) 3 的大小,我们将把这个卷积核在整个图像上滑动,并计算出在每一个空间定位(Spatial Location)时的 Dot Product。
首先,我们采用的卷积核总是会将输入量扩展至完全(extend the Full Depth of the input volume)。它们都是很小的空间区域,这里是 5 \( \times \) 5 而不是输入空间的全部大小 32 \( \times \) 32,但是他们通常会遍历所有的RGB通道 ,所以这里我们采用的卷积核的大小为 5 \( \times \) 5 \(\times\) 3 。
]]>该系列文章将会涉及以下几个方面:
Idea 概述 - 在命名实体识别任务中,为什么要在 BiLSTM模型上添加CRF层?
案例解读 - 通过一个简单的实现来揭示:CRF 层是怎样工作的?
Chainer 实现 BiLSTM+CRF 模型(翻译者会努力用 TensorFlow or PyTorch 来实现一番!)
谁适合阅读本系列文章?
本系列文章适合 NLP 或其他 AI 相关领域的初学者或者在校学生,希望你们在我的文章中能有所收获。期待有建设性的意见和建议!
如果你不知道神经网络、CRF 或者其他相关的知识,别担心,我会尽量从直觉上来帮助你来理解它们。唯一需要你知道的是命名实体识别的概念!
对于命名实体识别任务来说,基于神经网络和深度学习的方法越来越流行了。比如在这篇Paper中,作者就提出了 BiLSTM-CRF 模型用于命名实体识别任务,文中使用了 word level 和 character level 的 embedding。我将使用这篇文章中的模型来解释模型中 CRF层 是如何工作的 :) 。
如果你还不了解有关 BiLSTM 和 CRF 的细节的话,只要记住它们不过是命名实体识别模型中两种不同的 Layer 罢了!
首先,假设我们的数据集中有两种不同的实体类型:Person(人物) 和 Organization(组织)。那么,实际上,我们便有了五种实体的类别 Label :
这样的话,假如我们使用 $x$ 代表包含五个单词的句子,$w_0,w_1,w_2,w_3,w_4$。那么,在句子 $x$ 中,$[w_0,w_1]$ 是一个 Person 实体,$[w_3]$ 是一个 Organization 实体,其他的单词我们用 $O$ 表示。
在这里我会简要介绍一下 BiLSTM-CRF 模型。
如下图所示:
首先,在句子 $x$ 中的每一个词 $w_i$都对应着一个向量表示,这个向量由字符级别的词嵌入(character embedding)和单词级别的词嵌入(word embedding)共同组成(concat 操作?)。其中,字符级别的词嵌入(character embedding)由随机初始化得到,而单词级别的词嵌入(word embedding)一般来自于预先训练好的 word embedding 文件(word2vec 或者 GloVe)。所有的 embeddings 在训练过程中将会被 fine-tuned。
其次,BiLSTM-CRF 模型的输入便是这些词向量,模型的输出是对句子 $x$ 中单词对应的标签类别的预测。尽管了解 BiLSTM 层的细节对于我们来说并不必要,但是为了更加容易的理解 CRF 层,还是有必要知道一下 BiLSTM 层输出结果表示什么意思。
如上所示, BiLSTM 层的输出是每个类别的预测分数值。譬如,对于词 $w_0$ 来说,BiLSTM 层的输出为:1.5 (B-Person), 0.9 (I-Person), 0.1 (B-Organization), 0.08 (I-Organization) 和 0.05 (O)。这些分数值将会作为 CRF 层的输入。
之后,在所有由 BiLSTM 层预测的分数值输入到 CRF 层之后,CRF 便会选择具有最高预测分数值的类别标记序列作为最佳的答案。
你可能已经注意到了,假使没有 CRF 层,我们一样可以只训练 LSTM 来进行命名实体识别,流程如下:
因为 BiLSTM 层输出的正是每个单词的在各个类标上的分数值,我们完全可以选择具有最高分数的类标作为单词的命名实体类别标注。
譬如,对于 $w_0$ 来说, “B-Person” 具有最高的得分(1.5),因而我们可以选择 “B-Person”作为最佳的预测。同理,对于$w_1$,我们可以选择 “I-Person”;对于 $w_2$,我们可以选择 “O”;对于 $w_3$,我们可以选择 “B-Org”;对于 $w_2$,我们可以选择 “O”。
在这个例子中,尽管我们可以得到句子$x$中各个单词的正确类别标记。但是,有些情况下并不总是如此,看一看这个例子:
很显然,沿用上面的方法,我们得到的输出(“I-Organization I-Person” 和 “B-Organization I-Person” )便显得非常的不合理了,I-Organization 之后竟然会出现 I-Person 的标注!
The CRF layer could add some constrains to the final predicted labels to ensure they are valid. These constrains can be learned by the CRF layer automatically from the training dataset during the training process.
CRF 层能够给最终的预测 Labels 添加一些约束来确保其合理有效。在训练过程中,这些约束会被 CRF 层自动学习到。
这些约束可以是:
“B-label1 I-label2 I-label3 I-…”,在这个模式中, label1, label2, label3 … 应该是同一实体的 Label。譬如,“B-Person I-Person” 是合理有效的,但是 “B-Person I-Organization” 便是无效的。
“O I-label” 是无效的。命名实体的第一个起始标注应该是 “B-“ 开头的,而不是 “I-“。换一句话说,合理有效的模式应该是 “O B-label”
有了这些必要的约束,出现不合理标注序列的数量将会显著下降!
接下来,我将通过分析 CRF 的 Loss Function 来解释 CRF 层如何从训练数据集中学习到上述约束,以及为什么 CRF 能够学习到它们。
别走开,后续更加精彩!
参考文献
[1] CRF_Layer_on_the_Top_of_BiLSTM_1
[2] Lample, G., Ballesteros, M., Subramanian, S., Kawakami, K. and Dyer, C., 2016. Neural architectures for named entity recognition. arXiv preprint arXiv:1603.01360.)
1 | npm install hexo-math –save |
Enter node_modules\kramed\lib\rules\inline.js
1 | //escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/, |
1 | # MathJax Support |
MathJax Enabled:
\( x_i \)
$s$
$y{1}$
]]>[x] ed
Decision Boundary
dropout
1 | import tensorflow as tf |
Logistic Regression
所谓 Bag-of-words model 即“词袋模型”.
]]>