diff --git a/BasicAlgorithm/BatchNormVsLayerNorm.md b/BasicAlgorithm/BatchNormVsLayerNorm.md deleted file mode 100644 index 9ae6b1d..0000000 --- a/BasicAlgorithm/BatchNormVsLayerNorm.md +++ /dev/null @@ -1,180 +0,0 @@ -# 【关于 BatchNorm vs LayerNorm】那些你不知道的事 - -![](img/BatchNormvsLayerNorm.png) - -## 一、动机篇 - -### 1.1 独立同分布(independent and identically distributed)与白化 - -- 独立同分布 - - 为什么? - - 独立同分布的数据可以简化常规机器学习模型的训练、提升机器学习模型的预测能力 - - 相关性: - - 强相关:Naive Bayes 模型就建立在特征彼此独立的基础之 - - 弱相关:Logistic Regression 和 神经网络 则在非独立的特征数据上依然可以训练出很好的模型 -- 白化【数据预处理步骤】 - - 作用: - - 去除特征间的相关性 -> 独立; - - 使所有特征具有相同的均值和方差 -> 同分布 - -### 1.2 ( Internal Covariate Shift,ICS) - -- 动机:深度神经网络涉及到很多层的叠加,而每一层的参数更新会导致上层的输入数据分布发生变化,通过层层叠加,高层的输入分布变化会非常剧烈,这就使得高层需要不断去重新适应底层的参数更新。为了训好模型,我们需要非常谨慎地去设定学习率、初始化权重、以及尽可能细致的参数更新策略。 -- 模型训练对于数据的一个假设:“源空间(source domain)和目标空间(target domain)的数据分布(distribution)是一致的”。如果不一致,那么就出现了新的机器学习问题,如 transfer learning / domain adaptation 等。而 covariate shift 就是分布不一致假设之下的一个分支问题,它是指源空间和目标空间的条件概率是一致的,但是其边缘概率不同; -- ICS 【每个神经元的输入数据不再是“独立同分布”】导致的后果: - - 上层参数需要不断适应新的输入数据分布,降低学习速度; - - 下层输入的变化可能趋向于变大或者变小,导致上层落入饱和区,使得学习过早停止; - - 每层的更新都会影响到其它层,因此每层的参数更新策略需要尽可能的谨慎; - -### 1.3 ICS问题带来的后果是什么? - -1. 上层参数需要不断适应新的输入数据分布,导致学习速度下降; -2. 下层输入的变化可能趋于变大或变小,导致上层落入饱和区,从而学习过早停止; -3. 每层的更新都会影响到其他层,因此每层参数更新策略需要尽可能谨慎; - -## 二、Normalization 篇 - -### 2.1 Normalization 的通用框架与基本思想 - -- 前言 - -假设 神经元的输入: - -![](img/20201223130440.png) - -输出的结果: - -![](img/20201223130525.png) - -- ICS 问题: X 的 分布可能相差很大 -- 解决方法: - - 方法:对每一层的数据做白化操作 - - 存在问题:成本高,因为要保证 白化操作是可微的 - -- 基本思想:在将 x 送给神经元之前,先对其做平移和伸缩变换, 将 x 的分布规范化成在固定区间范围的标准分布; -- 变换框架: - -![](img/20201223131020.png) - -> 参数介绍:
-> μ:平移参数
-> δ:缩放参数
- -- 步骤: -1. 对 x 进行 shift 和 scale 变换 - -![](img/20201223131344.png) - -> 得到的数据符合均值为 0、方差为 1 的标准分布 - -1. b 是再平移参数(re-shift parameter), g 是再缩放参数(re-scale parameter),再进一步变换为 - -![](img/20201223131525.png) - -> 得到的数据符合均值为 b 、方差为 $g^2$ 的分布 - -## 三、Batch Normalization 篇 - -### 3.1 Batch Normalization(纵向规范化)是什么? - -![](img/20201223132028.png) - -- 方式:针对单个神经元进行,利用网络训练时一个 mini-batch 的数据来计算该神经元 $x_i$ 的均值和方差,因而称为 Batch Normalization。 - -![](img/20201223132145.png) - -> 其中 M 是 mini-batch 的大小。 - -### 3.2 Batch Normalization(纵向规范化)存在什么问题? - -- BN 独立地规范化每一个输入维度 $x_i$ ,但规范化的参数是一个 mini-batch 的一阶统计量和二阶统计量。这就要求 每一个 mini-batch 的统计量是整体统计量的近似估计,或者说每一个 mini-batch 彼此之间,以及和整体数据,都应该是近似同分布的。分布差距较小的 mini-batch 可以看做是为规范化操作和模型训练引入了噪声,可以增加模型的鲁棒性;但如果每个 mini-batch的原始分布差别很大,那么不同 mini-batch 的数据将会进行不一样的数据变换,这就增加了模型训练的难度。 -- 由于 BN 需要在运行过程中统计每个 mini-batch 的一阶统计量和二阶统计量,因此不适用于 动态的网络结构 和 RNN 网络 - -### 3.3 Batch Normalization(纵向规范化)适用的场景是什么? - -每个 mini-batch 比较大,数据分布比较接近。在进行训练之前,要做好充分的 shuffle. 否则效果会差很多。 - -### 3.4 BatchNorm 存在什么问题? - -1. BN特别依赖Batch Size;当Batch size很小的时候,BN的效果就非常不理想了。在很多情况下,Batch size大不了,因为你GPU的显存不够。所以,通常会有其他比较麻烦的手段去解决这个问题,比如MegDet的CGBN等; -2. BN对处理序列化数据的网络比如RNN是不太适用的;So,BN的应用领域减少了一半; -3. BN只在训练的时候用,inference的时候不会用到,因为inference的输入不是批量输入。 - -## 四、Layer Normalization(横向规范化) 篇 - -### 4.1 Layer Normalization(横向规范化)是什么? - -![](img/20201223132445.png) - -- 方式:综合考虑一层所有维度的输入,计算该层的平均输入值和输入方差,然后用同一个规范化操作来转换各个维度的输入。 - -![](img/20201223132538.png) - -> 其中 i 枚举了该层所有的输入神经元。对应到标准公式中,四大参数 μ, δ, g, b 均为标量(BN中是向量),所有输入共享一个规范化变换。 - -### 4.2 Layer Normalization(横向规范化)有什么用? - -LN 针对单个训练样本进行,不依赖于其他数据,因此可以避免 BN 中受 mini-batch 数据分布影响的问题,可以用于 小mini-batch场景、动态网络场景和 RNN,特别是自然语言处理领域。此外,LN 不需要保存 mini-batch 的均值和方差,节省了额外的存储空间。 - -## 五、BN vs LN 篇 - -BN 的转换是针对单个神经元可训练的——不同神经元的输入经过再平移和再缩放后分布在不同的区间,而 LN 对于一整层的神经元训练得到同一个转换——所有的输入都在同一个区间范围内。如果不同输入特征不属于相似的类别(比如颜色和大小),那么 LN 的处理可能会降低模型的表达能力。 - -## 六、主流 Normalization 方法为什么有效? - -![](img/20201223135451.png) - -1. Normalization 的权重伸缩不变性 - -- 介绍:权重 W 按照常量 λ 进行伸缩时,得到的规范化后的值保持不变 - -![](img/20201223135552.png) - -> 其中:W' = λW - -- 原因:当权重 W 伸缩时,对应的均值和标准差均等比例伸缩,分子分母相抵。 - -![](img/20201223135720.png) - -- 优点: - - 权重伸缩不变性可以有效地提高反向传播的效率 - -![](img/20201223135807.png) - -> 注:因此,权重的伸缩变化不会影响反向梯度的 Jacobian 矩阵,因此也就对反向传播没有影响,避免了反向传播时因为权重过大或过小导致的梯度消失或梯度爆炸问题,从而加速了神经网络的训练。 - - - 权重伸缩不变性还具有参数正则化的效果,可以使用更高的学习率。 - -![](img/20201223135855.png) - -> 因此,下层的权重值越大,其梯度就越小。这样,参数的变化就越稳定,相当于实现了参数正则化的效果,避免参数的大幅震荡,提高网络的泛化性能。 - -2. Normalization 的数据伸缩不变性 - -- 介绍:当数据 x 按照常量 λ 进行伸缩时,得到的规范化后的值保持不变 - -![](img/20201223140010.png) - -> 注:x'= λx - -- 优点: - - 数据伸缩不变性可以有效地减少梯度弥散,简化对学习率的选择 - -对于某一层神经元 : - -![](img/20201223140135.png) - -可得: - -![](img/20201223140211.png) - -每一层神经元的输出依赖于底下各层的计算结果。如果没有正则化,当下层输入发生伸缩变化时,经过层层传递,可能会导致数据发生剧烈的膨胀或者弥散,从而也导致了反向计算时的梯度爆炸或梯度弥散。 - -加入 Normalization 之后,不论底层的数据如何变化,对于某一层神经元 而言,其输入 $x_i$ 永远保持标准的分布,这就使得高层的训练更加简单。从梯度的计算公式来看: - -![](img/20201223140304.png) - -数据的伸缩变化也不会影响到对该层的权重参数更新,使得训练过程更加鲁棒,简化了对学习率的选择。 - - - diff --git a/BasicAlgorithm/img/1610160500583.png b/BasicAlgorithm/img/1610160500583.png deleted file mode 100644 index 36e28d4..0000000 Binary files a/BasicAlgorithm/img/1610160500583.png and /dev/null differ diff --git a/BasicAlgorithm/img/1610177872501.png b/BasicAlgorithm/img/1610177872501.png deleted file mode 100644 index dac4a6e..0000000 Binary files a/BasicAlgorithm/img/1610177872501.png and /dev/null differ diff --git a/BasicAlgorithm/img/20180404113714719.png b/BasicAlgorithm/img/20180404113714719.png deleted file mode 100644 index 214d398..0000000 Binary files a/BasicAlgorithm/img/20180404113714719.png and /dev/null differ diff --git a/BasicAlgorithm/img/20180404135638186.png b/BasicAlgorithm/img/20180404135638186.png deleted file mode 100644 index ec7f811..0000000 Binary files a/BasicAlgorithm/img/20180404135638186.png and /dev/null differ diff --git a/BasicAlgorithm/img/20180404150134375.png b/BasicAlgorithm/img/20180404150134375.png deleted file mode 100644 index cef86fe..0000000 Binary files a/BasicAlgorithm/img/20180404150134375.png and /dev/null differ diff --git a/BasicAlgorithm/img/20200812200223.png b/BasicAlgorithm/img/20200812200223.png deleted file mode 100644 index 0811a3d..0000000 Binary files a/BasicAlgorithm/img/20200812200223.png and /dev/null differ diff --git a/BasicAlgorithm/img/20200812200551.png b/BasicAlgorithm/img/20200812200551.png deleted file mode 100644 index deb0248..0000000 Binary files a/BasicAlgorithm/img/20200812200551.png and /dev/null differ diff --git a/BasicAlgorithm/img/20200812200740.png b/BasicAlgorithm/img/20200812200740.png deleted file mode 100644 index 525b625..0000000 Binary files a/BasicAlgorithm/img/20200812200740.png and /dev/null differ diff --git a/BasicAlgorithm/img/20200812203815.png b/BasicAlgorithm/img/20200812203815.png deleted file mode 100644 index 9677ecd..0000000 Binary files a/BasicAlgorithm/img/20200812203815.png and /dev/null differ diff --git a/BasicAlgorithm/img/20200812204613.png b/BasicAlgorithm/img/20200812204613.png deleted file mode 100644 index c762226..0000000 Binary files a/BasicAlgorithm/img/20200812204613.png and /dev/null differ diff --git a/BasicAlgorithm/img/20200906192126.png b/BasicAlgorithm/img/20200906192126.png deleted file mode 100644 index c4d6678..0000000 Binary files a/BasicAlgorithm/img/20200906192126.png and /dev/null differ diff --git a/BasicAlgorithm/img/20200906192221.png b/BasicAlgorithm/img/20200906192221.png deleted file mode 100644 index 21e2bba..0000000 Binary files a/BasicAlgorithm/img/20200906192221.png and /dev/null differ diff --git a/BasicAlgorithm/img/20200906192249.png b/BasicAlgorithm/img/20200906192249.png deleted file mode 100644 index 22b4175..0000000 Binary files a/BasicAlgorithm/img/20200906192249.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223130440.png b/BasicAlgorithm/img/20201223130440.png deleted file mode 100644 index 5bfaa76..0000000 Binary files a/BasicAlgorithm/img/20201223130440.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223130525.png b/BasicAlgorithm/img/20201223130525.png deleted file mode 100644 index 8074582..0000000 Binary files a/BasicAlgorithm/img/20201223130525.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223131020.png b/BasicAlgorithm/img/20201223131020.png deleted file mode 100644 index 2fd2a58..0000000 Binary files a/BasicAlgorithm/img/20201223131020.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223131344.png b/BasicAlgorithm/img/20201223131344.png deleted file mode 100644 index 6f004d0..0000000 Binary files a/BasicAlgorithm/img/20201223131344.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223131446.png b/BasicAlgorithm/img/20201223131446.png deleted file mode 100644 index 7e25651..0000000 Binary files a/BasicAlgorithm/img/20201223131446.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223131525.png b/BasicAlgorithm/img/20201223131525.png deleted file mode 100644 index 2343744..0000000 Binary files a/BasicAlgorithm/img/20201223131525.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223132028.png b/BasicAlgorithm/img/20201223132028.png deleted file mode 100644 index 7e741af..0000000 Binary files a/BasicAlgorithm/img/20201223132028.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223132145.png b/BasicAlgorithm/img/20201223132145.png deleted file mode 100644 index 41f6138..0000000 Binary files a/BasicAlgorithm/img/20201223132145.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223132445.png b/BasicAlgorithm/img/20201223132445.png deleted file mode 100644 index d6db901..0000000 Binary files a/BasicAlgorithm/img/20201223132445.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223132538.png b/BasicAlgorithm/img/20201223132538.png deleted file mode 100644 index bf7cf1b..0000000 Binary files a/BasicAlgorithm/img/20201223132538.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223135451.png b/BasicAlgorithm/img/20201223135451.png deleted file mode 100644 index 4fc276b..0000000 Binary files a/BasicAlgorithm/img/20201223135451.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223135552.png b/BasicAlgorithm/img/20201223135552.png deleted file mode 100644 index a66dd30..0000000 Binary files a/BasicAlgorithm/img/20201223135552.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223135720.png b/BasicAlgorithm/img/20201223135720.png deleted file mode 100644 index 2b7dc59..0000000 Binary files a/BasicAlgorithm/img/20201223135720.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223135807.png b/BasicAlgorithm/img/20201223135807.png deleted file mode 100644 index 5426781..0000000 Binary files a/BasicAlgorithm/img/20201223135807.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223135855.png b/BasicAlgorithm/img/20201223135855.png deleted file mode 100644 index cba1f27..0000000 Binary files a/BasicAlgorithm/img/20201223135855.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223140010.png b/BasicAlgorithm/img/20201223140010.png deleted file mode 100644 index 3098a3d..0000000 Binary files a/BasicAlgorithm/img/20201223140010.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223140135.png b/BasicAlgorithm/img/20201223140135.png deleted file mode 100644 index e026375..0000000 Binary files a/BasicAlgorithm/img/20201223140135.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223140211.png b/BasicAlgorithm/img/20201223140211.png deleted file mode 100644 index 00db714..0000000 Binary files a/BasicAlgorithm/img/20201223140211.png and /dev/null differ diff --git a/BasicAlgorithm/img/20201223140304.png b/BasicAlgorithm/img/20201223140304.png deleted file mode 100644 index 717df5b..0000000 Binary files a/BasicAlgorithm/img/20201223140304.png and /dev/null differ diff --git a/BasicAlgorithm/img/2021-01-06-16-16-19.png b/BasicAlgorithm/img/2021-01-06-16-16-19.png deleted file mode 100644 index 8572051..0000000 Binary files a/BasicAlgorithm/img/2021-01-06-16-16-19.png and /dev/null differ diff --git a/BasicAlgorithm/img/2021-01-06-16-16-50.png b/BasicAlgorithm/img/2021-01-06-16-16-50.png deleted file mode 100644 index 5befe41..0000000 Binary files a/BasicAlgorithm/img/2021-01-06-16-16-50.png and /dev/null differ diff --git a/BasicAlgorithm/img/2021-01-06-16-21-27.png b/BasicAlgorithm/img/2021-01-06-16-21-27.png deleted file mode 100644 index 0efa4bf..0000000 Binary files a/BasicAlgorithm/img/2021-01-06-16-21-27.png and /dev/null differ diff --git a/BasicAlgorithm/img/2021-01-06-16-22-53.png b/BasicAlgorithm/img/2021-01-06-16-22-53.png deleted file mode 100644 index 07eb893..0000000 Binary files a/BasicAlgorithm/img/2021-01-06-16-22-53.png and /dev/null differ diff --git a/BasicAlgorithm/img/2021-01-06-16-25-42.png b/BasicAlgorithm/img/2021-01-06-16-25-42.png deleted file mode 100644 index 0f8aff3..0000000 Binary files a/BasicAlgorithm/img/2021-01-06-16-25-42.png and /dev/null differ diff --git a/BasicAlgorithm/img/2021-01-06-16-29-17.png b/BasicAlgorithm/img/2021-01-06-16-29-17.png deleted file mode 100644 index 4db5a05..0000000 Binary files a/BasicAlgorithm/img/2021-01-06-16-29-17.png and /dev/null differ diff --git a/BasicAlgorithm/img/2021-01-06-16-30-53.png b/BasicAlgorithm/img/2021-01-06-16-30-53.png deleted file mode 100644 index 4c5026b..0000000 Binary files a/BasicAlgorithm/img/2021-01-06-16-30-53.png and /dev/null differ diff --git a/BasicAlgorithm/img/2021-01-06-16-37-37.png b/BasicAlgorithm/img/2021-01-06-16-37-37.png deleted file mode 100644 index 0c79822..0000000 Binary files a/BasicAlgorithm/img/2021-01-06-16-37-37.png and /dev/null differ diff --git "a/BasicAlgorithm/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" "b/BasicAlgorithm/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index 6a2c781..0000000 Binary files "a/BasicAlgorithm/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git a/BasicAlgorithm/img/BatchNormvsLayerNorm.png b/BasicAlgorithm/img/BatchNormvsLayerNorm.png deleted file mode 100644 index 611891e..0000000 Binary files a/BasicAlgorithm/img/BatchNormvsLayerNorm.png and /dev/null differ diff --git "a/BasicAlgorithm/img/BatchNorm\346\223\215\344\275\234.png" "b/BasicAlgorithm/img/BatchNorm\346\223\215\344\275\234.png" deleted file mode 100644 index 82245b5..0000000 Binary files "a/BasicAlgorithm/img/BatchNorm\346\223\215\344\275\234.png" and /dev/null differ diff --git a/BasicAlgorithm/img/CNN.png b/BasicAlgorithm/img/CNN.png deleted file mode 100644 index 2e96f24..0000000 Binary files a/BasicAlgorithm/img/CNN.png and /dev/null differ diff --git "a/BasicAlgorithm/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" "b/BasicAlgorithm/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index 882606b..0000000 Binary files "a/BasicAlgorithm/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git a/BasicAlgorithm/img/Normalization.png b/BasicAlgorithm/img/Normalization.png deleted file mode 100644 index bdda78e..0000000 Binary files a/BasicAlgorithm/img/Normalization.png and /dev/null differ diff --git a/BasicAlgorithm/img/batch_size.png b/BasicAlgorithm/img/batch_size.png deleted file mode 100644 index b43d656..0000000 Binary files a/BasicAlgorithm/img/batch_size.png and /dev/null differ diff --git a/BasicAlgorithm/img/cnn-dilation-in_7_out_3.gif b/BasicAlgorithm/img/cnn-dilation-in_7_out_3.gif deleted file mode 100644 index 98158a6..0000000 Binary files a/BasicAlgorithm/img/cnn-dilation-in_7_out_3.gif and /dev/null differ diff --git a/BasicAlgorithm/img/eec076b0b1aec804c74f1e9b726832a.jpg b/BasicAlgorithm/img/eec076b0b1aec804c74f1e9b726832a.jpg deleted file mode 100644 index 9d14672..0000000 Binary files a/BasicAlgorithm/img/eec076b0b1aec804c74f1e9b726832a.jpg and /dev/null differ diff --git a/BasicAlgorithm/img/pr16808o61q24973o42q7rsqq88os391.jpg b/BasicAlgorithm/img/pr16808o61q24973o42q7rsqq88os391.jpg deleted file mode 100644 index a6aa05e..0000000 Binary files a/BasicAlgorithm/img/pr16808o61q24973o42q7rsqq88os391.jpg and /dev/null differ diff --git "a/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" "b/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" deleted file mode 100644 index b126f64..0000000 Binary files "a/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" "b/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" deleted file mode 100644 index 354bb07..0000000 Binary files "a/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" and /dev/null differ diff --git "a/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" "b/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" deleted file mode 100644 index f4d8010..0000000 Binary files "a/BasicAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" and /dev/null differ diff --git "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" "b/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" deleted file mode 100644 index 1df5ee5..0000000 Binary files "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" "b/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" deleted file mode 100644 index a65a966..0000000 Binary files "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" "b/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" deleted file mode 100644 index 881b3e2..0000000 Binary files "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" "b/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" deleted file mode 100644 index 6c42db6..0000000 Binary files "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203230623.png" "b/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203230623.png" deleted file mode 100644 index afae5b5..0000000 Binary files "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203230623.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203231140.png" "b/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203231140.png" deleted file mode 100644 index 62b58e6..0000000 Binary files "a/BasicAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203231140.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" "b/BasicAlgorithm/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" deleted file mode 100644 index f7f5368..0000000 Binary files "a/BasicAlgorithm/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\346\255\243\345\210\231\345\214\226.png" "b/BasicAlgorithm/img/\346\255\243\345\210\231\345\214\226.png" deleted file mode 100644 index ff8a910..0000000 Binary files "a/BasicAlgorithm/img/\346\255\243\345\210\231\345\214\226.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" "b/BasicAlgorithm/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" deleted file mode 100644 index 0325d90..0000000 Binary files "a/BasicAlgorithm/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" "b/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" deleted file mode 100644 index 8505602..0000000 Binary files "a/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" "b/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" deleted file mode 100644 index 6e0246a..0000000 Binary files "a/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" "b/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" deleted file mode 100644 index da180da..0000000 Binary files "a/BasicAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" "b/BasicAlgorithm/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" deleted file mode 100644 index 201909f..0000000 Binary files "a/BasicAlgorithm/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" "b/BasicAlgorithm/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" deleted file mode 100644 index 923e9db..0000000 Binary files "a/BasicAlgorithm/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" and /dev/null differ diff --git "a/BasicAlgorithm/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" "b/BasicAlgorithm/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" deleted file mode 100644 index 8d1b1bb..0000000 Binary files "a/BasicAlgorithm/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" and /dev/null differ diff --git "a/BasicAlgorithm/\344\274\230\345\214\226\347\256\227\346\263\225\345\217\212\345\207\275\346\225\260.md" "b/BasicAlgorithm/\344\274\230\345\214\226\347\256\227\346\263\225\345\217\212\345\207\275\346\225\260.md" deleted file mode 100644 index 6834150..0000000 --- "a/BasicAlgorithm/\344\274\230\345\214\226\347\256\227\346\263\225\345\217\212\345\207\275\346\225\260.md" +++ /dev/null @@ -1,214 +0,0 @@ -# 【关于 优化算法】那些你不知道的事 - -![优化算法](img/优化算法.png) - -## 一、动机篇 - -### 1.1 为什么需要 优化函数? - -在机器学习算法中,通常存在很多问题并没有最优的解,或是要计算出最优的解要花费很大的计算量,面对这类问题一般的做法是利用迭代的思想尽可能的逼近问题的最优解。将解决此类优化问题的方法叫做优化算法,优化算法本质上是一种数学方法。 - -### 1.2 优化函数的基本框架是什么? - -- 基本框架:定义当前时刻待优化参数为$\theta_t\in R^{d}$,损失函数为$J(\theta)$,学习率为$\eta$,参数更新框架为: - -1. 计算损失函数关于当前参数的梯度:$g_t=\nabla J(\theta_t)$; -2. 根据历史梯度计算一阶动量(一次项)和二阶动量(二次项):$m_t=\phi(g_1,g_2,...,g_t),V_t=\psi(g_1,g_2,...,g_t)$; -3. 计算当前时刻的下降梯度:$\Delta\theta_t=-\eta\cdot\cfrac{m_t}{\sqrt{V_t}}$ -4. 根据下降梯度更新参数:$\theta_{t+1}=\theta_t+\Delta\theta_t$ - -## 二、优化函数介绍篇 - -### 2.1 梯度下降法是什么? - -每次使用一批数据进行梯度的计算,而非计算全部数据的梯度,因为如果每次计算全部数据的梯度,会导致运算量加大,运算时间变长,容易陷入局部最优解,而随机梯度下降可能每次不是朝着真正最小的方向,这样反而可以跳出局部的最优解。 - -### 2.2 随机梯度下降法是什么? - -- 介绍:由于SGD没有动量的概念,也即没有考虑历史梯度,所以当前时刻的动量即为当前时刻的梯度$m_t=g_t$,且二阶动量$V_t=E$,所以SGD的参数更新公式为 - - $$\Delta\theta_t=-\eta\cdot g_t$$ - - $$\theta_{t+1}=\theta_t-\eta\cdot g_t$$ - -- 优点:每次使用一批数据进行梯度的计算,而非计算全部数据的梯度,因为如果每次计算全部数据的梯度,会导致运算量加大,运算时间变长,容易陷入局部最优解,而随机梯度下降可能每次不是朝着真正最小的方向,这样反而可以跳出局部的最优解。 - -- 缺点:下降速度慢,而且可能会在沟壑(还有鞍点)的两边持续震荡,停留在一个局部最优点。 - -### 2.3 Momentum 是什么? - -- 介绍:为了抑制SGD的震荡,SGDM认为梯度下降过程可以加入惯性。下坡的时候,如果发现是陡坡,那就利用惯性跑的快一些。SGDM全称是SGD with momentum,在SGD基础上引入了一阶动量。而所谓的一阶动量就是该时刻梯度的指数加权移动平均值:$\eta\cdot m_t:=\beta\cdot m_{t-1}+\eta\cdot g_t$(其中当前时刻的梯度$g_t$并不严格按照指数加权移动平均值的定义采用权重$1-\beta$,而是使用我们自定义的学习率$\eta$),那么为什么要用移动平均而不用历史所有梯度的平均?因为移动平均存储量小,且能近似表示历史所有梯度的平均。由于此时仍然没有二阶动量,所以$V_t=E$,那么SGDM的参数更新公式为 - - $$\Delta\theta_t=-\eta\cdot m_t=-\left(\beta m_{t-1}+\eta g_t\right)$$ - - $$\theta_{t+1}=\theta_t-\left(\beta m_{t-1}+\eta g_t\right)$$ - -- 所以,当前时刻参数更新的方向不光取决于当前时刻的梯度,还取决于之前时刻的梯度,特别地,当$\beta=0.9$时,$m_t$近似表示的是前10个时刻梯度的指数加权移动平均值,而且离得越近的时刻的梯度权重也越大。 -- 优点:在随机梯度下降法的基础上,增加了动量(Momentum)的技术。其核心是通过优化相关方向的训练和弱化无关方向的振荡,来加速SGD训练。Momentum的方法能够在一定程度上缓解随机梯度下降法收敛不稳定的问题,并且有一定的摆脱陷入局部最优解的能力。 -- 缺点:对于比较深的沟壑有时用Momentum也没法跳出 - - - 指数加权移动平均值(exponentially weighted moving average,EWMA):假设$v_{t-1}$是$t-1$时刻的指数加权移动平均值,$\theta_t$是$t$时刻的观测值,那么$t$时刻的指数加权移动平均值为 - - $$ - \begin{aligned} - v_t&=\beta v_{t-1}+(1-\beta)\theta_t \\ - &=(1-\beta)\theta_t+\sum_{i=1}^{t-1}(1-\beta)\beta^i\theta_{t-i} - \end{aligned} - $$ - - > 其中$0 \leq \beta < 1,v_0=0$。显然,由上式可知,$t$时刻的指数加权移动平均值其实可以看做前$t$时刻所有观测值的加权平均值,除了第$t$时刻的观测值权重为$1-\beta$外,其他时刻的观测值权重为$(1-\beta)\beta^i$。由于通常对于那些权重小于$\frac{1}{e}$的观测值可以忽略不计,所以忽略掉那些观测值以后,上式就可以看做在求加权移动平均值。那么哪些项的权重会小于$\frac{1}{e}$呢?由于 - - $$\lim_{n \rightarrow +\infty} \left(1-\frac{1}{n}\right)^n = \frac{1}{e} \approx 0.3679$$ - - > 若令$n=\frac{1}{1-\beta}$,则 - - $$\lim_{n \rightarrow +\infty} \left(1-\frac{1}{n}\right)^n =\lim_{\beta \rightarrow 1} \left(\beta\right)^{\frac{1}{1-\beta}}=\frac{1}{e} \approx 0.3679$$ - - > 所以,当$\beta\rightarrow 1$时,那些$i\geq\frac{1}{1-\beta}$的$\theta_{t-i}$的权重$(1-\beta)\beta^i$一定小于$\frac{1}{e}$。代入计算可知,那些权重小于$\frac{1}{e}$的观测值就是近$\frac{1}{1-\beta}$个时刻之前的观测值。例如当$t=20,\beta=0.9$时,$\theta_1,\theta_2,..,\theta_9,\theta_{10}$的权重都是小于$\frac{1}{e}$的,因此可以忽略不计,那么此时就相当于在求$\theta_11,\theta_12,..,\theta_19,\theta_{20}$这最近10个时刻的加权移动平均值。所以指数移动平均值可以近似看做在求最近$\frac{1}{1-\beta}$个时刻的加权移动平均值,$\beta$常取$\geq 0.9$。由于当$t$较小时,指数加权移动平均值的偏差较大,所以通常会加上一个修正因子$1-\beta^t$,加了修正因子后的公式为 - - $$v_t=\cfrac{\beta v_{t-1}+(1-\beta)\theta_t}{1-\beta^t} \\$$ - - > 显然,当$t$很小时,修正因子$1-\beta^t$会起作用,当$t$足够大时$(1-\beta^t)\rightarrow 1$,修正因子会自动退场。 - -### 2.4 SGD with Nesterov Acceleration 是什么? - -- 介绍:除了利用惯性跳出局部沟壑以外,我们还可以尝试往前看一步。想象一下你走到一个盆地,四周都是略高的小山,你觉得没有下坡的方向,那就只能待在这里了。可是如果你爬上高地,就会发现外面的世界还很广阔。因此,我们不能停留在当前位置去观察未来的方向,而要向前一步、多看一步、看远一些。NAG全称Nesterov Accelerated Gradient,是在SGD、SGD-M的基础上的进一步改进,改进点在于当前时刻梯度的计算,我们知道在时刻t的主要下降方向是由累积动量决定的,自己的梯度方向说了也不算,那与其看当前梯度方向,不如先看看如果跟着累积动量走了一步,那个时候再怎么走。也即在Momentum的基础上将当前时刻的梯度$g_t$换成下一时刻的梯度$\nabla J(\theta_t-\beta m_{t-1})$,由于此时也没有考虑二阶动量,所以$V_t=E$,NAG的参数更新公式为 - - $$\Delta\theta_t=-\eta\cdot m_t=-\left(\beta m_{t-1}+\eta\nabla J(\theta_t-\beta m_{t-1})\right)$$ - - $$\theta_{t+1}=\theta_t-\left(\beta m_{t-1}+\eta\nabla J(\theta_t-\beta m_{t-1})\right)$$ - -- 优点:在Momentum的基础上进行了改进,比Momentum更具有前瞻性,除了利用历史梯度作为惯性来跳出局部最优的沟壑以外,还提前走一步看看能否直接跨过沟壑。 - -### 2.5 Adagrad 是什么? - -- 介绍:此前我们都没有用到二阶动量。二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来。SGD及其变种以同样的学习率更新每个维度的参数(因为$\theta_t$通常是向量),但深度神经网络往往包含大量的参数,这些参数并不是总会用得到(想想大规模的embedding)。对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。因此,AdaGrad则考虑对于不同维度的参数采用不同的学习率,具体的,对于那些更新幅度很大的参数,通常历史累计梯度的平方和会很大,相反的,对于那些更新幅度很小的参数,通常其累计历史梯度的平方和会很小(具体图示参见:https://zhuanlan.zhihu.com/p/29920135 )。所以在一个固定学习率的基础上除以历史累计梯度的平方和就能使得那些更新幅度很大的参数的学习率变小,同样也能使得那些更新幅度很小的参数学习率变大,所以AdaGrad的参数更新公式为 - - $$v_{t,i}=\sum_{t=1}^{t}g_{t,i}^2$$ - $$\Delta\theta_{t,i}=-\frac{\eta}{\sqrt{v_{t,i}+\epsilon}}g_{t,i}$$ - - $$\theta_{t+1,i}=\theta_{t,i}-\frac{\eta}{\sqrt{v_{t,i}+\epsilon}}g_{t,i}$$ - -> 其中$g_{t,i}^2$表示第$t$时刻第$i$维度参数的梯度值,$\epsilon$是防止分母等于0的平滑项(常取一个很小的值$1e-8$)。显然,此时上式中的$\frac{\eta}{\sqrt{v_{t,i}+\epsilon}}$这个整体可以看做是学习率,分母中的历史累计梯度值$v_{t,i}$越大的参数学习率越小。上式仅仅是第$t$时刻第$i$维度参数的更新公式,对于第$t$时刻的所有维度参数的整体更新公式为 - - $$V_{t}=\operatorname{diag}\left(v_{t,1},v_{t,2},...,v_{t,d}\right)\in R^{d\times d}$$ - - $$\Delta\theta_{t}=-\frac{\eta}{\sqrt{V_{t}+\epsilon}}\odot g_t$$ - - $$\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{V_{t}+\epsilon}}\odot g_t$$ - -> 注意,由于$V_t$是对角矩阵,所以上式中的$\epsilon$只用来平滑$V_t$对角线上的元素。 - -- 优点:Adagrad即adaptive gradient,是一种自适应学习率的梯度法。它通过记录并调整每次迭代过程中的前进方向和距离,使得针对不同问题都有一套自适应学习率的方法。Adagrad最大的优势是不需要手动来调整学习率,但与此同时会降低学习率。 -- 缺点:随着时间步的拉长,历史累计梯度平方和$v_{t,i}$会越来越大,这样会使得所有维度参数的学习率都不断减小(单调递减),无论更新幅度如何。而且,计算历史累计梯度平方和时需要存储所有历史梯度,而通常神经网络的参数不仅多维度还高,因此存储量巨大。 - -### 2.6 RMSProp/AdaDelta 是什么? - -- 介绍a:由于AdaGrad单调递减的学习率变化过于激进,我们考虑一个改变二阶动量计算方法的策略:不累积全部历史梯度,而只关注过去一段时间窗口的下降梯度,采用Momentum中的指数加权移动平均值的思路。这也就是AdaDelta名称中Delta的来历。首先看最简单直接版的RMSProp,RMSProp就是在AdaGrad的基础上将普通的历史累计梯度平方和换成历史累计梯度平方和的指数加权移动平均值,所以只需将AdaGrad中的$v_{t,i}$的公式改成指数加权移动平均值的形式即可,也即 - - $$v_{t,i}=\beta v_{t-1,i}+(1-\beta)g_{t,i}^2$$ - - $$V_{t}=\operatorname{diag}\left(v_{t,1},v_{t,2},...,v_{t,d}\right)\in R^{d\times d}$$ - - $$\Delta\theta_{t}=-\frac{\eta}{\sqrt{V_{t}+\epsilon}}\odot g_t$$ - - $$\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{V_{t}+\epsilon}}\odot g_t$$ - - 而AdaDelta除了对二阶动量计算指数加权移动平均以外,还对当前时刻的下降梯度$\Delta\theta_{t}$也计算一个指数加权移动平均,具体地 - - $$\operatorname{E}[\Delta\theta^2]_{t,i}=\gamma\operatorname{E}[\Delta\theta^2]_{t-1,i}+(1-\gamma)\Delta\theta^2_{t,i}$$ - - 由于$\Delta\theta^2_{t,i}$目前是未知的,所以只能用$t-1$时刻的指数加权移动平均来近似替换,也即 - - $$\operatorname{E}[\Delta\theta^2]_{t-1,i}=\gamma\operatorname{E}[\Delta\theta^2]_{t-2,i}+(1-\gamma)\Delta\theta^2_{t-1,i}$$ - - 除了计算出$t-1$时刻的指数加权移动平均以外,AdaDelta还用此值替换我们预先设置的学习率$\eta$,因此,AdaDelta的参数更新公式为 - - $$v_{t,i}=\beta v_{t-1,i}+(1-\beta)g_{t,i}^2$$ - - $$V_{t}=\operatorname{diag}\left(v_{t,1},v_{t,2},...,v_{t,d}\right)\in R^{d\times d}$$ - - $$\operatorname{E}[\Delta\theta^2]_{t-1,i}=\gamma\operatorname{E}[\Delta\theta^2]_{t-2,i}+(1-\gamma)\Delta\theta^2_{t-1,i}$$ - - $$\Theta_{t}=\operatorname{diag}\left(\operatorname{E}[\Delta\theta^2]_{t-1,1},\operatorname{E}[\Delta\theta^2]_{t-1,2},...,\operatorname{E}[\Delta\theta^2]_{t-1,d}\right)\in R^{d\times d}$$ - - $$\Delta\theta_{t}=-\frac{\sqrt{\Theta_{t}+\epsilon}}{\sqrt{V_{t}+\epsilon}}\odot g_t$$ - - $$\theta_{t+1}=\theta_{t}-\frac{\sqrt{\Theta_{t}+\epsilon}}{\sqrt{V_{t}+\epsilon}}\odot g_t$$ - -> 显然,对于AdaDelta算法来说,已经不需要我们自己预设学习率$\eta$了,只需要预设$\beta$和$\gamma$这两个指数加权移动平均值的衰减率即可。 -- 优点:和AdamGrad一样对不同维度的参数采用不同的学习率,同时还改进了AdamGrad的梯度不断累积和需要存储所有历史梯度的缺点(因为移动平均不需要存储所有历史梯度)。特别地,对于AdaDelta还废除了预设的学习率,当然效果好不好还是需要看实际场景。 - -### 2.7 Adam 是什么? - -- 介绍:Adam即Adaptive Moment Estimation,是能够自适应时刻的估计方法,能够针对每个参数,计算自适应学习率。这是一种综合性的优化方法,在机器学习实际训练中,往往能够取得不错的效果。 - -Adam=adagrad(用于处理稀疏的梯度)+RMSPro(处理非常态数据) - -- 流程: - -1. 首先计算一阶动量 - -$$m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t $$ - -2. 类似AdaDelta和RMSProp计算二阶动量 - -$$v_{t,i}=\beta_2 v_{t-1,i}+(1-\beta_2)g_{t,i}^2$$ - -$$V_{t}=\operatorname{diag}\left(v_{t,1},v_{t,2},...,v_{t,d}\right)\in R^{d\times d}$$ - -3. 分别加上指数加权移动平均值的修正因子 - -$$ -\begin{aligned} -\hat{m}_t &= \dfrac{m_t}{1 - \beta^t_1} \\ -\hat{v}_{t,i} &= \dfrac{v_{t,i}}{1 - \beta^t_2} \\ -\hat{V}_{t}&=\operatorname{diag}\left(\hat{v}_{t,1},\hat{v}_{t,2},...,\hat{v}_{t,d}\right)\in R^{d\times d} -\end{aligned} -$$ - -所以,Adam的参数更新公式为 - -$$\Delta\theta_{t}=-\frac{\eta}{\sqrt{\hat{V}_{t}+\epsilon}}\odot \hat{m}_t$$ - -$$\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{V}_{t}+\epsilon}}\odot \hat{m}_t$$ - -- 问题: - - 问题一、某些情况不收敛:由于Adam中的二阶动量非单调变化,导致Adam在训练后期容易出现学习率震荡,使得模型收敛不了【这也是为什么现在 SGD还被使用的原因】; - - 问题二、有可能错过全局最优解。由于后期Adam学习率太低,影响其收敛; - -### 2.8 Nadam 是什么? - -- 介绍:Adam只是将Momentum和Adaptive集成了,但是没有将Nesterov集成进来,而Nadam则是在Adam的基础上将Nesterov集成了进来,也即Nadam = Nesterov + Adam。具体思想如下:由于NAG 的核心在于,计算当前时刻的梯度$g_t$时使用了「未来梯度」$\nabla J(\theta_t-\beta m_{t-1})$。NAdam 提出了一种公式变形的思路,大意可以这样理解:只要能在梯度计算中考虑到「未来因素」,就算是达到了 Nesterov 的效果。既然如此,我们就不一定非要在计算$g_t$时使用「未来因素」,可以考虑在其他地方使用「未来因素」。具体地,首先NAdam在Adam的基础上将$\hat{m}_t$展开 - -$$ - \begin{aligned} - \theta_{t+1}&=\theta_{t}-\frac{\eta}{\sqrt{\hat{V}_{t}+\epsilon}}\odot \hat{m}_t \\ - &= \theta_{t} - \frac{\eta}{\sqrt{\hat{V}_{t}+\epsilon}} \odot(\frac{\beta_1 m_{t-1}}{1 - \beta^t_1} + \dfrac{(1 - \beta_1) g_t}{1 - \beta^t_1}) \\ - \end{aligned} -$$ - -此时,如果我们将第$t-1$时刻的动量$m_{t-1}$用第$t$时刻的动量$m_{t}$近似代替的话,那么我们就引入了「未来因素」,所以将$m_{t-1}$替换成$m_{t}$即可得到Nadam的表达式 - -$$ - \begin{aligned} - \theta_{t+1}&= \theta_{t} - \frac{\eta}{\sqrt{\hat{V}_{t}+\epsilon}} \odot(\frac{\beta_1 m_{t}}{1 - \beta^t_1} + \dfrac{(1 - \beta_1) g_t}{1 - \beta^t_1}) \\ - &= \theta_{t} - \frac{\eta}{\sqrt{\hat{V}_{t}+\epsilon}} \odot(\beta_1\hat{m}_t+ \dfrac{(1 - \beta_1) g_t}{1 - \beta^t_1}) - \end{aligned} -$$ - -## 三、优化函数学霸笔记篇 - -> 作者:言溪 - -![微信图片_20201224233945](img\优化算法手写笔记_1.jpg) - -![微信图片_20201224234032](img\优化算法手写笔记_2.jpg) - - -## 参考资料 - -1. [一个框架看懂优化算法之异同 SGD/AdaGrad/Adam](https://zhuanlan.zhihu.com/p/32230623) -2. [https://blog.csdn.net/u010089444/article/details/76725843](https://blog.csdn.net/u010089444/article/details/76725843) -3. [优化算法之指数移动加权平均](https://zhuanlan.zhihu.com/p/32335746) - diff --git "a/BasicAlgorithm/\345\210\244\345\210\253\345\274\217vs\347\224\237\346\210\220\345\274\217.md" "b/BasicAlgorithm/\345\210\244\345\210\253\345\274\217vs\347\224\237\346\210\220\345\274\217.md" deleted file mode 100644 index f614252..0000000 --- "a/BasicAlgorithm/\345\210\244\345\210\253\345\274\217vs\347\224\237\346\210\220\345\274\217.md" +++ /dev/null @@ -1,46 +0,0 @@ -# 【关于 判别式(discriminative)模型 vs. 生成式(generative)模型】 那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20210203231140.png) - - -## 一、判别式模型篇 - -### 1.1 什么是判别式模型? - -判别模型是直接对P(Y|X)建模,就是说,直接根据X特征来对Y建模训练。 - -### 1.2 判别式模型是思路是什么? - -1. 对P(Y|X)建模; -2. 对所有的样本只构建一个模型,确认总体判别边界; -3. 观测到输入什么特征,就预测最可能的label; - -### 1.3 判别式模型的优点是什么? - -对数据量要求没生成式的严格,速度也会快,小数据量下准确率也会好些。 - -## 二、生成式模型篇 - -### 2.1 什么是生成式模型? - -在模型训练中,我学习到的是X与Y的联合模型 P(X,Y) ,也就是说,我在训练阶段是只对 P(X,Y) 建模,我需要确定维护这个联合概率分布的所有的信息参数。完了之后在inference再对新的sample计算 P(Y|X) ,导出 Y,但这已经不属于建模阶段了。 - -### 2.2 生成式模型是思路是什么? - -1. 1.对 P(X,Y) 建模; -2. 这里我们主要讲分类问题,所以是要对每个label( yi)都需要建模,最终选择最优概率的label为结果,所以没有什么判别边界。(对于序列标注问题,那只需要构件一个model); -3. 中间生成联合分布,并可生成采样数据。 - -### 2.3 生成式模型的优点是什么? - -所包含的信息非常齐全,我称之为“上帝信息”,所以不仅可以用来输入label,还可以干其他的事情。生成式模型关注结果是如何产生的。 - -### 2.4 生成式模型的缺点是什么? - -但是生成式模型需要非常充足的数据量以保证采样到了数据本来的面目,所以速度相比之下较慢。 \ No newline at end of file diff --git "a/BasicAlgorithm/\345\275\222\344\270\200\345\214\226.md" "b/BasicAlgorithm/\345\275\222\344\270\200\345\214\226.md" deleted file mode 100644 index 165aafa..0000000 --- "a/BasicAlgorithm/\345\275\222\344\270\200\345\214\226.md" +++ /dev/null @@ -1,54 +0,0 @@ -# 【关于 归一化】那些你不知道的事 - -![](img/微信截图_20210203230623.png) - -## 一、动机篇 - -### 1.1 为什么要归一化? - -因为 每一列 数据的量纲不同,导致 数据分布区间存在差异。 -举例:(人的身高可以是 180cm,也可以是 1.8m,这两个虽然表示意义相同,但是由于单位的不同,导致 机器学习在计算过程中也容易出现差异,所以就需要对数据进行归一化)。 - -## 二、介绍篇 - -### 2.1 归一化有哪些方法? - -- 线性比例变换法: - -![](img/20200906192126.png) - -- 极差变换法: - -![](img/20200906192221.png) - -- 0 均值标准化(z-score 方法): - -![](img/20200906192249.png) - -### 2.2 归一化各方法特点? - -- 线性比例变换法 and 极差变换法 - - 特点:将原始数据线性化的方法转换到[0 1]的范围,该方法实现对原始数据的等比例缩放。通过利用变量取值的最大值和最小值(或者最大值)将原始数据转换为界于某一特定范围的数据,从而消除量纲和数量级影响,改变变量在分析中的权重来解决不同度量的问题。由于极值化方法在对变量无量纲化过程中仅仅与该变量的最大值和最小值这两个极端值有关,而与其他取值无关,这使得该方法在改变各变量权重时过分依赖两个极端取值。 -- 0 均值标准化(z-score 方法) - - 特点:即每一变量值与其平均值之差除以该变量的标准差。虽然该方法在无量纲化过程中利用了所有的数据信息,但是该方法在无量纲化后不仅使得转换后的各变量均值相同,且标准差也相同,即无量纲化的同时还消除了各变量在变异程度上的差异,从而转换后的各变量在聚类分析中的重要性程度是同等看待的。而实际分析中,经常根据各变量在不同单位间取值的差异程度大小来决定其在分析中的重要性程度,差异程度大的其分析权重也相对较大。 - -### 2.3 归一化 的 意义? - -每个维度都是去量纲化的,避免了不同量纲的选取对距离计算产生的巨大影响。 - -## 三、应用篇 - -### 3.1 哪些机器学习算法 需要做 归一化? - -- 机器学习算法算法: - - 基于距离计算的模型:KNN; - - 通过梯度下降法求解的模型:线性回归、逻辑回归、支持向量机、神经网络 - -### 3.2 哪些机器学习算法 不需要做 归一化? - -- 机器学习算法算法: - - 树形模型:决策树、随机森林(Random Forest) -- 为什么: - - 原因1:因为它们不关心变量的值,而是关心变量的分布和变量之间的条件概率; - - 原因2:因为数值缩放不影响分裂点位置,对树模型的结构不造成影响。按照特征值进行排序的,排序的顺序不变,那么所属的分支以及分裂点就不会有不同。而且,树模型是不能进行梯度下降的,因为构建树模型(回归树)寻找最优点时是通过寻找最优分裂点完成的,因此树模型是阶跃的,阶跃点是不可导的,并且求导没意义,也就不需要归一化。 - diff --git "a/BasicAlgorithm/\346\255\243\345\210\231\345\214\226.md" "b/BasicAlgorithm/\346\255\243\345\210\231\345\214\226.md" deleted file mode 100644 index 1f46043..0000000 --- "a/BasicAlgorithm/\346\255\243\345\210\231\345\214\226.md" +++ /dev/null @@ -1,178 +0,0 @@ -# 【关于 正则化】那些你不知道的事 - -![正则化](img/正则化.png) - -## 一、L0,L1,L2正则化 篇 - -### 1.1 正则化 是什么? - -我们所说的正则化,就是在原来的loss function的基础上,加上了一些正则化项或者称为模型复杂度惩罚项。 - -### 1.2 什么是 L0 正则化 ? - -- 介绍:指向量中非零元素的个数,希望参数中大部分元素为0,希望参数是稀疏的; - -- 公式:$\sum_{j=1, \theta_{j} \neq 0}^{m} \theta_{j}^{0}$ -- 直观理解:即将所有的非零项都作为1加起来,然后再用步长$\lambda$调节。意思很明显,每一个对预测产生了贡献的参数,我都惩罚一次,不多不少,大家都一样。 - -> 就像一个法官判决,你偷了一毛钱,他杀了一个人,法官均以“价值观不正确”为由,把你们判一样的罪……只有一点都没参与的人,才不会被判刑。 - -- 缺点:难以优化(存在NP难问题) - -### 1.3 什么是 L1 (稀疏规则算子 Lasso regularization)正则化 ? - -- 介绍:指向量中各元素绝对值之和,是 L0 正则项的最优凸近似; -- 公式: - -$\sum_{j=1}^{m}\left|\theta_{j}\right|$ - -- 直观理解:即将所有的绝对值值相加。 - -> 拿法官举例子,就是,法官要按照你们的罪行量刑判罪,但是都得判,无论你影响最终是好是坏(比如你杀了个人,这个人也是个坏人,但是你还是犯了杀人罪得判刑)都按照罪行判罪。于是就都取个绝对值,表示都判,然后按照罪行大小判罪了…… - -- 优点: - - 比 L0 容易优化求解,L0存在NP难问题,所以 使用 较多; - - L1范数是L0范数的最优凸近似; -- 参数稀疏 的 优点: - - 特征选择:通过将无用特征所对应的权重设为0,以去除无用特征; - - 可解释性:因为无用特征的权重对应权重都为0,所以只需要介绍权重不为 0 的特征; - -### 1.4 什么是 L2 正则化(岭回归 Ridge Regression 或者 权重衰减 Weight Decay)正则化 ? - -- 介绍:向量各元素的平方和然后求平方根,防止模型出现过拟合的问题 -- 公式: - -$\sum_{j=1}^{m} \theta_{j}^{2}$ - -- 直观理解:所有项目的平方和相加最后开根 -- 作用:防止过拟合问题 -- 优点: - - 防止过拟合,提升模型的泛化能力; - - 有助于处理 condition number 不好的情况下矩阵求逆很困难的问题。 - -## 二、对比篇 - -### 2.1 什么是结构风险最小化? - -在经验风险最小化的基础上(也就是训练误差最小化),尽可能采用简单的模型,以此提高泛化预测精度。 - -下面是一个图像解释(假设X为一个二维样本,那么要求解参数$w$也是二维): - -- 原函数曲线等高线(同颜色曲线上,每一组$w_1,w_2$带入值都相同) - -![image-20200326162459363](img/结构化风险最小化理解正则化_1.png) - - -### 2.2 从结构风险最小化的角度理解L1和L2正则化 - -- L1和L2加入后的函数图像: - - ![image-20200326162535758](img\结构化风险最小化理解正则化_2.png) - -从上面两幅图中我们可以看出: - -- 如果不加L1和L2正则化的时候,对于线性回归这种目标函数凸函数的话,我们最终的结果就是最里边的紫色的小圈圈等高线上的点。 - -- 当加入L1正则化的时候,我们先画出以下函数的图像: - - $$ - \left|\omega_{1}\right|+\left|\omega_{2}\right|=F - $$ - - 该图像也就是一个菱形,代表这些曲线上的点算出来的1范数 $\left|\omega_{1}\right|+\left|\omega_{2}\right|$ 都为F,那我们现在的目标是不仅是原曲线算得值要小(越来越接近中心的紫色圈圈),还要使得这个菱形越小越好(F越小越好)。那么还和原来一样的话,过中心紫色圈圈的那个菱形明显很大,因此我们要取到一个恰好的值。那么如何求值呢? - - ![image-20200326162832569](img\结构化风险最小化理解正则化_3.png) - - 1. 以同一条原曲线目标等高线来说,现在以最外圈的红色等高线为例,我们看到,对于红色曲线上的每个点都可以做一个菱形,根据上图可知,当这个菱形与某条等高线相切(仅有一个交点)的时候,这个菱形最小。用公式说这个时候能使得在相同的$1 / N * \sum_{i=1}^{N}\left(y_{i}-\omega^{T} x_{i}\right)^{2}$下,由于相切的时候的$C\|\omega\|_{1}$,即$\left|\omega_{1}\right|+\left|\omega_{2}\right|$小,所以:能够使得$1 / N * \sum_{i=1}^{N}\left(y_{i}-\omega^{T} x_{i}\right)^{2}+C\|\omega\|_{1}$更小。 - - 2. 有了上述说明,我们可以看出,最终加入L1范数得到的解,一定是某个菱形和某条原函数等高线的切点。现在有个比较重要的结论来了,**我们经过观察可以看到,几乎对于很多原函数等高曲线,和某个菱形相交的时候及其容易相交在坐标轴(比如上图),也就是说最终的结果,解的某些维度及其容易是0,比如上图最终解是** - $$ - \omega=(0, x) - $$ - **这也就是我们所说的L1更容易得到稀疏解(解向量中0比较多)的原因。** - - 3. 当然了,光看着图说,L1的菱形更容易和等高线相交在坐标轴,一点都没说服力,只是个感性的认识,不过不要紧,其实是很严谨的,我们直接用求导来证明,具体的证明这里有一个很好的答案了,简而言之就是假设现在我们是一维的情况下 - - $$ - h(\omega)=f(\omega)+C|\omega| - $$ - - 其中$ h(\omega) $是目标函数,$f(\omega)$是没加L1正则化的目标函数,$C|\omega|$是L1正则项,那么要使得0点成为最值的可能得点,,虽然在0点不可导,但是我们只需要让0点左右的导数异号,即 - - $$ - h_{\mathrm{左}}^{\prime}(0) * h_{\mathrm{右}}^{\prime}(0)=\left(f^{\prime}(0)+C\right) \quad\left(f^{\prime}(0)-C\right)<0 - $$ - - 也就是$C>\left|f^{\prime}(0)\right|$的情况下,0点都是可能得最值点。 - -- 当加入L2正则化的时候,分析和L1正则化是类似的,也就是说我们仅仅是从菱形变成了圆形而已,同样还是求原曲线和圆形的切点作为最终解。当然与L1范数比,我们这样求的L2范数的**从图上来看,不容易交在坐标轴上,但是仍然比较靠近坐标轴**。**因此这也就是我们老说的,L2范数能让解比较小(靠近0),但是比较平滑(不等于0)。** - -综上所述,我们可以看见,加入正则化项,在最小化经验误差的情况下,可以让我们选择解更简单(趋向于0)的解。 - -### 2.3 L1 vs L2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
L1L2
目标绝对值最小化平方值最小化
下降速度以绝对值函数方式下降,较快以二次函数函数方式下降,较慢
规则化的代价函数图 1 图 2
最优解是 w1 和 w2 的取值L1在和每个坐标轴相交的地方都有“角”出现,而目标函数的测地线除非位置摆得非常好,大部分时候都会在角的地方相交。注意到在角的位置就会产生稀疏性,例如图中的相交点就有w1=0,而更高维的时候(想象一下三维的L1-ball 是什么样的?)除了角点以外,还有很多边的轮廓也是既有很大的概率成为第一次相交的地方,又会产生稀疏性 因为没有角,所以第一次相交的地方出现在具有稀疏性的位置的概率就变得非常小了。这就从直观上来解释了为什么L1-regularization 能产生稀疏性,而L2-regularization 不行的原因了
总结L1 会趋向于产生少量的特征,而其他的特征都是0 L2 会选择更多的特征,这些特征都会接近于0
特点Lasso在特征选择时候非常有用 Ridge就只是一种规则化而已
使用选择方面特征多,但是其作用的特征少的情况【自动选择特征】 特征中起作用的特征多的情况
分布类型拉普拉斯分布 高斯分布
- -## 三、dropout 篇 - -### 3.1 什么是 dropout? - -- 方式:通过以概率p主动临时性地忽略掉神经网站中的部分隐藏节点来防止过拟合,即让这些神经元以一定概率不工作; - -![](img/20200812203815.png) - -### 3.2 dropout 在训练和测试过程中如何操作? - -- 训练过程:在**训练**开始时,随机删除一些隐藏层神经元,即认为这些神经元不存在,同时保持输入层与输出层的神经元个数不变,按照反向传播学习算法对神经网络中的参数进行学习更新(被删除的节点不参与更新)。在这个“残缺”的网络中,让神经网络学习数据中的局部特征(即部分分布式特征)。在多个“残缺”之网(相当于多个简单网络)中实施特征,总要比仅在单个健全网络上进行特征学习,其泛化能力来得更加健壮。这里的“泛化”,实际上就是适应各种情况的能力。如果神经网络仅仅在训练集合上表现好(好比“窝里横”),而在应对其他新情况表现不佳,就表明陷入“过拟合”状态,其实就是泛化能力差。 -- 在**测试**阶段,将参与学习的节点和那些被隐藏的节点以一定的概率p加权求和,综合计算得到网络的输出。对于这样的“分分合合”的学习过程,有学者认为,“丢弃学习”可视为一种集成学习(Ensemble Learning)。 - -### 3.3 dropout 如何防止过拟合? - -1. 先回到正常的模型(没有dropout),我们用相同的训练数据去训练5个不同的神经网络,一般会得到5个不同的结果,此时我们可以采用 “5个结果取均值”或者“多数取胜的投票策略”去决定最终结果。(例如 3个网络判断结果为数字9,那么很有可能真正的结果就是数字9,其它两个网络给出了错误结果)。这种“综合起来取平均”的策略通常可以有效防止过拟合问题。因为不同的网络可能产生不同的过拟合,取平均则有可能让一些“相反的”拟合互相抵消。dropout掉不同的隐藏神经元就类似在训练不同的网络(随机删掉一半隐藏神经元导致网络结构已经不同),整个dropout过程就相当于 对很多个不同的神经网络取平均。而不同的网络产生不同的过拟合,一些互为“反向”的拟合相互抵消就可以达到整体上减少过拟合。 -2. dropout减少神经元之间复杂的共适应关系:因为dropout程序导致两个神经元不一定每次都在一个dropout网络中出现。(这样权值的更新不再依赖于有固定关系的隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况)。迫使网络去学习更加鲁棒的特征 (这些特征在其它的神经元的随机子集中也存在)。换句话说假如我们的神经网络是在做出某种预测,它不应该对一些特定的线索片段太过敏感,即使丢失特定的线索,它也应该可以从众多其它线索中学习一些共同的模式,提升模型鲁棒性,从这个角度看 dropout就有点像L1,L2正则,减少权重使得网络对丢失特定神经元连接的鲁棒性提高) \ No newline at end of file diff --git "a/BasicAlgorithm/\346\277\200\346\264\273\345\207\275\346\225\260.md" "b/BasicAlgorithm/\346\277\200\346\264\273\345\207\275\346\225\260.md" deleted file mode 100644 index 460953f..0000000 --- "a/BasicAlgorithm/\346\277\200\346\264\273\345\207\275\346\225\260.md" +++ /dev/null @@ -1,91 +0,0 @@ -# 【关于 激活函数】那些你不知道的事 - -![](img/激活函数.png) - -## 一、动机篇 - -### 1.1 为什么要有激活函数? - -1. 数据角度:由于数据是线性不可分的,如果采用线性化,那么需要复杂的线性组合去逼近问题,因此需要非线性变换对数据分布进行重新映射; -2. 线性模型的表达力问题:由于线性模型的表达能力不够,引入激活函数添加非线性因素 - -## 二、激活函数介绍篇 - -### 2.1 sigmoid 函数篇 - -#### 2.1.1 什么是 sigmoid 函数? - -- 公式 - -$$\sigma(x)=\frac {1}{1+e^{-x}}$$ - -- 图像 - -![](img/微信截图_20201228220004.png) - -#### 2.1.2 为什么选 sigmoid 函数 作为激活函数? - -sigmoid 函数 能够把输入的连续实值变换为0和1之间的输出,特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1. - -#### 2.1.3 sigmoid 函数 有什么缺点? - -1. 如果我们初始化神经网络的权值为[0,1]之间的随机数,由反向传播算法的数学推导可以知道,梯度从后向前传播时,每传递一层梯度值都会下降为原来原来的0.25倍,如果神经网络层比较多是时,那么梯度会穿过多层之后变得接近于0,也就出现梯度消失问题,当权值初始化为 [1,+]期间内的值时,则会出现梯度爆炸问题; - -![](img/微信截图_20201228220429.png) - -2. output 不是0均值(即zero-centered); - 1. 后果:会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。 产生的一个结果就是:x>0, f=wTx+b那么对w求局部梯度则都为正,这样在反向传播的过程中w要么都往正方向更新,要么都往负方向更新,导致有一种捆绑的效果; -3. 幂函数耗时; - -### 2.2 tanh 函数篇 - -#### 2.2.1 什么是 tanh 函数? - -- 公式: - -$$tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}$$ - -- 图像 - -![](img/微信截图_20201228220549.png) - -#### 2.2.2 为什么选 tanh 函数 作为激活函数? - -tanh 函数 能够 解决 sigmoid 函数 非 0 均值 问题 - -#### 2.2.3 tanh 函数 有什么缺点? - -1. 梯度爆炸和梯度消失; -2. 幂函数耗时; - -### 2.3 relu 函数篇 - -#### 2.3.1 什么是 relu 函数? - -- 公式 - -$$f(x)=max(0, x)$$ - -- 图像 - -![](img/微信截图_20201228220848.png) - -#### 2.3.2 为什么选 relu 函数 作为激活函数? - -1. 解决了gradient vanishing问题 (在正区间) -2. 计算速度非常快,只需要判断输入是否大于0 -3. 收敛速度远快于sigmoid和tanh - -#### 2.3.3 relu 函数 有什么缺点? - -1. ReLU的输出不是zero-centered; -2. Dead ReLU Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新; - -## 三、激活函数选择篇 - -1. 深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以,总体上来讲,训练深度学习网络尽量使用zero-centered数据 (可以经过数据预处理实现) 和zero-centered输出。所以要尽量选择输出具有zero-centered特点的激活函数以加快模型的收敛速度; -2. 如果使用 ReLU,那么一定要小心设置 learning rate,而且要注意不要让网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU、PReLU 或者 Maxout; -3. 最好不要用 sigmoid,你可以试试 tanh,不过可以预期它的效果会比不上 ReLU 和 Maxout. - - - diff --git "a/BasicAlgorithm/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.md" "b/BasicAlgorithm/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.md" deleted file mode 100644 index f55f64c..0000000 --- "a/BasicAlgorithm/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.md" +++ /dev/null @@ -1,59 +0,0 @@ -# 【关于 过拟合和欠拟合】那些你不知道的事 - -![过拟合欠拟合脑图](img/过拟合和欠拟合.png) - -## 一、过拟合和欠拟合 是什么? - -![eec076b0b1aec804c74f1e9b726832a.jpg](img/eec076b0b1aec804c74f1e9b726832a.jpg) - -欠拟合和过拟合属于对立情况,都是导致模型泛化能力不高的两种常见原因,均是模型学习能力和数据复杂性失调的表现 - -## 二、过拟合/高方差(overfiting / high variance)篇 - -### 2.1 过拟合是什么及检验方法? - -- 问题表现方式:高方差 - - 如果 训练集 和 测试集 的 误差间 呈现较大的差异时,即为高方差; - - 在 高方差 时,训练集 训练效果很好, 但是 验证集 的验证效果很差的时候, 即 训练集 和 验证集 呈现出 较大的差异,即模型的泛化能力差。这种现象 称为 过拟合; -- 检验方法:此时,观察模型在训练集和测试集上的损失函数值随着epoch的变化情况,当 模型 在 测试集 上的 损失函数值 出现 先下降后上升,那么此时可能出现过拟合。 - -### 2.2 导致过拟合的原因是什么? - -1. 训练集数量不足,样本类型单一。例如:如果 我们 利用 只包含 负样本的训练集 训练 模型,然后利用训练好的模型 预测 验证集中 的 正样本时,此时就会出现,模型 在 训练的时候,效果特别好,但是在验证的时候效果下降问题。因此,在选取训练集时,应当覆盖所有的数据类型; -2. 训练集中存在噪声。噪声指的是 训练数据中 的 干扰数据,噪声数据 会 误导模型 记录 较多 的 错误特征,而 忽略了 真实样本 中 的正确特征信息; -3. 模型复杂度过高。当模型过于复杂时,会导致 模型 **过于充分** 的 学习到 训练数据集中特征信息,但是遇到没有见过的数据的时候不能够变通,泛化能力太差。我们希望模型对不同的数据都有稳定的输出。模型太复杂是过拟合的重要因素。 - -### 2.3 过拟合的解决方法是什么? - -1. 标注不同类型的样本,是 样本尽可能的均衡。数据经过清洗之后再进行模型训练,防止噪声数据干扰模型; -2. 降低训练模型复杂度。在训练和建立模型的时候,从相对简单的模型开始,不要一开始就把特征做的非常多,模型参数挑的非常复杂; -3. 正则化。在模型算法中添加惩罚函数来防止模型出现过拟合问题。常见的有L1,L2,dropout 正则化等。而且 L1正则还可以自动进行特征选择; -4. 采用 bagging(如随机森林等)集成学习方法 来 防止过拟合; -5. 减少特征个数(不是太推荐,但也是一种方法)。可以使用特征选择,减少特征数或使用较少的特征组合,对于按区间离散化的特征,增大划分的区间; -6. 交叉检验。利用 交叉检验的方法,来让模型得到充分的训练,以得到较优的模型参数; -7. 早停策略。本质上是交叉验证策略,选择合适的训练次数,避免训练的网络过度拟合训练数据; -8. DropOut策略。核心思想就是bagging,可以看作是低成本的集成学习。所谓的Dropout指的是在用前向传播算法和反向传播算法训练DNN模型时,一批数据迭代时,随机的从全连接DNN网络中去掉一部分隐藏层的神经元。 在对训练集中的一批数据进行训练时,我们随机去掉一部分隐藏层的神经元,并用去掉隐藏层的神经元的网络来拟合我们的一批训练数据。使用基于dropout的正则化比基于bagging的正则化简单,这显而易见,当然天下没有免费的午餐,由于dropout会将原始数据分批迭代,因此原始数据集最好较大,否则模型可能会欠拟合。 - -## 三、欠拟合/高偏差(underfiting / high bias)篇 - -### 3.1 欠拟合是什么及检验方法? - -- 问题表现:高偏差 - - 如果 训练集 和 测试集 的 误差 收敛 但是收敛值 很高时,即为高偏差; - - 虽然 训练集 和 测试集 都可以收敛,但是偏差很高,训练集和验证集的准确率都很低,这种现象 称为 欠拟合; -- 检验方法:模型 无法很好的拟合数据,导致 训练集和测试集效果都不佳。 - -### 3.2 导致欠拟合的原因是什么? - -- 原因:模型没有 充分 学习到 数据中的特征信息,使得 模型 无法很好地拟合数据 - -### 3.3 欠拟合的解决方法是什么? - -1. 特征工程。添加更多的特征项,eg:特征组合、高次特征 等,来增大假设空间; -2. 集成学习方法。 boosting(如GBDT)能有效解决 high bias; -3. 提高 模型复杂度。当 所采用的模型比较简单,不能够应对复杂的任务。可以考虑 提升 模型复杂度,选用复杂度更好、学习能力更强的模型。比如说可以使用 SVM 的核函数,增加了模型复杂度,把低维不可分的数据映射到高维空间,就可以线性可分,减小欠拟合; -4. 减小正则化系数。 - -## 参考资料 - -1. [为什么PCA不被推荐用来避免过拟合?](https://www.zhihu.com/question/47121788) diff --git "a/DeepLearningAlgorithm/adversarial_training_study/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200805232522.png" "b/DeepLearningAlgorithm/adversarial_training_study/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200805232522.png" deleted file mode 100644 index 88379fc..0000000 Binary files "a/DeepLearningAlgorithm/adversarial_training_study/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200805232522.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/adversarial_training_study/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203235123.png" "b/DeepLearningAlgorithm/adversarial_training_study/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203235123.png" deleted file mode 100644 index e5ba48e..0000000 Binary files "a/DeepLearningAlgorithm/adversarial_training_study/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203235123.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/adversarial_training_study/readme.md b/DeepLearningAlgorithm/adversarial_training_study/readme.md deleted file mode 100644 index 823957b..0000000 --- a/DeepLearningAlgorithm/adversarial_training_study/readme.md +++ /dev/null @@ -1,148 +0,0 @@ -# 【关于生成对抗网络GAN】那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20210203235123.png) - -## 一、动机 - -之前我们提到[玻尔兹曼机(Boltzmann machine)](https://note.wiz.cn/web?dc=677f1e8f-ec8c-43eb-b0dc-fd5a17721384&cmd=kw%2C&kb=cc2cc09f-709e-444d-ab2f-da6218b57dd2),波尔茨曼机作为一种基于能量函数的概率模型,因为能量函数比较复杂,所以存在较多的限制。虽然受限玻尔兹曼机(Restricted Boltzmann machine) 针对该问题,对能量函数进行进一步简化,即假设网络中仅有隐藏变量与观察变量的连接,而观察变量将没有连接,隐藏变量间也没有连接,且隐藏变量可用 $n_h$ 个二进制随机变量表示,但是仍然存在限制问题。同时,该过程应用了马尔科夫链,导致计算成本较高。针对上述问题,Ian Goodfellow 于 2014 年提出了[生成对抗网络(Generative Adversarial Network,GAN)模型](https://link.zhihu.com/?target=https%3A//arxiv.org/pdf/1406.2661.pdf),GAN 作为一类在无监督学习中使用的神经网络,有效地避免了马尔科夫链以及减低了波尔茨曼机所存在的限制问题,以至于在按文本生成图像、提高图片分辨率、药物匹配、检索特定模式的图片等任务中 GAN 的研究如火如荼。大牛Yann LeCun甚至评价GAN为 “adversarial training is the coolest thing since sliced bread”。 - -本文将通过一个简单的例子(发论文问题)向读者深入浅出的介绍 GAN 原理及其应用。 - -## 二、介绍篇 - -### 2.1 GAN 的基本思想 - -作为生成模型中的一种,生成对抗网络(Generative Adversarial Network,GAN)模型的训练过程可以被视为两个网络互相博弈的过程。下面我们将举一个简单的例子解释 GAN 的基本思想。 - -> 假设你是一门研究生,你想尽快地将实验结果写成一篇论文发表。 -> 于是在每一次做完实验并写完初稿之后,都会跟你的导师进行沟通: -> -> 你:boss,我实验结果出来,我想发论文 -> -> 导师:(瞄了瞄你的实验结果之后) ... 算了吧 -> -> (你通过跟其他论文的实验结果进行比较,发现自己的实验结果还偏低,于是,你又调整了实验参数,重新进行实验) -> -> 你:boss,我实验结果提高了,我想发论文 -> -> 导师:... (瞄了瞄你的论文初稿之后)嗯 还有所欠缺 -> -> (你通过跟其他论文进行比较,发现自己写的论文初稿在表达方面还有所不足) -> -> ... -> -> 你:boss,我想发论文 -> -> 导师:... (仔细看了看你的论文之后)嗯 可以试一试 -> -> (通过这样不断的修改和被拒绝,你的论文最终获得了导师的赞赏与肯定) - -通过上面的例子,大家应该对 GAN 的思想有一个比较感性的认识了吧,下面我们可以进一步对 GAN 的基本结构和思想进行介绍。 - -### 2.2 GAN 基本介绍 - -#### 2.2.1 GAN 的基本结构 - -GAN 的主要结构包括一个生成器 G(Generator)和一个判别器 D(Discriminator)。 - -在上面的例子中,研究生相对于生成器。在一开始的时候,他只是一个什么都不懂的初学者,为了能让该研究生发出好的 paper,需要给他裴蓓一个导师来指导他做实验写论文,并告诉他 paper 面前的质量,通过反复的修改和被拒绝,paper 最终达到了可以投稿的标准,而这个导师就相当于生成对抗网络 GAN 中的判别器。 - -#### 2.2.2 GAN 的基本思想 - -生成对抗网络 GAN 主要包含两个模块:生成器 G(Generator)和一个判别器 D(Discriminator)。生成对抗网络 GAN 中所描述的对抗,其实就是指生成网络与判别网络之间的相互对抗。以下图为例: - -![](img/微信截图_20200805232522.png) - -生成器模型(上图中蓝色部分 Generator)的主要工作就是学习真实图片集数据,从而使自己生成的图片更加接近与真实图片,以到达“以假乱真”,也就是“欺骗”判别器。 - -判别器模型(上图中红色部分 Discriminator)的主要工作就是从图片集中找出生成器所生成的图片,并区分该图片与真实图片的差异,以进行真假判别。 - -在整个迭代过程中,生成器不断的生成越来越逼真的图片,而判别器不断额努力鉴别出图片的真假。该过程可以视为两个网络互相博弈的过程,随着迭代次数的增加,最终两者将会趋于平衡,也就是说生成器能够生成出和真实图片一模一样的的图片,而判别器已经很难从图片集中辨别出生成器所生成的假图片了。也就是说,对于图片集中的每一张图片,判别器都给出接近 0.5 的概率认为该图片是真实的。 - -## 三、训练篇 - -### 3.1 生成器介绍 - -生成器模型的任务:首先需要将一个 $n$ 维向量输入生成器模型,然后输出一个图片像素大小的图片(这里,生成器模型可以是任意可以输出图片的模型,如全连接神经网络,反卷积神经网络等)。 - -> 注:输入向量:携带输出的某些信息,这些信息可以是手写数字为数字几,手写的潦草程度等。由于这里我们对于输出数字的具体信息不做要求,只要求其能够最大程度与真实手写数字相似(能骗过判别器)即可。所以我们使用随机生成的向量来作为输入即可,这里面的随机输入最好是满足常见分布比如均值分布,高斯分布等。 - -### 3.2 判别器介绍 - -判别器模型的任务:主要能够辨别输入的图片的真假都可以作为判别器。 - -### 3.3 训练过程 - -前面分别介绍了生成器和判别器的任务,在这一节,我们将主要介绍生成对抗网络的训练过程,其基本流程如下: - -step 1: 初始化:对判别器 D 的参数 $\theta_d$ 和生成器 G 的参数 $\theta_g$; - -step 2: 生成器“伪造”生成样本:首先,从真实样本中采样 $m$ 个样本 $\left\{x^1, x^2, \ldots x^m\right\}$;然后,从先验分布噪声中采样 $m$ 个噪声样本 ${z^1, z^2, \ldots, z^m}$;接下去,利用生成器“伪造” $m$ 个新样本 $\left\{\tilde{\boldsymbol{x}}^1, \tilde{\boldsymbol{x}}^2, \ldots, \tilde{\boldsymbol{x}}^m\right\}$;最后,固定生成器 G。 - -step 3:判别器“鉴别”生成样本:通过对判别器 D 进行训练,以让它尽可能准确的“鉴别”出生成样本。 - -step 4: “欺骗”判别器:循环更新判别器 k 次之后,再利用较小的学习率来更新一次生成器的参数。使得判别器已经很难从样本集中辨别出生成器所生成的生成样本了。也就是说,对于样本集中的每一个样本,判别器都给出接近 0.5 的概率认为该样本是真实的。 - -> 注:为什么是先训练判别器再训练生成器呢? -> -> 以上面的导师和学生的例子吧,学生(生成器)要写出一篇好的 paper (生成样本),那么就需要有一个能够较好的区分好 paper (真实样本)和坏 paper (生成样本)的好导师(判别器)之后,才能指导学生(生成器)如何对 paper (生成样本)进行优化。 - -### 3.4 训练所涉及相关理论基础 - -前面已经对生成对抗网络进行介绍,接下去,我们将从理论基础方面介绍生成对抗网络的训练过程。 - -首先,需要从优化目标函数开始介绍,其表达式如下所示: - -$$ -\min _{G} \max _D V(G, D)=\min _G \max _D \mathbb{E}_{x \sim p_{\text { data }}}[\log D(x)]+\mathbb{E}_{z \sim p_z}[\log (1-D(G(z))] -$$ - -对于判别式而言,其主要用于区别样本的真伪,所以可以视为是一个二分类问题,上式中所使用的 $V(G, D)$为二分类问题中常见的交叉熵损失。公式如下所示: - -$$ -H(p, q) :=-\sum_i p_i \log q_i -$$ - -> $p_i$ 和 $q_i$ 为真实的样本分布和生成器的生成分布。 - -对于生成器 G 而言,为了尽可能欺骗 D,所以需要最大化生成样本的判别概率 $D(G(z))$,即最小化 $log(1-D(G(z)))$。 - -> 注意:$log(D(x))$ 一项与生成器 G 无关,所以可以忽略。 - - -实际训练过程中,生成器和判别器采用交替训练的方式进行。因为对于生成器,其最小化为 $\max _{D} V(D, G)$,即最小化 $ V(D, G) $的最大值。所以为了保证 $ V(D, G) $ 取得最大值,需要对判别器迭代训练 $k$ 次,然后再训练一次生成器。 - -当生成器 G 固定时,我们可以对 $V(D,G)$ 求导,求出最优判别器 $D*(x)$: - -$$ -D^{*}(x)=\frac{p_{g}(x)}{p_{g}(x)+p_{d a t a}(x)} -$$ - -把最优判别器代入上述目标函数,可以进一步求出在最优判别器下,生成器的目标函数等价于优化 $p_{d a t a}(x)$ , $p_{g}(x)$ 的 JS 散度(JSD, Jenson Shannon Divergence)。 - -可以证明,当 G,D 二者的 capacity 足够时,模型会收敛,二者将达到纳什均衡。此时,$p_{d a t a}(x)$= $p_{g}(x)$,判别器不论是对于 $p_{d a t a}(x)$ 还是 $p_{g}(x)$ 中采样的样本,其预测概率均为 1/2,即生成样本与真实样本达到了难以区分的地步。 - - -通过上述min max的博弈过程,理想情况下会收敛于生成分布拟合于真实分布。 - - -## 四、总结 - -本文首先,通过以一个学生发 paper 的 example 的方式引入了生成对抗网络;然后,并进一步介绍了生成对抗网络的框架和思想,中生成器和判别器;最后,通过介绍生成对抗网络的训练过程,以引入生成对抗网络的训练公式。 - - -## 参考资料 - -1. [通俗理解生成对抗网络GAN](https://zhuanlan.zhihu.com/p/33752313) -2. [白话生成对抗网络 GAN,50 行代码玩转 GAN 模型!【附源码】](https://juejin.im/post/5b5694c5e51d4534b8582b56) -3. [万字综述之生成对抗网络(GAN)](https://juejin.im/entry/5c92f8f7f265da60ea145dc8) -4. [生成对抗网络原理与应用:GAN如何使生活更美好](https://www.jiqizhixin.com/articles/2017-08-23-6) -5. [玻尔兹曼机、生成随机网络与自回归网络——深度学习第二十章(二)](https://zhuanlan.zhihu.com/p/50745191) -6. [生成对抗网络(GAN)相比传统训练方法有什么优势?](https://www.zhihu.com/question/56171002) -7. [火热的生成对抗网络(GAN),你究竟好在哪里](https://bigquant.com/community/t/topic/127988) diff --git a/DeepLearningAlgorithm/attention/img/20200916164600.png b/DeepLearningAlgorithm/attention/img/20200916164600.png deleted file mode 100644 index 8e7090c..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916164600.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916170948.png b/DeepLearningAlgorithm/attention/img/20200916170948.png deleted file mode 100644 index d361ddf..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916170948.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916171345.png b/DeepLearningAlgorithm/attention/img/20200916171345.png deleted file mode 100644 index 5524d3e..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916171345.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916171708.png b/DeepLearningAlgorithm/attention/img/20200916171708.png deleted file mode 100644 index 1ed6470..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916171708.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916172001.png b/DeepLearningAlgorithm/attention/img/20200916172001.png deleted file mode 100644 index 51829bd..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916172001.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916172200.png b/DeepLearningAlgorithm/attention/img/20200916172200.png deleted file mode 100644 index 7b33c28..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916172200.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916172542.png b/DeepLearningAlgorithm/attention/img/20200916172542.png deleted file mode 100644 index a509150..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916172542.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916172726.png b/DeepLearningAlgorithm/attention/img/20200916172726.png deleted file mode 100644 index d0504a6..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916172726.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916172920.png b/DeepLearningAlgorithm/attention/img/20200916172920.png deleted file mode 100644 index b9f81bf..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916172920.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916182920.png b/DeepLearningAlgorithm/attention/img/20200916182920.png deleted file mode 100644 index 87d9a5d..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916182920.png and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/img/20200916183221.png b/DeepLearningAlgorithm/attention/img/20200916183221.png deleted file mode 100644 index 1a3bbc6..0000000 Binary files a/DeepLearningAlgorithm/attention/img/20200916183221.png and /dev/null differ diff --git "a/DeepLearningAlgorithm/attention/img/\344\270\213\350\275\275.jfif" "b/DeepLearningAlgorithm/attention/img/\344\270\213\350\275\275.jfif" deleted file mode 100644 index 3c4c361..0000000 Binary files "a/DeepLearningAlgorithm/attention/img/\344\270\213\350\275\275.jfif" and /dev/null differ diff --git "a/DeepLearningAlgorithm/attention/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203234353.png" "b/DeepLearningAlgorithm/attention/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203234353.png" deleted file mode 100644 index 53625a1..0000000 Binary files "a/DeepLearningAlgorithm/attention/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203234353.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/attention/readme.md b/DeepLearningAlgorithm/attention/readme.md deleted file mode 100644 index 410cc32..0000000 --- a/DeepLearningAlgorithm/attention/readme.md +++ /dev/null @@ -1,162 +0,0 @@ -# 【关于 Attention 】那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20210203234353.png) - -## 一、seq2seq 篇 - -### 1.1 seq2seq (Encoder-Decoder)是什么? - -- 介绍:seq2seq (Encoder-Decoder)将一个句子(图片)利用一个 Encoder 编码为一个 context,然后在利用一个 Decoder 将 context 解码为 另一个句子(图片)的过程 ; -- 应用: - - 在 Image Caption 的应用中 Encoder-Decoder 就是 CNN-RNN 的编码 - 解码框架; - - 在神经网络机器翻译中 Encoder-Decoder 往往就是 LSTM-LSTM 的编码 - 解码框架,在机器翻译中也被叫做 [Sequence to Sequence learning](https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf)。 - -![seq2seq](img/20200916164600.png) - -### 1.2 seq2seq 中 的 Encoder 怎么样? - -- 目标:将 input 编码成一个固定长度 语义编码 context -- context 作用: - - 1、做为初始向量初始化 Decoder 的模型,做为 decoder 模型预测y1的初始向量; - - 2、做为背景向量,指导y序列中每一个step的y的产出; -- 步骤: - - 1. 遍历输入的每一个Token(词),每个时刻的输入是上一个时刻的隐状态和输入 - - 2. 会有一个输出和新的隐状态。这个新的隐状态会作为下一个时刻的输入隐状态。每个时刻都有一个输出; - - 3. 保留最后一个时刻的隐状态,认为它编码了整个句子的 语义编码 context,并把最后一个时刻的隐状态作为Decoder的初始隐状态; - -### 1.3 seq2seq 中 的 Decoder 怎么样? - -- 目标:将 语义编码 context 解码 为 一个 新的 output; -- 步骤: - - 1. 一开始的隐状态是Encoder最后时刻的隐状态,输入是特殊的; - - 2. 使用RNN计算新的隐状态,并输出第一个词; - - 3. 接着用新的隐状态和第一个词计算第二个词,直到decoder产生一个 EOS token, 那么便结束输出了; - -### 1.4 在 数学角度上 的 seq2seq ,你知道么? - -- 场景介绍:以 机器翻译 为例,给定 一个 句子集合对 (X 表示 一个 英文句子集合,Y 表示 一个 中文句子集合); - -![](img/20200916170948.png) - -- 目标:对于 X 中 的 xi,我们需要采用 seq2seq 框架 来 生成 Y 中对应 的 yi; -- 步骤: - -1. 编码器 encoder:将 输入 句子集合 X 进行编码,也就是将 其 通过 非线性变换 转化为 中间语义编码 Context C - -![](img/20200916171345.png) - -2. 解码器 decoder:对中间语义编码 context 进行解码,根据句子 X 的中间语义编码 Context C 和之前已经生成的历史信息 y1,y2,...,yi-1 生成 当前时刻信息 yi - -![](img/20200916171708.png) - -### 1.5 seq2seq 存在 什么 问题? - -- **忽略了输入序列X的长度**:当输入句子长度很长,特别是比训练集中最初的句子长度还长时,模型的性能急剧下降; -- **对输入序列X缺乏区分度**:输入X编码成一个固定的长度,对句子中每个词都赋予相同的权重,这样做没有区分度,往往是模型性能下降。 - -## 二、Attention 篇 - -### 2.1 什么是 Attention? - -- 通俗易懂介绍:注意力机制模仿了生物观察行为的内部过程,即一种将内部经验和外部感觉对齐从而增加部分区域的观察精细度的机制。例如人的视觉在处理一张图片时,会通过快速扫描全局图像,获得需要重点关注的目标区域,也就是注意力焦点。然后对这一区域投入更多的注意力资源,以获得更多所需要关注的目标的细节信息,并抑制其它无用信息。 -- **Attention 介绍**:帮助模型对输入的x每部分赋予不同的权重,抽取更重要的信息,使模型做出准确判断。同时,不会给模型计算与存储带来更大开销; - -### 2.2 为什么引入 Attention机制? - -根据通用近似定理,前馈网络和循环网络都有很强的能力。但为什么还要引入注意力机制呢? - -- 计算能力的限制:当要记住很多“信息“,模型就要变得更复杂,然而目前计算能力依然是限制神经网络发展的瓶颈。 -- 优化算法的限制:虽然局部连接、权重共享以及pooling等优化操作可以让神经网络变得简单一些,有效缓解模型复杂度和表达能力之间的矛盾;但是,如循环神经网络中的长距离以来问题,信息“记忆”能力并不高。 - -### 2.3 Attention 有什么作用? - -- 让神经网络把 “ 注意力 ” 放在一部分输入上,即:区分输入的不同部分对输出的影响; -- 从增强字 / 词的语义表示这一角度介绍 - - 一个字 / 词在一篇文本中表达的意思通常与它的上下文有关。光看 “ 鹄 ” 字,我们可能会觉得很陌生(甚至连读音是什幺都不记得吧),而看到它的上下文 “ 鸿鹄之志 ” 后,就对它立马熟悉了起来。因此,字 / 词的上下文信息有助于增强其语义表示。同时,上下文中的不同字 / 词对增强语义表示所起的作用往往不同。比如在上面这个例子中, “ 鸿 ” 字对理解 “ 鹄 ” 字的作用最大,而 “ 之 ” 字的作用则相对较小。为了有区分地利用上下文字信息增强目标字的语义表示,就可以用到 Attention 机制。 - -### 2.4 Attention 流程是怎么样? - -#### 步骤一 执行encoder (与 seq2seq 一致) - -- 思路:将源数据依次输入Encoder,执行Encoder -- 目标:将源序列的信息,编译成语义向量,供后续decoder使用 - -![](img/20200916172001.png) - -#### 步骤二 计算对齐系数 a - -- 思路:在 decoder 的每个词,我们需要关注源序列的所有词和目标序列当前词的相关性大小,并输出相关(对齐)系数 a; -- 步骤: - - 1. 在decoder输出一个预测值前,都会针对encoder的所有step,计算一个score; - - 2. 将score汇总向量化后,每个decoder step能获得一个维度为[step_len,1]的score向量; - - 3. 计算出score后,很自然地按惯例使用softmax进行归一化,得到对齐向量a,维度也是[step_len,1]; - -![](img/20200916172200.png) -- 常用对齐函数: - -![](img/20200916182920.png) - -#### 步骤三 计算上下文语义向量 C - -- 思路:对齐系数 a 作为权重,对 encoder 每个 step 的 output 向量进行加权求和(对齐向量a点乘outputs矩阵),得到decoder当前 step 的上下文语义向量 c - -![](img/20200916172542.png) - -#### 步骤四 更新decoder状态 - -- 思路:更新decoder状态,这个状态可以是h,也可以是 s - -![](img/20200916172726.png) - -#### 步骤五 计算输出预测词 - -- 思路:做一个语义向量到目标词表的映射(如果attention用于分类模型,那就是做一个到各个分类的映射),然后再进行softmax就可以了 - -![](img/20200916172920.png) - -### 2.5 Attention 的应用领域有哪些? - -随着 Attention 提出 开始,就被 广泛 应用于 各个领域。比如:自然语言处理,图片识别,语音识别等不同方向深度学习任务中。随着 【[Transformer](https://github.com/km1994/nlp_paper_study/tree/master/transformer_study/Transformer) 】的提出,Attention被 推向了圣坛。 - -## 三、Attention 变体篇 - -### 3.1 Soft Attention 是什么? - -Soft Attention:传统的 Attention 方法,是参数化的(Parameterization),因此可导,可以被嵌入到模型中去,直接训练。梯度可以经过Attention Mechanism模块,反向传播到模型其他部分。 - -### 3.2 Hard Attention 是什么? - -Hard Attention:一个随机的过程。Hard Attention不会选择整个encoder的输出做为其输入,Hard Attention会依概率Si来采样输入端的隐状态一部分来进行计算,而不是整个encoder的隐状态。为了实现梯度的反向传播,需要采用蒙特卡洛采样的方法来估计模块的梯度。 - -### 3.3 Global Attention 是什么? - -- Global Attention:传统的Attention model一样。所有的hidden state都被用于计算Context vector 的权重,即变长的对齐向量at,其长度等于encoder端输入句子的长度。 - -![](img/微信截图_20210109115925.png) - -### 3.4 Local Attention 是什么? - -- 动机:Global Attention 在做每一次 encoder 时,encoder 中的所有 hidden state 都需要参与到计算中,这种方法容易造成 计算开销增大,尤其是 句子偏长的时候。 -- 介绍:Local Attention 通过结合 Soft Attention 和 Hard Attention 的一种 Attention方法 - -![](img/微信截图_20210109120012.png) - -### 3.5 self-attention 是什么? - -- 核心思想:self-attention的结构在计算每个token时,总是会考虑整个序列其他token的表达; -举例:“我爱中国”这个序列,在计算"我"这个词的时候,不但会考虑词本身的embedding,也同时会考虑其他词对这个词的影响 - -> 注:具体内容可以参考 [self-attention 长怎么样?](https://github.com/km1994/nlp_paper_study/tree/master/DL_algorithm/transformer_study#self-attention-长怎么样) - - -## 参考 - -1. [【关于 Attention 】那些你不知道的事](https://github.com/km1994/nlp_paper_study/tree/master/DL_algorithm/Attention_study) -2. [nlp中的Attention注意力机制+Transformer详解](https://zhuanlan.zhihu.com/p/53682800) -3. [模型汇总24 - 深度学习中Attention Mechanism详细介绍:原理、分类及应用](https://zhuanlan.zhihu.com/p/31547842) \ No newline at end of file diff --git a/DeepLearningAlgorithm/cnn/img/1610160500583.png b/DeepLearningAlgorithm/cnn/img/1610160500583.png deleted file mode 100644 index 36e28d4..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/1610160500583.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/1610177872501.png b/DeepLearningAlgorithm/cnn/img/1610177872501.png deleted file mode 100644 index dac4a6e..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/1610177872501.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20180404113714719.png b/DeepLearningAlgorithm/cnn/img/20180404113714719.png deleted file mode 100644 index 214d398..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20180404113714719.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20180404135638186.png b/DeepLearningAlgorithm/cnn/img/20180404135638186.png deleted file mode 100644 index ec7f811..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20180404135638186.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20180404150134375.png b/DeepLearningAlgorithm/cnn/img/20180404150134375.png deleted file mode 100644 index cef86fe..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20180404150134375.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20200812200223.png b/DeepLearningAlgorithm/cnn/img/20200812200223.png deleted file mode 100644 index 0811a3d..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20200812200223.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20200812200551.png b/DeepLearningAlgorithm/cnn/img/20200812200551.png deleted file mode 100644 index deb0248..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20200812200551.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20200812200740.png b/DeepLearningAlgorithm/cnn/img/20200812200740.png deleted file mode 100644 index 525b625..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20200812200740.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20200812203815.png b/DeepLearningAlgorithm/cnn/img/20200812203815.png deleted file mode 100644 index 9677ecd..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20200812203815.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20200812204613.png b/DeepLearningAlgorithm/cnn/img/20200812204613.png deleted file mode 100644 index c762226..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20200812204613.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20200906192126.png b/DeepLearningAlgorithm/cnn/img/20200906192126.png deleted file mode 100644 index c4d6678..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20200906192126.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20200906192221.png b/DeepLearningAlgorithm/cnn/img/20200906192221.png deleted file mode 100644 index 21e2bba..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20200906192221.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20200906192249.png b/DeepLearningAlgorithm/cnn/img/20200906192249.png deleted file mode 100644 index 22b4175..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20200906192249.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223130440.png b/DeepLearningAlgorithm/cnn/img/20201223130440.png deleted file mode 100644 index 5bfaa76..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223130440.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223130525.png b/DeepLearningAlgorithm/cnn/img/20201223130525.png deleted file mode 100644 index 8074582..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223130525.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223131020.png b/DeepLearningAlgorithm/cnn/img/20201223131020.png deleted file mode 100644 index 2fd2a58..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223131020.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223131344.png b/DeepLearningAlgorithm/cnn/img/20201223131344.png deleted file mode 100644 index 6f004d0..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223131344.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223131446.png b/DeepLearningAlgorithm/cnn/img/20201223131446.png deleted file mode 100644 index 7e25651..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223131446.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223131525.png b/DeepLearningAlgorithm/cnn/img/20201223131525.png deleted file mode 100644 index 2343744..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223131525.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223132028.png b/DeepLearningAlgorithm/cnn/img/20201223132028.png deleted file mode 100644 index 7e741af..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223132028.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223132145.png b/DeepLearningAlgorithm/cnn/img/20201223132145.png deleted file mode 100644 index 41f6138..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223132145.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223132445.png b/DeepLearningAlgorithm/cnn/img/20201223132445.png deleted file mode 100644 index d6db901..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223132445.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223132538.png b/DeepLearningAlgorithm/cnn/img/20201223132538.png deleted file mode 100644 index bf7cf1b..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223132538.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223135451.png b/DeepLearningAlgorithm/cnn/img/20201223135451.png deleted file mode 100644 index 4fc276b..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223135451.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223135552.png b/DeepLearningAlgorithm/cnn/img/20201223135552.png deleted file mode 100644 index a66dd30..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223135552.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223135720.png b/DeepLearningAlgorithm/cnn/img/20201223135720.png deleted file mode 100644 index 2b7dc59..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223135720.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223135807.png b/DeepLearningAlgorithm/cnn/img/20201223135807.png deleted file mode 100644 index 5426781..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223135807.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223135855.png b/DeepLearningAlgorithm/cnn/img/20201223135855.png deleted file mode 100644 index cba1f27..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223135855.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223140010.png b/DeepLearningAlgorithm/cnn/img/20201223140010.png deleted file mode 100644 index 3098a3d..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223140010.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223140135.png b/DeepLearningAlgorithm/cnn/img/20201223140135.png deleted file mode 100644 index e026375..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223140135.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223140211.png b/DeepLearningAlgorithm/cnn/img/20201223140211.png deleted file mode 100644 index 00db714..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223140211.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20201223140304.png b/DeepLearningAlgorithm/cnn/img/20201223140304.png deleted file mode 100644 index 717df5b..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20201223140304.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-16-19.png b/DeepLearningAlgorithm/cnn/img/2021-01-06-16-16-19.png deleted file mode 100644 index 8572051..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-16-19.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-16-50.png b/DeepLearningAlgorithm/cnn/img/2021-01-06-16-16-50.png deleted file mode 100644 index 5befe41..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-16-50.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-21-27.png b/DeepLearningAlgorithm/cnn/img/2021-01-06-16-21-27.png deleted file mode 100644 index 0efa4bf..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-21-27.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-22-53.png b/DeepLearningAlgorithm/cnn/img/2021-01-06-16-22-53.png deleted file mode 100644 index 07eb893..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-22-53.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-25-42.png b/DeepLearningAlgorithm/cnn/img/2021-01-06-16-25-42.png deleted file mode 100644 index 0f8aff3..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-25-42.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-29-17.png b/DeepLearningAlgorithm/cnn/img/2021-01-06-16-29-17.png deleted file mode 100644 index 4db5a05..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-29-17.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-30-53.png b/DeepLearningAlgorithm/cnn/img/2021-01-06-16-30-53.png deleted file mode 100644 index 4c5026b..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-30-53.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-37-37.png b/DeepLearningAlgorithm/cnn/img/2021-01-06-16-37-37.png deleted file mode 100644 index 0c79822..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/2021-01-06-16-37-37.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20210105193358.png b/DeepLearningAlgorithm/cnn/img/20210105193358.png deleted file mode 100644 index 584d774..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20210105193358.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/20210105193728.png b/DeepLearningAlgorithm/cnn/img/20210105193728.png deleted file mode 100644 index 0d71437..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/20210105193728.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/68747470733a2f2f69322e6b6b6e6577732e63632f5349473d327374667567352f6374702d767a6e74722f713072306e36383872707337343832326f726e6e3538393538727172723472312e6a7067.gif b/DeepLearningAlgorithm/cnn/img/68747470733a2f2f69322e6b6b6e6577732e63632f5349473d327374667567352f6374702d767a6e74722f713072306e36383872707337343832326f726e6e3538393538727172723472312e6a7067.gif deleted file mode 100644 index 7b22538..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/68747470733a2f2f69322e6b6b6e6577732e63632f5349473d327374667567352f6374702d767a6e74722f713072306e36383872707337343832326f726e6e3538393538727172723472312e6a7067.gif and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" "b/DeepLearningAlgorithm/cnn/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index 6a2c781..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/BatchNormvsLayerNorm.png b/DeepLearningAlgorithm/cnn/img/BatchNormvsLayerNorm.png deleted file mode 100644 index 611891e..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/BatchNormvsLayerNorm.png and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/BatchNorm\346\223\215\344\275\234.png" "b/DeepLearningAlgorithm/cnn/img/BatchNorm\346\223\215\344\275\234.png" deleted file mode 100644 index 82245b5..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/BatchNorm\346\223\215\344\275\234.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/CNN.png b/DeepLearningAlgorithm/cnn/img/CNN.png deleted file mode 100644 index 2e96f24..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/CNN.png and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" "b/DeepLearningAlgorithm/cnn/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index 882606b..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/Normalization.png b/DeepLearningAlgorithm/cnn/img/Normalization.png deleted file mode 100644 index bdda78e..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/Normalization.png and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/cnn-dilation-in_7_out_3.gif b/DeepLearningAlgorithm/cnn/img/cnn-dilation-in_7_out_3.gif deleted file mode 100644 index 98158a6..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/cnn-dilation-in_7_out_3.gif and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/eec076b0b1aec804c74f1e9b726832a.jpg b/DeepLearningAlgorithm/cnn/img/eec076b0b1aec804c74f1e9b726832a.jpg deleted file mode 100644 index 9d14672..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/eec076b0b1aec804c74f1e9b726832a.jpg and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/img/pr16808o61q24973o42q7rsqq88os391.jpg b/DeepLearningAlgorithm/cnn/img/pr16808o61q24973o42q7rsqq88os391.jpg deleted file mode 100644 index a6aa05e..0000000 Binary files a/DeepLearningAlgorithm/cnn/img/pr16808o61q24973o42q7rsqq88os391.jpg and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" "b/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" deleted file mode 100644 index b126f64..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" "b/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" deleted file mode 100644 index 354bb07..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" "b/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" deleted file mode 100644 index f4d8010..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" "b/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" deleted file mode 100644 index 1df5ee5..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" "b/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" deleted file mode 100644 index a65a966..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" "b/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" deleted file mode 100644 index 881b3e2..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" "b/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" deleted file mode 100644 index 6c42db6..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203233936.png" "b/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203233936.png" deleted file mode 100644 index b739653..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203233936.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" "b/DeepLearningAlgorithm/cnn/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" deleted file mode 100644 index f7f5368..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\346\255\243\345\210\231\345\214\226.png" "b/DeepLearningAlgorithm/cnn/img/\346\255\243\345\210\231\345\214\226.png" deleted file mode 100644 index ff8a910..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\346\255\243\345\210\231\345\214\226.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" "b/DeepLearningAlgorithm/cnn/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" deleted file mode 100644 index 0325d90..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" "b/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" deleted file mode 100644 index 8505602..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" "b/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" deleted file mode 100644 index 6e0246a..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" "b/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" deleted file mode 100644 index da180da..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" "b/DeepLearningAlgorithm/cnn/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" deleted file mode 100644 index 201909f..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" "b/DeepLearningAlgorithm/cnn/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" deleted file mode 100644 index 923e9db..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/cnn/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" "b/DeepLearningAlgorithm/cnn/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" deleted file mode 100644 index 8d1b1bb..0000000 Binary files "a/DeepLearningAlgorithm/cnn/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/cnn/readme.md b/DeepLearningAlgorithm/cnn/readme.md deleted file mode 100644 index cc0892b..0000000 --- a/DeepLearningAlgorithm/cnn/readme.md +++ /dev/null @@ -1,257 +0,0 @@ -# 【关于 CNN】那些你不知道的事 - -> 贡献者:天骄,小猪呼噜,沐风,杨夕,芙蕖,李玲 - -![CNN](img/微信截图_20210203233936.png) - -## 一、动机篇 - -- 全连接网络:任意一对输入与输出神经元间都存在连接,现成稠密结构 -- 局部特征存在相关性 - -## 二、CNN 卷积层篇 - -### 2.1 卷积层的本质是什么? - -- 稀疏交互 - - 动机:全连接网络,任意一对输入与输出神经元间都存在连接,现成稠密结构 - - 思路:卷积核尺度远小于输入维度,每个输出神经元仅与前一层特定局部区域内的神经元存在连接 - - 优点:全连接层的 参数 为 m*n;卷积层为 k*n (m为输入,n为输出,k 为 卷积维度) -- 参数共享 - - 思路:在同一模型的不同模块中使用相同参数,为卷积运算的固有属性 - - 区别 - - NN:计算每层输出时,权值参数矩阵中每个元素只作用于每个输入元素一次 - - CNN:卷积核中每个元素将作用于每个局部输入的特定位置上 - - 物理意义:使卷积层具有平移不变性 (满足 f(g(x)) = g(f(x)) 时,称 f(x) 关于g 具有等变性) - -### 2.2 CNN 卷积层与全连接层的联系? - -1. 卷积核中的权值每次滑动计算时只是局部连接,且在卷积列中的神经元共享参数——计算局部信息,而全连接层神经元的权值与所有输入相连——计算全局信息。 -2. 两者都是采用的矩阵点积运算,具有相似的计算形式,能够实现互相转化。 - 1. **卷积——>全连接:** 权重矩阵参数增大,权重补0,由于参数共享性质,在其中大部分块中,存在大量相等参数。 - 2. **全连接——>全卷积:** 将卷积核的尺寸设置为和输入数据体的尺寸一致(NxWxHxC)。除第一层全连接外,其他通道数都为1,N表示本层神经元的个数,为一个提前设定的超参数,结果与初始的那个全连接层一致。 -3. 一个深度卷积神经网络模型通常由若干卷积层叠加若干全连接层组成,中间也包含各种非线性操作以及池化操作。卷积层的作用是从输入数据中采集关键数据内容。全连接层在深度卷积神经网络中的作用是将前面经过多次卷积后高度抽象的特征进行整合。最后一层作归一化,然后输出概率。卷积层提供了一个有意义、低维度且几乎不变的特征空间,然后全连接层在这个空间里学习一个非线性的方程。通俗的说,卷积层是特征提取器,全连接层执行分类操作。 -4. 全连接层可以视作一种特殊的卷积。考虑下面两种情况: - 1. (1) 特征图和全连接层相连,AlexNet经过五次池化后得到7\*7\*512的特征图,下一层全连接连向4096个神经元,这个过程可以看作有4096个7\*7\*512的卷积核和7\*7\*512的特征图进行卷积操作,最终得到1\*1\*4096的特征图,等价于全连接得到4096个神经元。 - 2. (2) 全连接层和全连接层相连,AlexNet的再下一层依然是4096个神经元,即4096个神经元和4096个神经元全连接,由(1)得到了1\*1\*4096的特征图,本次全连接过程可以看作存在4096个1\*1\*4096的卷积核,依次和1\*1\*4096的特征图进行卷积操作,等价于全连接。 - -### 2.3 channel的含义是什么? - -在卷积神经网络中,channel的含义是每个卷积层中卷积核的数量。卷积层的卷积个数就等于卷积层输出的out_channels。这个值也与下一层卷积的in_channels相同。下面举例说明。 - -如下图,假设现有一个为 6×6×3 的图片样本,使用 3×3×3 的卷积核(filter)进行卷积操作。此时输入图片的 `channels` 为 3 ,而**卷积核中**的 `in_channels` 与 需要进行卷积操作的数据的 `channels` 一致(这里就是图片样本,为3)。 - -![cnn](img/20180404135638186.png) - -接下来,进行卷积操作,卷积核中的27个数字与分别与样本对应相乘后,再进行求和,得到第一个结果。依次进行,最终得到 4×4的结果。 - -![单个卷积核](img/20180404113714719.png) - -上面步骤完成后,由于只有一个卷积核,所以最终得到的结果为 4×4×1, `out_channels` 为 1 。 - -在实际应用中,都会使用多个卷积核。这里如果再加一个卷积核,就会得到 4×4×2 的结果。 - -![多个卷积核](img/20180404150134375.png) - -总结一下, `channels` 分为三种: - -1. 最初输入的图片样本的 `channels` ,取决于图片类型,比如RGB; -2. 卷积操作完成后输出的 `out_channels` ,取决于卷积核的数量。此时的 `out_channels` 也会作为下一次卷积时的卷积核的 `in_channels`; -3. 卷积核中的 `in_channels` ,就是上一次卷积的 `out_channels` ,如果是第一次做卷积,就是样本图片的 `channels` 。 - -## 三、CNN 池化层篇 - -### 3.1 池化层针对区域是什么? - -池化层针对区域是非重叠区域。 - -### 3.2 池化层的种类有哪些? - -- 均值池化 - - 思路:对领域内特征值取平均 - - 优点:抑制由领域大小受限造成的估计值方差增大现象 - - 特点:对背景的保留效果好 -- 最大值池化 - - 思路:取领域内最大值 - - 优点:抑制网络参数误差造成估计均值偏移问题 - - 特点:更好提取纹理信息 - -### 3.3 池化层的作用是什么? - -除降低参数量外,能够保持对平移、伸缩、旋转操作的不变性 - -### 3.4 池化层 反向传播 是什么样的? - -- 动机:由于 Pooling 操作容易改变 feature map 的 尺寸大小,使得 Pooling 层不可导; -- 举例说明:假定 2*2 的 池化,会生成 2*2*2*2 = 16 个梯度,即梯度无法传递到对应的位置; -- 方法:将一个像素的loss (梯度) 传递给4个像素,且需要保证传递的 loss (梯度)总和不变。 - -### 3.5 mean pooling 池化层 反向传播 是什么样的? - -- mean pooling 前向传播介绍:将 patch 中的值求平均来做 pooling; -- mean pooling 反向传播介绍:将值的梯度均等分为 n*n 份 分配给上一层,以保证 池化 前后 梯度之和保存不变; - -![](img/20210105193358.png) - -### 3.6 max pooling 池化层 反向传播 是什么样的? - -- max pooling 前向传播介绍:将 patch 中的值取 max 来做 pooling 结果 传递给下一层; -- max pooling 反向传播介绍:把梯度直接传给前一层 值最大的一个像素,而其他像素不接受梯度,也就是为0; - -![](img/20210105193728.png) - -## 四、CNN 整体篇 - -### 4.1 CNN 的流程是什么? - -- s1 输入变长的字符串或单词串 -- s2 利用滑动窗口加池化的方式将原先的输入转化为固长的向量表示 - -### 4.2 CNN 的特点是什么? - -CNN 能够捕获文本中的局部特征 - -### 4.3 卷积神经网络为什么会具有平移不变性? - -平移不变性:即目标在空间内发生平移,但是结果(标签)不变 - -平移不变性=卷积+最大池化。卷积层具有平移等变性,池化层具有平移不变性。**卷积神经网络的平移不变性,是池化层赋予的**。 - -如果一个函数满足“输入改变,输出也以同样的方式进行改变”这一性质,我们就说该函数是**等变的**(equivariant)。形式化地,如果函数$f(x)$与$g(x)$满足$f(g(x))=g(f(x))$,我们就说$f(x)$对于变换$g$具有等变性。 - -卷积层具有**平移等变性**,也就是说卷积层对平移是敏感的,输入的平移能等价地影响输出。直观地,如果把一张输入图像先平移后卷积,其结果与先卷积后平移效果是一样的。如果我们移动输入图像中的物体,它的表示也会在输出中移动同样的量。 - -卷积层的**参数共享**(Parameter Sharing)特性使得卷积层具有平移等变性。参数共享是指在一个模型的多个函数中使用相同的参数。在传统的神经网络中,当计算一层的输出时,权重矩阵的每个元素只使用一次。当它乘以输入的一个元素后,就再也不会用到了。但是在卷积神经网络中,卷积核的每一个元素都作用在输入的每一个位置上。卷积运算中的参数共享保证了我们只需要学习一个参数集合,而不是对于每个位置都需要学习一个单独的参数集合。 - -如果一个函数满足“输入改变,输出不会受影响”这一性质,我们就说该函数是**不变的**(invariant)。形式化地,如果函数$f(x)$与$g(x)$满足$g(x)=x'$且$f(x)=f(x')=f(g(x))$,我们就说$f(x)$对于变换$g$具有不变性。 - -池化层具有(近似)**平移不变性**,也就是说池化层对平移不敏感。不管采用什么样的池化函数,当输入做出少量平移时,池化能够帮助输入的表示近似不变。例如我们**使用最大池化,只要变换不影响到最大值,我们的池化结果不会收到影响**。对于一个卷积核来说,只有一个值的变动会影响到输出, 其他的变换都不会造成扰动。平均池化的近似不变性就稍弱些。 - -局部平移不变性是一个很有用的性质,尤其是当我们关心某个特征是否出现而不关心它出现的具体位置时。 - - -### 4.4 卷积神经网络中im2col是如何实现的? - -卷积的运算量十分巨大,如果将卷积运算转化为矩阵运算,便能利用GPU来提升性能。 - -im2col全称image to column(从图像到矩阵),作用为加速卷积运算。即把包含批数量的4维数据转换成2维数据。也就是将输入数据降维,然后通过numpy的矩阵运算后得到结果,再将结果的形状还原,从而通过用矩阵运算来代替for循环语句。 - -`im2col`将卷积核和卷积核扫过的区域都转化为列(行)向量。举个例子方便理解: - -假设一个3*3卷积核为: - -![](img/2021-01-06-16-16-19.png) - -输入图像是5*5像素的单通道图像: - -![](img/2021-01-06-16-16-50.png) - -卷积核会锁定3*3的滑动窗口: - -![](img/2021-01-06-16-21-27.png) - -`im2col`会将每个滑动窗口内的像素转为列向量: - -![](img/2021-01-06-16-22-53.png) - -就这样转化所有滑动窗口的列向量,将其拼接成9行的矩阵(行数与滑动窗口数目相关,列数则与卷积核大小相关): - -![](img/2021-01-06-16-29-17.png) - -`im2col`还会将卷积核转化为行向量: - -![](img/2021-01-06-16-25-42.png) - -最后使用卷积核行向量乘以滑动窗口元素组成的矩阵: - -![](img/2021-01-06-16-30-53.png) - -得到1*9的列向量,将其拼接成特征图: - -![](img/2021-01-06-16-37-37.png) - -### 4.5 CNN 的局限性是什么? - -1. 以CNN为代表的前馈神经网络使用了条件独立假设,其特征提取范围受到限制;而循环神经网络或者Attention机制的模型能够看到序列整体的信息,因此对于序列建模任务,单纯的CNN存在先天不足。 -2. 卷积神经网络的核心思想是捕捉局部特征。对于序列任务,比如文本来说,局部特征就是由若干单词组成的滑动窗口(类似N-Gram)。卷积神经网络的优势在于能够自动地对N-Gram特征进行组合和筛选,获得不同抽象层次的语义信息。 - 1. 解决方法:加入更多卷积层 -> 网络深度增加 -> 参数量增大 -> 容易过拟合 -> 引入 Dropout 正则化 -> 引入超参数 -> 网络庞大冗余,难以训练 -3. 使用CNN做序列任务的优点在于其共享权重的机制,使得训练速度相对较快;但是其最大的缺点在于CNN无法构建长距离依存关系。 -4. 有许多研究者试图改进CNN模型,使其能够应用于序列任务。诸如用于句子语义建模的动态卷积神经网络DCNN、可以在整个序列的所有窗口上进行卷积的时延神经网络TDNN等。 - -## 五、Iterated Dilated CNN 篇 - -### 5.1 什么是 Dilated CNN 空洞卷积? - -- 动机: - - 正常CNN 的 filler 作用于输入矩阵连续位置,利用 卷积 和 池化 整合多尺度的上下文信息,导致分辨率损失 - - pooling 会损失信息,降低精度,不加则导致感受野变小,学不到全局信息 - - CNN提取特征的能力受到卷积核大小的限制,特别是对于序列问题,容易造成长距离依赖问题 -- 介绍:Dilated Convolutions,翻译为扩张卷积或空洞卷积。空洞卷积与普通的卷积相比,除了卷积核的大小以外,还有一个扩张率参数,主要用来表示扩张的大小,以及去掉 pooling。 -- 空洞卷积与普通卷积的相同点:卷积核的大小是一样的,在神经网络中即参数数量不变,区别在于扩张卷积具有更大的感受野。感受野指的是特征图上某个元素的计算受输入图像影响区域的范围,即特征图上神经元能够“看到”的图像范围,例如3×3卷积核的感受野大小为9。 - -具体地,空洞卷积通过给卷积核插入“空洞”变相增加其大小。如果在卷积核的每两个元素之间插入$D-1$个空洞,该卷积核的有效大小为$K'=K+(K-1)\times (D-1)$。其中$K$为原始卷积核大小,$D$称为膨胀率(扩张率,dilation rate)。当$D=1$时卷积核为普通的卷积核。 - -例如下图中 - -- (a) 普通卷积,1-dilated convolution,卷积核的感受野为3×3=9。 -- (b) 空洞卷积,2-dilated convolution,卷积核的感受野为7×7=49。 -- (c) 空洞卷积,4-dilated convolution,卷积核的感受野为15×15=225。 - -![1610177872501](img/1610177872501.png) -- 优点:dilated width 会随着层数增加而指数增加,层数 增加,参数量线性增长, 感受野 指数增加,可覆盖全部信息 - -**例如卷积核大小为3,步长为1,膨胀率为2的空洞卷积动态示意图:** - -![卷积核大小为3,步长为1,膨胀率为1的空洞卷积示意图](img/cnn-dilation-in_7_out_3.gif) - -- 空洞卷积的作用 - - 扩大感受野。如果希望增加输出单元的感受野,一般可以通过增加卷积核大小、增加卷积层数,或在卷积前增加池化操作来实现。但是前两者会增加参数数目,第三种方式会损失信息。空洞卷积就是一种增加感受野的同时不增加参数数量的方法。 - - 捕获多尺度上下文信息:在进行空洞卷积前,通过双线性插值,对feature map进行上采样之后,再进行空洞卷积,这样可以在提高feature map的像素的同时,提取更多的全局信息 - -### 5.2 什么是 Iterated Dilated CNN? - -- 思路:利用四个结构相同的 Dilated CNN 拼接起来,每个 block 里面 dilated width 为 1,1,2 的三层 DCNN,能够捕获更大感受野的信息 - -## 六、反卷积 篇 - -### 6.1 解释反卷积的原理和用途? - -**1.反卷积原理** - -​ 反卷积=上采样=(转置卷积+微步卷积)⊆ 空洞卷积=一般意义上的广义卷积(包含上采样和下采样)。 - -上采样:在应用在计算机视觉的深度学习领域,由于输入图像通过卷积神经网络(CNN)提取特征后,输出的尺寸往往会变小,而有时我们需要将图像恢复到原来的尺寸以便进行进一步的计算(e.g.:图像的语义分割),这个采用扩大图像尺寸,实现图像由小分辨率到大分辨率的映射的操作,叫做上采样(Upsample)。 - -反卷积是一种特殊的正向卷积,先按照一定的比例通过补0来扩大输入图像的尺寸,接着旋转卷积核,再进行正向卷积。 - -反卷积又被称为Transposed(转置) Convolution,其实卷积层的前向传播过程就是反卷积层的反向传播过程,卷积层的反向传播过程就是反卷积层的前向传播过程。因为卷积层的前向反向计算分别为乘 $C$ 和 $C^T$,而反卷积层的前向反向计算分别为乘 $C^T$ 和 $(C^T)^T$,所以它们的前向传播和反向传播刚好交换过来。 - -![img](img/pr16808o61q24973o42q7rsqq88os391.jpg) - -上图展示一个反卷积的工作过程,乍看一下好像反卷积和卷积的工作过程差不多,主要的区别在于反卷积输出图片的尺寸会大于输入图片的尺寸,通过增加padding来实现这一操作,上图展示的是一个strides(步长)为1的反卷积。下面看一个strides不为1的反卷积 - -![img](https://i2.kknews.cc/SIG=2stfug5/ctp-vzntr/q0r0n688rps74822ornn58958rqrr4r1.jpg) - -上图中的反卷积的stride为2,通过间隔插入padding来实现的。同样,可以根据反卷积的o、s、k、p参数来计算反卷积的输出i,也就是卷积的输入。公式如下:**i=(o−1)∗s+k−2∗p**。 - -**2.作用** - -- 通过反卷积可以用来可视化卷积的过程 - -- 反卷积在GAN等领域中有着大量的应用。 比如用GANs生成图片,其中的generator和discriminator均采用深度学习,generator生成图片过程中采用的就是反卷积操作(当然discriminator采用卷积对generator生成的图片判别真伪)。 - -- 将一些低分辨率的图片转换为高分辨率的图片。 - -参考: - -https://kknews.cc/code/zb2jr43.html - -https://zhuanlan.zhihu.com/p/48501100 - -## 参考 - -1. [理解为什么要将全连接层转化为卷积层](https://www.cnblogs.com/liuzhan709/p/9356960.html) -2. [What do the fully connected layers do in CNNs?](https://stats.stackexchange.com/questions/182102/what-do-the-fully-connected-layers-do-in-cnns?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa) -3. [CNN全连接层和卷积层的转化](https://blog.csdn.net/weixin_43199584/article/details/105125620) -4. [【CNN】理解卷积神经网络中的通道 channel](https://blog.csdn.net/sscc_learning/article/details/79814146) -5. [万字长文概述NLP中的深度学习技术](https://www.linkresearcher.com/information/6c7a15b5-236a-40f3-879f-af2ac06c2557) \ No newline at end of file diff --git a/DeepLearningAlgorithm/readme.md b/DeepLearningAlgorithm/readme.md deleted file mode 100644 index e69de29..0000000 diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124195411.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124195411.png" deleted file mode 100644 index 97dc325..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124195411.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124200244.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124200244.png" deleted file mode 100644 index 06f8931..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124200244.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201238.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201238.png" deleted file mode 100644 index cdbc088..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201238.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201611.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201611.png" deleted file mode 100644 index ea21528..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201611.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201807.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201807.png" deleted file mode 100644 index d05325a..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124201807.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203442.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203442.png" deleted file mode 100644 index 59de51f..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203442.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203639.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203639.png" deleted file mode 100644 index 63a34e0..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203639.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203827.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203827.png" deleted file mode 100644 index 182db15..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124203827.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204437.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204437.png" deleted file mode 100644 index 8d9f2bc..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204437.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204901.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204901.png" deleted file mode 100644 index 4c7b56b..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204901.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204920.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204920.png" deleted file mode 100644 index 24f92ea..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124204920.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205049.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205049.png" deleted file mode 100644 index 8889eab..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205049.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205104.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205104.png" deleted file mode 100644 index bb473e1..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205104.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205209.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205209.png" deleted file mode 100644 index b7a0886..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205209.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205226.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205226.png" deleted file mode 100644 index b03820a..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205226.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205311.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205311.png" deleted file mode 100644 index 6a5805a..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205311.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205329.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205329.png" deleted file mode 100644 index 23022a6..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205329.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205501.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205501.png" deleted file mode 100644 index ef8c6ed..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205501.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205517.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205517.png" deleted file mode 100644 index e1ac66f..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205517.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205549.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205549.png" deleted file mode 100644 index cb95257..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205549.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205602.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205602.png" deleted file mode 100644 index 4fe8e33..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220124205602.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125161534.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125161534.png" deleted file mode 100644 index d4d83e3..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125161534.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125161629.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125161629.png" deleted file mode 100644 index e619895..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125161629.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162246.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162246.png" deleted file mode 100644 index 77e8ced..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162246.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162329.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162329.png" deleted file mode 100644 index 6b4c2b2..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162329.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162404.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162404.png" deleted file mode 100644 index 6a32ff5..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162404.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162415.png" "b/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162415.png" deleted file mode 100644 index fc718fb..0000000 Binary files "a/DeepLearningAlgorithm/rnn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220125162415.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/rnn/readme.md b/DeepLearningAlgorithm/rnn/readme.md deleted file mode 100644 index 9a099d3..0000000 --- a/DeepLearningAlgorithm/rnn/readme.md +++ /dev/null @@ -1,234 +0,0 @@ -# 【关于 RNN】那些你不知道的事 - -> 作者:杨夕、芙蕖、李玲、陈海顺、twilight、LeoLRH、JimmyDU、张永泰 -> -> 介绍:本项目是作者们根据个人面试和经验总结出的自然语言处理(NLP)面试准备的学习笔记与资料,该资料目前包含 自然语言处理各领域的 面试题积累。 -> -> NLP 百面百搭 地址:https://github.com/km1994/NLP-Interview-Notes -> -> **[手机版NLP百面百搭](https://mp.weixin.qq.com/s?__biz=MzAxMTU5Njg4NQ==&mid=100005719&idx=3&sn=5d8e62993e5ecd4582703684c0d12e44&chksm=1bbff26d2cc87b7bf2504a8a4cafc60919d722b6e9acbcee81a626924d80f53a49301df9bd97&scene=18#wechat_redirect)** -> -> 推荐系统 百面百搭 地址:https://github.com/km1994/RES-Interview-Notes -> -> **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** -> -> 搜索引擎 百面百搭 地址:https://github.com/km1994/search-engine-Interview-Notes 【编写ing】 -> -> NLP论文学习笔记:https://github.com/km1994/nlp_paper_study -> -> 推荐系统论文学习笔记:https://github.com/km1994/RS_paper_study -> -> GCN 论文学习笔记:https://github.com/km1994/GCN_study -> -> **推广搜 军火库**:https://github.com/km1994/recommendation_advertisement_search - -![](img/微信截图_20210301212242.png) -> **关注公众号 【关于NLP那些你不知道的事】 加入 【NLP && 推荐学习群】一起学习!!!** - -- [【关于 RNN】那些你不知道的事](#关于-rnn那些你不知道的事) - - [一、RNN 篇](#一rnn-篇) - - [1.2 为什么需要 RNN?](#12-为什么需要-rnn) - - [1.2 RNN 结构是怎么样的?](#12-rnn-结构是怎么样的) - - [1.3 RNN 前向计算公式?](#13-rnn-前向计算公式) - - [1.4 RNN 存在什么问题?](#14-rnn-存在什么问题) - - [二、长短时记忆网络(Long Short Term Memory Network, LSTM) 篇](#二长短时记忆网络long-short-term-memory-network-lstm-篇) - - [2.1 为什么 需要 LSTM?](#21-为什么-需要-lstm) - - [2.2 LSTM 的结构是怎么样的?](#22-lstm-的结构是怎么样的) - - [2.3 LSTM 如何缓解 RNN 梯度消失和梯度爆炸问题?](#23-lstm-如何缓解-rnn-梯度消失和梯度爆炸问题) - - [2.3 LSTM 的流程是怎么样的?](#23-lstm-的流程是怎么样的) - - [2.4 LSTM 中激活函数区别?](#24-lstm-中激活函数区别) - - [2.5 LSTM的复杂度?](#25-lstm的复杂度) - - [2.6 LSTM 存在什么问题?](#26-lstm-存在什么问题) - - [三、GRU (Gated Recurrent Unit)](#三gru-gated-recurrent-unit) - - [3.1 为什么 需要 GRU?](#31-为什么-需要-gru) - - [3.2 GRU 的结构是怎么样的?](#32-gru-的结构是怎么样的) - - [3.3 GRU 的前向计算?](#33-gru-的前向计算) - - [3.4 GRU 与其他 RNN系列模型的区别?](#34-gru-与其他-rnn系列模型的区别) - - [四、RNN系列模型篇](#四rnn系列模型篇) - - [4.1 RNN系列模型 有什么特点?](#41-rnn系列模型-有什么特点) - - [参考](#参考) - -## 一、RNN 篇 - -### 1.2 为什么需要 RNN? - -无论是 全连接网络 还是 卷积神经网络 他们的前提假设都是 元素间相互独立,也就是输入和输出的一一对应,也就是一个输入得到一个输出。不同的输入之间是没有联系的。 - -![](img/微信截图_20220124200244.png) - -然而,在 序列数据(自然语言处理任务、时间序列任务)中,对于每一个输出,他不仅和他所对应的输入相关,还与前面其他词 和 词间的顺序相关。 - -这个时候,全连接网络 还是 卷积神经网络 将不能很好解决该问题。 - -RNN 之所以被称为"循环",是因为它对序列中的每个元素执行相同的任务,输出取决于先前的计算。考虑RNN的另一种方式是它们有一个“记忆”,它可以捕获到目前为止计算的信息。 - -### 1.2 RNN 结构是怎么样的? - -![](img/微信截图_20220124201238.png) - -从 上面图片中,可以看出 RNN网络 的 核心在于 $s_t$ 的值 不仅取决 xt,而且还与 $s_{t-1}$ 相关。 - -### 1.3 RNN 前向计算公式? - -- 第一步,计算隐藏层的输出值 - -![](img/微信截图_20220124201611.png) -> 注:f 为隐藏层的激活函数,一般用 softmax 函数 - -- 第二步,计算输出层的输出值 - -![](img/微信截图_20220124201807.png) -> 注:g 为输出层的激活函数,一般用 tanh 函数 或者 ReLU 函数 - -### 1.4 RNN 存在什么问题? - -1. 梯度消失和梯度爆炸 问题 - -- 原因 - -误差沿时间反向传播: - -![](img/微信截图_20220124203442.png) - -![](img/微信截图_20220124203827.png) - -矩阵的模的值取决 于 上图 红框部分: - -> 当其大于1时,随着RNN深度的增加,矩阵的模的值呈指数函数增加,此时将出现 梯度爆炸; -> -> 当其小于1时,随着RNN深度的增加,矩阵的模的值呈指数函数减少,此时将出现 梯度消失; - -- 解决方法 - - 梯度消失问题解决方法: - - 合理的初始化权重值; - - 使用relu代替sigmoid和tanh作为激活函数; - - 使用其他结构的RNNs; - - 梯度爆炸问题解决方法: - - 设置一个梯度阈值,当梯度超过这个阈值的时候可以直接截取 - -2. 长距离的依赖问题 - -导致训练时梯度不能在较长序列中一直传递下去,从而使RNN无法捕捉到长距离的影响 - -## 二、长短时记忆网络(Long Short Term Memory Network, LSTM) 篇 - -### 2.1 为什么 需要 LSTM? - -RNN 梯度消失和梯度爆炸问题 - -### 2.2 LSTM 的结构是怎么样的? - -![](img/微信截图_20220124204437.png) - -### 2.3 LSTM 如何缓解 RNN 梯度消失和梯度爆炸问题? - -- 引用门控机制 - - 遗忘门:控制继续保存长期状态c; - - 输入门:控制把即时状态输入到长期状态c; - - 输出门:控制是否把长期状态c作为当前的LSTM的输出; - -- 原理:门实际上就是一层全连接层,它的输入是一个向量,输出是一个0到1之间的实数向量。 - -### 2.3 LSTM 的流程是怎么样的? - -1. 遗忘门计算 - -![](img/微信截图_20220124204901.png) - -![](img/微信截图_20220124204920.png) - -> δ 是 sigmoid 函数 - -2. 输入门 - -![](img/微信截图_20220124205049.png) - -![](img/微信截图_20220124205104.png) - -3. 计算用于描述当前输入的 单元状态 - -![](img/微信截图_20220124205209.png) - -![](img/微信截图_20220124205226.png) - -4. 计算当前时刻的单元状态 - -![](img/微信截图_20220124205311.png) - -![](img/微信截图_20220124205329.png) - -5. 输出门 - -![](img/微信截图_20220124205501.png) - -![](img/微信截图_20220124205517.png) - -6. 最终输出 - -![](img/微信截图_20220124205549.png) - -![](img/微信截图_20220124205602.png) - -### 2.4 LSTM 中激活函数区别? - -- 门控的激活函数为 sigmoid; -- 输出的激活函数为tanh函数; - -### 2.5 LSTM的复杂度? - -序列长度为T,隐藏层维度为H - -O(T * H^2) - -### 2.6 LSTM 存在什么问题? - -计算量大 - -## 三、GRU (Gated Recurrent Unit) - -### 3.1 为什么 需要 GRU? - -LSTM 计算量大 - -### 3.2 GRU 的结构是怎么样的? - -![](img/微信截图_20220125161534.png) - -### 3.3 GRU 的前向计算? - -- 重置门(reset gate)的计算: - -![](img/微信截图_20220125162246.png) - -- 候选激活值(candidate activation)的计算 - -![](img/微信截图_20220125162329.png) - -- 更新门(update gate)的计算 - -![](img/微信截图_20220125162404.png) - -- 激活值的计算 - -![](img/微信截图_20220125162415.png) - -### 3.4 GRU 与其他 RNN系列模型的区别? - -GRU输入输出的结构与普通的RNN相似,其中的内部思想与LSTM相似。 - -与LSTM相比,GRU内部少了一个”门控“,参数比LSTM少,但是却也能够达到与LSTM相当的功能。考虑到硬件的计算能力和时间成本,因而很多时候我们也就会选择更加”实用“的GRU啦。 - -## 四、RNN系列模型篇 - -### 4.1 RNN系列模型 有什么特点? - -- 具有记忆能力:针对文本序列,能够从头到尾阅读文章中每个单词,将前面阅读到的有用信息编码到状态变量中,从而拥有一定记忆能力,可更好理解之后的内容 - -## 参考 - -1. [循环神经网络(RNN)知识入门](https://zhuanlan.zhihu.com/p/149869659) -2. [LSTM基本原理](https://docs.rnn.knowledge-precipitation.site/lstm-ji-ben-yuan-li) -3. [循环神经网络 – Recurrent Neural Network | RNN](https://easyai.tech/ai-definition/rnn/) -4. [循环神经网络--传统RNN、LSTM循序渐进的通俗易懂解释](https://blog.csdn.net/weixin_40363423/article/details/89925364) - - diff --git a/DeepLearningAlgorithm/transformer/img/1.png b/DeepLearningAlgorithm/transformer/img/1.png deleted file mode 100644 index 928b495..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/1.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200623092901.png b/DeepLearningAlgorithm/transformer/img/20200623092901.png deleted file mode 100644 index 322a005..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200623092901.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200623093042.png b/DeepLearningAlgorithm/transformer/img/20200623093042.png deleted file mode 100644 index 3f69db3..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200623093042.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200623093217.png b/DeepLearningAlgorithm/transformer/img/20200623093217.png deleted file mode 100644 index c0a6484..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200623093217.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200624080740.png b/DeepLearningAlgorithm/transformer/img/20200624080740.png deleted file mode 100644 index ceb9a79..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200624080740.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200624081753.png b/DeepLearningAlgorithm/transformer/img/20200624081753.png deleted file mode 100644 index fb88048..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200624081753.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200624083258.png b/DeepLearningAlgorithm/transformer/img/20200624083258.png deleted file mode 100644 index b6f3353..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200624083258.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200624084515.png b/DeepLearningAlgorithm/transformer/img/20200624084515.png deleted file mode 100644 index 4a76dd4..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200624084515.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200624090026.png b/DeepLearningAlgorithm/transformer/img/20200624090026.png deleted file mode 100644 index ed904b4..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200624090026.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200624090034.png b/DeepLearningAlgorithm/transformer/img/20200624090034.png deleted file mode 100644 index ef61bc4..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200624090034.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20200624090357.png b/DeepLearningAlgorithm/transformer/img/20200624090357.png deleted file mode 100644 index 72c6dbc..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20200624090357.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20201009163936.png b/DeepLearningAlgorithm/transformer/img/20201009163936.png deleted file mode 100644 index 6cdf98c..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20201009163936.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20201009164019.png b/DeepLearningAlgorithm/transformer/img/20201009164019.png deleted file mode 100644 index 174e3cb..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20201009164019.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20201009164053.png b/DeepLearningAlgorithm/transformer/img/20201009164053.png deleted file mode 100644 index aa9563d..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20201009164053.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/20201125164433.png b/DeepLearningAlgorithm/transformer/img/20201125164433.png deleted file mode 100644 index cf90b09..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/20201125164433.png and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625101229.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625101229.png" deleted file mode 100644 index 8814146..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625101229.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625103634.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625103634.png" deleted file mode 100644 index 77374e8..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625103634.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625110603.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625110603.png" deleted file mode 100644 index 9490c81..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625110603.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625110706.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625110706.png" deleted file mode 100644 index 4cc4f09..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200625110706.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626120834.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626120834.png" deleted file mode 100644 index 065709f..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626120834.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626122726.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626122726.png" deleted file mode 100644 index e812a2a..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626122726.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626152309.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626152309.png" deleted file mode 100644 index 3c4c40a..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626152309.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626153600.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626153600.png" deleted file mode 100644 index df15ad1..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626153600.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626154711.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626154711.png" deleted file mode 100644 index 773c5ec..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620200626154711.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620201222225802.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620201222225802.png" deleted file mode 100644 index b248232..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620201222225802.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620201222230028.png" "b/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620201222230028.png" deleted file mode 100644 index 82d58eb..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/QQ\346\210\252\345\233\27620201222230028.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/Transformer.png b/DeepLearningAlgorithm/transformer/img/Transformer.png deleted file mode 100644 index 9fbc0e5..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/Transformer.png and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/v2-595ce4ebf9b3fccb479f7d234190af35_b.gif b/DeepLearningAlgorithm/transformer/img/v2-595ce4ebf9b3fccb479f7d234190af35_b.gif deleted file mode 100644 index eaa828e..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/v2-595ce4ebf9b3fccb479f7d234190af35_b.gif and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/img/v2-595ce4ebf9b3fccb479f7d234190af35_b.png b/DeepLearningAlgorithm/transformer/img/v2-595ce4ebf9b3fccb479f7d234190af35_b.png deleted file mode 100644 index eaa828e..0000000 Binary files a/DeepLearningAlgorithm/transformer/img/v2-595ce4ebf9b3fccb479f7d234190af35_b.png and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" deleted file mode 100644 index bba4c4e..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625085139.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625085139.png" deleted file mode 100644 index 384b52c..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625085139.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625085922.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625085922.png" deleted file mode 100644 index 4d83bb3..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625085922.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625090454.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625090454.png" deleted file mode 100644 index ea460fc..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625090454.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625093537.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625093537.png" deleted file mode 100644 index 2fabef6..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625093537.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625095930.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625095930.png" deleted file mode 100644 index e46b5c7..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625095930.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" deleted file mode 100644 index 0073695..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201222225938.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201222225938.png" deleted file mode 100644 index 89b81c0..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201222225938.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128073806.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128073806.png" deleted file mode 100644 index 600bd85..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128073806.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128074033.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128074033.png" deleted file mode 100644 index 6b84d4d..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128074033.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128074300.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128074300.png" deleted file mode 100644 index a78a3cd..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128074300.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203094546.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203094546.png" deleted file mode 100644 index 71ce3a9..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203094546.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095003.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095003.png" deleted file mode 100644 index eeed254..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095003.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095438.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095438.png" deleted file mode 100644 index cbe02fd..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095438.png" and /dev/null differ diff --git "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095511.png" "b/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095511.png" deleted file mode 100644 index 5a7aea2..0000000 Binary files "a/DeepLearningAlgorithm/transformer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211203095511.png" and /dev/null differ diff --git a/DeepLearningAlgorithm/transformer/readme.md b/DeepLearningAlgorithm/transformer/readme.md deleted file mode 100644 index 0e8108f..0000000 --- a/DeepLearningAlgorithm/transformer/readme.md +++ /dev/null @@ -1,969 +0,0 @@ -# 【关于Transformer】那些你不知道的事 - -> 作者:杨夕 -> -> 论文链接:https://arxiv.org/pdf/1706.03762.pdf -> -> 【注:手机阅读可能图片打不开!!!】 - -本章主要介绍 Transformer 常见的问题,如下图所属: - -![](img/Transformer.png) -> Transformer 常见问题 - -- [【关于Transformer】那些你不知道的事](#关于transformer那些你不知道的事) - - [一、动机篇](#一动机篇) - - [1.1 为什么要有 Transformer?](#11-为什么要有-transformer) - - [1.2 Transformer 作用是什么?](#12-transformer-作用是什么) - - [二、整体结构篇](#二整体结构篇) - - [2.1 Transformer 整体结构是怎么样?](#21-transformer-整体结构是怎么样) - - [2.2 Transformer-encoder 结构怎么样?](#22-transformer-encoder-结构怎么样) - - [2.3 Transformer-decoder 结构怎么样?](#23-transformer-decoder-结构怎么样) - - [三、模块篇](#三模块篇) - - [3.1 self-attention 模块](#31-self-attention-模块) - - [3.1.1 传统 attention 是什么?](#311-传统-attention-是什么) - - [3.1.2 为什么 会有self-attention?](#312-为什么-会有self-attention) - - [3.1.3 self-attention 的核心思想是什么?](#313-self-attention-的核心思想是什么) - - [3.1.4 self-attention 的目的是什么?](#314-self-attention-的目的是什么) - - [3.1.5 self-attention 的怎么计算的?](#315-self-attention-的怎么计算的) - - [3.1.6 self-attention 为什么Q和K使用不同的权重矩阵生成,为何不能使用同一个值进行自身的点乘?](#316-self-attention-为什么q和k使用不同的权重矩阵生成为何不能使用同一个值进行自身的点乘) - - [3.1.7 为什么采用点积模型的 self-attention 而不采用加性模型?](#317-为什么采用点积模型的-self-attention-而不采用加性模型) - - [3.1.8 Transformer 中在计算 self-attention 时为什么要scaled dot product? 即 除以 $\sqrt{d}$?](#318-transformer-中在计算-self-attention-时为什么要scaled-dot-product-即-除以-sqrtd) - - [3.1.9 self-attention 如何解决长距离依赖问题?](#319-self-attention-如何解决长距离依赖问题) - - [3.1.10 self-attention 如何并行化?](#3110-self-attention-如何并行化) - - [3.1.11 为什么用双线性点积模型(即Q,K两个向量)](#3111-为什么用双线性点积模型即qk两个向量) - - [3.2 multi-head attention 模块](#32-multi-head-attention-模块) - - [3.2.1 multi-head attention 的思路是什么样?](#321-multi-head-attention-的思路是什么样) - - [3.2.2 multi-head attention 的步骤是什么样?](#322-multi-head-attention-的步骤是什么样) - - [3.2.3 Transformer为何使用多头注意力机制?(为什么不使用一个头)](#323-transformer为何使用多头注意力机制为什么不使用一个头) - - [3.2.4 多头机制为什么有效?](#324-多头机制为什么有效) - - [3.2.5 为什么在进行多头注意力的时候需要对每个head进行降维?](#325-为什么在进行多头注意力的时候需要对每个head进行降维) - - [3.2.6 multi-head attention 代码介绍](#326-multi-head-attention-代码介绍) - - [3.3 位置编码(Position encoding)模块](#33-位置编码position-encoding模块) - - [3.3.1 为什么要 加入 位置编码(Position encoding) ?](#331-为什么要-加入-位置编码position-encoding-) - - [3.3.2 位置编码(Position encoding)的思路是什么 ?](#332-位置编码position-encoding的思路是什么-) - - [3.3.3 位置编码(Position encoding)的作用是什么 ?](#333-位置编码position-encoding的作用是什么-) - - [3.3.4 位置编码(Position encoding)的步骤是什么 ?](#334-位置编码position-encoding的步骤是什么-) - - [3.3.5 Position encoding为什么选择相加而不是拼接呢?](#335-position-encoding为什么选择相加而不是拼接呢) - - [3.3.6 Position encoding和 Position embedding的区别?](#336-position-encoding和-position-embedding的区别) - - [3.3.7 为何17年提出Transformer时采用的是 Position Encoder 而不是Position Embedding?而Bert却采用的是 Position Embedding ?](#337-为何17年提出transformer时采用的是-position-encoder--而不是position-embedding而bert却采用的是-position-embedding-) - - [3.3.8 位置编码(Position encoding)的代码介绍](#338-位置编码position-encoding的代码介绍) - - [3.4 残差模块模块](#34-残差模块模块) - - [3.4.1 为什么要 加入 残差模块?](#341-为什么要-加入-残差模块) - - [3.5 Layer normalization 模块](#35-layer-normalization-模块) - - [3.5.1 为什么要 加入 Layer normalization 模块?](#351-为什么要-加入-layer-normalization-模块) - - [3.5.2 Layer normalization 模块的是什么?](#352-layer-normalization-模块的是什么) - - [3.5.3 Batch normalization 和 Layer normalization 的区别?](#353-batch-normalization-和-layer-normalization-的区别) - - [3.5.4 Transformer 中为什么要舍弃 Batch normalization 改用 Layer normalization 呢?](#354-transformer-中为什么要舍弃-batch-normalization-改用-layer-normalization-呢) - - [3.5.5 Layer normalization 模块代码介绍](#355--layer-normalization-模块代码介绍) - - [3.6 Mask 模块](#36-mask-模块) - - [3.6.1 什么是 Mask?](#361-什么是-mask) - - [3.6.2 Transformer 中用到 几种 Mask?](#362-transformer-中用到-几种-mask) - - [3.6.3 能不能介绍一下 Transformer 中用到几种 Mask?](#363-能不能介绍一下-transformer-中用到几种-mask) - - [3.7 Feed forward network (FFN)](#37-feed-forward-network-ffn) - - [3.7.1 Feed forward network (FFN)的作用?](#371-feed-forward-network-ffn的作用) - - [3.8 GELU](#38-gelu) - - [3.8.1 GELU原理?相比RELU的优点?](#381-gelu原理相比relu的优点) - - [3.9 Transformer的非线性来自于哪里?](#39-transformer的非线性来自于哪里) - - [参考](#参考) - -## 一、动机篇 - -### 1.1 为什么要有 Transformer? - -为什么要有 Transformer? 首先需要知道在 Transformer 之前都有哪些技术,这些技术所存在的问题: - -- RNN:能够捕获长距离依赖信息,但是无法并行; -- CNN: 能够并行,无法捕获长距离依赖信息(需要通过层叠 or 扩张卷积核 来 增大感受野); -- 传统 Attention - - 方法:基于源端和目标端的隐向量计算Attention, - - 结果:源端每个词与目标端每个词间的依赖关系 【源端->目标端】 - - 问题:忽略了 远端或目标端 词与词间 的依赖关系 - -### 1.2 Transformer 作用是什么? - -基于Transformer的架构主要用于建模语言理解任务,它避免了在神经网络中使用递归,而是完全依赖于self-attention机制来绘制输入和输出之间的全局依赖关系。 - -## 二、整体结构篇 - -### 2.1 Transformer 整体结构是怎么样? - -- Transformer 整体结构: - - encoder-decoder 结构 -- 具体介绍: - - 左边是一个 Encoder; - - 右边是一个 Decoder; - -![此次是图片,手机可能打不开](img/20200623092901.png) -> Transformer 整体结构 - -1. 整体结构放大一点 - -从上一张 Transformer 结构图,可以知道 Transformer 是一个 encoder-decoder 结构,但是 encoder 和 decoder 又包含什么内容呢? -- Encoder 结构: - - 内部包含6层小encoder 每一层里面有2个子层; -- Decoder 结构: - - 内部也是包含6层小decoder ,每一层里面有3个子层 - -![此次是图片,手机可能打不开](img/20200623093042.png) -> Transformer encoder-decoder 结构 - -1. 整体结构再放大一点 - - 其中上图中每一层的内部结构如下图所求。 - - 上图左边的每一层encoder都是下图左边的结构; - - 上图右边的每一层的decoder都是下图右边的结构; - -具体内容,后面会逐一介绍。 - -![此次是图片,手机可能打不开](img/20200623093217.png) -> Transformer encoder-decoder 内部结构 - -- 代码讲解【注:代码采用 tensorflow 框架编写】 - -```s - class Transformer(tf.keras.Model): - def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, target_vocab_size, pe_input, pe_target, rate=0.1): - super(Transformer, self).__init__() - # Encoder 模块 - self.encoder = Encoder(num_layers, d_model, num_heads, dff, input_vocab_size, pe_input, rate) - # Decoder 模块 - self.decoder = Decoder(num_layers, d_model, num_heads, dff, target_vocab_size, pe_target, rate) - # 全连接层 - self.final_layer = tf.keras.layers.Dense(target_vocab_size) - - def call(self, inp, tar, training, enc_padding_mask, look_ahead_mask, dec_padding_mask): - # step 1: encoder - enc_output = self.encoder(inp, training, enc_padding_mask) - # step 2:decoder - dec_output, attention_weights = self.decoder(tar, enc_output, training, look_ahead_mask, dec_padding_mask) - # step 3:全连接层 - final_output = self.final_layer(dec_output) - - return final_output, attention_weights -``` - -### 2.2 Transformer-encoder 结构怎么样? - -![此次是图片,手机可能打不开](img/20200624080740.png) -> Transformer encoder 结构 - -- 特点: - - 与 RNN,CNN 类似,可以当成一个特征提取器; -- 组成结构介绍 - - embedding 层:将 input 转化为 embedding 向量 $X$; - - Position encodding: input的位置与 input 的 embedding $X$ 相加 得到 向量 $X$; - - self-attention : 将融合input的位置信息 与 input 的 embedding 信息的 $X$ 输入 Self-Attention 层得到 $Z$; - - 残差网络:$Z$ 与 $X$ 相加后经过 layernorm 层; - - 前馈网络:经过一层前馈网络以及 Add&Normalize,(线性转换+relu+线性转换 如下式) - -![此次是图片,手机可能打不开](img/20200624081753.png) - -- 举例说明(假设序列长度固定,如100,如输入的序列是“我爱中国”): - - 首先需要 **encoding**: - - 将词映射成一个数字,encoding后,由于序列不足固定长度,因此需要padding, - - 然后输入 embedding层,假设embedding的维度是128,则输入的序列维度就是100*128; - - 接着是**Position encodding**,论文中是直接将每个位置通过cos-sin函数进行映射; - - 分析:这部分不需要在网络中进行训练,因为它是固定。但现在很多论文是将这块也embedding,如bert的模型,至于是encoding还是embedding可取决于语料的大小,语料足够大就用embedding。将位置信息也映射到128维与上一步的embedding相加,输出100*128 - - 经过**self-attention层**: - - 操作:假设v的向量最后一维是64维(假设没有多头),该部分输出100*64; - - 经过残差网络: - - 操作:即序列的embedding向量与上一步self-attention的向量加总; - - 经过 **layer-norm**: - - 原因: - - 由于在self-attention里面更好操作而已; - - 真实序列的长度一直在变化; - - 经过 **前馈网络**: - - 目的:增加非线性的表达能力,毕竟之前的结构基本都是简单的矩阵乘法。若前馈网络的隐向量是512维,则结构最后输出100*512; -- Transformer Encoder 单元 代码讲解【注:代码采用 tensorflow 框架编写】 - -```s - class EncoderLayer(tf.keras.layers.Layer): - def __init__(self, d_model, num_heads, dff, rate=0.1): - super(EncoderLayer, self).__init__() - - self.mha = MultiHeadAttention(d_model, num_heads) - self.ffn = point_wise_feed_forward_network(d_model, dff) - - self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - - self.dropout1 = tf.keras.layers.Dropout(rate) - self.dropout2 = tf.keras.layers.Dropout(rate) - - def call(self, x, training, mask): - # step 1:多头自注意力 - attn_output, _ = self.mha(x, x, x, mask) - # step 2:前馈网络 - attn_output = self.dropout1(attn_output, training=training) - # step 3:Layer Norml - out1 = self.layernorm1(x + attn_output) - # step 4:前馈网络 - ffn_output = self.ffn(out1) - ffn_output = self.dropout2(ffn_output, training=training) - # step 5:Layer Norml - out2 = self.layernorm2(out1 + ffn_output) - - return out2 -``` - -- Transformer Encoder 模块代码讲解【注:代码采用 tensorflow 框架编写】 - -```s - class Encoder(tf.keras.layers.Layer): - def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, maximum_position_encoding, rate=0.1): - super(Encoder, self).__init__() - - self.d_model = d_model - self.num_layers = num_layers # encoder 层数 - # 词嵌入 - self.embedding = tf.keras.layers.Embedding(input_vocab_size, d_model) - # 位置编码 - self.positional_encoding_obj = Positional_Encoding() - self.pos_encoding = self.positional_encoding_obj.positional_encoding(maximum_position_encoding, self.d_model) - # Encoder 模块构建 - self.enc_layers = [EncoderLayer(d_model, num_heads, dff, rate) for _ in range(num_layers)] - - self.dropout = tf.keras.layers.Dropout(rate) - - def call(self, x, training, mask): - seq_len = tf.shape(x)[1] - # step 1:词嵌入 - x = self.embedding(x) - x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32)) - # step 2:位置编码 - x += self.pos_encoding[:, :seq_len, :] - x = self.dropout(x, training=training) - # step 3:Encoder 模块构建 - for i in range(self.num_layers): - x = self.enc_layers[i](x, training, mask) - return x -``` - -### 2.3 Transformer-decoder 结构怎么样? - -![此次是图片,手机可能打不开](img/20200624083258.png) -> Transformer decoder 结构 - -- 特点:与 encoder 类似 -- 组成结构介绍 - - masked 层: - - 目的:确保了位置 i 的预测仅依赖于小于 i 的位置处的已知输出; - - Linear layer: - - 目的:将由解码器堆栈产生的向量投影到一个更大的向量中,称为对数向量。这个向量对应着模型的输出词汇表;向量中的每个值,对应着词汇表中每个单词的得分; - - softmax层: - - 操作:这些分数转换为概率(所有正数,都加起来为1.0)。选择具有最高概率的单元,并且将与其相关联的单词作为该时间步的输出 -- Transformer Decoder 单元 代码讲解【注:代码采用 tensorflow 框架编写】 - -```s - class DecoderLayer(tf.keras.layers.Layer): - def __init__(self, d_model, num_heads, dff, rate=0.1): - super(DecoderLayer, self).__init__() - - self.mha1 = MultiHeadAttention(d_model, num_heads) - self.mha2 = MultiHeadAttention(d_model, num_heads) - - self.ffn = point_wise_feed_forward_network(d_model, dff) - - self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - self.layernorm3 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - - self.dropout1 = tf.keras.layers.Dropout(rate) - self.dropout2 = tf.keras.layers.Dropout(rate) - self.dropout3 = tf.keras.layers.Dropout(rate) - - - def call(self, x, enc_output, training, look_ahead_mask, padding_mask): - # step 1:带 sequence mask 的 多头自注意力 - attn1, attn_weights_block1 = self.mha1(x, x, x, look_ahead_mask) - attn1 = self.dropout1(attn1, training=training) - # step 2:Layer Norm - out1 = self.layernorm1(attn1 + x) - # step 3:带 padding mask 的 多头自注意力 - attn2, attn_weights_block2 = self.mha2(enc_output, enc_output, out1, padding_mask) - attn2 = self.dropout2(attn2, training=training) - # step 4:Layer Norm - out2 = self.layernorm2(attn2 + out1) - # step 5:前馈网络 - ffn_output = self.ffn(out2) - ffn_output = self.dropout3(ffn_output, training=training) - # step 6:Layer Norm - out3 = self.layernorm3(ffn_output + out2) - return out3, attn_weights_block1, attn_weights_block2 - -``` - -- Transformer Decoder 模块代码讲解【注:代码采用 tensorflow 框架编写】 - -```s - class Decoder(tf.keras.layers.Layer): - def __init__(self, num_layers, d_model, num_heads, dff, target_vocab_size, maximum_position_encoding, rate=0.1): - super(Decoder, self).__init__() - - self.d_model = d_model - self.num_layers = num_layers # encoder 层数 - # 词嵌入 - self.embedding = tf.keras.layers.Embedding(target_vocab_size, d_model) - # 位置编码 - self.positional_encoding_obj = Positional_Encoding() - self.pos_encoding = self.positional_encoding_obj.positional_encoding(maximum_position_encoding, d_model) - # Dncoder 模块构建 - self.dec_layers = [DecoderLayer(d_model, num_heads, dff, rate) for _ in range(num_layers)] - self.dropout = tf.keras.layers.Dropout(rate) - - def call(self, x, enc_output, training, look_ahead_mask, padding_mask): - seq_len = tf.shape(x)[1] - attention_weights = {} - # step 1:词嵌入 - x = self.embedding(x) - x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32)) - # step 2:位置编码 - x += self.pos_encoding[:, :seq_len, :] - - x = self.dropout(x, training=training) - # step 3:Dncoder 模块构建 - for i in range(self.num_layers): - x, block1, block2 = self.dec_layers[i](x, enc_output, training, look_ahead_mask, padding_mask) - - attention_weights['decoder_layer{}_block1'.format(i+1)] = block1 - attention_weights['decoder_layer{}_block2'.format(i+1)] = block2 - - return x, attention_weights - -``` - -## 三、模块篇 - -### 3.1 self-attention 模块 - -#### 3.1.1 传统 attention 是什么? - -在介绍 self-attention 之前,首先需要介绍一下 传统的 attention,其结构如下图所示: - -![此次是图片,手机可能打不开](img/微信截图_20200625085139.png) -> 传统的 attention 结构 - -- 注意力机制是什么呢? - - 就是将精力集中于某一个点上 - - 举个例子: - - 你在超市买东西,突然一个美女从你身边走过,这个时候你会做什么呢? - - 没错,就是将视线【也就是注意力】集中于这个美女身上,而周围环境怎么样,你都不关注。 -- 思路 - - 输入 给定 Target 中某个 query; - - 计算权值 Score: - - 计算 query 和 各个 Key 的相似度或相关性,得到每个 Key 对应 value 的权值系数; - - 对 权值 Score 和 value 进行加权求和 -- 核心: - - Attention 机制 是对 source 中各个元素 的 value 进行加权求和,而 query 和 key 用于计算 对应 value 的权值系数 - -![此次是图片,手机可能打不开](img/微信截图_20200625085922.png) - -> $L_x=||Source||$代表Source的长度 - -- 概念: - - attention 的核心 就是从 大量信息中 筛选出少量的 重要信息; - - 具体操作:每个 value 的 权值系数,代表 其 重要度; - -![此次是图片,手机可能打不开](img/微信截图_20200625090454.png) -> 传统的 attention 流程 - -- 具体流程介绍 - - step 1:计算权值系数 - - 采用 不同的函数或计算方式,对 query 和 key 进行计算,求出相似度或相关性 - - 采用的计算方法: - - 向量点积: - - ![](img/20201009163936.png) - - - Cosine 相似度计算: - - ![](img/20201009164019.png) - - - MLP 网络: - - ![](img/20201009164053.png) - - - step 2: softmax 归一化 - - 原因: - 1. score 值分布过散,将原始计算分值整理成所有元素权重之和为1 的概率分布; - 2. 可以通过SoftMax的内在机制更加突出重要元素的权重; - - 公式介绍 - - ![此次是图片,手机可能打不开](img/微信截图_20200625093537.png) - - - step 3: 加权求和 - - 公式介绍: - - 计算结果 $a_i$ 即为 $value_i$ 对应的权重系数,然后进行加权求和即可得到Attention数值 - -![此次是图片,手机可能打不开](img/微信截图_20200625095930.png) - -- 存在问题 - - 忽略了 源端或目标端 词与词间 的依赖关系【以上面栗子为例,就是把注意力集中于美女身上,而没看自己周围环境,结果可能就扑街了!】 - -#### 3.1.2 为什么 会有self-attention? - -- CNN 所存在的长距离依赖问题; -- RNN 所存在的无法并行化问题【虽然能够在一定长度上缓解 长距离依赖问题】; -- 传统 Attention - - 方法:基于源端和目标端的隐向量计算Attention, - - 结果:源端每个词与目标端每个词间的依赖关系 【源端->目标端】 - - 问题:忽略了 远端或目标端 词与词间 的依赖关系 - -#### 3.1.3 self-attention 的核心思想是什么? - -- 核心思想:self-attention的结构在计算每个token时,总是会考虑整个序列其他token的表达; - - 举例:“我爱中国”这个序列,在计算"我"这个词的时候,不但会考虑词本身的embedding,也同时会考虑其他词对这个词的影响 - -#### 3.1.4 self-attention 的目的是什么? - -- 目的:学习句子内部的词依赖关系,捕获句子的内部结构。 - -#### 3.1.5 self-attention 的怎么计算的? - -![此次是图片,手机可能打不开](img/20200624084515.png) -> self-attention 计算公式 - -![此次是图片,手机可能打不开](img/微信截图_20200625082324.png) -> self-attention 结构图 - -- **一句话概述:每个位置的embedding对应 Q,K,V 三个向量,这三个向量分别是embedding点乘 WQ,WK,WV 矩阵得来的。每个位置的Q向量去乘上所有位置的K向量,其结果经过softmax变成attention score,以此作为权重对所有V向量做加权求和即可。** - -- 具体步骤 - - embedding层: - - 目的:将词转化成embedding向量; - - Q,K,V 向量计算: - - 根据 embedding 和权重矩阵,得到Q,K,V; - - Q:查询向量,目标字作为 Query; - - K:键向量,其上下文的各个字作为 Key; - - V:值向量,上下文各个字的 Value; - - 权重 score 计算: - - 查询向量 query 点乘 key; - - 目的:计算其他词对这个词的重要性,也就是权值; - - scale 操作: - - 乘以 $\frac{1}{\sqrt{d_{k}}}$; - - 目的:起到调节作用,使得内积不至于太大。实际上是Q,K,V的最后一个维度,当 $d_k$ 越大, $QK^T$ 就越大,可能会将 Softmax 函数推入梯度极小的区域; - - Softmax 归一化: - - 经过 Softmax 归一化; - - Attention 的输出计算: - - 权值 score 和各个上下文字的 V 向量 的加权求和 - - 目的:把上下文各个字的 V 融入目标字的原始 V 中 -- 举例 - - 答案就是文章中的Q,K,V,这三个向量都可以表示"我"这个词,但每个向量的作用并不一样,Q 代表 query,当计算"我"这个词时,它就能代表"我"去和其他词的 K 进行点乘计算其他词对这个词的重要性,所以此时其他词(包括自己)使用 K 也就是 key 代表自己,当计算完点乘后,我们只是得到了每个词对“我”这个词的权重,需要再乘以一个其他词(包括自己)的向量,也就是V(value),才完成"我"这个词的计算,同时也是完成了用其他词来表征"我"的一个过程 - -- 优点 - - 捕获源端和目标端词与词间的依赖关系 - - 捕获源端或目标端自身词与词间的依赖关系 -- 代码讲解【注:代码采用 tensorflow 框架编写】 - -```s - def scaled_dot_product_attention(q, k, v, mask): - # s1:权重 score 计算:查询向量 query 点乘 key - matmul_qk = tf.matmul(q, k, transpose_b=True) - # s2:scale 操作:除以 sqrt(dk),将 Softmax 函数推入梯度极小的区域 - dk = tf.cast(tf.shape(k)[-1], tf.float32) - scaled_attention_logits = matmul_qk / tf.math.sqrt(dk) - # s3: - if mask is not None: - scaled_attention_logits += (mask * -1e9) - # s4:Softmax 归一化 - attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1) - # s5:加权求和 - output = tf.matmul(attention_weights, v) - return output, attention_weights -``` - -#### 3.1.6 self-attention 为什么Q和K使用不同的权重矩阵生成,为何不能使用同一个值进行自身的点乘? - -因为Q、K、V的不同,可以保证在不同空间进行投影,增强了表达能力,提高了泛化能力。 - -#### 3.1.7 为什么采用点积模型的 self-attention 而不采用加性模型? - -主要原因:在理论上,加性模型和点积模型的复杂度差不多,但是点积模型在实现上可以更好地利用矩阵乘法,而矩阵乘法有很多加速策略,因此能加速训练。但是论文中实验表明,当维度$d$越来越大时,加性模型的效果会略优于点积模型,原因应该是加性模型整体上还是比点积模型更复杂(有非线性因素)。 - -#### 3.1.8 Transformer 中在计算 self-attention 时为什么要scaled dot product? 即 除以 $\sqrt{d}$? - -> 一句话回答:当输入信息的维度 d 比较高,会导致 softmax 函数接近饱和区,梯度会比较小。因此,缩放点积模型可以较好地解决这一问题。 - -> 具体分析: - -- 因为对于![](img/微信截图_20201222225938.png),如果某个![](img/QQ截图20201222230028.png)相对于其他元素很大的话,那么对此向量softmax后就容易得到一个onehot向量,不够“soft”了,而且反向传播时梯度为0会导致梯度消失; - -![](img/QQ截图20201222225802.png) - -- 原论文是这么解释的:假设每个$\boldsymbol q\in R^d$和$\boldsymbol k\in R^d$的每个维度都是服从均值为0方差为1的,那么二者的内积$\boldsymbol q^T\boldsymbol k$的均值就是0,方差就是$d$,所以内积的方差和原始方差之间的比例大约是维度值$d$,为了降低内积各个维度值的方差(这样各个维度取值就在均值附近,不会存在某个维度偏离均值太远),所以要除以$\sqrt{d}$(标准差) - -#### 3.1.9 self-attention 如何解决长距离依赖问题? - -- 引言: - - 在上一个问题中,我们提到 CNN 和 RNN 在处理长序列时,都存在 长距离依赖问题,那么你是否会有这样 几个问题: - - 长距离依赖问题 是什么呢? - - 为什么 CNN 和 RNN 无法解决长距离依赖问题? - - 之前提出过哪些解决方法? - - self-attention 是如何 解决 长距离依赖问题的呢? - -下面,我们将会围绕着几个问题,进行一一解答。 - -- 长距离依赖问题 是什么呢? - - 介绍:对于序列问题,第 $t$ 时刻 的 输出 $y_t$ 依赖于 $t$ 之前的输入,也就是 说 依赖于 $x_{t-k}, k=1,...,t$,当间隔 $k$ 逐渐增大时,$x_{t-k}$ 的信息将难以被 $y_t$ 所学习到,也就是说,很难建立 这种 长距离依赖关系,这个也就是 长距离依赖问题(Long-Term Dependencies Problem)。 -- 为什么 CNN 和 RNN 无法解决长距离依赖问题? - - CNN: - - 捕获信息的方式: - - CNN 主要采用 卷积核 的 方式捕获 句子内的局部信息,你可以把他理解为 **基于 n-gram 的局部编码方式**捕获局部信息 - - 问题: - - 因为是 n-gram 的局部编码方式,那么当 $k$ 距离 大于 $n$ 时,那么 $y_t$ 将难以学习 $x_{t-k}$ 信息; - - 举例: - - 其实 n-gram 类似于 人的 视觉范围,人的视觉范围 在每一时刻 只能 捕获 一定 范围内 的信息,比如,你在看前面的时候,你是不可能注意到背后发生了什么,除非你转过身往后看。 - - RNN: - - 捕获信息的方式: - - RNN 主要 通过 循环 的方式学习(记忆) 之前的信息$x_{t}$; - - 问题: - - 但是随着时间 $t$ 的推移,你会出现**梯度消失或梯度爆炸**问题,这种问题使你只能建立短距离依赖信息。 - - 举例: - - RNN 的学习模式好比于 人类 的记忆力,人类可能会对 短距离内发生的 事情特别清楚,但是随着时间的推移,人类开始 会对 好久之前所发生的事情变得印象模糊,比如,你对小时候发生的事情,印象模糊一样。 - - 解决方法: - - 针对该问题,后期也提出了很多 RNN 变体,比如 LSTM、 GRU,这些变体 通过引入 门控的机制 来 有选择性 的记忆 一些 重要的信息,但是这种方法 也只能在 一定程度上缓解 长距离依赖问题,但是并不能 从根本上解决问题。 - -![此次是图片,手机可能打不开](img/QQ截图20200626120834.png) -> 基于卷积网络和循环网络的变长序列编码 - -- 之前提出过哪些解决方法? - - 引言: - - 那么 之前 主要采用 什么方法 解决问题呢? - - 解决方法: - - 增加网络的层数 - - 通过一个深层网络来获取远距离的信息交互 - - 使用全连接网络 - - 通过全连接的方法对 长距离 建模; - - 问题: - - 无法处理变长的输入序列; - - 不同的输入长度,其连接权重的大小也是不同的; - -![此次是图片,手机可能打不开](img/QQ截图20200626122726.png) -> 全连接模型和自注意力模型 - -- self-attention 是如何 解决 长距离依赖问题的呢? - - 解决方式: - - 利用注意力机制来“动态”地生成不同连接的权重,从而处理变长的信息序列 - - 具体介绍: - - 对于 当前query,你需要 与 句子中 所有 key 进行点乘后再 Softmax ,以获得 句子中 所有 key 对于 当前query 的 score(可以理解为 贡献度),然后与 所有词 的 value 向量进行加权融合之后,就能使 当前 $y_t$ 学习到句子中 其他词$x_{t-k}$的信息; - -#### 3.1.10 self-attention 如何并行化? - -- 引言: - - 在上一个问题中,我们主要讨论了 CNN 和 RNN 在处理长序列时,都存在 长距离依赖问题,以及 Transformer 是 如何解决 长距离依赖问题,但是对于 RNN ,还存在另外一个问题: - - 无法并行化问题 - - 那么,Transformer 是如何进行并行化的呢? -- Transformer 如何进行并行化? - - 核心:self-attention - - 为什么 RNN 不能并行化: - - 原因:RNN 在 计算 $x_i$ 的时候,需要考虑到 $x_1 ~ x_{i-1}$ 的 信息,使得 RNN 只能 从 $x_1$ 计算到 $x_i$; - - 思路: - - 在 self-attention 能够 并行的 计算 句子中不同 的 query,因为每个 query 之间并不存在 先后依赖关系,也使得 transformer 能够并行化; - -#### 3.1.11 为什么用双线性点积模型(即Q,K两个向量) - -双线性点积模型使用Q,K两个向量,而不是只用一个Q向量,这样引入非对称性,更具健壮性(Attention对角元素值不一定是最大的,也就是说当前位置对自身的注意力得分不一定最高)。 - -### 3.2 multi-head attention 模块 - -#### 3.2.1 multi-head attention 的思路是什么样? - -- 思路: - - 相当于 $h$ 个 不同的 self-attention 的集成 - - 就是把self-attention做 n 次,取决于 head 的个数;论文里面是做了8次。 - -#### 3.2.2 multi-head attention 的步骤是什么样? - -- 步骤: - - step 1 : 初始化 N 组 $Q,K,V$矩阵(论文为 8组); - -![此次是图片,手机可能打不开](img/QQ截图20200625101229.png) -> 初始化 N 组 $Q,K,V$矩阵 - - - step 2 : 每组 分别 进行 self-attention; - - step 3: - - 问题:多个 self-attention 会得到 多个 矩阵,但是前馈神经网络没法输入8个矩阵; - - 目标:把8个矩阵降为1个 - - 步骤: - - 每次self-attention都会得到一个 Z 矩阵,把每个 Z 矩阵拼接起来, - - 再乘以一个Wo矩阵, - - 得到一个最终的矩阵,即 multi-head Attention 的结果; - -![此次是图片,手机可能打不开](img/20200624090026.png) -> 合并 8 个矩阵 - -最后,让我们来看一下完整的流程: - -![此次是图片,手机可能打不开](img/20200624090034.png) -> 完整的流程 - -换一种表现方式: - -![此次是图片,手机可能打不开](img/微信截图_20200625101800.png) -> multi-head attention 表示方式 - -- 动图介绍 - -![此次是图片,手机可能打不开](img/v2-595ce4ebf9b3fccb479f7d234190af35_b.gif) -> multi-head attention 动图展示 - -#### 3.2.3 Transformer为何使用多头注意力机制?(为什么不使用一个头) - -为了让 Transformer 能够注意到不同子空间的信息,从而捕获到跟多的特征信息。【本质:实验定律】 - -#### 3.2.4 多头机制为什么有效? - -类似于CNN中通过多通道机制进行特征选择。Transformer中使用切头(split)的方法,是为了在不增加复杂度($O(n^2 d)$)的前提下享受类似CNN中“不同卷积核”的优势。 - -#### 3.2.5 为什么在进行多头注意力的时候需要对每个head进行降维? - -Transformer的多头注意力看上去是借鉴了CNN中同一卷积层内使用多个卷积核的思想,原文中使用了 8 个“scaled dot-product attention”,在同一“multi-head attention”层中,输入均为“KQV”,同时进行注意力的计算,彼此之前参数不共享,最终将结果拼接起来,这样可以允许模型在不同的表示子空间里学习到相关的信息,在此之前的 A Structured Self-attentive Sentence Embedding 也有着类似的思想。简而言之,就是希望每个注意力头,只关注最终输出序列中一个子空间,互相独立。其核心思想在于,抽取到更加丰富的特征信息。 - -#### 3.2.6 multi-head attention 代码介绍 - -- multi-head attention 模块代码讲解【注:代码采用 tensorflow 框架编写】 -```s - class MultiHeadAttention(tf.keras.layers.Layer): - def __init__(self, d_model, num_heads): - super(MultiHeadAttention, self).__init__() - self.num_heads = num_heads - self.d_model = d_model - assert d_model % self.num_heads == 0 - self.depth = d_model // self.num_heads - # 初始化 Q,K,V 矩阵 - self.wq = tf.keras.layers.Dense(d_model) - self.wk = tf.keras.layers.Dense(d_model) - self.wv = tf.keras.layers.Dense(d_model) - self.dense = tf.keras.layers.Dense(d_model) - - def split_heads(self, x, batch_size): - x = tf.reshape(x, (batch_size, -1, self.num_heads, self.depth)) - return tf.transpose(x, perm=[0, 2, 1, 3]) - - def call(self, v, k, q, mask): - batch_size = tf.shape(q)[0] - # step 1:利用矩阵计算 q,k,v - q = self.wq(q) - k = self.wk(k) - v = self.wv(v) - # step 2: - q = self.split_heads(q, batch_size) - k = self.split_heads(k, batch_size) - v = self.split_heads(v, batch_size) - # step 3:每组 分别 进行 self-attention - scaled_attention, attention_weights = scaled_dot_product_attention( - q, k, v, mask) - # step 4:矩阵拼接 - scaled_attention = tf.transpose(scaled_attention, perm=[0, 2, 1, 3]) - concat_attention = tf.reshape(scaled_attention, (batch_size, -1, self.d_model)) - # step 5:全连接层 - output = self.dense(concat_attention) - return output, attention_weights -``` - -### 3.3 位置编码(Position encoding)模块 - -#### 3.3.1 为什么要 加入 位置编码(Position encoding) ? - -- 问题: - - 介绍:缺乏 一种 表示 输入序列中 单词顺序 的方法 - - 说明:因为模型不包括Recurrence/Convolution,因此是无法捕捉到序列顺序信息的,例如将K、V按行进行打乱,那么Attention之后的结果是一样的。但是序列信息非常重要,代表着全局的结构,因此必须将序列的分词相对或者绝对position信息利用起来 -- 目的:加入词序信息,使 Attention 能够分辨出不同位置的词 - -#### 3.3.2 位置编码(Position encoding)的思路是什么 ? - -- 思路: - - 在 encoder 层和 decoder 层的输入添加了一个额外的向量Positional Encoding,维度和embedding的维度一样,让模型学习到这个值 - -#### 3.3.3 位置编码(Position encoding)的作用是什么 ? - -- 位置向量的作用: - - 决定当前词的位置; - - 计算在一个句子中不同的词之间的距离 - -#### 3.3.4 位置编码(Position encoding)的步骤是什么 ? - -- 步骤: - - 将每个位置编号, - - 然后每个编号对应一个向量, - - 通过将位置向量和词向量相加,就给每个词都引入了一定的位置信息。 - -![此次是图片,手机可能打不开](img/QQ截图20200625103634.png) -> 位置编码(Position encoding) 结构图 - -- 论文的位置编码是使用三角函数去计算的。好处: - - 值域只有[-1,1] - - 容易计算相对位置。 - -![此次是图片,手机可能打不开](img/20200624090357.png) - -> 注:
-> pos 表示当前词在句子中的位置
-> i 表示向量中每个值 的 index
-> 在偶数位置:使用 正弦编码 sin();
-> 在奇数位置:使用 余弦编码 cos();
- -#### 3.3.5 Position encoding为什么选择相加而不是拼接呢? - -因为$[W1 W2][e; p] = W1e + W2p,W(e+p)=We+Wp$,就是说求和相当于拼接的两个权重矩阵共享(W1=W2=W),但是这样权重共享是明显限制了表达能力的。 - -#### 3.3.6 Position encoding和 Position embedding的区别? - -- Position encoding 构造简单直接无需额外的学习参数;能兼容预训练阶段的最大文本长度和训练阶段的最大文本长度不一致; -- Position embedding 构造也简单直接但是需要额外的学习参数;训练阶段的最大文本长度不能超过预训练阶段的最大文本长度(因为没学过这么长的,不知道如何表示);但是Position embedding 的潜力在直觉上会比 Position encoding 大,因为毕竟是自己学出来的,只有自己才知道自己想要什么(前提是数据量得足够大)。 - -#### 3.3.7 为何17年提出Transformer时采用的是 Position Encoder 而不是Position Embedding?而Bert却采用的是 Position Embedding ? - -- Transformer 的作者在论文中对比了 Position Encoder 和 Position Embedding,在模型精度上没有明显区别。出于对序列长度限制和参数量规模的考虑,最终选择了 Encode 的形式。那么为什么Bert不这么干呢?主要原因如下: - - 模型的结构需要服务于模型的目标:Transformer最开始提出是针对机器翻译任务的,而机器翻译任务对词序特征要求不高,因此在效果差不多的情况下选择Position Encoder 足矣。但是Bert是作为通用的预训练模型,下游任务有很多对词序特征要求很高,因此选择潜力比较大的Position Embedding会更好; - - 数据量的角度:Transformer用的数据量没有Bert的数据量大,所以使用潜力无限的 Position Embedding 会有大力出奇迹的效果; - -#### 3.3.8 位置编码(Position encoding)的代码介绍 - -- 位置编码(Position encoding)模块代码讲解【注:代码采用 tensorflow 框架编写】 - -```s - # 位置编码 类 - class Positional_Encoding(): - def __init__(self): - pass - # 功能:计算角度 函数 - def get_angles(self, position, i, d_model): - ''' - 功能:计算角度 函数 - input: - position 单词在句子中的位置 - i 维度 - d_model 向量维度 - ''' - angle_rates = 1 / np.power(10000, (2 * (i // 2)) / np.float32(d_model)) - return position * angle_rates - # 功能:位置编码 函数 - def positional_encoding(self, position, d_model): - ''' - 功能:位置编码 函数 - input: - position 单词在句子中的位置 - d_model 向量维度 - ''' - angle_rads = self.get_angles( - np.arange(position)[:, np.newaxis], - np.arange(d_model)[np.newaxis, :], - d_model - ) - - # apply sin to even indices in the array; 2i - angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2]) - - # apply cos to odd indices in the array; 2i+1 - angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2]) - - pos_encoding = angle_rads[np.newaxis, ...] - - return tf.cast(pos_encoding, dtype=tf.float32) -``` - -### 3.4 残差模块模块 - -#### 3.4.1 为什么要 加入 残差模块? - -- 动机:因为 transformer 堆叠了 很多层,容易 梯度消失或者梯度爆炸 - -### 3.5 Layer normalization 模块 - -#### 3.5.1 为什么要 加入 Layer normalization 模块? - -- 动机:因为 transformer 堆叠了 很多层,容易 梯度消失或者梯度爆炸; -- 原因: - - 数据经过该网络层的作用后,不再是归一化,偏差会越来越大,所以需要将 数据 重新 做归一化处理; -- 目的: - - 在数据送入激活函数之前进行normalization(归一化)之前,需要将输入的信息利用 normalization 转化成均值为0方差为1的数据,避免因输入数据落在激活函数的饱和区而出现 梯度消失或者梯度爆炸 问题 - -#### 3.5.2 Layer normalization 模块的是什么? - -- 介绍: - - 归一化的一种方式 - - 对每一个样本介绍均值和方差【这个与 BN 有所不同,因为他是在 批方向上 计算均值和方差】 - -#### 3.5.3 Batch normalization 和 Layer normalization 的区别? -- 公式 - -> BN 计算公式 - -![此次是图片,手机可能打不开](img/QQ截图20200625110603.png) - -> LN 计算公式 - -![此次是图片,手机可能打不开](img/QQ截图20200625110706.png) - -- Batch normalization — 为每一个小batch计算每一层的平均值和方差 -- Layer normalization — 独立计算每一层每一个样本的均值和方差 - -#### 3.5.4 Transformer 中为什么要舍弃 Batch normalization 改用 Layer normalization 呢? - -原始BN是为CNN而设计的,对整个batchsize范围内的数据进行考虑; - -**对于RNN来说,sequence的长度是不一致的,所以用很多padding来表示无意义的信息。如果用 BN 会导致有意义的embedding 损失信息。** - -所以,BN一般用于CNN,而LN用于RNN。 - -layernorm是**在hidden size的维度进行**的,**跟batch和seq_len无关**。每个hidden state都计算自己的均值和方差,这是因为不同hidden state的量纲不一样。beta和gamma的维度都是(hidden_size,),经过白化的hidden state * beta + gamma得到最后的结果。 - -**LN在BERT中主要起到白化的作用,增强模型稳定性(如果删除则无法收敛)** - -- 参考:[Transformer代码+面试细节](https://zhuanlan.zhihu.com/p/438634058) - -#### 3.5.5 Layer normalization 模块代码介绍 - -- Layer normalization 模块代码讲解【注:代码采用 tensorflow 框架编写】 -```s - class EncoderLayer(tf.keras.layers.Layer): - def __init__(self, d_model, num_heads, dff, rate=0.1): - ... - self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - ... - - def call(self, x, training, mask): - ... - # step 3:Layer Norml - out1 = self.layernorm1(x + attn_output) - # step 4:前馈网络 - ffn_output = self.ffn(out1) - ffn_output = self.dropout2(ffn_output, training=training) - # step 5:Layer Norml - out2 = self.layernorm2(out1 + ffn_output) - - return out2 -``` - -### 3.6 Mask 模块 - -#### 3.6.1 什么是 Mask? - -- 介绍:掩盖某些值的信息,让模型信息不到该信息; - -#### 3.6.2 Transformer 中用到 几种 Mask? - -- 答案:两种 -- 类别:padding mask and sequence mask - -#### 3.6.3 能不能介绍一下 Transformer 中用到几种 Mask? - -1. padding mask - -- 作用域:每一个 scaled dot-product attention 中 -- 动机:输入句子的长度不一问题 -- 方法: - - 短句子:后面 采用 0 填充 - - 长句子:只截取 左边 部分内容,其他的丢弃 -- 原因:对于 填充 的位置,其所包含的信息量 对于 模型学习 作用不大,所以 self-attention 应该 抛弃对这些位置 进行学习; -- 做法:在这些位置上加上 一个 非常大 的负数(负无穷),使 该位置的值经过 Softmax 后,值近似 0,利用 padding mask 标记哪些值需要做处理; -- 实现: -```s - # 功能: padding mask - def create_padding_mask(seq): - ''' - 功能: padding mask - input: - seq 序列 - ''' - seq = tf.cast(tf.math.equal(seq, 0), tf.float32) - return seq[:, tf.newaxis, tf.newaxis, :] -``` - -2. sequence mask - -- 作用域:只作用于 decoder 的 self-attention 中 -- 动机:不可预测性; -- 目标:sequence mask 是为了使得 decoder 不能看见未来的信息。也就是对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。因此我们需要想一个办法,把 t 之后的信息给隐藏起来。 -- 做法: - - 产生一个下三角矩阵,上三角的值全为0,下三角全是 1。把这个矩阵作用在每一个序列上,就可以达到我们的目的 - -![](img/微信截图_20210128073806.png) -> sequence mask 公式 - -![](img/微信截图_20210128074033.png) -> 注意力矩阵, 每个元素 $a_{ij}$ 代表 第 i 个词和第 j 个词的内积相似度 - -![](img/微信截图_20210128074300.png) -> 下三角矩阵,上三角的值全为0,下三角全是 1 - -> 注: -> -> 在 decoder 的 scaled dot-product attention 中,里面的 attn_mask = padding mask + sequence mask -> -> 在 encoder 的 scaled dot-product attention 中,里面的 attn_mask = padding mask - -- 实现: -```s - # 功能:sequence mask - def create_look_ahead_mask(size): - ''' - 功能: sequence mask - input: - seq 序列 - ''' - mask = 1 - tf.linalg.band_part(tf.ones((size, size)), -1, 0) - return mask -``` - -### 3.7 Feed forward network (FFN) - -#### 3.7.1 Feed forward network (FFN)的作用? - -答:Transformer在抛弃了 LSTM 结构后,FFN 中的激活函数成为了一个主要的提供**非线性变换的单元**。 - -- 参考:[Transformer代码+面试细节](https://zhuanlan.zhihu.com/p/438634058) - -### 3.8 GELU - -#### 3.8.1 GELU原理?相比RELU的优点? - -答: - -- ReLU会确定性的将输入乘上一个0或者1(当x<0时乘上0,否则乘上1); -- Dropout则是随机乘上0; -- **GELU虽然也是将输入乘上0或1,但是输入到底是乘以0还是1,是在取决于输入自身的情况下随机选择的。** - -具体说明: - -我们将神经元的输入 x 乘上一个服从伯努利分布的 m 。而该伯努利分布又是依赖于 x 的: - -![](img/微信截图_20211203094546.png) - -其中, X~N(0,1),那么 φ(x) 就是标准正态分布的累积分布函数。这么做的原因是因为神经元的输入 x 往往遵循正态分布,尤其是深度网络中普遍存在Batch Normalization的情况下。当x减小时, φ(x) 的值也会减小,此时x被“丢弃”的可能性更高。所以说这是随机依赖于输入的方式。 - -现在,给出GELU函数的形式: - -![](img/微信截图_20211203095003.png) - -其中 φ(x) 是上文提到的标准正态分布的累积分布函数。因为这个函数没有解析解,所以要用近似函数来表示。 - -> 图像 - -![](img/微信截图_20211203095438.png) - -> 导数 - -![](img/微信截图_20211203095511.png) - -**所以,GELU的优点就是在ReLU上增加随机因素,x越小越容易被mask掉。** - -- 参考:[Transformer代码+面试细节](https://zhuanlan.zhihu.com/p/438634058) - -### 3.9 Transformer的非线性来自于哪里? - -FFN的gelu激活函数和self-attention,注意self-attention是非线性的(因为有相乘和softmax)。 - - -## 参考 - -1. [Transformer理论源码细节详解](https://zhuanlan.zhihu.com/p/106867810) -2. [论文笔记:Attention is all you need(Transformer)](https://zhuanlan.zhihu.com/p/51089880) -3. [深度学习-论文阅读-Transformer-20191117](https://zhuanlan.zhihu.com/p/92234185) -4. [Transform详解(超详细) Attention is all you need论文](https://zhuanlan.zhihu.com/p/63191028) -5. [目前主流的attention方法都有哪些?](https://www.zhihu.com/question/68482809/answer/597944559) -6. [transformer三部曲](https://zhuanlan.zhihu.com/p/85612521) -7. [Transformer代码+面试细节](https://zhuanlan.zhihu.com/p/438634058) \ No newline at end of file diff --git a/MachineLearningAlgorithm/img/1610160500583.png b/MachineLearningAlgorithm/img/1610160500583.png deleted file mode 100644 index 36e28d4..0000000 Binary files a/MachineLearningAlgorithm/img/1610160500583.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/1610177872501.png b/MachineLearningAlgorithm/img/1610177872501.png deleted file mode 100644 index dac4a6e..0000000 Binary files a/MachineLearningAlgorithm/img/1610177872501.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20180404113714719.png b/MachineLearningAlgorithm/img/20180404113714719.png deleted file mode 100644 index 214d398..0000000 Binary files a/MachineLearningAlgorithm/img/20180404113714719.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20180404135638186.png b/MachineLearningAlgorithm/img/20180404135638186.png deleted file mode 100644 index ec7f811..0000000 Binary files a/MachineLearningAlgorithm/img/20180404135638186.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20180404150134375.png b/MachineLearningAlgorithm/img/20180404150134375.png deleted file mode 100644 index cef86fe..0000000 Binary files a/MachineLearningAlgorithm/img/20180404150134375.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20200812200223.png b/MachineLearningAlgorithm/img/20200812200223.png deleted file mode 100644 index 0811a3d..0000000 Binary files a/MachineLearningAlgorithm/img/20200812200223.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20200812200551.png b/MachineLearningAlgorithm/img/20200812200551.png deleted file mode 100644 index deb0248..0000000 Binary files a/MachineLearningAlgorithm/img/20200812200551.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20200812200740.png b/MachineLearningAlgorithm/img/20200812200740.png deleted file mode 100644 index 525b625..0000000 Binary files a/MachineLearningAlgorithm/img/20200812200740.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20200812203815.png b/MachineLearningAlgorithm/img/20200812203815.png deleted file mode 100644 index 9677ecd..0000000 Binary files a/MachineLearningAlgorithm/img/20200812203815.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20200812204613.png b/MachineLearningAlgorithm/img/20200812204613.png deleted file mode 100644 index c762226..0000000 Binary files a/MachineLearningAlgorithm/img/20200812204613.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20200906192126.png b/MachineLearningAlgorithm/img/20200906192126.png deleted file mode 100644 index c4d6678..0000000 Binary files a/MachineLearningAlgorithm/img/20200906192126.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20200906192221.png b/MachineLearningAlgorithm/img/20200906192221.png deleted file mode 100644 index 21e2bba..0000000 Binary files a/MachineLearningAlgorithm/img/20200906192221.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20200906192249.png b/MachineLearningAlgorithm/img/20200906192249.png deleted file mode 100644 index 22b4175..0000000 Binary files a/MachineLearningAlgorithm/img/20200906192249.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223130440.png b/MachineLearningAlgorithm/img/20201223130440.png deleted file mode 100644 index 5bfaa76..0000000 Binary files a/MachineLearningAlgorithm/img/20201223130440.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223130525.png b/MachineLearningAlgorithm/img/20201223130525.png deleted file mode 100644 index 8074582..0000000 Binary files a/MachineLearningAlgorithm/img/20201223130525.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223131020.png b/MachineLearningAlgorithm/img/20201223131020.png deleted file mode 100644 index 2fd2a58..0000000 Binary files a/MachineLearningAlgorithm/img/20201223131020.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223131344.png b/MachineLearningAlgorithm/img/20201223131344.png deleted file mode 100644 index 6f004d0..0000000 Binary files a/MachineLearningAlgorithm/img/20201223131344.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223131446.png b/MachineLearningAlgorithm/img/20201223131446.png deleted file mode 100644 index 7e25651..0000000 Binary files a/MachineLearningAlgorithm/img/20201223131446.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223131525.png b/MachineLearningAlgorithm/img/20201223131525.png deleted file mode 100644 index 2343744..0000000 Binary files a/MachineLearningAlgorithm/img/20201223131525.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223132028.png b/MachineLearningAlgorithm/img/20201223132028.png deleted file mode 100644 index 7e741af..0000000 Binary files a/MachineLearningAlgorithm/img/20201223132028.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223132145.png b/MachineLearningAlgorithm/img/20201223132145.png deleted file mode 100644 index 41f6138..0000000 Binary files a/MachineLearningAlgorithm/img/20201223132145.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223132445.png b/MachineLearningAlgorithm/img/20201223132445.png deleted file mode 100644 index d6db901..0000000 Binary files a/MachineLearningAlgorithm/img/20201223132445.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223132538.png b/MachineLearningAlgorithm/img/20201223132538.png deleted file mode 100644 index bf7cf1b..0000000 Binary files a/MachineLearningAlgorithm/img/20201223132538.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223135451.png b/MachineLearningAlgorithm/img/20201223135451.png deleted file mode 100644 index 4fc276b..0000000 Binary files a/MachineLearningAlgorithm/img/20201223135451.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223135552.png b/MachineLearningAlgorithm/img/20201223135552.png deleted file mode 100644 index a66dd30..0000000 Binary files a/MachineLearningAlgorithm/img/20201223135552.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223135720.png b/MachineLearningAlgorithm/img/20201223135720.png deleted file mode 100644 index 2b7dc59..0000000 Binary files a/MachineLearningAlgorithm/img/20201223135720.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223135807.png b/MachineLearningAlgorithm/img/20201223135807.png deleted file mode 100644 index 5426781..0000000 Binary files a/MachineLearningAlgorithm/img/20201223135807.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223135855.png b/MachineLearningAlgorithm/img/20201223135855.png deleted file mode 100644 index cba1f27..0000000 Binary files a/MachineLearningAlgorithm/img/20201223135855.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223140010.png b/MachineLearningAlgorithm/img/20201223140010.png deleted file mode 100644 index 3098a3d..0000000 Binary files a/MachineLearningAlgorithm/img/20201223140010.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223140135.png b/MachineLearningAlgorithm/img/20201223140135.png deleted file mode 100644 index e026375..0000000 Binary files a/MachineLearningAlgorithm/img/20201223140135.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223140211.png b/MachineLearningAlgorithm/img/20201223140211.png deleted file mode 100644 index 00db714..0000000 Binary files a/MachineLearningAlgorithm/img/20201223140211.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/20201223140304.png b/MachineLearningAlgorithm/img/20201223140304.png deleted file mode 100644 index 717df5b..0000000 Binary files a/MachineLearningAlgorithm/img/20201223140304.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/2021-01-06-16-16-19.png b/MachineLearningAlgorithm/img/2021-01-06-16-16-19.png deleted file mode 100644 index 8572051..0000000 Binary files a/MachineLearningAlgorithm/img/2021-01-06-16-16-19.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/2021-01-06-16-16-50.png b/MachineLearningAlgorithm/img/2021-01-06-16-16-50.png deleted file mode 100644 index 5befe41..0000000 Binary files a/MachineLearningAlgorithm/img/2021-01-06-16-16-50.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/2021-01-06-16-21-27.png b/MachineLearningAlgorithm/img/2021-01-06-16-21-27.png deleted file mode 100644 index 0efa4bf..0000000 Binary files a/MachineLearningAlgorithm/img/2021-01-06-16-21-27.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/2021-01-06-16-22-53.png b/MachineLearningAlgorithm/img/2021-01-06-16-22-53.png deleted file mode 100644 index 07eb893..0000000 Binary files a/MachineLearningAlgorithm/img/2021-01-06-16-22-53.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/2021-01-06-16-25-42.png b/MachineLearningAlgorithm/img/2021-01-06-16-25-42.png deleted file mode 100644 index 0f8aff3..0000000 Binary files a/MachineLearningAlgorithm/img/2021-01-06-16-25-42.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/2021-01-06-16-29-17.png b/MachineLearningAlgorithm/img/2021-01-06-16-29-17.png deleted file mode 100644 index 4db5a05..0000000 Binary files a/MachineLearningAlgorithm/img/2021-01-06-16-29-17.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/2021-01-06-16-30-53.png b/MachineLearningAlgorithm/img/2021-01-06-16-30-53.png deleted file mode 100644 index 4c5026b..0000000 Binary files a/MachineLearningAlgorithm/img/2021-01-06-16-30-53.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/2021-01-06-16-37-37.png b/MachineLearningAlgorithm/img/2021-01-06-16-37-37.png deleted file mode 100644 index 0c79822..0000000 Binary files a/MachineLearningAlgorithm/img/2021-01-06-16-37-37.png and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" "b/MachineLearningAlgorithm/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index 6a2c781..0000000 Binary files "a/MachineLearningAlgorithm/img/BN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git a/MachineLearningAlgorithm/img/BatchNormvsLayerNorm.png b/MachineLearningAlgorithm/img/BatchNormvsLayerNorm.png deleted file mode 100644 index 611891e..0000000 Binary files a/MachineLearningAlgorithm/img/BatchNormvsLayerNorm.png and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/BatchNorm\346\223\215\344\275\234.png" "b/MachineLearningAlgorithm/img/BatchNorm\346\223\215\344\275\234.png" deleted file mode 100644 index 82245b5..0000000 Binary files "a/MachineLearningAlgorithm/img/BatchNorm\346\223\215\344\275\234.png" and /dev/null differ diff --git a/MachineLearningAlgorithm/img/CNN.png b/MachineLearningAlgorithm/img/CNN.png deleted file mode 100644 index 2e96f24..0000000 Binary files a/MachineLearningAlgorithm/img/CNN.png and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" "b/MachineLearningAlgorithm/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" deleted file mode 100644 index 882606b..0000000 Binary files "a/MachineLearningAlgorithm/img/LN\345\234\250\347\245\236\347\273\217\347\275\221\347\273\234\346\226\271\345\220\221\347\244\272\346\204\217\345\233\276.png" and /dev/null differ diff --git a/MachineLearningAlgorithm/img/Normalization.png b/MachineLearningAlgorithm/img/Normalization.png deleted file mode 100644 index bdda78e..0000000 Binary files a/MachineLearningAlgorithm/img/Normalization.png and /dev/null differ diff --git a/MachineLearningAlgorithm/img/cnn-dilation-in_7_out_3.gif b/MachineLearningAlgorithm/img/cnn-dilation-in_7_out_3.gif deleted file mode 100644 index 98158a6..0000000 Binary files a/MachineLearningAlgorithm/img/cnn-dilation-in_7_out_3.gif and /dev/null differ diff --git a/MachineLearningAlgorithm/img/eec076b0b1aec804c74f1e9b726832a.jpg b/MachineLearningAlgorithm/img/eec076b0b1aec804c74f1e9b726832a.jpg deleted file mode 100644 index 9d14672..0000000 Binary files a/MachineLearningAlgorithm/img/eec076b0b1aec804c74f1e9b726832a.jpg and /dev/null differ diff --git a/MachineLearningAlgorithm/img/pr16808o61q24973o42q7rsqq88os391.jpg b/MachineLearningAlgorithm/img/pr16808o61q24973o42q7rsqq88os391.jpg deleted file mode 100644 index a6aa05e..0000000 Binary files a/MachineLearningAlgorithm/img/pr16808o61q24973o42q7rsqq88os391.jpg and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" "b/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" deleted file mode 100644 index b126f64..0000000 Binary files "a/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" "b/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" deleted file mode 100644 index 354bb07..0000000 Binary files "a/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_1.jpg" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" "b/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" deleted file mode 100644 index f4d8010..0000000 Binary files "a/MachineLearningAlgorithm/img/\344\274\230\345\214\226\347\256\227\346\263\225\346\211\213\345\206\231\347\254\224\350\256\260_2.jpg" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" deleted file mode 100644 index 1df5ee5..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220004.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" deleted file mode 100644 index a65a966..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220429.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" deleted file mode 100644 index 881b3e2..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220549.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" deleted file mode 100644 index 6c42db6..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201228220848.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004718.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004718.png" deleted file mode 100644 index 322413d..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004718.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004807.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004807.png" deleted file mode 100644 index 5d6ed63..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004807.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004852.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004852.png" deleted file mode 100644 index 1a218f0..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123004852.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123165921.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123165921.png" deleted file mode 100644 index 55f0fec..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123165921.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123170106.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123170106.png" deleted file mode 100644 index 66cd739..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123170106.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123170726.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123170726.png" deleted file mode 100644 index 0b3757a..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210123170726.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232348.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232348.png" deleted file mode 100644 index d17d673..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232348.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232723.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232723.png" deleted file mode 100644 index 79e2daf..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232723.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232919.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232919.png" deleted file mode 100644 index a7a15bb..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232919.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232945.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232945.png" deleted file mode 100644 index 9e31a47..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203232945.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203233004.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203233004.png" deleted file mode 100644 index 8ac370c..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210203233004.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210211182431.png" "b/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210211182431.png" deleted file mode 100644 index 3dcc715..0000000 Binary files "a/MachineLearningAlgorithm/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210211182431.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" "b/MachineLearningAlgorithm/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" deleted file mode 100644 index f7f5368..0000000 Binary files "a/MachineLearningAlgorithm/img/\346\250\241\345\236\213\345\244\215\346\235\202\345\272\246\345\257\271\346\254\240\346\213\237\345\220\210\345\222\214\350\277\207\346\213\237\345\220\210\345\275\261\345\223\215.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\346\255\243\345\210\231\345\214\226.png" "b/MachineLearningAlgorithm/img/\346\255\243\345\210\231\345\214\226.png" deleted file mode 100644 index ff8a910..0000000 Binary files "a/MachineLearningAlgorithm/img/\346\255\243\345\210\231\345\214\226.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" "b/MachineLearningAlgorithm/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" deleted file mode 100644 index 0325d90..0000000 Binary files "a/MachineLearningAlgorithm/img/\346\277\200\346\264\273\345\207\275\346\225\260.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" "b/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" deleted file mode 100644 index 8505602..0000000 Binary files "a/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_1.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" "b/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" deleted file mode 100644 index 6e0246a..0000000 Binary files "a/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_2.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" "b/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" deleted file mode 100644 index da180da..0000000 Binary files "a/MachineLearningAlgorithm/img/\347\273\223\346\236\204\345\214\226\351\243\216\351\231\251\346\234\200\345\260\217\345\214\226\347\220\206\350\247\243\346\255\243\345\210\231\345\214\226_3.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" "b/MachineLearningAlgorithm/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" deleted file mode 100644 index 201909f..0000000 Binary files "a/MachineLearningAlgorithm/img/\350\277\207\346\213\237\345\220\210\345\222\214\346\254\240\346\213\237\345\220\210.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" "b/MachineLearningAlgorithm/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" deleted file mode 100644 index 923e9db..0000000 Binary files "a/MachineLearningAlgorithm/img/\350\277\207\346\213\237\345\220\210\346\254\240\346\213\237\345\220\210\350\204\221\345\233\276.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" "b/MachineLearningAlgorithm/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" deleted file mode 100644 index 8d1b1bb..0000000 Binary files "a/MachineLearningAlgorithm/img/\351\200\273\350\276\221\345\233\236\345\275\222.png" and /dev/null differ diff --git "a/MachineLearningAlgorithm/\346\224\257\346\214\201\345\220\221\351\207\217\346\234\272.md" "b/MachineLearningAlgorithm/\346\224\257\346\214\201\345\220\221\351\207\217\346\234\272.md" deleted file mode 100644 index 7169cb9..0000000 --- "a/MachineLearningAlgorithm/\346\224\257\346\214\201\345\220\221\351\207\217\346\234\272.md" +++ /dev/null @@ -1,493 +0,0 @@ -# 【关于 支持向量机】那些你不知道的事 - -> 作者:芙蕖 - -![](img/微信截图_20210211182431.png) - -## 一、原理篇 - -### 1.1 什么是SVM? - -- 数学模型 - - 支持向量机的提出基于统计学习理论和结构风险最小化准则,统计学习理论避免分类模型受样本量的限制,结构风险最小化准则避免模型训练时出现的模型问题。在这样的背景下,支持向量机技术的推广及其判别能力较强,其最终的目的是根据输入数据样本寻找到一个最优分类超平面。 - - 支持向量机最优分类面的求解问题可转化为求数据样本分类间隔最大化的二次函数的解,关键是求得分类间隔最大值的目标解。以两类线性可分数据为例,一类数据用圆形代表,另一类数据用菱形代表,则最优分类线示例图如图1所示。 - -![图片.png](https://i.loli.net/2021/02/06/hew1MdFT4qXkclv.png) - - 图1中, margin代表分类平面间的最大分类间隔,处于分类线两侧的数据点为待分类的样本。在该例图中,基本分类判别面方程如公式(1)所示,若对线性可分的样本集进行数据归一化处理,分类间隔表达式如公式(2)所示。 - -![图片.png](https://i.loli.net/2021/02/06/6eFiEfkLtgNY4qx.png) - - 基于上述分析,通过加入有效约束条件,引入拉格朗日乘子后,解得最优分类判别函数,且其参数的确定依赖于支持向量。实际应用中,核函数结合最优分类判别面形成的支持向量机模型解决了其只处理线性可分样本的弊端,两者结合形成最终的支持向量机模型。 - - 相应的通用支持向量机分类函数表达式如公式(3)所示。 - -![图片.png](https://i.loli.net/2021/02/06/1Ub7ZyqM68AdIT9.png) - - 公式(3)中, a*i和b*i是调控支持向量机确定最优分类平面的参数。 - -- 核支持向量机 - - 支持向量机是基于两类线性可分的样本数据发展而来,但是在实际应用中,需要识别和分类的数据大多数情况下都处于非线性不可分状态,并非理想化状态。由此,研究人员设计一个核函数应用于支持向量机的分类过程中解决该问题,其主要目的是将原低维空间中非线性不可分数据映射到高维空间中,即解决低维特征空间无法构造分类超平面的问题。支持向量机的应用性能关键在于核函数方法的选取。 - - 核函数方法计算公式如下所示: - -![图片.png](https://i.loli.net/2021/02/08/s5fgIJAwQkiLWhz.png) - - 公式(4)表示在特征空间直接计算内积,φ代表x映射到内积特征空间的过程。 - - 研究人员在解决不同的数据分类问题的时候需选择不同的参数,简单来说就是选择不同的核函数。核函数主要分为线性核、多项式核、Sigmoid核和Gauss径向基核。 - - (1)**线性核** - -![图片.png](https://i.loli.net/2021/02/08/16lBtboTgjq9hNV.png) - - 公式(5)代表数据所处的原空间中的内积计算。其作用是统一两空间数据形式,即数据处于原空间的形式与数据经映射后所处空间的形式。 - - (2)**多项式核** - -![图片.png](https://i.loli.net/2021/02/08/X49Rmcg18WV5Jds.png) - - 公式(6)代表多项式空间中的内积计算,注重数据的全局性。其计算过程不同于线性核,这是由于直接在多项式空间计算会造成维数灾难,所以其计算包含一个转换过程,即从高维空间转到低维空间,利用低维空间计算其内积值。 - - (3) **Sigmoid核** - -![图片.png](https://i.loli.net/2021/02/08/lOWI4FRpNf5X9gY.png) - - 公式(7)实现将 Sigmoid函数作为核函数,其近似为多层感知器神经网络,注重样本数据的全局最优值。 - - (4)**Gauss径向基核(RBF)** - -![图片.png](https://i.loli.net/2021/02/08/xiDMGpBsm9TVwdo.png) - - 公式(8)可将原始特征空间映射到无穷维特征空间中,其性能好坏在于y参数的调控,局部性较强。y参数选取的值较小,映射后的特征空间近似一个低维空间;y参数选取的值较大,易造成过拟合问题.正因为其具有较强的可调控性,其在实际应用中更为广泛。 - - 实际应用中,研究者通过权衡各个核函数的优势与劣势,通常将最佳的核函数应用于特定数据分类领域中。将上述介绍的核函数与支持向量机结合后用于实验中的Matlab 代码实现如表1所示。 - -![图片.png](https://i.loli.net/2021/02/08/cK6Y3dDhsLPqHXM.png) - -参考:刘方园, 王水花, 张煜东. 支持向量机模型与应用综述[J]. 计算机系统应用, 2018. - -#### Q.A - -- **那你讲一下SVM吧**。(面试题) - -- **讲了下SVM的推导**:hard margin, soft margin, 几何距离、函数距离,最优化,拉格朗日乘子法,对偶问题,KKT条件,损失函数,惩罚系数等。面试题) - - 或者直接问:**手推SVM**(面试题) - - ![图片.png](https://i.loli.net/2021/02/08/fnbz9i7xho2EZVS.png) - - 注:手推SVM还可参考 https://blog.csdn.net/Oscar6280868/article/details/88391530 - - https://www.cnblogs.com/hello-ai/p/11332654.html - - http://blog.sina.com.cn/s/blog_4298002e010144k8.html - -- **讲一讲SVM,知道多少说多少?为什么要用对偶问题求解?**(今日头条)(面试题) - - 1)首先是我们有不等式约束方程,这就需要我们写成min max的形式来得到最优解。而这种写成这种形式对x不能求导,所以我们需要转换成max min的形式,这时候,x就在里面了,这样就能对x求导了。而为了满足这种对偶变换成立,就需要满足KKT条件(KKT条件是原问题与对偶问题等价的必要条件,当原问题是凸优化问题时,变为充要条件)。 - - 2)对偶问题将原始问题中的约束转为了对偶问题中的等式约束 - - 3)方便核函数的引入 - - 4)改变了问题的复杂度。由求特征向量w转化为求比例系数a,在原始问题下,求解的复杂度与样本的维度有关,即w的维度。在对偶问题下,只与样本数量有关。 - -参考:https://www.cnblogs.com/shiyublog/p/10580603.html - -- **支持向量机中到底什么是支持向量,即支持向量中的向量是指什么** - - 支持向量本质是向量,而这些向量却起着很重要的作用,如果做分类,它们就是离分界线最近的向量。也就是说分界面是靠这些向量确定的,它们支撑着分类面。即就是离最优分类平面最近的离散点,也可以称为向量。 - -- 既然有很多的核函数,针对具体问题该怎么选择? 如果使用核函数向高维空间映射后,问题仍然是线性不可分的,那怎么办? - - 对核函数的选择,现在还缺乏指导原则,各种实验的观察结果(不光是文本分类)的确表明,某些问题用某些核函数效果很好,用另一些就很差,但是一般来讲,径向基核函数(rbf)是不会出太大偏差的一种首选。(在做文本分类系统的时候,使用径向基核函数,没有参数调优的情况下,绝大部分类别的准确和召回都在85%以上,可见。虽然libSVM的作者林智仁认为文本分类用线性核函数效果更佳,待考证) - - 对于松弛变量来说。它是控制近似可分样本的对错分样本惩罚程度C,而这个参数没有一定的公式作参考,只能凭借经验核试验选取。 - -参考:https://blog.csdn.net/qq_23291783/article/details/51271468 - - -- **SVM中惩罚参数C的理解(正则化参数对支持向量数的影响)** - - C理解为调节优化方向中两个指标(间隔大小,分类准确度)偏好的权重 - - soft-margin SVM针对hard-margin SVM容易出现的过度拟合问题,适当放宽了margin的大小,容忍一些分类错误(violation),把这些样本当做噪声处理,本质上是间隔大小和噪声容忍度的一种trade-off,至于具体怎么trade-off,对哪个指标要求更高,那就体现在C这个参数上了。 - - - 当C趋于无穷大时,这个问题也就是不允许出现分类误差的样本存在,那这就是一个hard-margin SVM问题(过拟合) - - 当C趋于0时,我们不再关注分类是否正确,只要求间隔越大越好,那么我们将无法得到有意义的解且算法不会收敛。(欠拟合) - -参考:https://blog.csdn.net/csdn_lzw/article/details/80185529 - -参考:https://blog.csdn.net/abcdefg90876/article/details/105283341 - -- **如何解决线性不可分问题?** - -- **高维一定线性可分?**(面试题) - -- **传统机器学习算法了解吗,比如XGBoost和SVM这些?**(面试题) - -了解。 - -参考:https://blog.csdn.net/abcdefg90876/article/details/105283341 - -- **SVM的核函数了解多少?**(面试题) - -- **SVM引入核函数本质?**(面试题) - - 提高维度,增加模型复杂度 - -- **介绍下SVM以及它的核函数**(面试题) - -- **SVM加核函数用过吗?讲一讲其中的差别?**(今日头条)(面试题) - - 训练样本多,维度大就可以用核函数;如果样本少,用核函数比较容易过拟合 - -- **SVM核函数的选择?多项式核和RBF核的关系?**(面试题) - -- **核函数的选择就是svm中的难点,也是核心问题(举出不同的例子?)**(面试题) - -- **核函数是什么?高斯核映射到无穷维是怎么回事?**(面试题) - -- **一个核函数都隐式定义了一个成为“再生核希尔伯特空间”的特征空间(iff条件)?**(面试题) - -- **SVM 中有哪些核函数?** -- **为什么SVM要引入核函数?** - - 当样本在原始空间线性不可分时,可将样本从原始空间映射到一个更高维的特征空间,使得样本在这个特征空间内线性可分。 - -- **SVM核函数有哪些?** - - 线性(Linear)核函数:主要用于线性可分的情形。参数少,速度快。 - - 多项式核函数 - - 高斯(RBF)核函数:主要用于线性不可分的情形。参数多,分类结果非常依赖于参数。 - - Sigmoid核函数 - - 拉普拉斯(Laplac)核函数 - -注:如果feature数量很大,跟样本数量差不多,建议使用LR或者Linear kernel的SVM。如果feature数量较少,样本数量一般,建议使用Gaussian Kernel的SVM。 - - - - - **SVM在训练的时候有没有遇到hard example?**(今日头条)(面试题) - - SVM对hard example的应用很重要,先用一部分训练集训练一个模型,然后用剩下的一部分训练集的一部分做测试,把出错的再送入重新训练,重复二三次,效果会比较好 - -- **函数间隔/几何间隔是什么,有什么意义?**(面试题) - - 相关关键词:硬间隔最大化(几何间隔)、函数间隔、学习的对偶问题、软间隔最大化(引入松弛变量)、非线性支持向量机(核技巧)、Hinge Loss(面试题) - - - SVM中硬间隔和软间隔 - -硬间隔分类即线性可分支持向量机,软间隔分类即线性不可分支持向量机,利用软间隔分类时是因为存在一些训练集样本不满足函数间隔(泛函间隔)大于等于1的条件,于是加入一个非负的参数 ζ (松弛变量),让得出的函数间隔加上 ζ 满足条件。于是软间隔分类法对应的拉格朗日方程对比于硬间隔分类法的方程就多了两个参数(一个ζ ,一个 β),但是当我们求出对偶问题的方程时惊奇的发现这两种情况下的方程是一致的。下面我说下自己对这个问题的理解。 - -我们可以先考虑软间隔分类法为什么会加入ζ 这个参数呢?硬间隔的分类法其结果容易受少数点的控制,这是很危险的,由于一定要满足函数间隔大于等于1的条件,而存在的少数离群点会让算法无法得到最优解,于是引入松弛变量,从字面就可以看出这个变量是为了缓和判定条件,所以当存在一些离群点时我们只要对应给他一个ζi,就可以在不变更最优分类超平面的情况下让这个离群点满足分类条件。 - -综上,我们可以看出来软间隔分类法加入ζ 参数,使得最优分类超平面不会受到离群点的影响,不会向离群点靠近或远离,相当于我们去求解排除了离群点之后,样本点已经线性可分的情况下的硬间隔分类问题,所以两者的对偶问题是一致的。 - -- **SVM为什么采用间隔最大化?** - -当训练数据线性可分时,存在无穷个分离超平面可以将两类数据正确分开。 - -感知机利用误分类最小策略,求得分离超平面,不过此时的解有无穷多个。 - -线性可分支持向量机利用间隔最大化求得最优分离超平面,这时,解是唯一的。另一方面,此时的分隔超平面所产生的分类结果是最鲁棒的,对未知实例的泛化能力最强。 - -然后应该借此阐述,几何间隔,函数间隔,及从函数间隔—>求解最小化1/2 ||w||^2 时的w和b。即线性可分支持向量机学习算法—最大间隔法的由来。 - -- **怎么理解SVM的损失函数?**(面试题) - - -- **使用高斯核函数,请描述SVM的参数C和σ对分类器的影响**(面试题) - -- **SVM 为什么可以处理非线性问题?** - - -### 1.2 SVM怎么发展的? - -SVM是由模式识别中广义肖像算法(generalized portrait algorithm)发展而来的分类器,其早期工作来自前苏联学者Vladimir N. Vapnik和Alexander Y. Lerner在1963年发表的研究。1964年,Vapnik和Alexey Y. Chervonenkis对广义肖像算法进行了进一步讨论并建立了硬边距的线性SVM。此后在二十世纪70-80年代,随着模式识别中最大边距决策边界的理论研究 、基于松弛变量(slack variable)的规划问题求解技术的出现 ,和VC维(Vapnik-Chervonenkis dimension, VC dimension)的提出,SVM被逐步理论化并成为统计学习理论的一部分。1992年,Bernhard E. Boser、Isabelle M. Guyon和Vapnik通过核方法得到了非线性SVM。1995年,Corinna Cortes和Vapnik提出了软边距的非线性SVM并将其应用于手写字符识别问题,这份研究在发表后得到了关注和引用,为SVM在各领域的应用提供了参考。 - -参考:https://baike.baidu.com/item/%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%9C%BA/9683835?fr=aladdin - -### 1.3 SVM存在什么问题? - -(1) SVM算法对大规模训练样本难以实施 - - SVM的空间消耗主要是存储训练样本和核矩阵,由于SVM是借助二次规划来求解支持向量,而求解二次规划将涉及m阶矩阵的计算(m为样本的个数),当m数目很大时该矩阵的存储和计算将耗费大量的机器内存和运算时间。针对以上问题的主要改进有有J.Platt的SMO算法、T.Joachims的SVM、C.J.C.Burges等的PCGC、张学工的CSVM以及O.L.Mangasarian等的SOR算法。 - - 如果数据量很大,SVM的训练时间就会比较长,如垃圾邮件的分类检测,没有使用SVM分类器,而是使用了简单的naive bayes分类器,或者是使用逻辑回归模型分类。 - - -(2) 用SVM解决多分类问题存在困难 - - 经典的支持向量机算法只给出了二类分类的算法,而在数据挖掘的实际应用中,一般要解决多类的分类问题。可以通过多个二类支持向量机的组合来解决。主要有一对多组合模式、一对一组合模式和SVM决策树;再就是通过构造多个分类器的组合来解决。主要原理是克服SVM固有的缺点,结合其他算法的优势,解决多类问题的分类精度。如:与粗集理论结合,形成一种优势互补的多类问题的组合分类器。 - - -(3)对缺失数据敏感,对参数和核函数的选择敏感 - - 支持向量机性能的优劣主要取决于核函数的选取,所以对于一个实际问题而言,如何根据实际的数据模型选择合适的核函数从而构造SVM算法.目前比较成熟的核函数及其参数的选择都是人为的,根据经验来选取的,带有一定的随意性.在不同的问题领域,核函数应当具有不同的形式和参数,所以在选取时候应该将领域知识引入进来,但是目前还没有好的方法来解决核函数的选取问题. - -参考:https://www.cnblogs.com/hanxiaosheng/p/9908763.html - -(1)支持向量机算法的核心是核函数及其参数,它们的正确选取对SVM的预测及泛化性能影响很大。对于具体的研究问题,究竟选择哪种核函数并找到最优的参数对求解问题至关重要。因此,如何快速准确地选择核函数及对应的参数来满足快速性和准确性要求是迄待解决的问题。 - -(2)在大规模及实时性要求较高的系统中,SVM算法受制于求解问题的收敛速度和系统规模的复杂程度。在非线性系统的SVM训练算法中,尤其要处理大规模数据时,需要解决样本规模和速度间的矛盾,提高训练算法的效率和精度。 - -(3)如何有效地将二类别分类器有效地扩展到多类别问题上,多类SVM的优化设计也是今后研究的内容。 - -(4)针对特定问题如何实现支持向量机与其他算法的融合,从而顺利解决待求问题也是需要研究的方向。 - -(5)目前的SVM研究侧重于理论研究,真正的实践应用还有一段距离。 - -目前, SVM仍然存在很多问题需进一步的研究,可将SVM与离散余弦变换、小波包分解、主元分析、独立分量分析﹑聚类﹑粗糙集理论等方法结合,提高应用效果并不断探索SVM新的应用领域。 - -参考:张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -#### Q.A - - 1、精通svm,那你说一下svm中的难点是什么?以及你是怎么解决这个难点的?(熟悉的问法) - - 2、SVM 中的优化技术有哪些? - -## 二、算法篇 - - 基本的支持向量机算法基本思想是在二次规划的基础上不断迭代寻找支持向量,主要有块算法、分解算法、序列最小优化算法﹑增量算法等,下面介绍这几种基本的支持向量机算法。 - -### 2.1 什么是块算法? - - Chunking算法的出发点是删除矩阵中对应Lagrange乘数为零的行和列将不会影响最终的结果。对于给定的样本,Chunking算法的目标是通过某种迭代方式逐步排除非支持向量,从而降低训练过程对存储器容量的要求。具体做法是,将一个大型QP问题分解为一系列较小规模的QP问题,然后找到所有非零的Lagrange乘数并删除。在算法的每步中Chunking都解决一个QP问题,其样本为上一步所剩的具有非零Lagrange乘数的样本以及M个不满足KKT条件的最差样本。如果在某一步中,不满足KKT条件的样本数不足M个,则这些样本全部加入到新的QP问题中。每个QP子问题都采用上一个QP子问题的结果作为初始值。在算法进行到最后一步时,所有非零Lagrange乘数都被找到,从而解决了初始的大型QP问题。 - - Chunking算法将矩阵规模从训练样本数的平方减少到具有非零Lagrange乘数的样本数的平方,在很大程度上降低了训练过程对存储容量的要求。Chunking算法能够大大提高训练速度,尤其是当支持向量的数目远远小于训练样本的数目时。然而,如果支持向量个数比较多,随着算法迭代次数的增多,所选的块也会越来越大,算法的训练速度依旧会变得十分缓慢。 - -参考:丁世飞, 齐丙娟, 谭红艳. 支持向量机理论与算法研究综述[J]. 电子科技大学学报, 2011, 40(001):2-10. - -### 2.2 什么是分解算法? - - 分解算法最早在1997年OSUNA等人中提出,是目前有效解决大规模问题的主要方法。分解算法将二次规划问题分解成一系列规模较小的二次规划子问题,进行迭代求解。在每次迭代中,选取拉格朗日乘子分量的一个子集做为工作集,利用传统优化算法求解一个二次规划的子问题。以分类SVM为例,分解算法的主要思想是将训练样本分成工作集B和非工作集N,工作集B中的样本个数为q,q远小于训练样本总数。每次只针对工作集B中的样本进行训练,而固定N中的训练样本。该算法的关键在于选择一种最优工作集选择算法,而在工作集的选取中采用了随机的方法,因此限制了算法的收敛速度。 - - 1998年,JOACHIMS等人在分解算法的基础上对工作集的选择做了重要改进。采用类似可行方向法的策略确定工作集B。如果存在不满足KTT条件的样本,利用最速下降法,在最速下降方向中存在q个样本,然后以这q个样本构成工作集,在该工作集上解决QP问题,直到所有样本满足KTT条件。如此改进提高了分解算法的收敛速度,并且实现了sVMlieht算法。 - - 1998年,PLATT等人提出的序列最小优化(sequentialminimal optimization,SMO)算法是分解算法的一个特例,工作集中只有2个样本,其优点是针对2个样本的二次规划问题可以有解析解的形式,从而避免多样本情况下的数值解不稳定及耗时问题,且不需要大的矩阵存储空间,特别适合稀疏样本。工作集的选择不是传统的最陡下降法,而是启发式。通过两个嵌套的循环寻找待优化的样本,然后在内环中选择另一个样本,完成一次优化,再循环,进行下一次优化,直到全部样本都满足最优条件。SMO算法主要耗时在最优条件的判断上,所以应寻找最合理即计算代价最低的最优条件判别式。 - - SMO算法提出后,许多学者对其进行了有效的改进。DAI等人在2005年提出了在内循环中每次优化3个变量,因为3个变量的优化问题同样可以解析求解,实验表明该算法比SMO的训练时间更短。KEERTHI和PLATT等人在迭代过程中的判优条件和循环策略上做了一定的修改,加快了算法的速度。 - -参考:丁世飞, 齐丙娟, 谭红艳. 支持向量机理论与算法研究综述[J]. 电子科技大学学报, 2011, 40(001):2-10. - -### 2.3 什么是序列最小优化算法? - - PLATT等人在1998年提出的序列最小优化(sequential minimal optimization,SMO)算法是在分解算法的基础上发展起来的,它将工作集减少为只有2个样本。通过两个嵌套的循环寻找待优化的两个样本,外层循环主要寻找工作集的第一个样本;然后采用启发式规则选择第二个样本,选择的原则是使目标函数靠近最优点的速度达到最快;最后用解析的方法快速对选定的样本进行优化。工作集的选择采用启发式选择策略加快了算法的收敛速度,同时减小了矩阵存储空间,适合于稀疏样本。 - -参考:张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -### 2.4 什么是增量算法? - - 增量学习是机器学习系统在处理新增样本时,能够只对原学习结果中与新样本有关的部分进行增加修改或删除操作,与之无关的部分则不被触及。增量训练算法的一个突出特点是支持向量机的学习不是一次离线进行的,而是一个数据逐一加入反复优化的过程。 - - SYED等人在1999年最早提出了SVM增量训练算法,每次只选一小批常规二次算法能处理的数据作为增量,保留原样本中的支持向量和新增样本混合训练,直到训练样本用完。GAUWENBERGHS等人提出了增量训练的精确解,即增加一个训练样本或减少一个样本对Lagrange系数和支持向量的影响。RALAIVOLA等人提出了另一种增量式学习方法,其思想是基于高斯核的局部特性,只更新对学习机器输出影响最大的Lagrange系数,以减少计算复杂度。孔锐等人提出了一种“快速增量学习算法”,该算法依据边界向量不一定是支持向量,但支持向量一定是边界向量的原理,首先选择那些可能成为支持向量的边界向量,进行SVM的增量学习,找出支持向量,最终求出最优分类面,提高训练速度。孔波等人提出了基于中心距离比值的增量运动向量机,利用中心距离比值,在保证训练和测试准确率没有改变的情况下,提高收敛速度。李东晖等人提出了基于壳向量的线性SVM增量学习算法,通过初始样本集求得壳向量,进行SVM训练,得到支持向量集降低二次规划过程的复杂度,提高整个算法的训练速度和分类精度。 - - - 以上几种基本算法本质上都是将一个大规模的二次规划问题分解为小的二次规划问题,不同的是分解策略和工作集的选取方法,这也是导致算法收敛速度快慢的原因。 - -参考:丁世飞, 齐丙娟, 谭红艳. 支持向量机理论与算法研究综述[J]. 电子科技大学学报, 2011, 40(001):2-10. - - -#### Q.A - - - -## 三、其他SVM篇 - -### 3.1 什么是最小二次支持向量机? - -![图片.png](https://i.loli.net/2021/02/08/PID9OyuG1JMA58C.png) - - 在求解大型QP问题时,基本支持向量机算法中的块算法和分解算法会存在维数灾难和求解速度过慢等问题,在支持向量机的求解过程中约束条件为不等式约束,为简化寻优过程并保证一定的学习速度,用等式约束来代替式(1)中的不等式约束,用最小二乘损失函数代替不敏感损失函数来简化求解过程,从而得到最小二乘支持向量机算法,如下所示: - -![图片.png](https://i.loli.net/2021/02/08/IP8zHRFmD6lQ5s7.png) - -参考:张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -### 3.2 什么是模糊支持向量机? - - 由于实际样本检测时存在不同程度的噪声,需要从样本数据中将非正常数据筛以除降低其影响。具体实施方法为:通过在训练样本数据集中增加每个样本的隶属度项,如对样本中的噪声数据和孤立点给予较小的隶属度,正常的样本赋予较大的隶属度,从而对不同的样本起到惩罚作用,降低噪声数据对分类最优平面的影响。模糊支持向量机算法结合模糊数学方法通过在基本支持向量机算法的基础上增加隶属度值对最优平面起到调节作用,提高分类精度。但样本数据中如果异常数据较多时,会影响支持向量机的泛化学习能力,另外由于增加了隶属度项,使得核函数计算复杂,训练速度降低。 - - 为了克服噪声和野值点对支持向量机的影响,LIN等人将模糊数学和支持向量机相结合,提出了模糊支持向量机,主要用于处理训练样本中的噪声数据。其主要思想是针对支持向量机对训练样本内的噪音和孤立点的敏感性,在训练样本集中增加一项隶属度,并赋予支持向量较高的隶属度,而非支持向量及噪声野值点赋予较小的隶属度,从而降低非支持向量、噪声和野值点对最优超平面的影响。 - - FSVM中存在的问题是如何确定隶属度值,即如何确定各个样本的权重。LIN等人提出了基于类中心的隶属度确定方法,将样本点到其类中心的距离的线性函数作为隶属度函数,但是隶属函数会严重依赖训练样本集的几何形状,降低支持向量的隶属度。HUANG和张翔等人也提出相似的隶属度确定方法。张贵香等人提出一种基于类内超平面距离的隶属度确定方法,将样本点到类内平面距离的线性函数作为隶属度函数,降低了隶属度函数对训练样本集几何形状的依赖,提高了支持向量的隶属度。李苗苗等人提出了一种新的核隶属度函数,该新的隶属度函数不仅依赖于每个样本点到类型中心的距离,还依赖于该样本点最邻近的K个其他样本点的距离。孙名松等人通过对每个样本赋予不同的双隶属度,得到最优分类器。吴青和YAN等人提出了去边缘的FSVM主要是根据训练集的几何形状,将其分成两个子集,认为其中一个子集不包含支持向量并将其舍去;另一子集包含支持向量并在该子集中进行训练,但会人为地去除一些支持向量而导致分类精度降低。针对一般模糊支持向量机训练时间过长,训练效率低下的问题,刘宏冰等人对边缘数据赋予较大的隶属度,而对类中心附近的数据赋予较小的隶属度,体现加大对容易错分样本进行惩罚的改进策略。施其权等人进一步对离分类超平面较远不可能成为支持向量的数据赋予较小的隶属度,使训练样本集中的数据大大减少。 - -参考:丁世飞, 齐丙娟, 谭红艳. 支持向量机理论与算法研究综述[J]. 电子科技大学学报, 2011, 40(001):2-10. -参考:张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -### 3.3 什么是粒度支持向量机? - - GSVM的主要思想是通过常用的粒度划分方法构建粒度空间获得一系列信息粒,然后在每个信息粒上进行学习,最后通过聚合信息粒上的信息(或数据、规则知识、属性等)获得最终的支持向量机决策函数。该学习机制通过数据的粒化可以将一个线性不可分问题转化为一系列线性可分问题,从而获得多个决策函数;该学习机制还使数据的泛化性能增强,即可在SVM的训练中得到间隔更宽的超平面。 - - 原空间的GSVM模型在原空间进行粒划分,然后在核空间进行SVM学习。基于关联规则的GSVM是TANG等人提出的,其基本思想是通过RBF核函数原空间的样本映射到特征空间并展开成麦克劳林级数,并从展开式中挖掘对分类分析起重要作用的关联规则,利用这些有用的相关关联规则划分粒度,从而在SVM的分类模式中学习出关联规则分类器。基于聚类的GSVM,其基本思想是首先采用常用的聚类方法结合一定的评价规则将原始数据划分为若干个粒,然后选择其中含有较多信息量的粒参与SVM的分类或者回归,使SVM在大规模数据集的训练中能得到较高的效率和泛化能力。基于粗糙集的GSVM,其基本思想是首先用粗糙集对数据进行预处理,以达到减少冗余数据,压缩数据规模的目的,进而提高支持向量机的分类速度。基于树形层次结构的GSVM33其基本思想是根据聚类训练结果对正类数据与负类数据分别构造两棵“支持向量粒度树”,离边缘较近的继续延伸,直到达到需要的精度为止。此外,我国还有很多学者研究基于商空间(34-35]、决策树、神经网络的GSVM学习算法。 - - GUO和王文剑等人提出的核空间的GSVM(KGSVM)模型首先将原始数据映射到核空间,然后在核空间进行粒的划分和粒的代替,最后在相同的核空间中进行粒的SVM训练。与传统的GSVM模型相比,KGSVM模型克服了核空间数据分布不一致的问题。传统的GSVM由于分粒是在原空间中进行的,粒划分时非常可能丢失大量有用的信息。但是GSVM是在核空间中进行粒的划分和替代,因此可以利用半径规则获得更好的分类精度和泛化性能。张文浩等人对KGSVM模型进行了改进,提出了核粒度下基于关联规则的GSVM。 - -参考:丁世飞, 齐丙娟, 谭红艳. 支持向量机理论与算法研究综述[J]. 电子科技大学学报, 2011, 40(001):2-10. - -### 3.4 什么是多类训练算法? - - 随着研究问题的复杂化,现实的分类问题不单纯是正反两类,会存在多类的现象。对多分类问题需构造多类SVM分类器,主要通过目标函数和分类器来完成。对应的实现途径主要有两种:一种是通过选取合适的目标函数来实现k类分类支持向量机。由于实际问题存在多类,因而选择的目标函数变量多,求解过程复杂,一般只用于解决小型问题。另--种实现方法基于两分类器的分类思想,将多个两分类器进行组合,主要方法有一对多算法、一对一算法﹑决策导向无环图。一对多算法对k个类的样本需构造k个分类器,样本对应的决策函数最大即为所对应的类。一对一算法对k类训练样本中的任两类构造一个分类器,两两组合构造多个分类器,然后在这些分类器中使用投票法累计各个类的投票数,其中得票数最多的类即为样本点所属的类。当类别较大时组合分类器数量较多,影响分类预测速度。对此Platt等提出了一个新的学习架构:决策导向无环图。每个分类器有两类,类似于二叉树,在分类过程中由根部开始经各层中间节点逐步向叶节点分类,这种分类方法能提高支持向量机的分类速度和性能。 - -参考:张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -### 3.5 什么是孪生支持向量机? - - JAYADCVA等人提出了一种二值数据的分类器——孪生支持向量机(又称双分界面支持向量机)。TWSVMs在形式上类似于传统的支持向量机,不仅具有传统支持向量机的优点,而且对大规模数据具有更好的处理能力。TWSVMs为两个类各自得到一个分类平面,属于每个类的数据尽量围绕在与之相对应的分类平面周围,然后TWSVMs通过优化一对分类平面来构建分类超平面。也就是说,TWSVMs需要解决一对QP问题,而SVM则是解决一个QP问题,但是在TWSVMs中,其中一个类的数据要作为另一个QP问题的约束条件,反之亦然。 - - 尽管TWSVMs相比较于SVM具有更为快速的训练速度,但如今信息时代面临的是“数据海量,知识匮乏”,对于机器学习是一个很大的挑战,同样,对TWSVMs而言,训练速度也非常重要。尽管目前传统SVM已有许多成熟的学习算法,并且也可以推广到孪生模型,但这些算法并没有考虑到孪生模型的具体区别,因而有必要提出基于具体孪生模型的高效学习算法,以体现TWSVMs的具体特性。另外,现有的孪生模型并不具有类似于传统支持向量机的特性,即间隔。因此,如果能将孪生模型与传统支持向量的优点成功结合在一起,则可以得到既具有较快训练速度又具有较好理论基础的孪生支持向量机模型。 - - 有了好的模型、好的算法之后,可以考虑将孪生模型推广到一些具体问题,如半监督学习问题、模糊或区间数据的学习问题、回归问题,并将该模型推广到各类实际问题,特别是生物信息学方面的应用,如基因调控网络预测。 - -参考:丁世飞, 齐丙娟, 谭红艳. 支持向量机理论与算法研究综述[J]. 电子科技大学学报, 2011, 40(001):2-10. - -### 3.6 什么是排序支持向量机? - - 排序学习是当前信息检索和机器学习领域的热点问题,广泛应用于许多领域,包括文档检索、协同过滤、关键字提取、定义发现等等。排序学习问题大致分为基于回归的排序学习和基于分类的排序学习两类。从上面的介绍可以看出,SVM的排序学习模型可以基于分类又可以基于顺序回归,所以自RSVM 61提出以来,该排序学习方法便得到了很大的发展。 - - RSVM在应用中大部分用于信息检索,其中最主要的问题是如何针对检索问题建立适用于具体应用的损伤函数。可以与基本的SVM一样,两类数据使用相同的代价函数;也可以针对两类数据分别建立不同的代价函数,对某些应用会大大提高排序的精确度。 - - YAJIMA等人将RSVM用于推荐系统,文中使用1-SVM对给定数据的相关度顺序进行预测,通过使用图核处理数据集,取得了很好的效果。SVM的回归排序模型也能用于推荐系统,与传统的使用启发式的推荐系统相比,该方法在大样本下的性能是相当高效的。 - - 在实际应用中,速度永远是人们追求的目标。传统的RSVM都是使用2-SVM进行学习,YU等人使用1-SVM学习排序,该方法可以使用更少的支持向量,大大提高训练速度。参数选择对于SVM的训练速度起着至关重要的作用,使用用于核方法的正则化路径方法可以加速RSVM中的参数选择并使该过程自动化,从而提高训练速度。在分子测序中,由于数据为结构数据,RSVM的训练速度很长,将粒度计算与RSVM结合,使用粒度计算进行属性约简和问题分割,在保证学习质量的情况下提高训练速度。 - - 传统的RSVM在应用中有其局限性,即模型过于简单而不能用于复杂的排序;很难将先验知识加入模型中。为了克服这些局限,一种新的排序支持向量机被提出,它将一般RSVM输出的打分函数映射为一个概率sigmoid函数,该函数用交叉检验进行训练,实际上该函数就是输入数据集的后验概率,可以用其进行一些后处理的工作,避免传统RSVM的应用局限性。 - -参考:丁世飞, 齐丙娟, 谭红艳. 支持向量机理论与算法研究综述[J]. 电子科技大学学报, 2011, 40(001):2-10. - -#### Q.A - -- SVM如何解决多分类问题(面试题) - 或者SVM可以用来划分多类别吗? 如果可以,要怎么实现?(面试题) - - 一般有两种做法: - - 1)直接法:直接在目标函数上修改,将多个分类面的参数求解合并到一个最优化问题里面。看似简单但是计算量却非常的大。 - - 2)间接法:对训练器进行组合。其中比较典型的有一对一,和一对多。 - - - 一对多:对每个类都训练出一个分类器,由svm是二分类,所以将此而分类器的两类设定为目标类为一类,其余类为另外一类。这样针对k个类可以训练出k个分类器,当有一个新的样本来的时候,用这k个分类器来测试,那个分类器的概率高,那么这个样本就属于哪一类。这种方法效果不太好,bias比较高。 - - 一对一:针对任意两个类训练出一个分类器,如果有k类,一共训练出C(2,k) 个分类器,这样当有一个新的样本要来的时候,用这C(2,k) 个分类器来测试,每当被判定属于某一类的时候,该类就加一,最后票数最多的类别被认定为该样本的类。 - - - - - -## 四、应用篇 - -### 4.1 模式识别 - - 在手写字体识别方面,当采用5层神经网络算法时,其识别的错误率为5.1%;贝尔实验室最先将SVM应用于手写字体识别研究,选取三种不同的核函数时,得到的误识率分别为4.0% ,4.1%和4.2%,可看出支持向量机方法比神经网络算法具有更好的分类准确性。柳回春等在SVM 的基础上结合与RBF神经网络将其用于UK心理测试自动分析系统的手写体数字识别问题。手写体识别属于多类问题。相关专家学者在研究2类问题的SVM前提下,形成了能够处理多类问题的相关SVM,其中主要核函数就是sigmoid核函数、径向基核函数、多项式核函数。不但可以支持比较其他分类和支持向量机,还能够支持比较不同形式的SVM,经过大量实践可以发现,存在很大优势。 - - 在人脸识别方面,由于人脸图像存储和SVM训练需要大量的存储空间,周志明等人将小波变换与支持向量机相结合,由小波变换提取人脸特征,减小特征向量维数并将其输入到SVM中,并结合最近邻分类器进行分类,提高了分类器的鲁棒性和分类精度。相关学者和专家经过不断研究和分析以后形成以层次结构形式的支持向量机分类器,由一个非线性和线性支持向量机构成,上述方式不但具备比较低的误差率和比较高的检测率,还存在比较快的速度。此后,人们利用SVM方式来有效判断人脸姿态,并且合理分为6个类别,手工标定方式在多姿态人脸库中发现测试样本和训练样本集,在SVM基础上的训练集姿态分类器,可以降低到1.67%的错误率。在支持向量机和小波技术上形成的识别人脸技术,压缩提取人脸特征的时候应用小波技术,然后结合支持向量机技术和邻近分类器进行分类,确保具备比较好的鲁棒性能和分类性能。 - - 在语音识别方面,由于背景环境中存在不同程度的噪杂声,根据支持向量机和隐式马尔可夫模型相结合的特点,忻栋等建立SVM和隐式马尔可夫模型两者相结合的混合模型,算法比较复杂,用来解决语音识别问题。 - -参考:张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -### 4.2 网页分类 - - 在中文网页分类问题上,贺海军等在网页文本的特征表示和二分类问题的基础上,把二叉决策树和SVM算法相结合构成多类分类器,实现网页文本的分类,取得了较好的分类效果和训练速度。 - - 在网络入侵检测分类方面,网络入侵检测其实也是一种网页分类。徐文龙等提出了一种基于从特殊到特殊的直推式支持向量机,从获取的网络数据中进行归纳式学习和标记样本,从中提出特征输入到TSVM学习机中进行学习,检测其异常的网络入侵,提高了测试样本的分类准确度。 - -参考:张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -### 4.3 系统建模与系统辨识 - - 在未知非线性系统建模方面,张浩然等'利用对象的输入输出数据集,在非线性系统的控制结构设计中采用支持向量机建模来获取对象的动态特性,以SVM作为辨识器在控制器中采用指数梯度法实现控制作用。 - - 在非线性系统的辨识方面,崔万照等将最小二乘方法应用于支持向量机算法中并选择小波函数作为支持向量机的核函数,构造最小二乘小波支持向量机来解决单输人单输出(SISO)非线性系统的辨识问题,仿真结果表明此方法能提高辨识效果,加快系统响应时间。 - -参考:张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -### 4.4 其他 - - 支持向量机具备一定的优越性,已经得到大量应用。专家学者提出了支持向量机基础上的水印算法,在数字水印中合理应用支持向量机,存在十分良好的应用效果。并且入侵监测系统已经是十分重要的网络安全技术之一,在分析入侵检测系统的时候,主要应用的就是SVM基础上的主动学习算法,可以在一定程度上降低学习样本,能够增加入侵监测系统整体分类性能。在处理图像中迷糊噪音的时候,依据SVM模糊推理方式形成的一种噪音检测系统,上述方式能够合理除去检测中的噪音,适当保存图像相关信息。在分析混合气体定量和多维光谱定性的时候,不能应用同一种方式来定性和定量分析组合气体吸收普线重叠、输入光谱的维数,训练样本数目有限,在分析地混合气体多维光谱的时候应用支持向量机,依据核函数有效把重叠光谱数据变为支持向量机回归模型,此时可以定量分析混合气体的组分浓度以及定性分析种类。 - -## 五、对比篇 - -- **SVM和LR的区别与联系?**(面试题) - - 或者SVM和Logistic回归的异同?(面试题) - -1)相同点 - - 第一,LR和SVM都是分类算法。 - - 看到这里很多人就不会认同了,因为在很大一部分人眼里,LR是回归算法。我是非常不赞同这一点的,因为我认为判断一个算法是分类还是回归算法的唯一标准就是样本label的类型,如果label是离散的,就是分类算法,如果label是连续的,就是回归算法。很明显,LR的训练数据的label是“0或者1”,当然是分类算法。其实这样不重要啦,暂且迁就我认为它是分类算法吧,再说了,SVM也可以回归用呢。 - - 第二,如果不考虑核函数,LR和SVM都是线性分类算法,也就是说他们的分类决策面都是线性的。 - - 这里要先说明一点,那就是LR也是可以用核函数的,至于为什么通常在SVM中运用核函数而不在LR中运用,后面讲到他们之间区别的时候会重点分析。总之,原始的LR和SVM都是线性分类器,这也是为什么通常没人问你决策树和LR什么区别,决策树和SVM什么区别,你说一个非线性分类器和一个线性分类器有什么区别? - - 第三,LR和SVM都是监督学习算法。 - - 这个就不赘述什么是监督学习,什么是半监督学习,什么是非监督学习了。 - - 第四,LR和SVM都是判别模型。 - - 判别模型会生成一个表示P(Y|X)的判别函数(或预测模型),而生成模型先计算联合概率p(Y,X)然后通过贝叶斯公式转化为条件概率。简单来说,在计算判别模型时,不会计算联合概率,而在计算生成模型时,必须先计算联合概率。或者这样理解:生成算法尝试去找到底这个数据是怎么生成的(产生的),然后再对一个信号进行分类。基于你的生成假设,那么那个类别最有可能产生这个信号,这个信号就属于那个类别。判别模型不关心数据是怎么生成的,它只关心信号之间的差别,然后用差别来简单对给定的一个信号进行分类。常见的判别模型有:KNN、SVM、LR,常见的生成模型有:朴素贝叶斯,隐马尔可夫模型。当然,这也是为什么很少有人问你朴素贝叶斯和LR以及朴素贝叶斯和SVM有什么区别(哈哈,废话是不是太多)。 - -2)不同点 - - 第一,本质上是其损失函数(loss function)不同。lr的损失函数是 cross entropy loss, adaboost的损失函数是 expotional loss ,svm是hinge loss,常见的回归模型通常用 均方误差 loss。 - - SVM 和正则化的逻辑回归它们的损失函数: - -![图片.png](https://i.loli.net/2021/01/28/jkJeVpcZDf3tnxR.png) - - 第二,支持向量机只考虑局部的边界线附近的点,而逻辑回归考虑全局(远离的点对边界线的确定也起作用)。 - - 第三,在解决非线性问题时,支持向量机采用核函数的机制,而LR通常不采用核函数的方法。 - - 第四,线性SVM依赖数据表达的距离测度,所以需要对数据先做normalization,LR不受其影响。 - - 第五,SVM的损失函数就自带正则(损失函数中的1/2||w||^2项),这就是为什么SVM是结构风险最小化算法的原因;而LR必须另外在损失函数上添加正则项。 - -- 说LR和SVM损失函数。(面试题) - -- SVM框架下引入Logistic函数:输出条件后验概率?(面试题) - -- 感知机的对偶形式和SVM对偶形式的对比(面试题) - -- 为什么要用对偶形式?如何理解对偶函数的引入对计算带来的优势?(面试题) - -## 六、拓展篇 - -- SVM用于回归问题:SVR(面试题) - -## 参考资料 - -1.https://github.com/datawhalechina/Daily-interview/blob/master/machine-learning/SVM.md - -2.刘方园, 王水花, 张煜东. 支持向量机模型与应用综述[J]. 计算机系统应用, 2018. - -3.https://www.cnblogs.com/shiyublog/p/10580603.html - -4.https://blog.csdn.net/qq_23291783/article/details/51271468 - -5.https://blog.csdn.net/csdn_lzw/article/details/80185529 - -6.https://blog.csdn.net/abcdefg90876/article/details/105283341 - -7.https://blog.csdn.net/abcdefg90876/article/details/105283341 - -8.https://baike.baidu.com/item/%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%9C%BA/9683835?fr=aladdin - -9.https://www.cnblogs.com/hanxiaosheng/p/9908763.html - -10.张松兰. 支持向量机的算法及应用综述[J]. 江苏理工学院学报(2):14-17. - -11.丁世飞, 齐丙娟, 谭红艳. 支持向量机理论与算法研究综述[J]. 电子科技大学学报, 2011, 40(001):2-10. - - diff --git "a/MachineLearningAlgorithm/\351\200\273\350\276\221\345\233\236\345\275\222.md" "b/MachineLearningAlgorithm/\351\200\273\350\276\221\345\233\236\345\275\222.md" deleted file mode 100644 index 4782abe..0000000 --- "a/MachineLearningAlgorithm/\351\200\273\350\276\221\345\233\236\345\275\222.md" +++ /dev/null @@ -1,95 +0,0 @@ -# 【关于 逻辑回归】那些你不知道的事 - -> 贡献者:姚鑫、艾春辉,芙蕖,李玲 - -![逻辑回归](img/逻辑回归.png) - -## 一、介绍篇 - -### 1.1什么是逻辑回归 - -LR是Logistic Regression Classifier,本质上是线性回归,特殊之处在于特征到结果的映射中加入了一层逻辑函数g(z),即先把特征线性求和,然后使用函数g(z)作为假设函数来预测。g(z)可以将连续值映射到0 和1。逻辑回归使用的g(z)函数是sigmoid函数。因此逻辑回归=线性回归 + sigmoid。 - -逻辑回归的表达式为 - -$\sigma(w^Tx)=\frac{1}{1+e^{-w^Tx}}$ - -图像 - -![1610160500583](img/1610160500583.png) - -### 1.2逻辑回归的优势 - -逻辑回归的优点: - -1. 它是直接对分类可能性进行建模,无需实现假设数据分布,这样就避免了假设分布不准确所带来的问题; -2. 它不是仅预测出“类别”,而是可得到近似概率预测,这对许多需利用概率辅助决策的任务很有用; -3. 逻辑回归函数是任意阶可导的凸函数,有很好的数学性质,现有的许多数值优化算法都可直接用于求取最优解。 -4. 对于线性数据,(大部分时候)逻辑回归的拟合和计算都非常快,计算效率优于SVM和随机森林 - -## 二、推导篇 - -### 2.1逻辑回归推导 - -假设数据集为 -$$ -Data: {\{(x_i, y_i)\}}^{N}_{i=1} \\ -x_i\in \mathbb{R}^p,y_i\in\{0,1\} -$$ -sigmoid函数为 -$$ -sigmoid:\sigma(z)=\frac{1}{1+e^{-z}} -$$ -在线性回归中有 -$$ -y=w^Tx+b -$$ -为了方便,我们将其中的权值向量$w$和输入向量$x$进行扩充,即$w=(w_1,w_2,...,w_n,b)$;$x=(x_1,x_2,...,x_n,1)$,则式(3)可以改写为$y=w^Tx$ - -线性回归是将向量$x$映射为具体的数值$y$(连续),而逻辑回归是用来解决分类问题(通常为二分类问题),希望得到$0$或$1$的概率(区间$[0,1]$),即通过某种方式将数值$y$映射到区间$[0,1]$范围内。逻辑回归采用sigmoid函数来完成这样的映射,从而建立$y$与$x$之间的概率判别模型 -$$ -P(Y|X) -$$ -有 -$$ -p_1=P(y=1|x)=\frac{1}{1+e^{-(w^Tx)}} -$$ - -$$ -p_0=P(y=0|x)=1-P(y=1|x)=\frac{e^{-(w^Tx)}}{1+e^{-(w^Tx)}} -$$ - -得到 -$$ -P(Y|X)=p_1^Yp_0^{1-Y},Y\in\{0,1\} -$$ -对应的似然函数为 -$$ -\prod_{i=1}^NP(y_i|x_i) -$$ -取对数,得到对数似然函数 - -![](img/微信截图_20210203232723.png) - - -对$L(w)$求极大值(即极大似然估计),即可得到$w$的估计值 -$$ -\hat w=\mathop{\arg\max}_{w}L(w) -$$ - -这样,问题就变成了以对数似然函数为目标的最优化问题,可采用梯度下降法或拟牛顿法。 - -### 2.2 求解优化 - -令 - -![](img/微信截图_20210203233004.png) - -此时, - -![](img/微信截图_20210203232919.png) - -因为这里是求最大值,采用梯度上升法: - -![](img/微信截图_20210203232945.png) - diff --git "a/MachineLearningAlgorithm/\351\233\206\346\210\220\345\255\246\344\271\240.md" "b/MachineLearningAlgorithm/\351\233\206\346\210\220\345\255\246\344\271\240.md" deleted file mode 100644 index 35a3dac..0000000 --- "a/MachineLearningAlgorithm/\351\233\206\346\210\220\345\255\246\344\271\240.md" +++ /dev/null @@ -1,279 +0,0 @@ -# 【关于 集成学习】那些你不知道的事 - -![](img/微信截图_20210203232348.png) - -## 一、动机 - -不同的模型通常会在测试集上产生不同的误差;如果成员的误差是独立的,集成模型将显著地比其成员表现更好。 - -## 二、集成学习介绍篇 - -### 2.1 介绍篇 - -#### 2.1.1 集成学习的基本思想是什么? - -结合多个学习器组合成一个性能更好的学习器 - -#### 2.1.2 集成学习为什么有效? - -不同的模型通常会在测试集上产生不同的误差;如果成员的误差是独立的,集成模型将显著地比其成员表现更好。 - -## 三、 Boosting 篇 - -### 3.1 用一句话概括 Boosting? - -Boosting 应用 迭代式学习 的方式进行学习 - -### 3.2 Boosting 的特点是什么? - -Boosting 分类器间存在依赖关系,基学习器之间存在依赖关系,新的学习器需要根据上一个学习器生成。 - -### 3.3 Boosting 的基本思想是什么? - -- s1:先从初始训练集训练一个基学习器;初始训练集中各样本的权重是相同的; -- s2:根据上一个基学习器的表现,调整样本权重,使分类错误的样本得到更多的关注; -- s3:基于调整后的样本分布,训练下一个基学习器; -- s4:测试时,对各基学习器加权得到最终结果; - -![](img/微信截图_20210123165921.png) - -### 3.4 Boosting 的特点是什么? - -每次学习都会使用全部训练样本 - -### 3.5 GBDT 是什么? - -- 思想:每一棵树学习的是之前所有树的整体预测和标签的误差; -- 举例说明:假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。 - -### 3.6 Xgboost 是什么? - -- 思想:不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数,去拟合上次预测的残差。当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数,最后只需要将每棵树对应的分数加起来就是该样本的预测值。 - -## 四、Bagging 篇 - -### 4.1 用一句话概括 Bagging? - -Bagging 应用 基于并行策略 的方式进行学习 - -### 4.2 Bagging 的特点是什么? - -基学习器之间不存在依赖关系,可同时生成. - -### 4.3 Bagging 的基本思想是什么? - -- s1:利用自助采样法对训练集随机采样,重复进行 T 次; -- s2:基于每个采样集训练一个基学习器,并得到 T 个基学习器; -- s3:预测时,集体**投票决策****。 - -![](img/微信截图_20210123170106.png) - -### 4.4 Bagging 的基分类器如何选择? - -所用基分类器最好本身对样本分布较为敏感(不稳定性) - -### 4.5 Bagging 的优点 是什么? - -集成后分类器方差比基分类器的小 - -### 4.6 Bagging 的特点是什么? - -- 训练每个基学习器时只使用一部分样本; -- 偏好不稳定的学习器作为基学习器。 - -> 注:所谓不稳定的学习器,指的是对样本分布较为敏感的学习器 - -### 4.7 随机森林 是什么? - -- 思想:用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输 入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,对于分类算法,看看这个样本应该属于哪一类,然后看看哪一类被选择最多,就预测这个样本为那一类。对回归问题,计算k个模型的均值作为最后的结果。 - -## 五、 Stacking 篇 - -### 5.1 用一句话概括 Stacking ? - -Stacking 应用 基于串行策略 的方式进行学习 - -### 5.2 Stacking 的特点是什么? - -初级学习器与次级学习器之间存在依赖关系,初学习器的输出作为次级学习器的输入 - -### 5.3 Stacking 的基本思路是什么? - -- s1:先从初始训练集训练 T 个不同的初级学习器; -- s2:利用每个初级学习器的输出构建一个次级数据集,该数据集依然使用初始数据集的标签; -- s3:根据新的数据集训练次级学习器; -- s4:多级学习器的构建过程类似; - -## 六、常见问题篇 - -### 6.1 为什么使用决策树作为基学习器? - -- (1). 决策树的表达能力和泛化能力,可以通过剪枝快速调整; -- (2). 决策树可以方便地将**样本的权重**整合到训练过程中;(适合 Boosting 策略) -- (3). 决策树是一种**不稳定**的学习器; (适合Bagging 策略) - - 所谓不稳定,指的是数据样本的扰动会对决策树的结果产生较大的影响; -- 类似问题: - - 基学习器有什么特点? - - 基学习器有什么要求? - -### 6.2 为什么不稳定的学习器更适合作为基学习器? - -- 不稳定的学习器容易受到样本分布的影响(方差大),很好的引入了随机性;这有助于在集成学习(特别是采用 Bagging策略)中提升模型的泛化能力。 -- 为了更好的引入随机性,有时会随机选择一个属性子集中的最优分裂属性,而不是全局最优(随机森林) - -### 6.3 哪些模型适合作为基学习器? - -- 决策树 -- 神经网络 - - 神经网络也属于不稳定的学习器; - - 通过调整神经元的数量、网络层数,连接方式初始权重也能很好的引入随机性和改变模型的表达能力和泛化能力 - -### 6.4 Bagging 方法中能使用线性分类器作为基学习器吗? Boosting 呢? - -- Bagging 方法中不推荐: - - 线性分类器都属于稳定的学习器(方差小),对数据不敏感; - - 甚至可能因为 Bagging 的采样,导致在训练中难以收敛,增大集成分类器的偏差 -- Boosting 方法中可以使用: - - Boosting 方法主要通过降低偏差的方式来提升模型的性能,而线性分类器本身具有方差小的特点,所以两者有一定相性 - - XGBoost 中就支持以线性分类器作为基学习器 - -### 6.5 Boosting/Bagging 与 偏差/方差 的关系? - -- 提升弱分类器性能的原因: - - Boosting :降低了偏差 - - Bagging :降低了方差 -- Boosting 方法 - - 基本思路:减小模型的训练误差拟合残差或者加大错类的权重),加强模型的学习能力,减小偏差 - - 缺点:但 Boosting 不会显著降低方差,因为其训练过程中各基学习器是强相关的,缺少独立性。 -- Bagging 方法 - - 对 n 个独立不相关的模型预测结果取平均,方差是原来的 1/n - - 假设所有基分类器出错的概率是独立的,超过半数基分类器出错的概率会随着基分类器的数量增加而下降 -- 泛化误差、偏差、方差、过拟合、欠拟合、模型复杂度(模型容量)的关系图 - -![](img/微信截图_20210123170726.png) - -## 七、对比篇 - -### 7.1 LR vs GBDT? - -#### 7.1.1 从机器学习三要素的角度 - -##### 7.1.1.1 从模型角度 - -- 相同点: - - 监督学习; - - 判别模型; - - 直接对数据的分布建模; - - 不尝试挖掘隐含变量; -- 不同点: - - Logistic Regression: - - 线性模型; - - 分类器:线性分类器; - - VC 维度: d+1; - - GBDT: - - 非线性模型; - - boosting 模型,可以无限分类,具有无限逼近样本 VC 维的特点; - - VC 维度:远远大于 d+1; - -##### 7.1.1.2 从策略角度 - - Loss(经验风险最小化) + 正则(结构风险最小化) - -###### 7.1.1.2.1 从 Loss 角度 - -- Logistic Regression: - - 输出: y = 1 的概率; - - Loss 损失函数:交叉熵; - - 准则:最大熵原理,“为了追求最小分类误差,追求最大熵 Loss”; - - 本质:分类器算法,而且对数据的噪声具有高斯假设; -- GBDT: - - 基分类器:CART,其无论是处理分类还是回归均是将采用回归拟合(将分类问题通过 softmax 转换为回归问题),用当前轮 CART 树拟合前一轮目标函数与实际值的负梯度 ht = -g; - - 本质:回归算法; - -> 也正是因为 GBDT 采用的 CART 树模型作为基分类器进行负梯度拟合,其是一种对特征样本空间进行划分的策略,不能使用 SGD 等梯度优化算法,而是 CART 树自身的节点分裂策略:均方差(回归) 也带来了算法上的不同; GBDT 损失函数指的是前一轮拟合模型与实际值的差异,而树节点内部分裂的特征选择则是固定为 CART 的均方差,目标损失函数可以自定义,当前轮 CART 树旨在拟合负梯度。 - -###### 7.1.1.2.2 从 特征空间 角度 - -- Logistic Regression: - - 特征的线性组合求交叉熵的最小化,也就是对特征的线性组合做 logistic,使得Logistic Regression会在特征空间中做线性分界面,适用于分类任务; -- GBDT: - - 采用 CART 树作为基分类器,其每轮树的特征拟合都是对特征空间做平行于坐标轴的空间分割,所以自带特征选择和可解释性,GBDT 即可处理分类问题也可解决回归问题,只是其统一采用回归思路进行求解(试想,如果不将分类转换为回归问题,GBDT 每轮目标函数旨在拟合上一轮组合模型的负梯度,分类信息无法求梯度,故而依旧是采用 softmax 转换为回归问题进行求解); - -- 相关知识 - - 线性分类器: - - 感知器准则函数: - - 原理:以使错分类样本到分界面距离之和最小为原则; - - 优点:通过错分类样本提供的信息对分类器函数进行修正,这种准则是人工神经元网络多层感知器的基础; - - SVM: - - 基本思想:在两类线性可分条件下,所设计的分类器界面使两类之间的间隔为最大; - - 基本出发点:使期望泛化风险尽可能小。(使用核函数可解决非线性问题) - - Fisher 准则【线性判别分析(LDA)】: - - 介绍:将所有样本投影到一条原点出发的直线,使得同类样本距离尽可能小,不同类样本距离尽可能大,具体为最大化“广义瑞利商”; - - 特点:两类样本一般类内密集,类间分离; - - 方式:寻找线性分类器最佳的法线向量方向,使两类样本在该方向上的投影满足类内尽可能密集,类间尽可能分开。这种度量通过类内离散矩阵 Sw 和类间离散矩阵 Sb 实现。 - -###### 7.1.1.2.3 从 正则 角度 - -- Logistic Regression: - - 方式:采用一种约束参数稀疏的方式; - - L2 正则整体约束权重系数的均方和,使得权重分布更均匀; - - L1 正则则是约束权重系数绝对值和,其自带特征选择特性; - -- GBDT: - - 弱算法的个数T,就是迭代T轮。T的大小就影响着算法的复杂度; - - 步长(Shrinkage)在每一轮迭代中,原来采用 $Ft(x) = F_{t-1}(x) + \alpha_{t}h_{t}(x;wt)$ 进行更新,可以加入步长v,使得一次不更新那么多: - -- 区别: - - LR 采用对特征系数进行整体的限定; - - GBDT 采用迭代的误差控制本轮参数的增长; - -![](img/20200930170312.png) - -> XGBoost的正则是在 GBDT 的基础上又添加了是一棵树里面节点的个数,以及每个树叶子节点上面输出分数的 L2 模平方。 - -##### 7.1.1.3 从算法角度 - -- Logistic Regression - - 若采用 SGB, Momentum, SGD with Nesterov Acceleration 等算法,只用到了一阶导数信息, - - 若用 AdaGrad, AdaDelta / RMSProp, Adam, Nadam, 牛顿法则用到了二阶导数信息, -- GBDT 直接拟合上一轮组合函数的特梯度,只用到了一阶倒数信息,XGBoost 则是用到了二阶导数信息。 - -#### 7.1.2 从特征的角度 - -##### 7.1.2.1 特征组合 - -- LR 特征选择方法:不具有特征组合的能力,只是一次性地寻求最大化熵的过程,对每一维的特征都假设独立,因此只具备对已有特征空间进行分割的能力,更不会对特征空间进行升维(特征组合) -- GBDT 特征选择方法:采用最小化均方损失来寻找分裂特征及对应分裂点,所以自动会在当前根据特征 A 分裂的子树下寻求其他能使负梯度最小的其他特征 B,这样就自动具备寻求好的特征组合的性能,因此也能给出哪些特征比较重要(根据该特征被选作分裂特征的次数)。 - -##### 7.1.2.2 特特征的稀疏性 - -- Logistic Regression不具有特征组合的能力,并假设特征各个维度独立,因此只具有线性分界面,实际应用中,多数特征之间有相关性,只有维度特别大的稀疏数据中特征才会近似独立,所以适合应用在特征稀疏的数据上; -- GBDT:其更适合处理稠密特征,如 GBDT+LR 的Facebook论文中,对于连续型特征导入 GBDT 做特征组合来代替一部分手工特征工程,而对于 ID 类特征的做法往往是 one-hot 之后直接传入 LR,或者先 hash,再 one-hot 传入树中进行特征工程,而目前的主流做法是直接 one-hot + embedding 来将高维稀疏特征压缩为低纬稠密特征,也进一步引入了语意信息,有利于特征的表达。 - -#### 7.1.3 数据假设不同 - -##### 7.1.3.1 LR - -- 第一个假设:假设数据服从伯努利分布。 - -伯努利分布有一个简单的例子是抛硬币,抛中为正面的概率是 p,抛中为负面的概率是 1−p。在逻辑回归这个模型里面是假设 $h_{theta}$ 为样本为正的概率, $1-h_{theta}$ 为样本为负的概率。那么整个模型可以描述为: - -![](img/20200930171238.png) - -- 第二个假设:假设样本为正的概率是 : - -![](img/20200930171323.png) - -- 第三个假设:噪声是高斯分布的 - -##### 7.1.3.2 GBDT - -未对数据做出上述假设。 - - - - -## 参考 - -1. [机器学习面试150题:不只是考SVM xgboost 特征工程(1-50)](https://zhuanlan.zhihu.com/p/213774840) -2. [机器学习面试150题:不只是考SVM xgboost 特征工程(51-100)](https://zhuanlan.zhihu.com/p/217494137) -3. [GBDT 与 LR 区别总结](https://zhuanlan.zhihu.com/p/60952744) \ No newline at end of file diff --git "a/NLPinterview/DialogueSystem/Rasa/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080805.png" "b/NLPinterview/DialogueSystem/Rasa/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080805.png" deleted file mode 100644 index ee1eb69..0000000 Binary files "a/NLPinterview/DialogueSystem/Rasa/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080805.png" and /dev/null differ diff --git "a/NLPinterview/DialogueSystem/Rasa/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080923.png" "b/NLPinterview/DialogueSystem/Rasa/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080923.png" deleted file mode 100644 index d2103c3..0000000 Binary files "a/NLPinterview/DialogueSystem/Rasa/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080923.png" and /dev/null differ diff --git a/NLPinterview/DialogueSystem/Rasa/init.md b/NLPinterview/DialogueSystem/Rasa/init.md deleted file mode 100644 index bf589b7..0000000 --- a/NLPinterview/DialogueSystem/Rasa/init.md +++ /dev/null @@ -1,176 +0,0 @@ -# 【关于 Rasa 入门】那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20210204080923.png) - -## 一、创建一个新的Rasa项目 - -1. 第一步是创建一个新的Rasa项目。要做到这一点,运行下面的代码: - -```s - rasa init --no-prompt -``` - -> 注:rasa init命令创建rasa项目所需的所有文件,并根据一些示例数据训练一个简单的机器人。如果你省略了——no-prompt参数,将会询问你一些关于项目设置的问题。 - -- 运行过程 - -```s - $ rasa init --no-prompt - >>> - Welcome to Rasa! 🤖 - - To get started quickly, an initial project will be created. - If you need some help, check out the documentation at https://rasa.com/docs/rasa. - - Created project directory at '/web/workspace/yangkm/python_wp/nlu/DSWp'. - Finished creating project structure. - Training an initial model... - Training Core model... - Processed Story Blocks: 100%|█████████████████████████████████████████████| 5/5 [00:00<00:00, 3562.34it/s, # trackers=1] - Processed Story Blocks: 100%|█████████████████████████████████████████████| 5/5 [00:00<00:00, 1523.54it/s, # trackers=5] - Processed Story Blocks: 100%|█████████████████████████████████████████████| 5/5 [00:00<00:00, 380.28it/s, # trackers=20] - Processed Story Blocks: 100%|█████████████████████████████████████████████| 5/5 [00:00<00:00, 301.26it/s, # trackers=24] - Processed trackers: 100%|█████████████████████████████████████████████████| 5/5 [00:00<00:00, 2233.39it/s, # actions=16] - Processed actions: 16it [00:00, 14986.35it/s, # examples=16] - Processed trackers: 100%|█████████████████████████████████████████████| 231/231 [00:00<00:00, 899.80it/s, # actions=126] - Epochs: 0%| | 0/100 [00:00 - - 文件名称作用说明 - - - init.py帮助python查找操作的空文件 - - - actions.py为你的自定义操作编写代码 - - - config.yml ‘*’配置NLU和Core模型 - - - credentials.yml连接到其他服务的详细信息 - - - data/nlu.md ‘*’你的NLU训练数据 - - - data/stories.md ‘*’你的故事 - - - config.yml ‘*’配置NLU和Core模型 - - - domain.yml ‘*’你的助手的域 - - - endpoints.yml接到fb messenger等通道的详细信息 - - - models/.tar.gz你的初始模型 - - - -> 注:最重要的文件用“*”标记。你将在本教程中了解所有这些文件。 - -## 三、Rasa 对话系统测试 - -```s - $ rasa shell - >>> - 2021-01-30 18:01:25.946702: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cudart64_101.dll'; dlerror: cudart64_101.dll not found - 2021-01-30 18:01:25.946959: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine. - 2021-01-30 18:01:28.518362: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library nvcuda.dll - 2021-01-30 18:01:28.938568: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1716] Found device 0 with properties: - pciBusID: 0000:01:00.0 name: GeForce 940MX computeCapability: 5.0 - coreClock: 0.8605GHz coreCount: 4 deviceMemorySize: 2.00GiB deviceMemoryBandwidth: 37.33GiB/s - 2021-01-30 18:01:28.939909: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cudart64_101.dll'; dlerror: cudart64_101.dll not found - 2021-01-30 18:01:28.940935: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cublas64_10.dll'; dlerror: cublas64_10.dll not found - 2021-01-30 18:01:28.942048: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cufft64_10.dll'; dlerror: cufft64_10.dll not found - 2021-01-30 18:01:28.942970: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'curand64_10.dll'; dlerror: curand64_10.dll not found - 2021-01-30 18:01:28.943862: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cusolver64_10.dll'; dlerror: cusolver64_10.dll not found - 2021-01-30 18:01:28.945788: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cusparse64_10.dll'; dlerror: cusparse64_10.dll not found - 2021-01-30 18:01:28.950147: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cudnn64_7.dll'; dlerror: cudnn64_7.dll not found - 2021-01-30 18:01:28.950220: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1753] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform. - Skipping registering GPU devices... - 2021-01-30 18:01:28 INFO rasa.model - Loading model models\20210130-175951.tar.gz... - 2021-01-30 18:01:31 INFO root - Connecting to channel 'cmdline' which was specified by the '--connector' argument. Any other channels will be ignored. To connect to all given channels, omit the '--connector' argument. - 2021-01-30 18:01:31 INFO root - Starting Rasa server on http://localhost:5005 - 2021-01-30 18:01:31 INFO rasa.model - Loading model models\20210130-175951.tar.gz... - 2021-01-30 18:01:36.663436: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN)to use the following CPU instructions in performance-critical operations: AVX2 - To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. - 2021-01-30 18:01:36.676013: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x27e2f29b300 initialized for platform Host (this does not guarantee that XLA will be used). Devices: - 2021-01-30 18:01:36.676366: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version - 2021-01-30 18:01:36.677138: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1257] Device interconnect StreamExecutor with strength 1 edge matrix: - 2021-01-30 18:01:36.677640: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1263] - 2021-01-30 18:01:45 INFO root - Rasa server is up and running. - Bot loaded. Type a message and press enter (use '/stop' to exit): - Your input -> hello - Hey! How are you? - Your input -> ok - Great, carry on! - Your input -> yes - Great, carry on! -``` - - -## 参考资料 - -1. [Rasa 文档](https://rasa.com/docs/rasa/) -2. [Rasa 安装](http://rasachatbot.com/2_Rasa_Tutorial/#rasa) -3. [Rasa 聊天机器人中文官方文档|磐创AI](http://rasachatbot.com/) -4. [Rasa 学习](https://blog.csdn.net/ljp1919/category_9656007.html) -5. [rasa_chatbot_cn](https://github.com/GaoQ1/rasa_chatbot_cn) -6. [用Rasa NLU构建自己的中文NLU系统](http://www.crownpku.com/2017/07/27/用Rasa_NLU构建自己的中文NLU系统.html) -7. [Rasa_NLU_Chi](https://github.com/crownpku/Rasa_NLU_Chi) -8. [_rasa_chatbot](https://github.com/zqhZY/_rasa_chatbot) -9. [rasa 源码分析](https://www.zhihu.com/people/martis777/posts) \ No newline at end of file diff --git a/NLPinterview/DialogueSystem/Rasa/install.md b/NLPinterview/DialogueSystem/Rasa/install.md deleted file mode 100644 index c303d21..0000000 --- a/NLPinterview/DialogueSystem/Rasa/install.md +++ /dev/null @@ -1,306 +0,0 @@ -# 【关于 Rasa安装】那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20210204080805.png) - -## 一、虚拟环境创建【这里默认 已安装 anaconda】 - -### 1.1 为什么要 创建虚拟环境,不创建不好么? - -由于 安装 Rasa 过程中,会安装各种 乱七八糟的 依赖库(eg:tensorflow 2.0,...),导致 安装失败,所以建议 用 conda ,新建 一个 conda 环境,然后在 该环境上面开发。 - -### 1.2 如何创建虚拟环境? - -- 创建环境 -``` - $ conda create -n rasa python=3.6 -``` -- 激活环境 -``` - $conda activate rasa -``` - -## 二、下载并安装 中文版本 的 Rasa-nlu - -### 2.1 为什么要 安装 Rasa-nlu? - -因为 Rasa-nlu 内置的版本只支持 英文版本,不支持中文版本,所以需要 安装 Rasa_NLU_Chi,使 其支持中文。 - -### 2.2 如何安装 Rasa-nlu? - -1. 下载 Rasa_NLU_Chi 包【如果没梯子,建议 直接下载 zip,节约时间】 - -```s - $ git clone https://github.com/crownpku/Rasa_NLU_Chi.git - $ cd rasa_nlu -``` - -2. 安装 python 必要包 - -由于 Rasa_NLU_Chi 需要依赖一些包,所以需要提前安装好,避免报错。 -```s - $ pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple -``` - -3. 安装 Rasa_NLU_Chi 包 - -```s - $ python setup.py install - >>> - Welcome to Rasa NLU! - If any questions please visit documentation page https://nlu.rasa.com - or join community chat on https://gitter.im/RasaHQ/rasa_nlu -``` -> 注:若未出现其他报错信息,而且出现上述信息,则表示安装成功 - -## 三、下载并安装 sklearn 和 jieba - -### 3.1 为什么要 安装 sklearn 和 jieba ? - -- sklearn:因为 Rasa 使用到 sklearn 一些相关 函数,所以需要提前安装,避免后期出错; -- jieba:中文需要利用 jieba 包分词; - -### 3.2 如何安装 sklearn 和 jieba? - -```s - $ pip install -U scikit-learn sklearn-crfsuite -i https://pypi.tuna.tsinghua.edu.cn/simple - >>> - ... - Installing collected packages: threadpoolctl, tabulate, python-crfsuite, joblib, sklearn-crfsuite, scikit-learn - Successfully installed joblib-1.0.0 python-crfsuite-0.9.7 scikit-learn-0.24.1 sklearn-crfsuite-0.3.6 tabulate-0.8.7 threadpoolctl-2.1.0 - - $ pip install jieba -i https://pypi.tuna.tsinghua.edu.cn/simple - Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple - Collecting jieba - Downloading https://pypi.tuna.tsinghua.edu.cn/packages/c6/cb/18eeb235f833b726522d7ebed54f2278ce28ba9438e3135ab0278d9792a2/jieba-0.42.1.tar.gz (19.2 MB) - |████████████████████████████████| 19.2 MB 504 kB/s - Building wheels for collected packages: jieba - Building wheel for jieba (setup.py) ... done - Created wheel for jieba: filename=jieba-0.42.1-py3-none-any.whl size=19314477 sha256=ecc685a8bf469323e6fbaed0450debd65e934ea11ae791a9b8b9f9247405410a - Stored in directory: c:\users\86130\appdata\local\pip\cache\wheels\de\9e\4f\5a72ec71510dfe06f9bbc96ad06077629654f87fb05766ab46 - Successfully built jieba - Installing collected packages: jieba - Successfully installed jieba-0.42.1 -``` - -> 安装过程中遇到的问题 - -- 有些包 可能会下载 错误,若出现下载错误可以尝试手动下载,以 scipy 为例 下载方法如下 - -1. 复制一下网址到 浏览器下载 - -```s - Downloading https://pypi.tuna.tsinghua.edu.cn/packages/f3/9f/80522344838ae24cac9e945240436269cbb92349f7f1f4c9dfc10cb6bad5/scipy-1.5.4-cp36-cp36m-win_amd64.whl (31.2 MB) - |█████████████████▌ | 17.1 MB 8.3 kB/s eta 0:28:23ERROR: Exception: -``` - -2. 通过 浏览器下载得到 scipy-1.5.4-cp36-cp36m-win_amd64.whl,执行以下命令 - -```s - pip install scipy-1.5.4-cp36-cp36m-win_amd64.whl - >>> - Processing e:\pythonwp\nlp\new\conversation_wp\rasa_study\worryfreegrocerystore\plugin\scipy-1.5.4-cp36-cp36m-win_amd64.whl - Collecting numpy>=1.14.5 - Using cached numpy-1.19.5-cp36-cp36m-win_amd64.whl (13.2 MB) - Installing collected packages: numpy, scipy - Attempting uninstall: numpy - Found existing installation: numpy 1.14.0 - Uninstalling numpy-1.14.0: - Successfully uninstalled numpy-1.14.0 - Successfully installed numpy-1.19.5 scipy-1.5.4 -``` - -## 四、下载并安装 MITIE 库 - -### 4.1 为什么要 安装 MITIE 库? - -因为 MITIE 整合到Rasa而言,它是Rasa的few backend choices之一。它提供few pipeline components,可以同时进行意图分类和NER。两者都使用SVM并使用total_word_feature_extractor.dat来提供单个单词向量。 - -### 4.2 Visual Studio环境、cmake、boost 等依赖包 - -#### 4.2.1 安装Visual Studio - -做过C#开发的童鞋,肯定很熟悉Visual Studio,即VS。windows 的集成开发环境。安装该环境的同时,它会附带安装很全的windows的类库。后面boost库运行的时候,需要使用其中的类库。 - -具体安装过程很简单,完全傻瓜式安装即可,下一步下一步搞定。这里提供一个下载地址: - -http://download.microsoft.com/download/0/7/5/0755898A-ED1B-4E11-BC04-6B9B7D82B1E4/VS2015_RTM_ULT_CHS.iso - -https://visualstudio.microsoft.com/zh-hans/thank-you-downloading-visual-studio/?sku=Community&rel=15# - -Microsoft Visual C++ Build Tools 2015:http://go.microsoft.com/fwlink/?LinkId=691126 - -#### 4.2.2 安装安装 cmake - -- 官网下载:https://cmake.org/download/ -- cmake 下载:https://github.com/Kitware/CMake/releases/download/v3.19.4/cmake-3.19.4-win64-x64.zip - -解压后把bin目录路径,配置到path环境变量中。 例如:D:\develop-environment\cmake-3.12.3-win64-x64\bin 执行文件为: - -- 验证是否安装成功 -```s - cmake.exe - >>> - Usage - - cmake [options] - cmake [options] - cmake [options] -S -B - - Specify a source directory to (re-)generate a build system for it in the - current working directory. Specify an existing build directory to - re-generate its build system. - - Run 'cmake --help' for more information. - - cmake-gui.ext - - cmcldeps.exe - >>> - ninja: FATAL: Couldn't parse arguments. - usage: - cmcldeps - - cpack.exe -``` - -#### 4.2.3 安装安装 boost - -- 官网下载:https://www.boost.org/ -- boost 下载:https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.zip - -> 因为官网下载需要翻墙,百度网盘提供一个: https://pan.baidu.com/s/1LOgKv_S-JdvUNZ2UQBNCjA 提取码: eeuw - -我本机boost的解压目录为: D:\develop-environment\boost\boost_1_67_0 - -```s - $ cd D:\develop-environment\boost\boost_1_67_0\tools\build - - $ bootstrap.bat - >>> - Bootstrapping the build engine - Bootstrapping is done. To build, run: - .\b2 --prefix=DIR install - - $ .\b2 --prefix=DIR install - >>> - ... - common.copy DIR\share\boost-build\src\build\generators.jam - D:\program\boost\tools\build\src\build\generators.jam - 已复制 1 个文件。 - common.copy DIR\share\boost-build\src\build\generators.py - D:\program\boost\tools\build\src\build\generators.py - 已复制 1 个文件。 - common.copy DIR\share\boost-build\src\build\project.jam - D:\program\boost\tools\build\src\build\project.jam - 已复制 1 个文件。 - common.copy DIR\share\boost-build\src\build\project.py - D:\program\boost\tools\build\src\build\project.py - 已复制 1 个文件。 - ...updated 435 targets... -``` - -### 4.3 如何 安装 MITIE 库? - -```s - pip install -U scikit-learn sklearn-crfsuite - pip install git+https://github.com/mit-nlp/MITIE.git -``` -- 下载 中文词向量 total_word_feature_extractor_zh.dat https://mega.nz/#!EWgTHSxR!NbTXDAuVHwwdP2-Ia8qG7No-JUsSbH5mNQSRDsjztSA - -> 注:MITIE 库比较大,所以这种 安装方式容易出现问题,所以我用另一种安装方式 - -```s - $ git clone https://github.com/mit-nlp/MITIE.git - $ cd MITIE/ - $ python setup.py install -``` - -> 安装结果 - -```s - Compiling src/text_feature_extraction.cpp - Compiling ../dlib/dlib/threads/multithreaded_object_extension.cpp - Compiling ../dlib/dlib/threads/threaded_object_extension.cpp - Compiling ../dlib/dlib/threads/threads_kernel_1.cpp - Compiling ../dlib/dlib/threads/threads_kernel_2.cpp - Compiling ../dlib/dlib/threads/threads_kernel_shared.cpp - Compiling ../dlib/dlib/threads/thread_pool_extension.cpp - Compiling ../dlib/dlib/misc_api/misc_api_kernel_1.cpp - Compiling ../dlib/dlib/misc_api/misc_api_kernel_2.cpp - Linking libmitie.so - Making libmitie.a - Build Complete - make[1]: Leaving directory `/web/workspace/yangkm/python_wp/nlu/DSWp/MITIE/mitielib' - running build_py - creating build - creating build/lib - creating build/lib/mitie - copying mitielib/__init__.py -> build/lib/mitie - copying mitielib/mitie.py -> build/lib/mitie - copying mitielib/libmitie.so -> build/lib/mitie - running install_lib - copying build/lib/mitie/__init__.py -> /home/amy/.conda/envs/yangkm/lib/python3.6/site-packages/mitie - copying build/lib/mitie/mitie.py -> /home/amy/.conda/envs/yangkm/lib/python3.6/site-packages/mitie - copying build/lib/mitie/libmitie.so -> /home/amy/.conda/envs/yangkm/lib/python3.6/site-packages/mitie - byte-compiling /home/amy/.conda/envs/yangkm/lib/python3.6/site-packages/mitie/__init__.py to __init__.cpython-36.pyc - byte-compiling /home/amy/.conda/envs/yangkm/lib/python3.6/site-packages/mitie/mitie.py to mitie.cpython-36.pyc - running install_egg_info - Writing /home/amy/.conda/envs/yangkm/lib/python3.6/site-packages/mitie-0.7.0-py3.6.egg-info -``` -> 注:会存在 一些 warning 警告,对结果 影响不大 - -## 五、安装 Rasa_core - -### 5.1 什么 Rasa_core,他有什么用? - -- Rasa Core:是一个对话管理平台,用于举行对话和决定下一步做什么。 - -### 5.2 如何安装 Rasa_core? - -```s - pip install rasa_core==0.9.0 -i https://pypi.tuna.tsinghua.edu.cn/simple - >>> - ... - Successfully built ConfigArgParse jsonpickle mattermostwrapper docopt slackclient twilio - Installing collected packages: MarkupSafe, Jinja2, itsdangerous, click, websocket-client, tzlocal, redis, PyJWT, h5py, flask, docopt, decorator, coloredlogs, twilio, slackclient, scikit-learn, ruamel.yaml, python-telegram-bot, pykwalify, networkx, mattermostwrapper, keras, jsonpickle, graphviz, flask-cors, fbmessenger, fakeredis, ConfigArgParse, colorhash, apscheduler, rasa-core - Attempting uninstall: coloredlogs - Found existing installation: coloredlogs 9.0 - Uninstalling coloredlogs-9.0: - Successfully uninstalled coloredlogs-9.0 - Attempting uninstall: scikit-learn - Found existing installation: scikit-learn 0.24.1 - Uninstalling scikit-learn-0.24.1: - Successfully uninstalled scikit-learn-0.24.1 - Successfully installed ConfigArgParse-0.13.0 Jinja2-2.11.2 MarkupSafe-1.1.1 PyJWT-1.7.1 apscheduler-3.7.0 click-7.1.2 coloredlogs-10.0 colorhash-1.0.3 decorator-4.4.2 docopt-0.6.2 fakeredis-0.10.3 fbmessenger-5.6.0 flask-1.1.2 flask-cors-3.0.10 graphviz-0.8.4 h5py-2.10.0 itsdangerous-1.1.0 jsonpickle-0.9.6 keras-2.4.3 mattermostwrapper-2.2 networkx-2.5 pykwalify-1.6.0 python-telegram-bot-10.1.0 rasa-core-0.9.0 redis-2.10.6 ruamel.yaml-0.15.100 scikit-learn-0.19.2 slackclient-1.3.2 twilio-6.51.1 tzlocal-2.1 websocket-client-0.54.0 -``` -> 注:这里需要避免版本问题,所以指定了版本号 - -## 六、 安装 Rasa - -### 6.1 为什么 Rasa? - -有同学一定会问,我们不是安装了 Rasa-nlu 和 Rasa_core 了,为什么还要安装 Rasa 呢? - -- 原因:因为 Rasa-nlu 和 Rasa_core 只是 两个主要模块如下,我们还需要 安装 Rasa 框架,才能确保 Rasa 能够 运行起来。 - - Rasa NLU :用于理解用户消息,包括意图识别和实体识别,它会把用户的输入转换为结构化的数据。 - - Rasa Core:是一个对话管理平台,用于举行对话和决定下一步做什么。 - -### 6.2 Rasa 怎么安装呢? - -```s - pip --default-timeout=500 install -U rasa==1.10.12 -i https://pypi.tuna.tsinghua.edu.cn/simple - pip install --upgrade --ignore-installed tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple - >>> - -``` - -## 参考 - -1. [在Win10上搭建Rasa_NLU_Chi中文语义识别](https://www.jianshu.com/p/063d7cd598d3) -2. [Rasa开发使用 Rasa_NLU及Rasa_Core模型训练与测试](https://blog.csdn.net/ling620/article/details/99845885) \ No newline at end of file diff --git a/NLPinterview/DialogueSystem/Rasa/run.md b/NLPinterview/DialogueSystem/Rasa/run.md deleted file mode 100644 index 7170880..0000000 --- a/NLPinterview/DialogueSystem/Rasa/run.md +++ /dev/null @@ -1,58 +0,0 @@ -# 【关于 Rasa 中文 任务型对话系统开发】那些你不知道的事 - -## 目录 - -## 一、流程介绍 - - - - -## 二、 NLU 模块 - -### 2.1 思路介绍 - -- 在 data/nlu.md 添加 意图 intent 【以添加 点外卖为例】 - - 确定 意图 名称:request_takeway; - - 确定需要的 槽位:refreshments、tea、address、phone_number; - - 确定 用户 query; - - 确定 当 某个 槽位 为空时,Bot 通过回复 什么获取 对应 槽位值 - -### 2.2 意图 和 槽位 设置 - -> 举例 - -```s -## intent: ask_tea -- 请问,这边有什么茶呢? -... - -## intent: ask_refreshments -- 请问,这边有什么好吃的? -... - -## intent: ask_address -- 请问送货地址在哪里呢? -... - -## intent: ask_phone_number -- 需要手机号么? - -## intent: request_takeway -- 点份外卖 -- 点一份[肠粉](refreshments),一杯[茉莉花茶](tea),送到[南山区](address),电话号码为[13025240602](phone_number) -- 麻烦送一份[蛋糕](refreshments)到[南山区](address) -- ... -``` - -## 三、 stories 模块 设置 - -### 3.1 为什么需要 stories 模块 ? - -因为 NLU 识别出 query 的意图和槽位之后,需要 确定 其 所触发的对应事件。 - -```s - eg: - query: 用户:我要点一份外卖 - NLU: {intent:"订外卖",slots:{}} - action: takeway_form -``` diff --git "a/NLPinterview/DialogueSystem/Rasa/xmind/\343\200\220\345\205\263\344\272\216 Rasa \345\205\245\351\227\250\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" "b/NLPinterview/DialogueSystem/Rasa/xmind/\343\200\220\345\205\263\344\272\216 Rasa \345\205\245\351\227\250\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" deleted file mode 100644 index 40da53d..0000000 Binary files "a/NLPinterview/DialogueSystem/Rasa/xmind/\343\200\220\345\205\263\344\272\216 Rasa \345\205\245\351\227\250\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" and /dev/null differ diff --git "a/NLPinterview/DialogueSystem/Rasa/xmind/\343\200\220\345\205\263\344\272\216 Rasa\345\256\211\350\243\205\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" "b/NLPinterview/DialogueSystem/Rasa/xmind/\343\200\220\345\205\263\344\272\216 Rasa\345\256\211\350\243\205\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" deleted file mode 100644 index 8a91ca8..0000000 Binary files "a/NLPinterview/DialogueSystem/Rasa/xmind/\343\200\220\345\205\263\344\272\216 Rasa\345\256\211\350\243\205\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" and /dev/null differ diff --git a/NLPinterview/DialogueSystem/img/20200917122718.png b/NLPinterview/DialogueSystem/img/20200917122718.png deleted file mode 100644 index 687b7a9..0000000 Binary files a/NLPinterview/DialogueSystem/img/20200917122718.png and /dev/null differ diff --git a/NLPinterview/DialogueSystem/img/20200917122948.png b/NLPinterview/DialogueSystem/img/20200917122948.png deleted file mode 100644 index ad3bc1d..0000000 Binary files a/NLPinterview/DialogueSystem/img/20200917122948.png and /dev/null differ diff --git a/NLPinterview/DialogueSystem/img/20200917125656.png b/NLPinterview/DialogueSystem/img/20200917125656.png deleted file mode 100644 index 50be2a5..0000000 Binary files a/NLPinterview/DialogueSystem/img/20200917125656.png and /dev/null differ diff --git "a/NLPinterview/DialogueSystem/img/QQ\346\210\252\345\233\27620201227114828.png" "b/NLPinterview/DialogueSystem/img/QQ\346\210\252\345\233\27620201227114828.png" deleted file mode 100644 index b2938a0..0000000 Binary files "a/NLPinterview/DialogueSystem/img/QQ\346\210\252\345\233\27620201227114828.png" and /dev/null differ diff --git "a/NLPinterview/DialogueSystem/img/\343\200\220\345\205\263\344\272\216 \345\257\271\350\257\235\347\263\273\347\273\237\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" "b/NLPinterview/DialogueSystem/img/\343\200\220\345\205\263\344\272\216 \345\257\271\350\257\235\347\263\273\347\273\237\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" deleted file mode 100644 index 57d1e8e..0000000 Binary files "a/NLPinterview/DialogueSystem/img/\343\200\220\345\205\263\344\272\216 \345\257\271\350\257\235\347\263\273\347\273\237\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" and /dev/null differ diff --git "a/NLPinterview/DialogueSystem/img/\343\200\220\345\205\263\344\272\216\345\257\271\350\257\235\347\263\273\347\273\237\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" "b/NLPinterview/DialogueSystem/img/\343\200\220\345\205\263\344\272\216\345\257\271\350\257\235\347\263\273\347\273\237\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" deleted file mode 100644 index d68c811..0000000 Binary files "a/NLPinterview/DialogueSystem/img/\343\200\220\345\205\263\344\272\216\345\257\271\350\257\235\347\263\273\347\273\237\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" and /dev/null differ diff --git "a/NLPinterview/DialogueSystem/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201227120645.png" "b/NLPinterview/DialogueSystem/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201227120645.png" deleted file mode 100644 index 610d53a..0000000 Binary files "a/NLPinterview/DialogueSystem/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201227120645.png" and /dev/null differ diff --git "a/NLPinterview/DialogueSystem/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080227.png" "b/NLPinterview/DialogueSystem/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080227.png" deleted file mode 100644 index f4aea64..0000000 Binary files "a/NLPinterview/DialogueSystem/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204080227.png" and /dev/null differ diff --git a/NLPinterview/DialogueSystem/readme.md b/NLPinterview/DialogueSystem/readme.md deleted file mode 100644 index 52ac973..0000000 --- a/NLPinterview/DialogueSystem/readme.md +++ /dev/null @@ -1,178 +0,0 @@ -# 【关于 对话系统】那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20210204080227.png) - -## 一、对话系统 介绍篇 - -### 1.1 对话系统有哪几种? - -- 类别: - - 任务型对话系统 - - 目标:通过对话系统能够找到用户完成一项特定任务 - - 类别: - - 基于规则 - - 基于数据 - - 面向开放域的对话系统 - - 支持类型:闲聊 - - 类别: - - 基于 海量 FAQ 的检索方式 - - 端到端方式 - -### 1.2 这几种对话系统的区别? - -- 区别:是否有明确的目标和任务 -- 面向开放域的对话系统 - - 特点:有户一般具有不确定的目的性 - - 如何衡量质量:以用户的主观体验为主 -- 任务型对话系统 - - 特点:具有目前的目的性 - - 如何衡量质量:以任务的完成情况来衡量对话质量 - -## 二、多轮对话系统 介绍篇 - -### 2.1 为什么要用 多轮对话系统? - -对于一项特定任务,需要多个不同的必要信息(eg:订餐任务:用户地址,用户电话等),单轮请求无法提供用户满足条件的充足信息。 - -### 2.2 常见的多轮对话系统解决方案是什么? - -- 基于手写规则,状态机state machines - - 缺陷:硬编码,不灵活,各种 if-else 的集合,一个场景对应一段代码,逻辑会越来越复杂,基本没有扩展性,泛化能力较差; - - 举例介绍: - -![](img/20200917122718.png) - -- 增强学习, reinforcement learning (RL) - - 方法:采用增强学习的方法,对机器人的回答结果进行鼓励或惩罚; - - 问题:需要大量数据和不停的与机器人对话,给予奖励才会变的智能,但是用户的对话是非理想状态不可控的 - -![](img/20200917122948.png) - -## 三、任务型对话系统 介绍篇 - -### 3.1 什么是任务型对话系统? - -- 介绍:完成用户所指定的一项特定任务(天气、订餐等) - -### 3.2 任务型对话系统的流程是怎么样? - -![](img/20200917125656.png) - -- ASR(语音识别) - - 介绍:识别用户输入的语音信息,将其转化为文本。 - - 例如:将 "定云海肴中关村店" 语音转化为 文本; -- SLU(语言理解) - - 介绍:将用户输入的自然语言语句映射为机器可读的结构化语义表述; - - 结构化语义: - - 意图识别: - - 槽值: - - 例如:对于文本 "定云海肴中关村店",SLU 会抽取出 如下结构化语义信息: - - 意图识别:预订 - - 槽位提取: - - 槽位:(restaurant_name,云海肴)、(subbranch,中关村店) -- DST(对话状态跟踪) - - 目标:跟踪用户需求并判断当前的对话状态 - - 工作原理:以多轮对话历史、当前用户动作为输入,通过总结和推理理解在上下文环境下用户当前输入自然语言的具体含义 - - 举例:根据 SLU 结果 {意图识别:预订,slot:{(restaurant_name,云海肴)、(subbranch,中关村店)}} 推理出 用户 想 预订(意图识别) 云海肴(restaurant_name)中关村店(subbranch)的餐位,更新 当前对话的意图和槽位信息; -- DPO(对话策略学习) - - 工作原理:根据当前的对话状态,对话策略决定下一步执行什么系统动作 - - 举例:根据 DST 的结果,判断用户的意图,已经完成该意图工作需要的槽位信息 request(phone,name) -- NLG(自然语言生成) - - 工作原理:负责将对话策略模块选择的系统动作转化到自然语言,最终反馈给用户 - - 举例:根据 DPL 的信息,输出对话:"麻烦请提供一下手机号和姓名" -- TTS(语音合成) - - 工作原理:将 NLG 的 文本回复转化为语音信息; - - 举例:将 文本信息 "麻烦请提供一下手机号和姓名" 转化为 语音信息 - -### 3.3 任务型对话系统 语言理解(SLU)篇 - -#### 3.3.1 什么是 语言理解(SLU)? - -将用户输入的自然语言映射为机器可读的结构化语义表述,即用户的意图信息和对应的槽位值信息。 - -#### 3.3.2 语言理解(SLU)的输入输出是什么? - -- 输入:用户当前的对话信息 Xn -- 输出:解析 语句Xn 后所得到的用户动作信息 Un (意图,槽位); - -#### 3.3.3 语言理解(SLU)所使用的技术是什么? - -- 意图识别->意图信息 - - 介绍:将用户输入的自然语言会谈划分为不同用户意图; - - 举例: - - query: 定云海肴中关村店 - - 意图 : 预订 -- 命名实体识别->槽位信息 - - 介绍:意图所带的参数,一个意图可以携带若干个相应槽位 - - 举例: - - query: 定云海肴中关村店 - - 槽位:(restaurant_name,云海肴)、(subbranch,中关村店) - - 目标:在已知特定领域或意图的语义框架下,从输入语句中抽取处该语义框架中余弦定义好的语义槽的值 - -### 3.4 任务型对话系统 DST(对话状态跟踪)篇 - -#### 3.4.1 什么是 DST(对话状态跟踪)? - -根据旧状态、最新的系统动作和用户动作,更新对话状态,以获得新的对话状态。 - -![](img/QQ截图20201227114828.png) - -#### 3.4.2 DST(对话状态跟踪)的输入输出是什么? - -- 输入:以旧状态、最新的系统动作和当前用户动作 (意图识别,槽位值) ; -- 输出:DST 模块判定得到的当前对话状态 - -#### 3.4.3 DST(对话状态跟踪)存在问题和解决方法? - -- 存在问题:由于 语音识别不准确 或 自然语言 本身存在 歧义问题,导致 NLU 的识别结果 往往 和真实结果间存在误差,所以 NLU 的 输出 是带概率的,及每一种可能的结果由一个相应的置信程度; -- DST 在判断当前对话存在两种选择: - - 第一种选择所对应的处理方法:1-Best - - 介绍:DSt 判断当前对话状态时只考虑置信程度最高的情况,维护对话状态的表示时,只需要等同于槽位数量的空间; - - 第二种选择所对应的处理方法:N-Best - - 介绍:DST 判断当前对话时会综合考虑所有槽位的置信程度,每一个槽位的N-best 结构都要考虑和维护,且最终还需要维护一个槽位组合在一起的整体置信程度,作为最终的对话状态判断依据; - -#### 3.4.4 DST(对话状态跟踪)实现方式是什么? - -- 基于CRF的系列跟踪模型 -- 基于 RNN 或 LSTM 的序列跟踪模型 - -### 3.5 任务型对话系统 DPO(对话策略学习)篇 - -#### 3.5.1 DPO(对话策略学习)是什么? - -根据当前的对话状态,对话策略决定下一步执行什么系统动作 - -#### 3.5.2 DPO(对话策略学习)的输入输出是什么? - -- 输入:DST 模块输出的当前对话状态; -- 输出:通过预设的对话策略,选择系统动作作为输出; - -#### 3.5.3 DPO(对话策略学习)的实现方法是什么? - -- 实现方式:增强学习,针对 DST 模块输出的当前对话状态 ,作为序列决策过程进行优化; - -![](img/微信截图_20201227120645.png) - -### 3.6 任务型对话系统 NLG(自然语言生成)篇 - -#### 3.6.1 NLG(自然语言生成)是什么? - -- 工作原理:负责将对话策略模块选择的系统动作转化到自然语言,最终反馈给用户 - -#### 3.6.2 NLG(自然语言生成)的输入输出是什么? - -- 输入:DPO 模块输出的当前系统动作; -- 输出:系统对用户输入 Xn 的回复; - -#### 3.6.3 NLG(自然语言生成)的实现方式? - -- 基于模板:麻烦请提供一下{phone}和{name} -- 基于语法规则 -- 生成式模型方法 - diff --git "a/NLPinterview/EventExtraction/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210211181340.png" "b/NLPinterview/EventExtraction/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210211181340.png" deleted file mode 100644 index 08bb991..0000000 Binary files "a/NLPinterview/EventExtraction/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210211181340.png" and /dev/null differ diff --git a/NLPinterview/EventExtraction/readme.md b/NLPinterview/EventExtraction/readme.md deleted file mode 100644 index 003a5b0..0000000 --- a/NLPinterview/EventExtraction/readme.md +++ /dev/null @@ -1,711 +0,0 @@ -# 【关于 事件抽取】那些你不知道的事 - -> 作者:芙蕖 - -![](img/微信截图_20210211181340.png) - -## 一、原理篇 - -### 1.1 什么是事件? - -事件在不同领域中有着不同的含义, 对于事件目前还没有统一的定义。在 IE ( Information Extraction) 中, 事件是指在某个特定的时间片段和地域范围内发生的, 由一个或多个角色参与, 由一个或多个动作组成的一件事情, 一般是句子级的。在 TDT ( Topic Detection Tracking) 中, 事件是指关于某一主题的一组相关描述, 这个主题可以是由分类或聚类形成的。 - -### 1.2 什么是事件抽取? - -事件抽取技术是从非结构化的信息中抽取出用户感兴趣的事件, 并以结构化的形式呈现给用户。 - -1、Closed-domain - -事件抽取使用预定义的事件模式从文本中发现和提取所需的特定类型的事件。事件模式包含多个事件类型及其相应的事件结构。D.Ahn首先提出将ACE事件抽取任务分成四个子任务:触发词检测、事件/触发词类型识别、事件论元检测和参数角色识别。我们使用ACE术语来介绍如下事件结构: -- 「事件提及」:描述事件的短语或句子,包括触发词和几个参数。 -- 「事件触发词」:最清楚地表达事件发生的主要词,一般指动词或名词。 -- 「事件论元」:一个实体,时间表达式,作为参与者的值和在事件中具有特定角色的属性。 -- 「论元角色」:论元与它所参与的事件之间的关系 - - -2、Open domain - -在没有预定义的事件模式的情况下,开放域事件抽取的目的是从文本中检测事件,在大多数情况下,还可以通过提取的事件关键词聚类相似的事件。事件关键词指的是那些主要描述事件的词/短语,有时关键词还进一步分为触发器和参数。 -- 「故事分割」:从新闻中检测故事的边界。 -- 「第一个故事检测」:检测新闻流中讨论新话题的故事。 -- 「话题检测」:根据讨论的主题将故事分组。 -- 「话题追踪」:检测讨论先前已知话题的故事。 -- 「故事链检测」:决定两个故事是否讨论同一个主题。 - -前两个任务主要关注事件检测;其余三个任务用于事件集群。虽然这五项任务之间的关系很明显,但每一项任务都需要一个不同的评价过程,并鼓励采用不同的方法来解决特定问题。 - -事件抽取涉及自然语言处理、机器学习、模式匹配等多个学科,对于相关学科理论的完善和发展起到积极的推进作用。同时,在情报研究工作中事件抽取技术能帮助情报人员从海量信息中快速提取相关事件, 提高了情报研究工作的时效性, 并为开展定量情报分析提供技术支撑。事件抽取在情报研究领域具有广阔的应用前景。 - -### 1.3 ACE测评中事件抽取涉及的几个基本术语及任务是什么? - -1、实体(Entity)。属于某个语义类别的对象或对象集合。其中包括:人(PER)、地理政治区域名( GPE)、组织机构(ORG)、地名(LOC)、武器(WEA)、建筑设施(FAC)和交通工具( VEH)。 - -2、事件触发词(Event Trigger)。表示事件发生的核心词,多为动词或名词。 - -3、事件论元(Event Argument)。事件的参与者,主要由实体、值、时间组成。值是一种非实体的事件参与者,例如工作岗位( Job-Title)。和实体一样,ACE05也标记出了句子中出现的值和时间。下文中,即将实体、值、时间统称为实体。 - -4、论元角色(Argument Role)。事件论元在事件中充当的角色。共有35类角色,例如,攻击者( Attacker)、受害者( Victim)等。 - -其中,我常用的ACE 2005定义了8种事件类型和33种子类型。其中,大多数事件抽取均采用33种事件类型。事件识别是基于词的34类( 33类事件类型+None)多元分类任务,角色分类是基于词对的36类(35类角色类型+None)多元分类任务。这里,参考文献 - - -### 1.4 事件抽取怎么发展的? - -从事件抽取的发展历史来看,事件抽取的研究几乎与信息抽取的研究同时开始 。 20世纪七、八十年代 ,耶鲁大学就针对新闻报道如地震 、工人罢工等领域或场景 ,开展有关故事理解的研究, 并根据故事脚本理论建立信息抽取系统,就是针对事件抽取的研究 ,开创了事件抽取研究的先河 。但是真正推进事件抽取研究进一步发展的动力主要是相关的评测会议的推动。 - -消息理解会议(MessageUnderstandingConference, MUC)对事件抽取这一研究方向的确立和发展起到了巨大的推动作用。 MUC定义的抽取任务的各种规范以及确立的评价体系已经成为事件抽取研究事实上的标准,同时也为事件抽取技术的研究奠定了坚实的基础。 MUC是由美国国防高级研究计划委员会(Defense Advanced Research Projects Agency, DARPA)资助 ,从 1987年开始到 1998年 , 会议共举行了 7届 ,具体的历次会议信息如表 1所示 。当前, 由 MUC 定义的概念、模型和技术规范对整个信息抽取领域起着主导作用, 其主要的评测项目是从新闻报道中提取特定的信息, 填入某种数据库中, 事件抽取 ( Scenario Template, ST) 始终是这一会议的评测项目之一。MUC 会议的很多研究都是探索性的, 对信息抽取领域起到了巨大的推动作用, 并为事件抽取的研究打下了坚实的基础。每一届 MUC 都针对一个特定领域和场景,并且提供预先定义好的模板 ( Template) 进行填充, 填充之后的模板形成了对文本核心事件的整体描述。 - -![图片.png](https://i.loli.net/2021/02/10/yTLNqARtb2WveBf.png) - -在强烈的应用需求下 ,来自美国国家标准技术研究所 (NIST)组织的 ACE评测会议应运而生, 这项评测真正推动了事件抽取研究的发展 。从 1999年开始酝酿, 2000年正式开始启动 。研究的主要内容是自动抽取新闻语料中出现的实体 、关系 、事件等内容, 即对新闻语料中实体 、关系、事件的识别与描述。 - -与 MUC相比, ACE评测不针对某个具体的领域或场景, 采用基于漏报 (标准答案中有而系统输出中没有)和误报 (标准答案中没有而系统输出中有 )为基础的一套评价体系 , 还对系统跨文档处理 (CrossDocumentProcessing)能力进行评测。这一新的评测会议把事件抽取技术研究引向新的高度 。具体的历次会议信息如表 2所示 。ACE 会议作为 MUC 会议的延伸, 是事件抽取领域最具影响力的评测会议, 该会议从 2000 年到 2007 年共举办了 7 届。目前大多数研究都是围绕 ACE 的评测任务开展,它把事件抽取的研究推向一个新的高度。会议研究的主要内容是自动抽取新闻语料中出现的实体、关系、事件等内容。ACE 定义的事件属于元事件的范畴, 包括事件类别和事件元素的识别。与 MUC 相比, ACE 评测不针对某个具体的领域或场景, 也不提供预先定义好的模板, 而是强调对文本基本意义或基本概念的刻画, 因此所定义的任务显得更为细致和深入。用户指定要检测的事件的类别, 系统给出检测文本中这些事件的出现, 但最后的输出并未形成对核心事件的整体描述, 并且 ACE 同 MUC 一样都是篇章级 ( Document Level) 的事件抽取, 不涉及跨文档抽取。 - -![图片.png](https://i.loli.net/2021/02/10/rBUuYxtweljNpkV.png) - -自 2009年 , ACE成为文本分析会议(TextAnalysisConference, TAC)中的一个任务 。 TAC主要由 3个评测任务组成 ,主要目的是促进自然语言处理技术发展和相关的应用 。 - -总而言之,从 20世纪七 、八十年代开始,事件抽取一直发展到今天 ,已经走过了几十年的研究历程 ,其所取得的进步与上述评测会议的推动密不可分 ,但从评测会议公布的结果来看, 抽取的精度离实用还相差甚远, 在领域扩展性和移植性方面的表现还不能令人满意, 注定今后事件抽取技术的研究还有很长的路要走。 - -### 1.5 事件抽取存在什么问题? - -1)对实体、关系识别、语法分析等相关技术的底层技术研究不够成熟,导致级联错误。事件抽取是在实体和关系识别的基础上发展起来的。它在某种程度上取决于实体、关系识别和文本预处理的效果,但是这些基础技术仍然不够成熟。并且,目前缺乏对子任务输出结果的评估及矫正技术。 - -2)事件抽取系统的现场可伸缩性和便携性并不理想。例如,有关中文事件抽取的相关研究主要集中在生物医学、微博、新闻、紧急情况等方面。其他领域和开放领域的研究很少。关于领域和跨语言事件抽取技术的研究很少。 - -3)缺乏大规模成熟的语料和标注语料,需要进一步完善。手动标注语料库既费时又费力,而且缺少语料库限制了事件抽取技术研究的发展。因此,大型语料库的自动构建技术方法需要进一步研究。 - -4)如何设计神经网络模型以实现多任务联合是一大难点。 - -## 二、基本任务篇 - -### 2.1 触发词检测 - -#### 2.1.1 什么是触发词检测? - -表示事件发生的核心词,多为动词或名词 - -#### 2.1.2 触发词检测有哪些方法? - -现有的检测事件句的方法主要是基于触发词的方法。Grisman、赵妍妍等都是采用这种方法来发现文本中的事件句。在这类方法中,将每个词作为一个实例来训练并判断是否为触发词的机器学习模型,但引入了大量的反例,导致正反例严重不平衡。为了解决了上述问题,哈尔滨工业大学的谭红叶提出了一种基于局部特征选择和正负特征相结合的事件检测与分类方法,取得了不错的识别效果。厦门大学的许红磊等人也提出了一种新的事件类别自动识别算法,很好地克服了传统基于触发词方法所带来的正反例失衡和数据稀疏问题。 - -### 2.2 类型识别 - -#### 2.2.1 什么是类型识别? - -ACE2005 定义了8种事件类型和33种子类型。其中,大多数事件抽取均采用33 种事件类型。事件识别是基于词的34 类(33类事件类型+None) 多元分类任务,角色分类是基于词对的36 类(35类角色类型+None) 多元分类任务。 - -事件类别识别是指从文本中检测出事件句,并依据一定的特征判断其所归属的类别。不难看出,事件类别识别是典型的分类问题,其重点在于事件句的检测和事件句的分类。 - -#### 2.2.2 类型识别有哪些方法? - -在已有的研究中 ,事件句分类主要采用最大熵模型 (MaximumEntropyModel, MEM)和支持向量机(SupportVectorMachine, SVM)。赵妍妍和许红磊等人分别使用上述两种分类器基于二元分类策略实现了候选事件句的类别识别,但二元分类的最大缺陷就是无法处理一个事件句属于多个事件类别的情况 ,多元分类应该是更合理的选择 。事件句分类的难点主要是如何选择合适的描述事件句的特征提高分类精度 。赵妍妍等人选取词法 、上下文和词典信息等语言学特征对候选事件进行描述 ,在 ACE2005中文语料上取得F-值为 61.2%的效果 。 付剑锋等人在此基础上引入依存分析发掘触发词与其它词之间的句法关系 ,并以此为特征在 SVM分类器上对事件句进行分类 F-值提高到 69.3% - -可见,事件类别的识别率还有很大的提升空间,选择更加合适的分类器以及事件特征进一步提高识别效果仍有待于下一步研究与探讨。 - -### 2.3 角色识别 - -#### 2.3.1 什么是角色识别? - -事件角色识别是事件抽取中又一核心任务 。该任务主要从众多命名实体(Entity)、时间表达式 (Time Expression)和属性值 (Value)中识别出真正的事件元素 ,并给予其准确的角色标注。事件句中通常包含大量的 Entity、TimeExpression和 Value等事件信息, 要想从中筛选出真正的事件元素, 首先要把所有信息识别并标注出来,而这也正是 MUC会议的主要研究内容 。在事件元素识别中 ,假定在文本预处理阶段已完成事件信息的识别与标注 。 - -事件的参与者,主要由实体、值、时间组成。值是一种非实体的事件参与者,例如工作岗位。 - -#### 2.3.2 角色识别有哪些方法? - -事件角色识别与语义角色标注 (SemanticRoleLabeling, SRL)任务有一定的相似性。所谓语义角色标注是根据一个句子中的动词(谓词)与相关的各类短语等句子成分之间的语义关系而赋予这些句子成分的语义角色信息 ,如施事、受事 、工具或附加语等。于江德等探索了基于条件随机场 (Conditional Random Fields, CRFs)的方法对任职事件和会见事件的事件元素进行角色标注 ,取得了不错标注效果,也从侧面揭示了事件元素与语义角色之间存在着一定的对应关系 。吴刚等利用这种对应关系实现了事件角色的识别,然而该方法依赖的底层模块较多,如 :分词、句法分析、SRL等 ,如果底层处理模块不够成熟, 将会导致级联错误过多 ,影响事件元素识别效果 。赵妍妍等是将事件元素识别看作分类问题 ,使用最大熵模型 ,选取词法、类别、上下文和句法结构等 4类特征多角度地描述候选元素 ,采用二元分类和多元分类两种策略实现了事件元素的自动识别 。 - -### 2.4 论元检测 - -#### 2.4.1 什么是论元检测? - -事件论元在事件中充当的角色。共有35类角色,例如,攻击者 、受害者等。 - -#### 2.4.2 论元检测有哪些方法? - -## 三、常见方法篇 - -### 3.1 模式匹配方法怎么用在事件抽取中? - -早期的事件抽取方法主要是基于规则的方法,后来发展成为基于模式匹配的方法。这些方法本质上是相同的,也就是说,它们需要构建规则或模式。基于模式匹配的事件抽取方法是指将要抽取的事件语句与相应的模式进行匹配的方法,其基本原理如图2所示。 - -![图片.png](https://i.loli.net/2021/02/09/nQVZ4o5x2aMuUPj.png) - -基于模式匹配事件抽取主要分为有监督的模式匹配方法和弱监督的模式匹配方法两大类。 - -有监督的模式匹配方法依赖于人工标注语料进行事件模式学习。Ellen等1993年通过建立触发词词典和13种事件匹配模式进行事件识别与抽取,事件匹配模式主要利用事件元素初始描述和事件元素上下文语义的进行构建,并开发了AutoSlog模式匹配事件抽取系统,在MUC语料上取得优异的性能。Kim等1995年引入WordNet语义词典,利用语义框架和短语结构进行事件抽取,并开发了PALKA模式匹配事件抽取系统。 - -弱监督的模式匹配方法只需对语料进行预分类或制定种子模式的少量人工标注工作,然后自动进行事件模式学习。Ellen等1995年在AutoSlog基础上开发出AutoSlog-ST系统,不需要对语料中的所有事件元素进行标注,只需标注事件类型,然后利用预分类语料自动学习事件模式。姜吉发2005年提出一种领域通用事件模式匹配方法IEPAM,将事件抽取模式分为语义模式、触发模式、抽取模式,在MUC-7语料的飞行事故事件抽取中获得优异结果。 - -北京科技大学的Meiying Jia用模式匹配法研究军事演习信息的抽取。它在抽取的不同阶段使用分层自动分类方法、基于子模式的引导方法和基于语料库的标注。其模式匹配方法侧重于模式获取和匹配算法,如图3所示。 - -![图片.png](https://i.loli.net/2021/02/09/PlQu83gOzTBX2kc.png) - -以上研究表明,模式匹配方法的核心是事件抽取模式的构建。Jifa Jiang研究了模式的自动获取,并提出了一种基于领域无关的概念知识库的事件抽取模型学习方法。只要定义了IE任务,他构建的系统就可以从原始语料库自动学习IE模式,而无需提供子模式和语料库的预处理,从而大大提高了效率。另一名学者Ming Luo基于有限状态机构建了层次化的词汇语义规则模型,用于自动抽取各种财务事件信息,具有较高的准确性。Liao et al.在构造事件抽取模式时使用谓词论元模式,并通过相似性扩展原始模式。 - -基于模式匹配的方法较好地应用于特定领域,但该方法的可移植性和灵活性较差。当它是跨域的时,它需要重建模型。模式匹配事件抽取方法在领域事件抽取任务中性能优异,但模板的制作需要耗费大量人力和时间,且模板局限于领域背景,很难在通用领域事件抽取任务中应用。使用机器学习和其他方法可以加快模式的获取,但是会带来不同模式之间的冲突。 - - - -### 3.2 统计机器学习方法怎么用在事件抽取中? - -通过机器学习抽取事件本质上是将事件抽取视为分类问题。主要任务是选择合适的特征并构造合适的分类器。与模式匹配方法相比,机器学习方法可应用于不同领域,具有较高的可移植性和灵活性,并已被广泛使用。 - -分类器通常是基于统计模型构建的。事件抽取中的主要统计模型主要包括最大熵模型、隐马尔可夫模型、条件随机场模型和支持向量机模型。 - -例如,2002年,Chieu et al.在事件元素的识别中首次应用最大熵模型,并抽取了演讲公告和人员管理事件。另一位学者H. Llorens在语义角色注释中引入了条件随机字段模型(CRF),并将其应用于TimeML事件抽取中,以提高系统的性能。国内Jiangde Yu et al.提出了中文文本,基于隐马尔可夫模型(HMM)的事件抽取方法。当抽取每种类型的事件元素时,此方法将构造一个独立的隐马尔可夫模型。 - -为了提高事件抽取的效果,有时会结合使用多种机器学习算法。 2006年,David Ahn集成了MegaM和Timbl机器学习方法来识别事件类别和事件元素。事件类型识别存在向后依赖事件元素识别的问题。 2012年,Bolei Hu et al.解决这个问题很好。他们将事件抽取视为序列标注,并构建了改进的条件随机域联合标注模型。主要思想是在图模型中同时标注事件类型和事件元素。改进的CRF模型如图4所示。 - -![图片.png](https://i.loli.net/2021/02/09/15htIxLdJRDZ7B6.png) - -许多机器学习方法都是基于触发词进行事件识别的。基于触发词的方法在训练中引入了大量的负例,导致正例与负例之间失衡。为了解决这个问题,哈尔滨工业大学的Yanyan Zhao通过结合触发词扩展和二进制分类来识别事件类别。另外,Honglei Xu提出了一种基于事件实例的事件类型识别方法。该方法通过使用句子代替词作为识别示例,克服了正负大小写不平衡和数据稀疏的问题。 - -当前在事件抽取研究中的主导作用是基于机器学习的方法,但是该方法需要大规模的标注训练语料库。如果训练语料不足或类别单一,将严重影响事件的抽取效果,语料库的建设成为一项重要任务。但是,语料库的建设需要大量的人力和时间。为了减轻这个问题,学者们进一步探索了深度学习的方法。 - - -### 3.3 深度学习方法怎么用在事件抽取中? - -深度学习是机器学习研究领域中的一个新方向。与浅层神经网络相比,深层神经网络(DNN)具有更好的特征学习能力,其抽象数学的无监督逐层预训练。可以更有效地表征原始数据基本特征的特征。Yajun Zhang et al.建立了基于深度学习的事件识别模型,并利用BP神经网络对事件进行识别,通过深度信念网络抽取词的深度语义信息。同时,文献还提出了一种混合式监督深度信念网络,将监督和非监督学习方法相结合,可以提高识别效果,控制训练时间。 - -传统的基于特征的事件抽取方法需要大量的特征设计工作,并且需要复杂的自然语言处理工具,这会消耗大量的人力和时间,并且会产生数据稀疏的问题。在这方面,Kai Wang提出了一种基于递归神经网络(RNN)的事件抽取方法,该方法可以自动学习句子中的特征,而无需进行大量的人工特征设计工作,并克服了复杂的特征工程。 - -递归神经网络(RNN)广泛用于自然语言处理领域。它主要用于解决序列问题,对事件抽取有很好的效果。这是因为递归神经网络模型的结构由三层组成,即输入层x、隐藏层h和输出层y,其中隐藏层h表示递归神经的内部状态网络,如图5所示。 - -![图片.png](https://i.loli.net/2021/02/09/kNZ3Bxizaj5RmGM.png) - -在时间t,隐藏层的输入h(t)由当前时间的输入x(t)和上一次隐藏层的输出h(t-1)组成,而h(t-1 )包含前一瞬间的输入信息和上一隐藏层中的信息。这样,通过添加前一时刻输入的隐藏层,添加了序列的历史信息,从而可以利用距离更长的信息。 - -另外,为避免复杂的特征工程,相关学者构建了联合学习的神经网络模型,并提出了基于联合模型的神经网络事件抽取方法。例如,Nguyen et al.提出了一种基于RNN模型的联合学习,用于事件类型识别和事件元素识别。北京邮电大学的Zhengkuan Zhang 设计了一种新的事件抽取框架,结合了window-winding卷积神经网络和递归神经网络,形成了一种连通学习方法,可以同时抽取事件触发词和事件元素,不仅避免了复杂的特征工程,而且还解决了错误传播的问题。 - -深度学习方法克服了浅层机器学习的局限性,可以学习更多抽象的数学特征,并使数据具有更好的特征表达,从而实现文本事件的有效抽取。与浅层机器学习相比,深度学习框架可以有效地指数捕获数据特征,已应用于事件抽取领域。 - -## 四、数据集及评价指标篇 - -### 4.1 事件抽取中常见的英文数据集有哪些? - -- ACE2005 English Corpus - -ACE 2005多语种训练语料库包含了用于2005年自动内容抽取(ACE)技术评价的完整的英语、阿拉伯语和汉语训练数据集。语料库由语言数据联盟(LDC)为实体、关系和事件注释的各种类型的数据组成,该联盟得到了ACE计划的支持和LDC的额外帮助。下载地址为:https://catalog.ldc.upenn.edu/LDC2006T06 - -- Rich ERE - -Rich ERE扩展了实体、关系和事件本体,并扩展了什么是taggable的概念。Rich ERE还引入了事件跳跃的概念,以解决普遍存在的事件共引用的挑战,特别是关于在文档内和文档之间的事件提及和事件参数粒度变化,从而为创建(分层的或嵌套的)跨文档的事件表示铺平了道路。下载地址为:https://www.aclweb.org/old_anthology/W/W15/W15-0812.pdf - -- TAC 2015 - -TAC KBP事件跟踪的目标是提取关于事件的信息,以便这些信息适合作为知识库的输入。轨迹包括用于检测和链接事件的事件块任务,以及用于提取属于同一事件的事件参数和链接参数的事件参数(EA)任务。2015年TAC KBP赛事轨迹分为5个子任务。下载地址为:https://tac.nist.gov//2015/KBP/Event/index.html - -- KBP 2017 - -TAC知识库填充(KBP)的目标是开发和评估从非结构化文本中填充知识库的技术。KBP包括为KBP开发特定组件和功能的组件跟踪,以及称为“冷启动”的端到端KB构建任务,该任务通过在技术成熟时集成选定的组件从头开始构建KB。与在冷启动KB任务中执行的功能相比,组件跟踪中所需的功能可以“更多”,也可以“更少”。组件轨道比冷启动“更多”,因为每个轨道可能探索未立即集成到冷启动任务中的试点任务; 他们是“少”,将组件集成到一个KB需要额外协调与和解各个组件之间的不匹配,这样KB符合知识库模式(例如,知识库不能断言一个实体是一个事件的“地方”如果它还断言,实体是一个“人”)。 下载地址为:https://tac.nist.gov/2017/KBP/ - -- Twitter datasets【CrisisLexT26 datasets】 - -CrisisLexT26来自26次危机的推文,贴有丰富的信息,信息类型和来源,2014年11月 - -此集合包括在2012年和2013年的26次大型危机事件中收集的推文,每个危机中大约有1,000条推文被标记为信息性(即“信息性”或“非信息性”),信息类型和来源。 - -- Genia Event Extraction dataset\Genia dataset - -GENIA语料库是为GENIA项目编写并标注的最初的生物医学文献集合。这个语料库是为了发展和评估分子生物学信息检索及文本挖掘系统而创建的。 - -这个语料库包含1999条Medline的摘要,这些摘要是由PubMed按照human、blood cells以及transcription factors三个医学主题词(medical subject heading terms )为搜索条件搜索到的。这个语料库已经被按照不同级别的语言信息、语义信息进行标注。 - -包含36种实体种类(医学数据集), 我们把所有的DNA子类别都合并为DNA种类。同样的设置也适用于RNA、蛋白质、细胞系和细胞类类别。最终只保留5种类别。 -最初始的GENIA语料库标注类别以及对应的资料如下: - • Part-of-Speech annotation - • Constituency (phrase structure) syntactic annotation - • Term annotation - • Event annotation - • Relation annotation - • Coreference annotation - • 词性标注 - • 句法标注 - • 术语标注 - • 事件标注 - • 关系表述 - • 共指标注 - - -其他的还有,Spainish ERE Corpus, Wikipedia article, BioNLP Cancer Genetics (CG) Shared Task 2013 等等 - - -### 4.2 事件抽取中常见的中文数据集有哪些? - -- ACE2005 Chinese Corpus - -ACE 2005多语种训练语料库包含了用于2005年自动内容抽取(ACE)技术评价的完整的英语、阿拉伯语和汉语训练数据集。语料库由语言数据联盟(LDC)为实体、关系和事件注释的各种类型的数据组成,该联盟得到了ACE计划的支持和LDC的额外帮助。下载地址为:https://catalog.ldc.upenn.edu/LDC2006T06 - -- CEC 中文突发事件语料库 - -事件本体是以“事件”为认知单元,研究事件的组成以及事件之间的关系,并对事件进行归纳和概括,形成事件类,进而构建事件本体模型。研究本体,必然要先构建语料库,所以在互联网上选取了突发事件语料来进行语料的事件标注,突发事件的分类体系,包括三个层次:一级4个大类(自然灾害类N、事故灾难类A、公共卫生事件P、社会安全事件S),二级33个子类,三级94个小类。我们标注的语料库称为CEC(Chinese Emergency Corpus),主要包括五类:地震、火灾、交通事故、恐怖袭击、食物中毒。合计332篇,下载地址为:https://github.com/shijiebei2009/CEC-Corpus - -中文突发事件语料库是由上海大学(语义智能实验室)所构建。根据国务院颁布的《国家突发公共事件总体应急预案》的分类体系,从互联网上收集了5类(地震、火灾、交通事故、恐怖袭击和食物中毒)突发事件的新闻报道作为生语料,然后再对生语料进行文本预处理、文本分析、事件标注以及一致性检查等处理,最后将标注结果保存到语料库中,CEC合计332篇。 - -- CEEC 中文环境突发事件语料库 - -中文环境突发事件语料库是由上海大学(语义智能实验室)所构建。根据国务院颁布的《国家突发公共事件总体应急预案》的分类体系,从互联网上收集了6类环境污染类突发事件的新闻报道作为生语料,然后再对生语料进行文本预处理、文本分析、事件标注以及一致性检查等处理,最后将标注结果保存到语料库中,CEEC合计100篇。下载地址为:https://github.com/shijiebei2009/CEEC-Corpus - -CEEC 采用了 XML 语言作为标注格式,其中包含了六个最重要的数据结构(标记):Event、Denoter、Time、Location、Participant 和 Object。Event用于描述事件;Denoter、Time、Location、Participant 和Object用于描述事件的指示词和要素。此外,我们还为每一个标记定义了与之相关的属性。与ACE和TimeBank语料库相比,CEEC语料库的规模虽然偏小,但是对事件和事件要素的标注却最为全面。 - - -### 4.3 事件抽取的评价指标是什么?怎么计算的? - -事件抽取主要采用准确率(Precision,P)、 召回率(Recall,R) 和 F1 值(F1-Measure,F1) 3 项作为基本评价指标。其中,准确率是指系统中抽取出的正确个数占抽取出总数的比例,用来衡量抽取准确程度;召回率是指系统中正确抽取的个数占所有正确总数的比例,用来衡量抽取全面程度;F1 值是准确率和召回率的加权平均值,作为系统性能的总体评价。事件抽取所采用的这三个评价指标的具体公式如下: - -![图片.png](https://i.loli.net/2021/02/05/FQlrxUvmpAGMZzu.png) - -其中,TP (True Positive)是正确抽取的预测为正例的数目,FP (False Positive)是被错误抽取的预测为正例的数目,FN (False Negative)则是被错误抽取的预测为负例的数目。事件抽取模型的性能通常通过 F1 值来综合判断, F1 值越大,模型性能越好。 - -远程监督兴起后,模型所需要处理的数据规模量级增加,在考察系统性能时,也将运行时间和内存占用作为评价指标的一部分进行考量。 - -F1平均值法一般多用于单一事件抽取任务中,如: 突发事件、门户网站、金融资讯的事件抽取。对于话题追踪任务而言,相对于正确率,人们对系统作出的错误判断往往更为敏感,这些错误包括:本应为是的判断为否 (丢失) ,本应为否的判断为是 (误报) ,因此常采用错误识别代价作为效果评价方法。另外,事件抽取的各种算法在实际应用中,除考虑其识别结果的正确率外,还应该考虑算法的复杂程度及其可实现性。一些抽取效果好的算法往往是以牺牲时间为代价的。一些算法可能由于硬件要求太高,或训练时间太长而不具备可行性。 - -## 五、对比篇 - -### 5.1 事件抽取和命名实体识别(即实体抽取)有什么异同? - -**命名实体识别** - -实体抽取:也就是命名实体识别,包括实体的检测(find)和分类(classify) - -1)主要任务: - -要识别出文本中出现的专有名称和有意义的数量短语并加以归类。 - -2)主要研究内容: - -就整个的命名实体识别的研究结果而言,时间表达式和数字表达式的识别相对简单,其规则的设计、数据的统计训练等也比较容易。而对于实体中的组织名、人名、地名,因为其具有开放性和发展性的特点,而且构成规律有很大的随意性,所以其识别就可能会有较多的错选或漏选。现在大多数的命名实体识别的研究都集中于对这三种实体的识别技术的研究。 - -3)发展历程: - -基于规则的方法->基于统计的方法->混合方法 - -4)汉语命名实体识别中的特殊难点: - -- 分词:边界模糊不仅存在于非实体词之间,也出现于实体词和非实体词之间。 - -- 汉语命名实体的生成规律以及结构更加复杂,尤其是缩略语的表示形式具有多样性,很难提取构成规则,因此不可能用一种识别模型应用于所有的命名实体。 - -- 与西方语言比较,汉语缺少在命名实体识别中起重要作用的词形变换特征。 - -- 汉语中除比较特殊的字词外,命名实体也可包含普通字词。 - -- 能用于汉语命名实体识别的开放型语料还很少,因此一方面需要开发大型命名实体标注语料库,另一方面研究不依赖大型命名实体标注文本库的算法也具有重要意义。 - -5)命名实体识别的结果: - -- 正确(correct) :系统识别结果和标准结果相同。 - -- 丢失(missing):系统未识别而标准结果中有。 - -- 虚假(spurious):系统识别但标准结果中没有。 - -6)主要的两个评价指标: - -查全率:正确/(正确+丢失) - -查准率:正确/(正确+虚假) - -有时为了综合评价系统的性能,通常还计算查全率和查准率的加权几何平均值即F指数。 - -7)方法: - -- 基于规则: - -- 如:NTU系统、FACILE系统、OKI系统。 - -- 缺点:缺乏鲁棒性和可移植性,对于每个新领域的文本都需要更新规则来保持最优性能,而这需要大量的专门知识和人力,代价往往非常大。 - -- 基于统计: - -- 如:n元模型、隐马尔科夫模型(HMM)、最大熵模型(ME)、决策树、基于转换的学习方法、推进方法、表决感知器方法、条件马尔科夫模型等。评价性能最好的是HMM。而ME因其自身的特点仍是当前主要的研究方向。 - -- 缺点:性能较基于规则的方法而言偏低,因为基于统计的方法获取的概率知识总赶不上人类专家的专业知识的可靠性,而且有些知识获取必需专家的经验。 - -- 混合方法: - -借助规则知识及早剪枝,再用统计模型是比较好的方法。 - -### 5.2 事件抽取和关系抽取有什么异同? - -**关系抽取** - -定义:自动识别实体之间具有的某种语义关系。根据参与实体的多少可以分为二元关系抽取(两个实体)和多元关系抽取(三个及以上实体)。 - -通过关注两个实体间的语义关系,可以得到(arg1, relation, arg2)三元组,其中arg1和arg2表示两个实体,relation表示实体间的语义关系。(比如通过Hanlp分析工具可以得到句子中各词之间的语义关系) - -1)抽取数据源分类: - -面向结构化文本的关系抽取:包括表格文档、XML文档、数据库数据等 - -面向非结构化文本的关系抽取:纯文本 - -面向半结构化文本的关系抽取:介于结构化和非结构化之间 - -2)抽取范围分类: - -句子级关系抽取:从一个句子中判别两个实体间是何种语义关系 -语料(篇章)级关系抽取:不限定两个目标实体所出现的上下文 - -3)抽取领域分类: - -限定域关系抽取:在一个或者多个限定的领域内对实体间的语义关系进行抽取,限定关系的类别,可看成是一个文本分类任务 -开放域关系抽取:不限定关系的类别 - -事件抽取:相当于一种多元关系的抽取 - -4)限定域关系抽取方法: - -基于模板的关系抽取方法:通过人工编辑或者学习得到的模板对文本中的实体关系进行抽取和判别,受限于模板的质量和覆盖度,可扩张性不强。(自己做的法院文书属于基于模板的抽取) - -基于机器学习的关系抽取方法:将关系抽取看成是一个分类问题 - -其中,基于机器学习的关系抽取方法又可分为 有监督 和 弱监督。 - -5)有监督的关系抽取方法: - -基于特征工程的方法:需要显示地将关系实例转换成分类器可以接受的特征向量 - -基于核函数的方法:直接以结构树为处理对象,在计算关系之间距离的时候不再使用特征向量的内积而是用核函数 - -基于神经网络的方法:直接从输入的文本中自动学习有效的特征表示,端到端 - -6)弱监督的关系抽取方法:不需要人工标注大量数据。 - -距离监督:用开放知识图谱自动标注训练样本,不需要人工逐一标注,属弱监督关系抽取的一种。 - -7)开放域关系抽取方法: - -不需要预先定义关系类别,使用实体对上下文中的一些词语来描述实体之间的关系。 - -**事件抽取** - - -定义:从描述事件信息的文本中抽取出用户感兴趣的事件并以结构化的形式呈现出来。 - -步骤:首先识别出事件及其类型,其次要识别出事件所涉及的元素(一般是实体),最后需要确定每个元素在事件中所扮演的角色。 - -1)事件抽取相关概念: - -事件指称:对一个客观发生的具体事件进行的自然语言形式的描述,通常是一个句子或句群 -事件触发词:指一个事件指称中最能代表事件发生的词,是决定事件类别的重要特征,一般是动词或名词 -事件元素:事件中的参与者,主要由实体、时间和属性值组成 -元素角色:事件元素在相应的事件中扮演什么角色 -事件类别:事件元素和触发词决定了事件的类别(类别又定义了若干子类别) - -2)限定域事件抽取:在进行抽取之前,预先定义好目标事件的类型及每种类型的具体结构(包含哪些具体的事件元素),通常会给出一定数量的标注数据。 - -限定域事件抽取方法: - -- 基于模式匹配的方法:对某种类型事件的识别和抽取是在一些模式的指导下进行的(步骤:模式获取、模式匹配) - - - 有监督的事件模式匹配:模式的获取完全基于人工标注的语料 - - - 弱监督的事件模式匹配:不需要对语料进行完全标注,只需要人工对语料进行一定的预分类或者制定少量种子模式 - -- 基于机器学习的方法 - - - 有监督事件抽取方法:将事件抽取建模成一个多分类问题 - - - 基于特征工程的方法:需要显示地将事件实例转换成分类器可以接受的特征向量,研究重点在于怎样提取具有区分性的特征 - - - 基于神经网络的方法:自动从文本中获取特征进而完成事件抽取,避免使用传统自然语言处理工具带来的误差累积问题 - - - 弱监督事件抽取方法:不需要人工大量标注样本,但需要给出具有规范语义标签(事件类别、角色名称等)的标注训练数据 - - - 基于Bootstrapping的事件抽取:利用少部分人工标注的数据自动生成大规模标注数据(高置信度抽取结果会作为训练样本,然后再训练,不断迭代) - - 基于Distant Supervison的事件抽取:完全自动生成事件标注样本,利用结构化的事件知识库直接在非结构化文本中回标训练样本 - -3)开放域事件抽取:在进行事件识别之前,可能的事件类型以及事件的结构都是未知的,因此该任务通常没有标注数据,主要基于无监督的方法和分布假设理论。 - -分布假设理论:如果候选事件触发词或者候选事件元素具有相似的语境,那么这些候选事件触发词倾向于触发相同类型的事件,相应的候选事件元素倾向于扮演相同的事件元素。 - -开放域事件抽取方法: - -- 基于内容特征的事件抽取方法 -- 基于异常检测的事件抽取方法 - -事件关系抽取,以事件为基本语义单元,实现事件逻辑关系的深层检测和抽取,包括: - -- 事件共指关系抽取 -- 事件因果关系抽取 -- 子事件关系抽取 -- 事件时序关系抽取 - - -### 5.3 什么是事理图谱?有哪些事件关系类型?事理图谱怎么构建?主要技术领域及当前发展热点是什么? - -事理图谱(Event Logic Graph,缩写ELG)是一个事理逻辑知识库,描述了事件之间的演化规律和模式。结构上,事理图谱是一个有向有环图,其中节点代表事件,有向边代表事件之间的顺承、因果、条件和上下位等事理逻辑关系。 - -理论上,事理图谱中的事件是具有一定抽象程度的泛化事件。表示为抽象、语义完备的谓词短语或句子,也可以表示为可变长度的、结构化的(主体、事件词、客体)多元组,其中必然包含一个事件词,标志事件的发生,例如:“跑步”,而事件的主体和客体都可以在不同的应用场景下被省略,例如:“(元首,出访)”可以省略事件的客体,“(购买,机票)”可以省略事件的主体。一般情况下,事件以及事件的抽象程度与该事件发生的场景紧密关联在一起,脱离了具体的场景,一个单独的事件可能变得过度抽象而难以理解。 - -例如,虽然脱离了具体的场景,但“吃火锅”, “看电影”, “去机场”,“地震” 仍是合理的事件表达;但“做事情”,“吃”等事件由于过度抽象,属于不合理或不完整的事件表达。事件词可以是动词或名词,但是绝大多数事件都是动词触发的。其中,按动词的内容意义进行划分,可将事件分为动作类事件、状态类事件、关系类事件与能愿类事件四个大类。 - -1)事理图谱中的事件关系类型 - -我们认为,现实世界中有四种事理逻辑关系特别重要,也是我们提出的事理图谱中主要关注的事理逻辑关系,包括事件之间的顺承关系、因果关系、条件关系和上下位关系。 - -- 顺承关系是指两个事件在时间上相继发生的偏序关系。我们借鉴TimeML时序关系类别中的before和after偏序关系,在事理图谱中的顺承关系包括两种情况:一种情况是顺承的前序事件a结束后,后序事件b紧接着发生;另一种情况是前序事件a结束后,隔一段时间后序事件b才会发生,具体如图1所示。两个前后顺承的事件之间存在一个介于0到1之间的转移概率,表示从一个事件按时序顺承关系演化到下一事件的置信度。 - -![图片.png](https://i.loli.net/2021/02/10/xGVKenIgFlLbySW.png) - -图1 两种顺承关系示例 - -- 因果关系是指两个事件之间,前一事件(原因)的发生导致后一事件(结果)的发生。在事理图谱中,因果关系满足原因事件在前,结果事件在后的时间上的偏序关系,因此在一定意义上,可以认为因果关系是顺承关系的子集。因果事件对之间存在一个介于0到1之间的因果强度值,表示该因果关系成立的置信度。 - -- 条件关系是指前一个事件是后一个事件发生的条件。条件关系属于思想中命题的某种逻辑关系,因果关系属于对客观事实的某种认识,我们认为“原因≠理由”,“原因”指的是事件之间的因果关系,是关于事实的,“理由”是前提与结论或论据与论点的内在联系,是关于逻辑的。举例来说,“如果买票的人多,那么电影好看”这一条件是成立的,而“因为买票的人多,所以电影好看”这一因果是不成立的。 - -- 上下位关系:事件之间的上下位关系有两种:名词性上下位关系和动词性上下位关系。例如,事件“食品价格上涨”与“蔬菜价格上涨”构成名词性上下位关系;事件“杀害”与“刺杀”互为动词性上下位关系。需要注意的是,上下位关系一般是没有疑义的确定知识,因此可认为该类关系的置信度为常数1或0,即表示该知识是正确的或者是错误的。 - -2)事理图谱中的事件属性 - -事理图谱除了关注事件之间的事理逻辑关系外,还关注事件自身的属性。事件属性用来描述事件发生的程度、持续时间等。在进行推理时,事件属性会起到非常重要的作用,例如,从金融文本中可以抽取到“货币超发”会导致“汇率贬值”,“汇率贬值”又会导致“货币紧缩”,而实际上“货币持续超发”才会导致“汇率贬值”,而“汇率大幅贬值”才会导致“货币紧缩”,这里面“持续”和“大幅”作为事件的属性,可以影响到事件未来的走势情况。此外,“股票下跌/上涨”的百分比也是事件重要的属性,股票上涨0.1%和上涨10%对未来事件的影响是有非常明显的区别的。 - -3)事理图谱与知识图谱的关系 - -“知识图谱”这一术语有两层含义。如果认为“知识图谱”表示广义上的知识库,是一种用以存储知识的本体的话,那么“事理图谱”可以认为是一种存储事理逻辑关系的“知识图谱”;如果认为“知识图谱”特指狭义上现阶段谷歌、百度所构建的以实体为中心、用于提升用户搜索体验的知识库,以及Freebase、 YAGO、 DBpedia、ConceptNet和微软的Concept Graph等产品的话,那么“事理图谱”便是与“知识图谱”相并列的一种新型常识知识库。 - -![%E5%9B%BE%E7%89%87.png](attachment:%E5%9B%BE%E7%89%87.png) - -事理图谱与传统知识图谱有本质上的不同。如表1所示,事理图谱以事件为核心研究对象,有向边表示事理逻辑关系,即顺承、因果、条件和上下位;边上标注有概率信息说明事理图谱是一种事件间相继发生可能性的刻画,不是确定性关系。而知识图谱以实体为核心研究对象,实体属性以及实体间关系种类往往成千上万。知识图谱以客观真实性为目标,某一条属性或关系要么成立,要么不成立。 - -4)事理图谱的构建 - -- 基本技术原理 - -事理图谱课题主要研究从大规模无结构化(或者结构化、半结构化)文本数据中自动获取事理逻辑知识,并将这些知识组织成有向有环图结构,用以描述事件之间的演化规律和模式。这样的知识库我们称之为“事理图谱”。 - -事理图谱项目包含“构建”、“推理”和“应用”三个关键技术点: - -(1) 事理图谱的构建 - -事理图谱的构建主要用到以下具体的自然语言处理技术:事件定义、开放域或限定域事件抽取,事理关系抽取(包含事件顺承、因果、上下位关系抽取等),事理关系置信强度计算,事件相似度计算,事件抽象与泛化等。 - -(2) 事理图谱的推理 - -事理图谱的推理可以用于事件及关系的补全,主要涉及到的技术有:结构化事件表示学习,短语级、句子级事件表示学习,事理图谱图结构上的图神经网络技术等。 - -(3) 事理图谱的应用 - -事理图谱的应用是指将构建好的事理图谱用于下游任务,例如消费意图识别和商品推荐、对话系统回复生成、股市涨跌预测、未来事件预测等,帮助提升具体任务的效果。此阶段用到的技术主要有:事理图谱的存储与查询(事件的搜索与匹配),事件表示学习,事理图谱表示学习等。 - -5)主要技术领域及当前发展热点 - -与事理图谱项目密切相关的技术领域主要包含以下几个方面: - -- 常识知识库资源构建 - -传统的常识知识库资源构建主要围绕实体及其关系展开。2012年谷歌成功将大规模知识图谱商业化,显著改善了搜索结果的呈现方式,并提升了搜索引擎的用户体验。之后以实体为中心的知识图谱获得了长足的发展以及广泛的应用。时至今日,知识图谱仍然是学术界的一个发展热点。知识图谱上的知识表示学习、实体链接、实体消歧、知识图谱补全等等研究方向仍然是当下研究的热点问题。 - -然而,已有研究者注意到事件常识的重要性,部分最新的研究工作开始研究以事件为中心的常识知识库构建。 - -- 统计脚本学习 - -给出多个事件组成的上文,统计脚本学习研究下一个可能发生的事件是什么,可以认为是建模事件预测的能力。 - -传统方法多在无监督抽取的结构化事件链条上进行模型的搭建,这条技术路线仍然在发展当中,不断有新的模型涌现;最近,学者们提出故事结尾预测的评估方式,是对传统评估方法的进一步完善。 - -- 事件顺承关系抽取 - -由于语料标注的限制,事件时序关系抽取研究进展相当缓慢。虽然曾经连续举办多个技术评测,推动了该技术的发展,但是进步仍然十分有限。最近,时序关系抽取重新引起了学者的研究兴趣,有许多相关研究发表。从预料的构建,识别方法的改进等多个方面继续推动该研究走向使用阶段。目前,已有开放域的时序关系抽取系统发布。 - -- 事件因果关系抽取 - -文本中的因果关系抽取一直是一个难点。虽然学者们提出了许多方法,但是仍以因果模板匹配的方法抽取精确度最好。模板匹配的缺点在于召回率难以保证,许多有价值的因果关系无法召回。目前,高效准确的因果关系抽取方法仍然是一个难点及研究热点。 - -- 知识表示学习与网络表示学习 - -知识表示学习是指将知识图谱中的实体及关系映射到低维稠密向量,进而可以更加方便地用于后续任务当中。网络表示学习的研究对象不仅仅包含知识图谱这种网络,而是更广义上的网络。这两个研究方向都是当下研究的热点问题,属于事理图谱应用阶段的实用技术。 - -## 六、应用篇 - -事件抽取在网络舆情监控、突发事件告警﹑情报收集领域有着重要应用。网络舆情变化通常是由某些热点社会事件引发的,事件抽取技术可以在第一时间发现这些热点事件,从而为预测网络舆情变化提供帮助。互联网传播消息的速度很快,如果能够及时地从互联网中挖掘突发事件,将为政府部门做好应对赢得时间。在情报收集领域,事件抽取技术可以帮助情报分析人员从大量的低价值情报数据中自动获取事件信息,大大减小情报人员的工作量,在数据量急剧膨胀的今天,自动化的事件抽取技术显得尤为重要。 - -新闻推荐:根据用户感兴趣的话题推送相关事件的周边报道可以提高个性化新闻系统的表现 - -医疗:从语料库中提取类似蛋白质分子行为的生物学事件 - -金融:实时监测突发经济新闻,如公司的兼并和收购、股票交易、分红等,帮助决策者迅速应对市场变化 - - -- 关于短句子事件短语抽取的论文: - -![图片.png](https://i.loli.net/2021/02/10/p5zSBbuPFjHnlgY.png) - -- 用 event embedding 做股票预测: - -![图片.png](https://i.loli.net/2021/02/10/mhBq6zoKGnw4F8k.png) - -- 爬虫:该爬虫爬取了 36 kr(科技资讯网站) 的新闻快讯,以 json 的格式储存,适合用来做信息提取的测试样本或自动摘要的语料。 - -相关地址:https://github.com/HughWen/wen_spiders - -- 中文 NER 识别:作者希望大家可以贡献自己的力量一起维护一个开源的中文 NER 项目。 - -相关地址:https://github.com/zjy-ucas/ChineseNER - -## 七、拓展篇 - -### 7.1 事件抽取论文综述 - -元事件抽取研究综述, 2019[https://doi.org/10.11896/j.issn.1002-137X.2019.08.002] -事件抽取是信息抽取领域的一个重要研究方向,在情报收集、知识提取、文档摘要、知识问答等领域有着广泛应用。写了一篇对当前事件抽取领域研究得较多的元事件抽取任务的综述。 - -首先,简要介绍了元事件和元事件抽取的基本概念,以及元事件抽取的主要实现方法。然后,重点阐述了元事件抽取的主要任务,详细介绍了元事件检测过程,并对其他相关任务进行了概述。最后,总结了元事件抽取面临的问题,在此基础上展望了元事件抽取的发展趋势。 - -An Overview of Event Extraction from Text, 2019[http://ceur-ws.org/Vol-779/derive2011_submission_1.pdf] -文本挖掘的一个常见应用是事件抽取,它包括推导出与事件相关的特定知识,这些知识重新映射到文本中。事件抽取可处理各种类型的文本,如(在线)新闻消息、博客和手稿。本文献回顾了用于各种事件抽取目的的文本挖掘技术。它提供了关于如何根据用户、可用内容和使用场景选择特定事件抽取技术的一般指南。 - -A Survey of Event Extraction from Text, 2019[https://doi.org/10.1109/ACCESS.2019.2956831] -事件抽取的任务定义、数据源和性能评估,还为其解决方案方法提供了分类。在每个解决方案组中,提供了最具代表性的方法的详细分析,特别是它们的起源、基础、优势和弱点。最后,对未来的研究方向进行了展望。 - -A Survey of Textual Event Extraction from Social Networks, 2017[http://ceur-ws.org/Vol-1988/LPKM2017_paper_15.pdf] -过去的十年中,在社交网络上挖掘文本内容以抽取相关数据和有用的知识已成为无所不在的任务。文本挖掘的一种常见应用是事件抽取,它被认为是一个复杂的任务,分为不同难度的多个子任务。 - -在本文中,对现有的主要文本挖掘技术进行了概述,这些技术可用于许多不同的事件抽取目标。首先,介绍基于统计模型将数据转换为知识的主要数据驱动方法。其次,介绍了基于专家知识的知识驱动方法,通常通过基于模式的方法来抽取知识。然后,介绍结合了数据驱动和知识驱动方法的主要现有混合方法。最后,比较社交网络事件抽取研究,概括了每种提出的方法的主要特征。 - -A Survey of event extraction methods from text for decision support systems, 2016[https://doi.org/10.1016/j.dss.2016.02.006] -事件抽取是一种可以追溯到20世纪80年代的专门的信息抽取流程,由于大数据的出现以及文本挖掘和自然语言处理等相关领域的发展,事件抽取技术得到了极大的普及。然而,到目前为止,对这一特殊领域的概述仍然是难以捉摸的。 - -因此,总结了文本数据的事件抽取技术,划分成数据驱动、知识驱动和混合方法三类,并对这些方法进行了定性评价。此外,还讨论了从文本语料库中抽取事件的常见决策支持应用。最后,对事件抽取系统的评价进行了阐述,并指出了当前的研究问题。 - -### 7.2 事件抽取常见问题 - -① **事件抽取的定义/概念是什么?哪些比赛/会议给出了定义?** - -A: 时间,地点,人物,故事情节。 -A: ACE 05 中对事件进行了明确的定义。 -A: 属性信息(Attribute),包括:类型(Type)、子类(Subtype)、模态(Modality)、倾向性(Polairty)、普遍性(Genericity)和时态(Tense)。 - -Q:**不同任务对事件的定义不同吧,能具体解释下这些字段吗?** - -A: 属性是实体、数值和时间的集合。 -A: 我认为关系抽取一般来说是针对两个实体的,而事件抽取的话,不同事件类型会对应不同的元素元素(事件要素)。 -A: 一般来说是的,需要提前定义好事件的类型以及每种类型包含的属性。 -A: ACE05 中给出了类似的 schema,此处给出 ace05 对事件抽取的定义: -![图片.png](https://i.loli.net/2021/02/10/PvLdfMHQKs5qiZ9.png) - -Q:**能简单介绍一些事件抽取的应用背景吗?** - -A: 比如一个事件里的被杀人数就是个数值,我记得最开始是用于反恐情报收集的。 -A: 之前看过有人写事件是一种特殊的关系,不知道是否正确。 -A: 新闻撰写机器人,比如百度知识图谱团队研发的写稿机器人,基于事件图谱自动生成一些大事件文章。 - -Q:**事件是要分类型的吧?** - -A: 看描述好像也有实体那种感觉。 -A: 事件类型要先定义出来。 -A: 有些研究是针对微博,将事件分为 4 元组:命名实体, 事件短句,日期,事件类型。 -A: 觉得定义事件跟抽取语义是一样的,此处放上一张分类ace05事件抽取分类图: -![图片.png](https://i.loli.net/2021/02/10/NKbydfslXoHT9pE.png) - -Q:**事件抽取针对的是一段话还是一篇文章呢?** - -A: 针对一句话是 sentence-level 的,还有 document-level,cross-sentence level,cross-document level 的等等。 - -② **有哪些常用的评测数据集和评测标准?** - -A: ACE2005 - -③ **国内外有哪些研究团队和学者,它们主要研究的目标是什么?** - -A: 国内好像苏州大学周国栋团队,哈工大刘挺,秦兵团队。 -A: 国外有韩家炜,继桓团队。 -A: 国内企业有百度知识图谱团队。 -A: 国内外相关研究团队发表的论文: -![图片.png](https://i.loli.net/2021/02/10/BIVOQcwAMGL2WUE.png) -![图片.png](https://i.loli.net/2021/02/10/YX2PIy6MCdHtvNO.png) -![图片.png](https://i.loli.net/2021/02/10/J6VK1x5jBpEeDUQ.png) -![图片.png](https://i.loli.net/2021/02/10/MztJniUvH4oPQTg.png) - -④ **事件抽取有哪些应用场景和实际的产品?** - -A: 股票,金融,QA,新闻趋势跟踪,舆情,事件型投资,并购。 -A: 反恐,反诈骗,政策性投资。 -A: 生物医学有类似药物不良反应的事件抽取。 -A: 通过对新闻热点事件的抽取,也许可以用来预测 IT 基础设施的故障,这个案例 NTT 做过,通过大量新闻事件的分析抽取预测了大规模网络故障。 - -Q: **为什么通过新闻可以预测网络故障呢?** - -A: 如果突然有个突发事件,网络上也许会引发大规模的群体关注,相关网络的服务器也许突然大规模负载上升。 -A: 百度的知识图谱团队在事件图谱这块开展了不少前沿性的工作,并已经落地在了一些产品上;他们的目标是打造一个覆盖面最全时效性最快分析最全面精准的中文事件图谱。目前的产品形态比如事件脉络,明星事件追踪,明星历史热点等产品。 - -⑤ **事件抽取的一般过程,有标注数据开展研究,如何扩展,没有数据怎么做?** - -A: 种子迭代,规则,模板。机器学习也可以用,比如论元的检测,就是构建一些特征,然后分类。 -A: 这个还是要做垂直领域,从规则和模板开始。 -A: 一些门户网站倒是可以通过访问量(检测波峰)的方法来看是不是发生了事件。 - -Q: **事件抽取一般有什么方法呢?** - -A: 带监督的深度卷积网络肯定是一个。 -A: CNN 用的比较多。 -A: 估计从规则到机器学习都有,看具体的场景和数据。 -A: 经典方法就是:规则+模板,前沿方法:强化+模版(深度卷积)。 -A: 基于模板的抽取方法、半监督学习的模板抽取方法、经典机器学习方法、latent model 等等。 - -⑥ **深度学习在事件抽取上有哪些应用,与传统方法比有什么优势/劣势?** - -A: 性能好,不用人工构造特征。 -A: 触发词的识别和分类,CNN 模型要好。 - -⑦ **事件抽取与其他信息抽取任务(关系抽取、NER 等)有什么联系,难点在哪?** - -A: 得先 NER。 -A: 时间是不是直接抽取就好了,其它属性该怎么办呢? -A: 配模板的嘛,时间也是模板的一部分。 - -Q: **触发词一般是预定义好的,还是需要做检测任务?** - -A: 一般是定义好的,也有检测触发词的任务。 - -⑧ **事件之间的关系如何表示,如何做事件之间的关系抽取,目前有哪些研究?** - -A: 我个人看法:事件也许应该是在时间轴上,有明确开始和结束的一段实体与实体产生关系的“运动”。 -A: 外国一般都是只做二元关系或者时序上的关系。 -A: 研究“事件”必须给他来个操作性定义。 -A: Semeval 2015 task4 是有定义的,但是产出产出太少。 - -⑨ **有哪些值得阅读的论文?有哪些开源了代码的工作?** -![图片.png](https://i.loli.net/2021/02/10/rJl3VKYGH8OoN9S.png) - -A: 基于符号特征的方法: -![图片.png](https://i.loli.net/2021/02/10/9hpWADtnNbT3dgJ.png) - -A: 基于表示学习的方法: -![图片.png](https://i.loli.net/2021/02/10/9uyfX7mL6IbMHhe.png) - -⑩ **最新的前沿进展有哪些?** - -A: 我觉得事件之间的关系或网络会是将来的热点。 -A: 事件抽取必然会和监控视频结合。 -A: 和关系抽取在一起应用。检测事件的关系,舆情监测。其实对话系统也能用。 -A: 适合社交媒体,通过分析过往当事人发布的微信及 Facebook,可以做性格分析工作介绍、相亲配对。 -A: 延伸过去也可以做推荐系统,顾客销售行为预测。 - -## 参考资料 - -1.秦彦霞, 张民, 郑德权. 神经网络事件抽取技术综述[J]. 智能计算机与应用, 2018, 008(003):1-5,10. - -2.许旭阳,韩永峰,宋文政.事件抽取技术的回顾与展望[J].信息工程大学学报,2011,12(01):113-118. - -3.https://github.com/xiaoqian19940510/Event-Extraction - -4.https://blog.csdn.net/weixin_42691585/article/details/106025951 - -5.项威, 王邦. 中文事件抽取研究综述[J]. 计算机技术与发展, 2020, 030(002):1-6. - -6.https://www.sohu.com/a/156430929_500659 - -7.https://www.cnblogs.com/cyandn/p/10915394.html - -8.https://blog.csdn.net/feng_zhiyu/article/details/80246690 - -9.https://baijiahao.baidu.com/s?id=1639726139800018430&wfr=spider&for=pc - - -```python - -``` diff --git a/NLPinterview/KG/KBQA/img/qa_route.png b/NLPinterview/KG/KBQA/img/qa_route.png deleted file mode 100644 index 80bff82..0000000 Binary files a/NLPinterview/KG/KBQA/img/qa_route.png and /dev/null differ diff --git "a/NLPinterview/KG/KBQA/img/\343\200\220\345\205\263\344\272\216 KBQA\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" "b/NLPinterview/KG/KBQA/img/\343\200\220\345\205\263\344\272\216 KBQA\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" deleted file mode 100644 index 022580d..0000000 Binary files "a/NLPinterview/KG/KBQA/img/\343\200\220\345\205\263\344\272\216 KBQA\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" and /dev/null differ diff --git "a/NLPinterview/KG/KBQA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210121004759.png" "b/NLPinterview/KG/KBQA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210121004759.png" deleted file mode 100644 index 0e04557..0000000 Binary files "a/NLPinterview/KG/KBQA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210121004759.png" and /dev/null differ diff --git "a/NLPinterview/KG/KBQA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204081440.png" "b/NLPinterview/KG/KBQA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204081440.png" deleted file mode 100644 index 45589da..0000000 Binary files "a/NLPinterview/KG/KBQA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210204081440.png" and /dev/null differ diff --git a/NLPinterview/KG/KBQA/readme.md b/NLPinterview/KG/KBQA/readme.md deleted file mode 100644 index 985313f..0000000 --- a/NLPinterview/KG/KBQA/readme.md +++ /dev/null @@ -1,527 +0,0 @@ -# 【关于 KBQA】那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 面筋:https://github.com/km1994/NLP-Interview-Notes -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20210204081440.png) - -## 一、基于词典和规则的方法 - -### 1.1 介绍 - -#### 1.1.1 开源知识图谱 - -工业界的知识图谱有两种分类方式,第一种是根据**领域的覆盖范围不同**分为通用知识图谱和领域知识图谱。其中通用知识图谱注重知识广度,领域知识图谱注重知识深度。通用知识图谱常常覆盖生活中的各个领域,从衣食住行到专业知识都会涉及,但是在每个领域内部的知识体系构建不是很完善;而领域知识图谱则是专注于某个领域(金融、司法等),结合领域需求与规范构建合适的知识结构以便进行领域内精细化的知识存储和问答。代表的知识图谱分别有: - -- 通用知识图谱 - - Google Knowledge Graph - - Microsoft Satori & Probase -- 领域知识图谱 - - Facebook 社交知识图谱 - - Amazon 商品知识图谱 - - 阿里巴巴商品知识图谱 - - [上海交大学术知识图谱](https://www.acemap.info/) - -第二种分类方式是按照**回答问题需要的知识类别**来定义的,分为常识知识图谱和百科全书知识图谱。针对常识性知识图谱,我们只会挖掘问题中的词之间的语义关系,一般而言比较关注的关系包括 isA Relation、isPropertyOf Relation,问题的答案可能根据情景不同而有不同,所以回答正确与否往往存在概率问题。而针对百科全书知识图谱,我们往往会定义很多谓词,例如DayOfbirth, LocatedIn, SpouseOf 等等。这些问题即使有多个答案,这些答案往往也都是确定的,所以构建这种图谱在做问答时最优先考虑的就是准确率。代表的知识图谱分别有: - -- 常识知识图谱 - - WordNet, KnowItAll, NELL, Microsoft Concept Graph -- 百科全书知识图谱 - - Freebase, Yago, Google Knowledge Graph - -#### 1.1.2 代表项目 - -1. [豆瓣影评问答](https://github.com/weizhixiaoyi/DouBan-KGQA) -2. [基于医疗知识图谱的问答系统](https://github.com/zhihao-chen/QASystemOnMedicalGraph) - -### 1.2 流程 - -#### 1.2.1. 句子输入 - -```s - - eg:query:高血压要怎么治?需要多少天? -``` - -#### 1.2.2. 问句解析 - -1. 实体抽取: - -- 作用:得到匹配的词和类型 -- 方法: - - 模式匹配: - - 介绍:主要采用规则 提槽 - - 工具:正则表达式 - - 词典: - - 介绍:利用词典进行匹配 - - 采用的词典匹配方法:trie和Aho-Corasick自动机,简称AC自动机 - - 工具:ahocorasick、FlashText 等 python包 - - 基于词向量的文本相似度计算: - - 介绍:计算 query 中 实体 与 实体库 中候选实体的相似度,通过设定阈值,得到最相似的 实体 - - 工具:词向量工具(TF-idf、word2vec、Bert 等)、相似度计算方法(余弦相似度、L1、L2等) - - 命名实体识别方法: - - 利用 命名实体识别方法 识别 query 中实体 - - 方法:BiLSTM-CRF等命名实体识别模型 - - 举例说明: - -```s - eg:通过解析 上面的 query ,获取里面的实体和实体类型:{'Disease': ['高血压'], 'Symptom': ['高血压'], 'Complication': ['高血压']} -``` - -2. 属性和关系抽取: - -- 作用:抽取 query 中 的 属性和关系 -- 方法: - - 模式匹配: - - 介绍:主要采用规则匹配 - - 工具:正则表达式 - - 词典: - - 介绍:利用词典进行匹配 - - 采用的词典匹配方法:trie和Aho-Corasick自动机,简称AC自动机 - - 工具:ahocorasick、FlashText 等 python包 - - 意图识别方法: - - 介绍:采用分类模型 对 query 所含关系 做预测 - - 工具: - - 机器学习方法:LR、SVM、NB - - 深度学习方法:TextCNN、TextRNN、Bert 等 - - 命名实体识别方法:【同样,可以采用命名实体识别挖掘出 query 中的某些动词和所属类型】 - - 利用 命名实体识别方法 识别 query 中实体 - - 方法:BiLSTM-CRF等命名实体识别模型 -- 举例说明: - -```s -- eg:通过解析 上面的 query ,获取里面的实体和实体类型: - - predicted intentions:['query_period'] 高血压要怎么治? - - word intentions:['query_cureway'] 需要多少天? -``` - -#### 1.2.3. 查询语句生成 - -- 作用:根据 【问句解析】 的结果,将 实体、属性和关系转化为对于的 图数据库(eg:Neo4j图数据库等)查询语句 -- 举例说明: - -```s -- eg: - 对于 query:高血压要怎么治?需要多少天? -- sql 解析结果: - [{'intention': 'query_period', 'sql': ["MATCH (d:Disease) WHERE d.name='高血压' return d.name,d.period"]}, {'intention': 'query_cureway', 'sql': ["MATCH (d:Disease)-[:HAS_DRUG]->(n) WHERE d.name='高血压' return d.name,d.treatment,n.name"]}] -``` - -#### 1.2.4. 查询数据库和结果生成 - -- 作用:利用 【查询语句生成】 的结果,去 图数据库 中 查询 答案,并利用预设模板 生成答案 - -```s -- eg: - - 高血压可以尝试如下治疗:药物治疗;手术治疗;支持性治疗 -``` - -## 二、基于信息抽取的方法 - -### 2.1 介绍 - -#### 2.1.1 开源知识图谱介绍 - -- [Knowledge Based Question Answering](https://github.com/wudapeng268/KBQA-Baseline) -- CCKS开放域知识图谱问答比赛数据集 - - 介绍: - - 问题类型:简单问题:复杂问题(多跳推理问题)=1:1 - - 训练集:2298 - - 验证集:766 - - 测试集:766 - - 资源地址:[知识库 密码(huc8)](https://pan.baidu.com/share/init?surl=MOv9PCTcALVIiodUP4bQ2Q),[问答集](https://github.com/duterscmy/ccks2019-ckbqa-4th-codes/tree/master/data) - - 方案:[ccks2019-ckbqa-4th-codes](https://github.com/duterscmy/ccks2019-ckbqa-4th-codes)、[CCKS2018 CKBQA 1st 方案](https://github.com/songlei1994/ccks2018)、[中文知识图谱问答 CCKS2019 CKBQA - 参赛总结](https://blog.nowcoder.net/n/630128e8e6dd4be5947adbfde8dcea44) -- NLPCC开放域知识图谱问答比赛数据集 - - 介绍: - - 问题类型:简单问题(单跳问题) - - 训练集:14609 - - 验证集 + 测试集:9870 - - 资源地址:[知识库](https://pan.baidu.com/s/1dEYcQXz),[问答集](http://tcci.ccf.org.cn/conference/2018/taskdata.php) - - 方案:[NLPCC2016 KBQA 1st 方案](https://github.com/huangxiangzhou/NLPCC2016KBQA) - -#### 2.1.2 评测标准 - -- **Mean Reciprocal Rank (MRR)** - - - - - |Q|代表问题总数,rank_i代表第一个正确的答案在答案集合C_i中的位置 - - 如果C_i中没有正确答案, - -- **Accuracy@N** - - - - - 当答案集合C_i中至少有一个出现在gold answerA_i中,,否则为0 - -- **Averaged F1** - - - - - F_i是Q_i问题产生答案的F1值,如果A_i和C_i无交集F1为0 - -### 2.2 流程 - -#### 2.2.1. 分类单跳和多跳问句 - -- 思路:利用 文本分类方法 对 query 进行分类,判断其属于 一跳问题还是多跳问题 -- 方法:文本分类方法【TextCNN、TextRNN、Bert 等】 -- 解析 - -> 单跳:SPARQL 只出现一个三元组 - -```s - q26:豌豆公主这个形象出自于哪? - select ?x where { <豌豆公主_(安徒生童话)> <作品出处> ?x. } - <安徒生童话> -``` - -> 双跳或多跳:SPARQL 只出现两个以上三元组 - -```s - q524:博尔赫斯的国家首都在哪里? - select ?x where { <豪尔赫·路易斯·博尔赫斯_(阿根廷作家)> <出生地> ?y. ?y <首都> ?x} - <布宜诺斯艾利斯_(阿根廷的首都和最大城市)> -``` - -#### 2.2.2. 分类链式问句(二分类) - -- 思路:利用 文本分类方法 对 query 进行分类,判断其是否 属于 链式问句 -- 介绍:链式:SPARQL 多个三元组呈递进关系,x->y->z,非交集关系 - -```s - q894:纳兰性德的父亲担任过什么官职? - select ?y where { <纳兰性德> <父亲> ?x. ?x <主要职位> ?y. } - "武英殿大学士" "太子太傅" - q554:宗馥莉任董事长的公司的公司口号是? - select ?y where { ?x <董事长> <宗馥莉>. ?x <公司口号> ?y. } - "win happy health,娃哈哈就在你身边" -``` - -#### 2.2.3. 主谓宾分类(三分类) - -- 思路:利用 文本分类方法 对 query 进行分类,判断 问句的答案对应三元组里面的 主谓宾 -- 问句的答案对应三元组里面的主语,spo=0 - -```s - q70:《悼李夫人赋》是谁的作品? - select ?x where { ?x <代表作品> <悼李夫人赋>. } - <汉武帝_(汉朝皇帝)> -``` - -- 问句的答案对应三元组里面的谓语,spo=1 - -```s - q506:林徽因和梁思成是什么关系? - select ?x where { <林徽因_(中国建筑师、诗人、作家)> ?x <梁思成>. } - <丈夫> -``` - -- 问句的答案对应三元组里面的宾语,spo=2 - -```s - q458:天津大学的现任校长是谁? - select ?x where { <天津大学> <现任校长> ?x . } - <李家俊_(天津市委委员,天津大学校长)> -``` - -#### 2.2.4. 实体提及(mention)识别 - -- 思路:对于 给定 query,我们需要 识别出 query 中 所含有的 实体提及(mention) -- 问题:主办方提供的数据中 包含 :query、sql语句,但是 sql语句中的实体并不能在 query 中被找到,如下: - -```s - q1440:济南是哪个省的省会城市? - select ?x where { ?x <政府驻地> <济南_(山东省省会)>. } - <山东_(中国山东省)> -``` - -> 注:query 中 的 济南 是 <济南_(山东省省会)>的 简称、省会城市 在 知识库中 对应 <政府驻地> - -- 解决方法:根据训练语料的SPARQL语句,查找实体的提及,反向构建训练数据 -- 思路 1:神经网络 - - 训练语料构建 - - 思路 1 - 1. 根据 query 和 sql,查询 实体提及 【常用做法: 寻找 query 和 sql 中 entity 的最长子串作为 query 实体提及】 - 2. 反向构建训练数据 - - 思路 2 - 1. 实体链接词典:实体链接词典为文本中的实体提及到知识库实体的映射【由CCKS2019 CKBQA主办方提供】 - 2. 反向构建训练数据 - - 命名实体识别:训练 命名实体识别模型 抽取 未标注数据 中 实体信息 - - 方法:BiLSTM-CRF、Bert-CRF 等 - -```s - q6:叔本华信仰什么宗教? - select ?y where { <亚瑟·叔本华> <信仰> ?y. } - <佛教> - - >>> - 叔本华信仰什么宗教? ['叔本华'] - 亚瑟·叔本华信仰什么宗教? ['亚瑟·叔本华'] - - >>> - 叔 本 华 信 仰 什 么 宗 教 ? B-SEG I-SEG E-SEG O O O O O O O - 亚 瑟 · 叔 本 华 信 仰 什 么 宗 教 ? B-SEG I-SEG I-SEG I-SEG I-SEG E-SEG O O O O O O O -``` - -- 思路 2:规则 - - 自定义字典(分词,词频,倒排索引)识别 - - 分词词典:将 语料中的实体信息、知识库中的实体信息 合并后构建成一个 jieba 分词词典 - - 词频:狗开源的中文词频词典 SogouLabDic.dic 、语料中的实体信息、知识库中的实体信息 - - 倒排索引字典:该词典用于识别属性值的模糊匹配,使用知识库中所有属性值,构建字到词的映射。 - - 建立停用词表删去无用词 - - 分词后的词与知识图谱的实体的字符串匹配(jaccord,编辑距离) -- 辅助工具 - - NER工具包识别问句中人名,地点,机构等 - -#### 2.2.5. 关系分类 (语义相似度计算,二分类问题) - -- 目标:查询实体关系中与问句最相似的关系 -- 思路: - - 正例:根据给定 训练集,获得 实体和关系 的样本 - - 负例:根据 该实体名 从 Neo4j 图数据库中随机抽取出 5个关系作为负例 - -```s - q1:莫妮卡·贝鲁奇的代表作? - select ?x where { <莫妮卡·贝鲁奇> <代表作品> ?x. } - <西西里的美丽传说> - - >>> 表达形式一: - 正例: - 莫妮卡·贝鲁奇的代表作? 代表作品 1 - 负例: - 莫妮卡·贝鲁奇的代表作? 出生地 0 - 莫妮卡·贝鲁奇的代表作? 类型 0 - 莫妮卡·贝鲁奇的代表作? 制片地区 0 - 莫妮卡·贝鲁奇的代表作? 主演 0 - 莫妮卡·贝鲁奇的代表作? 作者 0 - -``` - -- 模型选择: - - **关系模型1:关系识别与排序**(1/2hop) - - 关系和问题的语义相似度(bert-bilstm-fc-cosine) - - 关系值和问题的语义相似度(bert-bilstm-fc-cosine) - - 关系和问题的字符覆盖率 -- **关系模型2:路径排序** - - 将链接到的实体和 **实体的1/2跳关系** 组成路径,通过bert-similarity模型进行训练 - - 路径与问题的jaccard,编辑距离 - - 自身定义的模板匹配度... -- **关系模型3:规则匹配排序** - - 将问题分割为多个部分,参照word/phrases in the kb + existing word segmentation tools,将问题分为各部分都和kb中实体/属性/关系相似的部分,按分值高低与知识图谱对应部分进行链接。 - - 将问题分为单跳,多跳类型(共8种),记录下各自的结构,与问题中分割出的问题结构进行相似度比较 - -#### 2.2.6. 实体链指 【实体消歧】 - -- 问题:对于 问句中的实体提及在 Neo4j 图数据库 中可能存在多个相关实体,如何选取 将 实体提及 链指到 对应的 知识库中的实体 - -```s - q15:清明节起源于哪里? - select ?x where { <清明_(二十四节气之一)> <起源> ?x. } - <绵山风景名胜区> - - >>> - 问句中 实体提及:清明 - 对应的知识库中的 实体:<清明_(二十四节气之一)>、清明_(汉语词汇)、清明_(长篇小说)、清明_(唐代杜牧诗作)等 -``` - -- 目标:查找问句中实体提及对应的唯一实体 -- 思路: - - 在训练集上,令标注的实体标签为1,其余候选实体标签为0,使用逻辑回归对上述特征进行拟合。 - - 在验证集和测试集上,使用训练好的机器模型对每个实体打分,保留分数排名前n的候选实体。 -- 特征选择: - -1. 问题和实体提及间 特征 mention_features - 1. 实体提及的长度:该实体对应的实体提及的字数; - 2. 实体提及的词频:该实体对应的实体提及的词频; - 1. 该词典用于计算实体提及和属性值提及的词频特征,使用搜狗开源的中文词频词典 SogouLabDic.dic 构建; - 3. 实体提及的位置:该实体对应的实体提及距离句首的距离; - 5. 实体类型与问题的匹配度 - -```s - # 获取 mention 的特征 mention_features : [mention, f1, f2, f3] - # f1 : mention的长度 - # f2 : mention 在 SogouLabDic.dic 中 的词频 - # f3 : mention 在 question 中 的位置 - def get_mention_feature(self,question,mention): - f1 = float(len(mention)) #mention的长度 - try: - f2 = float(self.word_2_frequency[mention]) # mention的tf/10000 - except: - f2 = 1.0 - if mention[-2:] == '大学': - f2 = 1.0 - try: - f3 = float(question.index(mention)) - except: - f3 = 3.0 - #print ('这个mention无法提取位置') - return [mention,f1,f2,f3] -``` - -2. 图谱子图与问题的匹配度:计算问题和主语实体及其两跳内关系间的相似度 - 1. 实体提及及两跳内关系和实体与问题重叠词数量 - 2. 实体提及及两跳内关系和实体与问题重叠字数量 - -```s - # similar_features : [overlap,jaccard] * {(q_tokens,e_tokens), (q_chars,e_chars), (q_tokens,p_tokens), (q_chars,p_chars)} = 8 - - def extract_subject(self,entity_mentions,subject_props,question): - ... - #得到实体两跳内的所有关系 - entity = '<'+entity+'>' - if entity in self.entity2hop_dic: - relations = self.entity2hop_dic[entity] - else: - relations = kb.GetRelations_2hop(entity) - self.entity2hop_dic[entity] = relations - # 计算问题和主语实体及其两跳内关系间的相似度 - similar_features = ComputeEntityFeatures(question,entity,relations) - ... - - def ComputeEntityFeatures(question,entity,relations): - ''' - 抽取每个实体或属性值2hop内的所有关系,来跟问题计算各种相似度特征 - input: - question: python-str - entity: python-str - relations: python-dic key: - output: - [word_overlap,char_overlap,word_embedding_similarity,char_overlap_ratio] - ''' - #得到主语-谓词的tokens及chars - p_tokens = [] - for p in relations: - p_tokens.extend(segger.cut(p[1:-1])) - p_tokens = [token[0] for token in p_tokens] - p_chars = [char for char in ''.join(p_tokens)] - - q_tokens = segger.cut(question) - q_tokens = [token[0] for token in q_tokens] - q_chars = [char for char in question] - - e_tokens = segger.cut(entity[1:-1]) - e_tokens = [token[0] for token in e_tokens] - e_chars = [char for char in entity[1:-1]] - - qe_feature = features_from_two_sequences(q_tokens,e_tokens) + features_from_two_sequences(q_chars,e_chars) - qr_feature = features_from_two_sequences(q_tokens,p_tokens) + features_from_two_sequences(q_chars,p_chars) - #实体名和问题的overlap除以实体名长度的比例 - return qe_feature+qr_feature - - - def features_from_two_sequences(s1,s2): - #overlap - overlap = len(set(s1)&(set(s2))) - #集合距离 - jaccard = len(set(s1)&(set(s2))) / len(set(s1)|(set(s2))) - #词向量相似度 - #wordvecsim = model.similarity(''.join(s1),''.join(s2)) - return [overlap,jaccard] -``` - -3. 实体提及的流行度特征 - 1. 实体提及在图谱中关系个数/出现频率 - -```s - # popular_feature : GetRelationNum = 1 实体的流行度特征 - def extract_subject(self,entity_mentions,subject_props,question): - ... - #实体的流行度特征 - popular_feature = kb.GetRelationNum(entity) - ... - - - def GetRelationNum(self,entity): - '''根据实体名,得到与之相连的关系数量,代表实体在知识库中的流行度''' - cql= "match p=(a:Entity)-[r1:Relation]-() where a.name=$name return count(p)" - res = self.session.run(cql,name=entity) - ans = 0 - for record in res: - ans = record.values()[0] - return ans -``` - -4. 实体名称和问题的字符串匹配度(char/word) -5. 问题和实体提及语义相似度 -7. 问题和实体关系的最大相似度 -... - -- 标签:是否为 对应实体 - -```s - q15:清明节起源于哪里? - select ?x where { <清明_(二十四节气之一)> <起源> ?x. } - <绵山风景名胜区> - - >>> - 清明节起源于哪里? <清明_(二十四节气之一)> 1.0 1.0 0.43 0.15978466 0.6 0.99257445 ... 0 - 清明节起源于哪里? <清明_(汉语词汇)> 0.9 1.0 0.43 0.97132427 0.58 0.99660385 ... 1 - 清明节起源于哪里? <清明_(长篇小说)> 0.8 1.0 0.43 0.920861 0.38 0.0007164952 ... 0 - 清明节起源于哪里? <清明_(唐代杜牧诗作)> 0.8 1.0 0.43 0.920861 0.38 0.0007164952 ... 0 - ... -``` - -- 分类方法: - - LR、SVM、xgboost 等 - -#### 2.2.7. 候选查询路径生成及文本匹配 - -- 问题:根据前面的操作会得到 query 对应的候选实体和关系信息,由于预训练模型是基于自然语言训练的,而将生成的候选查询路径是不符合自然语言逻辑的,那如何 转化成自然语言处理能够理解的形式,和判断 所抽取的 实体提及 和 关系 是正确的呢? -- 目标:判断 所抽取的 实体提及 和 关系 是正确性 -- 方法:对于每个候选实体,抽取与其相连的单跳关系和两跳关系作为候选的查询路径,形式如(entity,relation)或(entity,relation1,relation2)。 -- 思路: - - 候选查询路径:将 (entity,relation) 转化成 自然语言处理 能够处理的 文本形式:eg : entity 的 relation - - 文本匹配:利用 Bert 计算 query 和 entity 的 relation 的相似度 - - 思路: - - 在训练集上,对于每个问题,随机选择三个候选查询路径作为负例,令标注的候选查询路径标签为1,负例的标签为0,将自然语言问题和人工问题拼接,训练一个文本分类模型。 - - 在验证集和测试集上,使用该模型对所有的自然语言问题-人工问题对进行打分。 - -```s - q15:清明节起源于哪里? - select ?x where { <清明_(二十四节气之一)> <起源> ?x. } - <绵山风景名胜区> - - >>> 实体提及 和 关系 - 实体提及 <清明_(二十四节气之一)> - 关系 起源 - - >>> (entity,relation) - (entity,relation):(<清明_(二十四节气之一)>,起源 ) - - >>> 候选查询路径:(entity,relation) => entity 的 relation - (<清明_(二十四节气之一)>,起源 ): 清明_(二十四节气之一)的起源 - - >>> 文本匹配: - 清明节起源于哪里? 清明_(二十四节气之一)的起源 1 - 清明节起源于哪里? 清明_(二十四节气之一)的类型 0 - 清明节起源于哪里? 清明_(汉语词汇)的起源地 0 - 清明节起源于哪里? 清明_(汉语词汇)的类型 0 -``` - -#### 2.2.8. 实体桥接及答案检索 - -- 动机: - - 2.2.7 节 所提方法只能处理 单实体问题,但是 样本中 不仅 包含 单实体问题,还包含 多实体问题,那需要怎么解决呢? - -```s - eg:北京大学出了哪些哲学家 -``` -- 解决方法:实体桥接 -- 思路: - - 对于每个问题,首先对2.2.7 节 打分后的候选查询路径进行排序,保留前30个单关系的查询路径(entity1,relation1)。 - - 对于这些查询路径,到知识库中进行检索,验证其是否能和其他候选实体组成多实体情况的查询路径(entity1,relation1,ANSWER,relation2,entity2),将其加入候选查询路径中。 - - 最后,本文将2.2.7 节 单实体情况排名前三的候选查询路径和本节得到的双实体情况查询路径同时和问题计算重叠的字数,选择重叠字数最多的作为最终的查询路径,认为其在语义和表达上最与问题相似。 - - -## 参考资料 - -1. [中文知识图谱问答 CCKS2019 CKBQA - 参赛总结](https://blog.nowcoder.net/n/630128e8e6dd4be5947adbfde8dcea44) -2. [ccks2019-ckbqa-4th-codes](https://github.com/duterscmy/ccks2019-ckbqa-4th-codes) -3. [QA-Survey](https://github.com/BDBC-KG-NLP/QA-Survey) -4. [中文知识图谱问答 CCKS2019 CKBQA 参赛总结](https://blog.csdn.net/zzkv587/article/details/102954876) -5. [CCKS2019 测评报告](https://arxiv.org/ftp/arxiv/papers/2003/2003.03875.pdf) \ No newline at end of file diff --git "a/NLPinterview/KG/img/\343\200\220\345\205\263\344\272\216 \347\237\245\350\257\206\345\233\276\350\260\261\343\200\221 \351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" "b/NLPinterview/KG/img/\343\200\220\345\205\263\344\272\216 \347\237\245\350\257\206\345\233\276\350\260\261\343\200\221 \351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" deleted file mode 100644 index efdb406..0000000 Binary files "a/NLPinterview/KG/img/\343\200\220\345\205\263\344\272\216 \347\237\245\350\257\206\345\233\276\350\260\261\343\200\221 \351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234724.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234724.png" deleted file mode 100644 index 13a1c04..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234724.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234802.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234802.png" deleted file mode 100644 index 6824280..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234802.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234821.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234821.png" deleted file mode 100644 index 51c9261..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234821.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234837.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234837.png" deleted file mode 100644 index c5b8504..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234837.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234850.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234850.png" deleted file mode 100644 index 3877e30..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234850.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234902.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234902.png" deleted file mode 100644 index 3758286..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234902.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234916.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234916.png" deleted file mode 100644 index 31793fd..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234916.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234957.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234957.png" deleted file mode 100644 index 35920e1..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128234957.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235014.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235014.png" deleted file mode 100644 index 211945b..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235014.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235028.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235028.png" deleted file mode 100644 index 6b9b883..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235028.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235042.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235042.png" deleted file mode 100644 index 03e8f6d..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235042.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235059.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235059.png" deleted file mode 100644 index 7926b51..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235059.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235109.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235109.png" deleted file mode 100644 index 9085228..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235109.png" and /dev/null differ diff --git "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210129233513.png" "b/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210129233513.png" deleted file mode 100644 index d16c48c..0000000 Binary files "a/NLPinterview/KG/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210129233513.png" and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/20201122155118.png b/NLPinterview/KG/neo4j/img/20201122155118.png deleted file mode 100644 index 90b446c..0000000 Binary files a/NLPinterview/KG/neo4j/img/20201122155118.png and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/20201122160353.png b/NLPinterview/KG/neo4j/img/20201122160353.png deleted file mode 100644 index 67def7c..0000000 Binary files a/NLPinterview/KG/neo4j/img/20201122160353.png and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/4aR1sToSEnve6bL.png b/NLPinterview/KG/neo4j/img/4aR1sToSEnve6bL.png deleted file mode 100644 index ddc6f68..0000000 Binary files a/NLPinterview/KG/neo4j/img/4aR1sToSEnve6bL.png and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/v2-8630e2f27bb7bc7551a9699a4a4f6d73_720w.png b/NLPinterview/KG/neo4j/img/v2-8630e2f27bb7bc7551a9699a4a4f6d73_720w.png deleted file mode 100644 index 36a3a78..0000000 Binary files a/NLPinterview/KG/neo4j/img/v2-8630e2f27bb7bc7551a9699a4a4f6d73_720w.png and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/v2-ac2a3c82ddfef52ee487b7efb59c9548_720w.jpg b/NLPinterview/KG/neo4j/img/v2-ac2a3c82ddfef52ee487b7efb59c9548_720w.jpg deleted file mode 100644 index ab8df79..0000000 Binary files a/NLPinterview/KG/neo4j/img/v2-ac2a3c82ddfef52ee487b7efb59c9548_720w.jpg and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/v2-e34f0e9adb7cefd59e26c16eec88e422_720w.jpg b/NLPinterview/KG/neo4j/img/v2-e34f0e9adb7cefd59e26c16eec88e422_720w.jpg deleted file mode 100644 index 0324b19..0000000 Binary files a/NLPinterview/KG/neo4j/img/v2-e34f0e9adb7cefd59e26c16eec88e422_720w.jpg and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/v2-e7850b5800fe28e628eda23b25ded3c6_720w.png b/NLPinterview/KG/neo4j/img/v2-e7850b5800fe28e628eda23b25ded3c6_720w.png deleted file mode 100644 index 0f5645e..0000000 Binary files a/NLPinterview/KG/neo4j/img/v2-e7850b5800fe28e628eda23b25ded3c6_720w.png and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/v2-ecbdeac21cc6dff47fb1b824757b7d17_720w.jpg b/NLPinterview/KG/neo4j/img/v2-ecbdeac21cc6dff47fb1b824757b7d17_720w.jpg deleted file mode 100644 index 32da2bc..0000000 Binary files a/NLPinterview/KG/neo4j/img/v2-ecbdeac21cc6dff47fb1b824757b7d17_720w.jpg and /dev/null differ diff --git a/NLPinterview/KG/neo4j/img/v2-fa8ab8074aaa811f7c1b95f7bf96f1dd_720w.jpg b/NLPinterview/KG/neo4j/img/v2-fa8ab8074aaa811f7c1b95f7bf96f1dd_720w.jpg deleted file mode 100644 index f3a6cc9..0000000 Binary files a/NLPinterview/KG/neo4j/img/v2-fa8ab8074aaa811f7c1b95f7bf96f1dd_720w.jpg and /dev/null differ diff --git "a/NLPinterview/KG/neo4j/img/\343\200\220\345\205\263\344\272\216 Neo4j \343\200\221 \351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" "b/NLPinterview/KG/neo4j/img/\343\200\220\345\205\263\344\272\216 Neo4j \343\200\221 \351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" deleted file mode 100644 index e21487f..0000000 Binary files "a/NLPinterview/KG/neo4j/img/\343\200\220\345\205\263\344\272\216 Neo4j \343\200\221 \351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" and /dev/null differ diff --git "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235237.png" "b/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235237.png" deleted file mode 100644 index 92af422..0000000 Binary files "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235237.png" and /dev/null differ diff --git "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235347.png" "b/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235347.png" deleted file mode 100644 index e9bc54b..0000000 Binary files "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235347.png" and /dev/null differ diff --git "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235416.png" "b/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235416.png" deleted file mode 100644 index 10d5f0b..0000000 Binary files "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235416.png" and /dev/null differ diff --git "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235434.png" "b/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235434.png" deleted file mode 100644 index 1e26f75..0000000 Binary files "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235434.png" and /dev/null differ diff --git "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235449.png" "b/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235449.png" deleted file mode 100644 index 5284bb4..0000000 Binary files "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235449.png" and /dev/null differ diff --git "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235507.png" "b/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235507.png" deleted file mode 100644 index 1d6406b..0000000 Binary files "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210128235507.png" and /dev/null differ diff --git "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210129232419.png" "b/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210129232419.png" deleted file mode 100644 index 8320145..0000000 Binary files "a/NLPinterview/KG/neo4j/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210129232419.png" and /dev/null differ diff --git a/NLPinterview/KG/neo4j/readme.md b/NLPinterview/KG/neo4j/readme.md deleted file mode 100644 index e5236a7..0000000 --- a/NLPinterview/KG/neo4j/readme.md +++ /dev/null @@ -1,401 +0,0 @@ -# 【关于 Neo4j 】 那些你不知道的事 - -> 作者:吴晓均 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes - -![](img/微信截图_20210129232419.png) - -## 一、Neo4J 介绍与安装 - -### 1.1 引言 - -“工欲善其事,必先利其器”,知识图谱作为一种特殊的图结构,自然需要专门的图数据库进行存储。 - -知识图谱由于其数据包含实体、属性、关系等,常见的关系型数据库诸如MySQL之类不能很好的体现数据的这些特点,因此知识图谱数据的存储一般是采用图数据库(Graph Databases)。而Neo4j是其中最为常见的图数据库。 - -### 1.2 Neo4J 怎么下载? - -首先在 [Neo4J官网](https://neo4j.com/download/) 下载 Neo4J。 - -- Neo4J分为社区版和企业版: - - 企业版:收费,在横向扩展、权限控制、运行性能、HA等方面都比社区版好,适合正式的生产环境; - - 社区版:**免费**,普通的学习和开发采用免费社区版就好。 - -### 1.3 Neo4J 怎么安装? - -- 在Mac或者Linux中,安装好jdk后,直接解压下载好的Neo4J包,运行命令 - -```s - bin/neo4j start -``` - -- windows系统下载好neo4j和jdk 1.8.0后,输入以下命令启动后neo4j -```s - neo4j.bat console -``` - -![image](img/4aR1sToSEnve6bL.png) -> 图 12 Neo4j 运行结果 - -### 1.4 Neo4J Web 界面 介绍 - -Neo4J 提供了一个用户友好的 Web 界面,可以进行各项配置、写入、查询等操作,并且提供了可视化功能。类似ElasticSearch一样,我个人非常喜欢这种开箱即用的设计。 - -打开浏览器,输入http://127.0.0.1:7474/browser/,如下图 13 所示,界面最上方就是交互的输入框。 - -![image](img/微信截图_20210128235347.png) -> 图 13 Neo4J Web界面 - -### 1.5 Cypher查询语言是什么? - -- Cypher: - - 介绍:是Neo4J的声明式图形查询语言,允许用户不必编写图形结构的遍历代码,就可以对图形数据进行高效的查询。 - - 设计目的:类似SQL,适合于开发者以及在数据库上做点对点模式(ad-hoc)查询的专业操作人员。 - - 其具备的能力包括: - - 创建、更新、删除节点和关系 - - 通过模式匹配来查询和修改节点和关系 - 管理索引和约束等 - -## 二、Neo4J 增删查改篇 - -### 2.1 引言 - -这个案例的节点主要包括人物和城市两类,人物和人物之间有朋友、夫妻等关系,人物和城市之间有出生地的关系。 - -- Person-Friends-PERSON -- Person-Married-PERSON -- Person-Born_in-Location - -### 2.2 Neo4j 怎么创建节点? - -1. 删除数据库中以往的图,确保一个空白的环境进行操作【注:慎用,如果库内有重要信息的话】: - -![image.png](img/微信截图_20210128235416.png) -> 图 14 Neo4J 删库操作 - -```s - MATCH (n) DETACH DELETE n -``` - -这里,MATCH是匹配操作,而小括号()代表一个节点node(可理解为括号类似一个圆形),括号里面的n为标识符。 - -1. 创建一个人物节点: - -```s - CREATE (n:Person {name:'John'}) RETURN n -``` -> 注:
-> CREATE是创建操作,Person是标签,代表节点的类型。
-> 花括号{}代表节点的属性,属性类似Python的字典。
-> 这条语句的含义就是创建一个标签为Person的节点,该节点具有一个name属性,属性值是John。 - -3. 创建更多的人物节点,并分别命名: - -```s - CREATE (n:Person {name:'Sally'}) RETURN n - CREATE (n:Person {name:'Steve'}) RETURN n - CREATE (n:Person {name:'Mike'}) RETURN n - CREATE (n:Person {name:'Liz'}) RETURN n - CREATE (n:Person {name:'Shawn'}) RETURN n -``` - -如图 15 所示,6个人物节点创建成功 - -![image](img/微信截图_20210128235434.png) -> 图 15 创建 人物节点 - -1. 创建地区节点 - -```s - CREATE (n:Location {city:'Miami', state:'FL'}) - CREATE (n:Location {city:'Boston', state:'MA'}) - CREATE (n:Location {city:'Lynn', state:'MA'}) - CREATE (n:Location {city:'Portland', state:'ME'}) - CREATE (n:Location {city:'San Francisco', state:'CA'}) -``` - -可以看到,节点类型为Location,属性包括city和state。 - -如图 16 所示,共有6个人物节点、5个地区节点,Neo4J贴心地使用不用的颜色来表示不同类型的节点。 - -![image](img/微信截图_20210128235449.png) -> 图 16 创建地区节点 - -### 2.3 Neo4j 怎么创建关系? - -1. 朋友关系 - -```s - MATCH (a:Person {name:'Liz'}), - (b:Person {name:'Mike'}) - MERGE (a)-[:FRIENDS]->(b) -``` -> 注:
-> 方括号[]即为关系,FRIENDS为关系的类型。
-> 注意这里的箭头-->是有方向的,表示是从a到b的关系。 这样,Liz和Mike之间建立了FRIENDS关系。 - -2. 关系增加属性 - -```s - MATCH (a:Person {name:'Shawn'}), - (b:Person {name:'Sally'}) - MERGE (a)-[:FRIENDS {since:2001}]->(b) -``` - -3. 增加更多的朋友关系: - -```s - MATCH (a:Person {name:'Shawn'}), (b:Person {name:'John'}) MERGE (a)-[:FRIENDS {since:2012}]->(b) - MATCH (a:Person {name:'Mike'}), (b:Person {name:'Shawn'}) MERGE (a)-[:FRIENDS {since:2006}]->(b) - MATCH (a:Person {name:'Sally'}), (b:Person {name:'Steve'}) MERGE (a)-[:FRIENDS {since:2006}]->(b) - MATCH (a:Person {name:'Liz'}), (b:Person {name:'John'}) MERGE (a)-[:MARRIED {since:1998}]->(b) -``` - -这样,图谱就已经建立好了: - -![image](img/微信截图_20210128235507.png) -> 图 17 图谱 - -### 2.4 Neo4j 怎么创建 出生地关系? - -1. 建立不同类型节点之间的关系-人物和地点的关系 - -```s - MATCH (a:Person {name:'John'}), (b:Location {city:'Boston'}) MERGE (a)-[:BORN_IN {year:1978}]->(b) - MATCH (a:Person {name:'Liz'}), (b:Location {city:'Boston'}) MERGE (a)-[:BORN_IN {year:1981}]->(b) - MATCH (a:Person {name:'Mike'}), (b:Location {city:'San Francisco'}) MERGE (a)-[:BORN_IN {year:1960}]->(b) - MATCH (a:Person {name:'Shawn'}), (b:Location {city:'Miami'}) MERGE (a)-[:BORN_IN {year:1960}]->(b) - MATCH (a:Person {name:'Steve'}), (b:Location {city:'Lynn'}) MERGE (a)-[:BORN_IN {year:1970}]->(b) -``` - -这里的关系是BORN_IN,表示出生地,同样有一个属性,表示出生年份。 - -如图 18 ,在人物节点和地区节点之间,人物出生地关系已建立好。 - -2. 创建节点的时候就建好关系 - -```s - CREATE (a:Person {name:'Todd'})-[r:FRIENDS]->(b:Person {name:'Carlos'}) -``` -最终该图谱如下图所示: - -![image](img/v2-ecbdeac21cc6dff47fb1b824757b7d17_720w.jpg) -> 图 18 图谱 - -### 2.5 Neo4j 怎么查询? - -1. 查询下所有在Boston出生的人物 - -```s - MATCH (a:Person)-[:BORN_IN]->(b:Location {city:'Boston'}) RETURN a,b -``` -结果如图 19: - -![image](img/v2-fa8ab8074aaa811f7c1b95f7bf96f1dd_720w.jpg) -> 图 19 查询下所有在Boston出生的人物 - -1. 查询所有对外有关系的节点 - -```s - MATCH (a)--() RETURN a -``` -结果如图 20: - -![查询所有对外有关系的节点](img/v2-e34f0e9adb7cefd59e26c16eec88e422_720w.jpg) -> 图 20 查询所有对外有关系的节点 - -1. 查询所有有关系的节点 - -```s - MATCH (a)-[r]->() RETURN a.name, type(r) -``` -结果如图21: - -![image](img/v2-e34f0e9adb7cefd59e26c16eec88e422_720w.jpg) -> 图 21 查询所有有关系的节点 - -1. 查询所有对外有关系的节点,以及关系类型 - -```s - MATCH (a)-[r]->() RETURN a.name, type(r) -``` - -结果如图22: - -![image](img/v2-ac2a3c82ddfef52ee487b7efb59c9548_720w.jpg) -> 图 22 查询所有对外有关系的节点,以及关系类型 - -1. 查询所有有结婚关系的节点 - -```s - MATCH (n)-[:MARRIED]-() RETURN n -``` - -结果如图 23: - -![image](img/v2-e7850b5800fe28e628eda23b25ded3c6_720w.png) -> 图 23 查询所有有结婚关系的节点 - -1. 查找某人的朋友的朋友 - -```s - MATCH (a:Person {name:'Mike'})-[r1:FRIENDS]-()-[r2:FRIENDS]-(friend_of_a_friend) RETURN friend_of_a_friend.name AS fofName -``` -返回Mike的朋友的朋友,结果如图 24: - -![image](img/v2-8630e2f27bb7bc7551a9699a4a4f6d73_720w.png) -> 图 24 查找某人的朋友的朋友 - -### 2.6 Neo4j 怎么删除和修改? - -1. 增加/修改节点的属性 - -```s - MATCH (a:Person {name:'Liz'}) SET a.age=34 - MATCH (a:Person {name:'Shawn'}) SET a.age=32 - MATCH (a:Person {name:'John'}) SET a.age=44 - MATCH (a:Person {name:'Mike'}) SET a.age=25 -``` -这里,SET表示修改操作 - -2. 删除节点的属性 - -```s - MATCH (a:Person {name:'Mike'}) SET a.test='test' - MATCH (a:Person {name:'Mike'}) REMOVE a.test -``` -删除属性操作主要通过REMOVE -3. 删除节点 - -```s - MATCH (a:Location {city:'Portland'}) DELETE a -``` -删除节点操作是DELETE -4. 删除有关系的节点 - -```s - MATCH (a:Person {name:'Todd'})-[rel]-(b:Person) DELETE a,b,rel -``` - -## 三、如何利用 Python 操作 Neo4j 图数据库? - -### 3.1 neo4j模块:执行CQL ( cypher ) 语句是什么? - -```s - # step 1:导入 Neo4j 驱动包 - from neo4j import GraphDatabase - # step 2:连接 Neo4j 图数据库 - driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password")) - # 添加 关系 函数 - def add_friend(tx, name, friend_name): - tx.run("MERGE (a:Person {name: $name}) " - "MERGE (a)-[:KNOWS]->(friend:Person {name: $friend_name})", - name=name, friend_name=friend_name) - # 定义 关系函数 - def print_friends(tx, name): - for record in tx.run("MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name " - "RETURN friend.name ORDER BY friend.name", name=name): - print(record["friend.name"]) - # step 3:运行 - with driver.session() as session: - session.write_transaction(add_friend, "Arthur", "Guinevere") - session.write_transaction(add_friend, "Arthur", "Lancelot") - session.write_transaction(add_friend, "Arthur", "Merlin") - session.read_transaction(print_friends, "Arthur") -``` -上述程序的核心部分,抽象一下就是: - -```s - neo4j.GraphDatabase.driver(xxxx).session().write_transaction(函数(含tx.run(CQL语句))) -``` -或者 - -```s - neo4j.GraphDatabase.driver(xxxx).session().begin_transaction.run(CQL语句) -``` - -### 3.2 py2neo模块是什么? - -- 介绍:通过操作python变量,达到操作neo4j的目的 - -```s - # step 1:导包 - from py2neo import Graph, Node, Relationship - # step 2:构建图 - g = Graph() - # step 3:创建节点 - tx = g.begin() - a = Node("Person", name="Alice") - tx.create(a) - b = Node("Person", name="Bob") - # step 4:创建边 - ab = Relationship(a, "KNOWS", b) - # step 5:运行 - tx.create(ab) - tx.commit() -``` - -py2neo模块符合python的习惯,写着感觉顺畅,其实可以完全不会CQL也能写 - -## 四、数据导入 Neo4j 图数据库篇 - -- 动机:前面学习的是单个创建节点,不适合大批量导入。这里我们使用neo4j-admin import命令导入,其他导入方法也可以参考[Neo4j之导入数据](https://zhuanlan.zhihu.com/p/93746655) - -csv分为两个nodes.csv和relations.csv,注意关系里的起始节点必须是在nodes.csv里能找到的: - -```s - # nodes.csv需要指定唯一ID和nam, - headers = [ - 'unique_id:ID', # 图数据库中节点存储的唯一标识 - 'name', # 节点展示的名称 - 'node_type:LABEL', # 节点的类型,比如Person和Location - 'property' # 节点的其他属性 - ] -``` - -```s - # relations.csv - headers = [ - 'unique_id', # 图数据库中关系存储的唯一标识 - 'begin_node_id:START_ID', # begin_node和end_node的值来自于nodes.csv中节点 - 'end_node_id:END_ID', - 'begin_node_name', - 'end_node_name', - 'begin_node_type', - 'end_node_type', - 'relation_type:TYPE', # 关系的类型,比如Friends和Married - 'property' # 关系的其他属性 - ] -``` -制作出两个csv后,通过以下步骤导入neo4j: - -1. 两个文件nodes.csv ,relas.csv放在 - -```s - neo4j安装绝对路径/import -``` -2. 导入到图数据库mygraph.db - -```s - neo4j bin/neo4j-admin import --nodes=/var/lib/neo4j/import/nodes.csv --relationships=/var/lib/neo4j/import/relas.csv --delimiter=^ --database=xinfang*.db -``` -delimiter=^ 指的是csv的分隔符 - -3. 指定neo4j使用哪个数据库 - -```s - 修改 /root/neo4j/conf/neo4j.conf 文件中的 dbms.default_database=mygraph.db -``` - -4. 重启neo4j就可以看到数据已经导入成功了 - -## 参考资料 - -1. [干货 | 从零到一学习知识图谱的技术与应用](https://blog.csdn.net/guleileo/article/details/80879158) -2. [手把手教你快速入门知识图谱 - Neo4J教程](https://zhuanlan.zhihu.com/p/88745411) -3. [python操作图数据库neo4j的两种方式](https://zhuanlan.zhihu.com/p/82958776) -4. [Neo4j之导入数据](https://zhuanlan.zhihu.com/p/93746655) -5. [schema 介绍](https://schema.org/) -6. [知识图谱Schema](https://ai.baidu.com/tech/kg/schema) -7. [美团大脑:知识图谱的建模方法及其应用](https://tech.meituan.com/2018/11/01/meituan-ai-nlp.html) -8. [肖仰华. *知识图谱:概念与技术*.北京:电子工业出版社, 2020.2-39.](https://item.jd.com/10166718622.html) \ No newline at end of file diff --git a/NLPinterview/KG/readme.md b/NLPinterview/KG/readme.md deleted file mode 100644 index d2ed7fa..0000000 --- a/NLPinterview/KG/readme.md +++ /dev/null @@ -1,174 +0,0 @@ -# 【关于 知识图谱】 那些你不知道的事 - -> 作者:吴晓均 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes -> - -![](img/微信截图_20210129233513.png) - -## 一、知识图谱简介 - -### 1.1 引言 - -从一开始的Google搜索,到现在的聊天机器人、大数据风控、证券投资、智能医疗、自适应教育、推荐系统,无一不跟知识图谱相关。它在技术领域的热度也在逐年上升。 - -早在 2010 年微软就开始构建知识图谱,包括 Satori 和 Probase;2012 年,Google 正式发布了 Google Knowledge Graph,现在规模已超 700 亿。目前微软和 Google 拥有全世界最大的通用知识图谱,Facebook 拥有全世界最大的社交知识图谱,而阿里巴巴和亚马逊则分别构建了商品知识图谱。 - -![业内布局.jpg](img/微信截图_20210128234724.png) -> 图 1 业内布局 - -![业内应用.jpg](img/微信截图_20210128234802.png) -> 图 2 业内应用 - -本章以通俗易懂的方式来讲解知识图谱相关的知识、介绍从零开始搭建知识图谱过程当中需要经历的步骤以及每个阶段。本次组队学习还将动手实践一个关于kg在智能问答中的应用。 - -### 1.2 什么是知识图谱呢? - -知识图谱是由 Google 公司在 2012 年提出来的一个新的概念。从学术的角度,我们可以对知识图谱给一个这样的定义:“知识图谱本质上是语义网络(Semantic Network)的知识库”。但这有点抽象,所以换个角度,从实际应用的角度出发其实可以简单地把知识图谱理解成多关系图(Multi-relational Graph)。 - -#### 1.2.1 什么是图(Graph)呢? - -图(Graph)是由节点(Vertex)和边(Edge)来构成,多关系图一般包含多种类型的节点和多种类型的边。实体(节点)指的是现实世界中的事物比如人、地名、概念、药物、公司等,关系(边)则用来表达不同实体之间的某种联系,比如人-“居住在”-北京、张三和李四是“朋友”、逻辑回归是深度学习的“先导知识”等等。 - -![image.png](img/微信截图_20210128234821.png) -> 图 3 图(Graph)介绍 - -#### 1.2.2 什么是 Schema 呢? - -- 知识图谱另外一个很重要的概念是 Schema: - - 介绍:限定待加入知识图谱数据的格式;相当于某个领域内的数据模型,包含了该领域内有意义的概念类型以及这些类型的属性 - - 作用:规范结构化数据的表达,一条数据必须满足Schema预先定义好的实体对象及其类型,才被允许更新到知识图谱中, **一图胜千言** - - 图中的DataType限定了知识图谱节点值的类型为文本、日期、数字(浮点型与整型) - - 图中的Thing限定了节点的类型及其属性(即图1-1中的边) - - 举例说明:基于下图Schema构建的知识图谱中仅可含作品、地方组织、人物;其中作品的属性为电影与音乐、地方组织的属性为当地的商业(eg:饭店、俱乐部等)、人物的属性为歌手 - - tips:本次组队学习不涉及schema的构建 - -![Schema定义.PNG](img/微信截图_20210128234837.png) -> 图 4 Schema定义 - -### 1.3 知识图谱的类别有哪些? - -先按知识图谱应用的深度主要可以分为两大类: -- 一是通用知识图谱,通俗讲就是大众版,没有特别深的行业知识及专业内容,一般是解决科普类、常识类等问题。 -- 二是行业知识图谱,通俗讲就是专业版,根据对某个行业或细分领域的深入研究而定制的版本,主要是解决当前行业或细分领域的专业问题。 - -### 1.4 知识图谱的价值在哪呢? - -从图5中可以看出,知识图谱是人工智能很重要的一个分支, 人工智能的目标为了让机器具备像人一样理性思考及做事的能力 -> - 在符号主义的引领下,知识工程(核心内容即建设专家系统)取得了突破性的进展 -> - 在整个知识工程的分支下,知识表示是一个非常重要的任务 -> - 而知识图谱又恰恰是知识表示的重要一环 - -![学科概念.PNG](img/微信截图_20210128234850.png) -> 图 5 学科概念 - -## 二、怎么构建知识图谱呢? - -### 2.1 知识图谱的数据来源于哪里? - -知识图谱的构建是后续应用的基础,而且构建的前提是需要把数据从不同的数据源中抽取出来。对于垂直领域的知识图谱来说,它们的数据源主要来自两种渠道: -- 第一种:业务本身的数据。这部分数据通常包含在公司内的数据库表并以结构化的方式存储,一般只需要简单预处理即可以作为后续AI系统的输入; -- 第二种:网络上公开、抓取的数据。这些数据通常是以网页的形式存在所以是非结构化的数据,一般需要借助于自然语言处理等技术来提取出结构化信息。 - -![image.png](img/微信截图_20210128234902.png) -> 图 6 数据来源 - -比如在下面的搜索例子里,Bill Gates和Malinda Gate的关系就可以从非结构化数据中提炼出来,比如维基百科等数据源。 - -![image.png](img/微信截图_20210128234916.png) -> 图 7 举例说明 - -### 2.2 信息抽取的难点在哪里? - -信息抽取的难点在于处理非结构化数据。在下面的图中,我们给出了一个实例。左边是一段非结构化的英文文本,右边是从这些文本中抽取出来的实体和关系。 -![image.png](img/微信截图_20210128234916.png) -> 图 8 信息抽取的难点举例 - -### 2.3 构建知识图谱所涉及的技术? - -在构建类似的图谱过程当中,主要涉及以下几个方面的自然语言处理技术: - -1. 实体命名识别(Name Entity Recognition) -2. 关系抽取(Relation Extraction) -3. 实体统一(Entity Resolution) -4. 指代消解(Coreference Resolution) -5. ... - -### 2.4、知识图谱的具体构建技术是什么? - -下面针对每一项技术解决的问题做简单的描述,至于这些是具体怎么实现的,不在这里一一展开,后续课程和知识图谱第二期的课程将会慢慢展开: - -![image.png](img/微信截图_20210128234957.png) -> 图 9 具体构建技术 示例 - -#### 2.4.1 实体命名识别(Named Entity Recognition) - -- 实体命名识别(英语:Named Entity Recognition),简称NER - - 目标:就是从文本里提取出实体并对每个实体做分类/打标签; - - 举例说明:比如从上述文本里,我们可以提取出实体-“NYC”,并标记实体类型为 “Location”;我们也可以从中提取出“Virgil's BBQ”,并标记实体类型为“Restarant”。 - - 这种过程称之为实体命名识别,这是一项相对比较成熟的技术,有一些现成的工具可以用来做这件事情。 - -#### 2.4.2 关系抽取(Relation Extraction) - -- 关系抽取(英语:Relation Extraction),简称 RE - - 介绍:通过关系抽取技术,把实体间的关系从文本中提取出来; - - 举例说明:比如实体“hotel”和“Hilton property”之间的关系为“in”;“hotel”和“Time Square”的关系为“near”等等。 - -![image.png](img/微信截图_20210128235014.png) -> 图 9 NER 和 RE 示例 - -#### 2.4.3 实体统一(Entity Resolution) - -- 实体统一(英语:Entity Resolution),简称 ER - - 介绍:对于有些实体写法上不一样,但其实是指向同一个实体; - - 举例说明:比如“NYC”和“New York”表面上是不同的字符串,但其实指的都是纽约这个城市,需要合并。 - - 价值:实体统一不仅可以减少实体的种类,也可以降低图谱的稀疏性(Sparsity); - -#### 2.4.4 指代消解(Disambiguation) - -- 指代消解(英语:Disambiguation) - - 介绍:文本中出现的“it”, “he”, “she”这些词到底指向哪个实体,比如在本文里两个被标记出来的“it”都指向“hotel”这个实体。 - -![image.png](img/微信截图_20210128235028.png) -> 图 10 ER 和 Disambiguation 示例 - -## 三、知识图谱怎么存储? - -- 知识图谱主要有两种存储方式: - - 一种是基于RDF的存储; - - 另一种是基于图数据库的存储。 - -它们之间的区别如下图所示。RDF一个重要的设计原则是数据的易发布以及共享,图数据库则把重点放在了高效的图查询和搜索上。其次,RDF以三元组的方式来存储数据而且不包含属性信息,但图数据库一般以属性图为基本的表示形式,所以实体和关系可以包含属性,这就意味着更容易表达现实的业务场景。其中Neo4j系统目前仍是使用率最高的图数据库,它拥有活跃的社区,而且系统本身的查询效率高,但唯一的不足就是不支持准分布式。相反,OrientDB和JanusGraph(原Titan)支持分布式,但这些系统相对较新,社区不如Neo4j活跃,这也就意味着使用过程当中不可避免地会遇到一些刺手的问题。如果选择使用RDF的存储系统,Jena或许一个比较不错的选择。 - -![image.png](img/微信截图_20210128235042.png) -> 图 11 RDF的存储 和 基于图数据库的存储 的区别 - -## 四、知识图谱可以做什么? - -- 通用知识图谱的应用 - - 搜索引擎搜索(百度搜索、搜狗搜索等) - - 搜索推荐(根据搜索内容进行推荐) - - 问答 - -![](img/微信截图_20210128235109.png) - -- 行业知识图谱的应用 - - 人脉路径查询。基于两个用户之间的关联实体(比如:所在单位、同事、同学、朋友、家人等)找到两者之间的关联路径。 - - 企业社交图谱查询。基于投资、任职、专利、招投标、涉诉关系以目标企业为核心心向外层层扩散,形成一个网络关系图,直观立体展现企业关联。 - - 辅助信贷审核。基于知识图谱数据的统一查询,全面掌握客户信息;避免由于系统、数据孤立、信息不一致造成信用重复使用、信息不完整等问题。 - - 征信系统。根据用户已有信息(例如:教育信息、身份信息、联系方式、担保或被担保人信息)关联多家平台信用记录。 - - ... - - -## 参考资料 - -1. [干货 | 从零到一学习知识图谱的技术与应用](https://blog.csdn.net/guleileo/article/details/80879158) -2. [手把手教你快速入门知识图谱 - Neo4J教程](https://zhuanlan.zhihu.com/p/88745411) -3. [python操作图数据库neo4j的两种方式](https://zhuanlan.zhihu.com/p/82958776) -4. [Neo4j之导入数据](https://zhuanlan.zhihu.com/p/93746655) -5. [schema 介绍](https://schema.org/) -6. [知识图谱Schema](https://ai.baidu.com/tech/kg/schema) -7. [美团大脑:知识图谱的建模方法及其应用](https://tech.meituan.com/2018/11/01/meituan-ai-nlp.html) -8. [肖仰华. *知识图谱:概念与技术*.北京:电子工业出版社, 2020.2-39.](https://item.jd.com/10166718622.html) -9. [知识图谱的前世今生](https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=2247523545&idx=6&sn=2d43b05a1e28d27a43563c167b392492&chksm=ebb7a40ddcc02d1b681d05111ee39a4662591c4ea0e3e307c06acc2784a08c3be852b7e4f8fa&mpshare=1&scene=22&srcid=01223XHEZbS9TaVjOHvj4tR9&sharer_sharetime=1611290089163&sharer_shareid=da84f0d2d31380d783922b9e26cacfe2#rd) \ No newline at end of file diff --git "a/NLPinterview/KnowledgeRepresentation/img/\343\200\220\345\205\263\344\272\216\347\237\245\350\257\206\350\241\250\347\244\272\345\255\246\344\271\240\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" "b/NLPinterview/KnowledgeRepresentation/img/\343\200\220\345\205\263\344\272\216\347\237\245\350\257\206\350\241\250\347\244\272\345\255\246\344\271\240\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" deleted file mode 100644 index dca7f02..0000000 Binary files "a/NLPinterview/KnowledgeRepresentation/img/\343\200\220\345\205\263\344\272\216\347\237\245\350\257\206\350\241\250\347\244\272\345\255\246\344\271\240\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" and /dev/null differ diff --git a/NLPinterview/KnowledgeRepresentation/readme.md b/NLPinterview/KnowledgeRepresentation/readme.md deleted file mode 100644 index b23752a..0000000 --- a/NLPinterview/KnowledgeRepresentation/readme.md +++ /dev/null @@ -1,185 +0,0 @@ -# 【关于 知识表示学习】那些你不知道的事 - -> 作者:JimmyDU - -![](img/【关于知识表示学习】那些你不知道的事.png) - -## 一. 理论及研究现状 - -### 1.1 理论 - -#### 1.1.1 知识表示学习的基本概念 - -**知识表示学习**的目标是**通过机器学习将研究对象的语义信息表示为稠密低维实值向量**。以知识库中的实体$e$和关系$r$为例,我们将学校得到的模型表示为%l_e%和l_r。在该向量空间中,我们可以通过欧氏距离或余弦距离等方式,计算任意两个对象之间的语义相似度。像我们常说的词向量就属于知识表示学习。 - -#### 1.1.2 知识表示的理论基础 - -知识表示学习得到的低维向量表示是一种**分布式表示(distributed representation)**,之所以这么命名,是因为孤立地看向量中的每一维,都没有明确对应的含义;而综合各维形成一个向量,则能够表示对象的语义信息。这种表示方案并非凭空而来,而是受到人脑的工作机制启发而来(具体详见参考文献【1】)。 - -#### 1.1.3 知识表示学习的典型应用 - -知识表示学习是面向知识库中实体和关系的表示学习,通过将实体或关系投影到低维向量空间,我们能够实现对实体和关系的语义信息的表示,可以高效地计算实体、关系及其之间的复杂语义关联。这对知识库的构建、推理和应用均有重要意义。 - -知识表示学习得到的分布式表示有以下典型应用: - -1. **语义相似度计算**:利用实体的分布式表示,我们可以快速计算实体间的语义相似度,这对于自然语言和信息检索的很多任务具有重要意义。 -2. **知识图谱补全**:构建大规模知识图谱,需要不断补充实体间的关系。利用知识表示学习模型,可以预测2个实体的关系,这一般称为知识库的链接预测(link prediction),又称为知识图谱补全(knowledge graph completion)。 -3. 其他应用,知识表示学习已被广泛应用于关系抽取、自动问答、实体链指等任务,展现出巨大的应用潜力。随着深度学习在自然语言处理各项任务中得到广泛应用,这将为知识表示学习带来更广阔的应用空间。 - -#### 1.1.4 知识表示学习的主要优点 - -知识表示学习实现了对实体和关系的分布式表示,它具有以下主要优点: - -1. **显著提升计算效率**:知识库的三元组表示实际就是基于独热表示(one-hot representation)的,独热表示的问题在于,需要设计专门的图算法计算实体键的语义和推理关系,计算复杂度高、可扩展性差。而表示学习得到的分布式表示,则能够**高效地实现语义相似度计算**等操作,显著提升计算效率。 -2. **有效缓解数据稀疏**:由于**表示学习将对象投影到统一的低维空间**中,使每个对象均对应一个稠密向量,从而有效缓解数据稀疏问题,这主要体现在2个方面。一方面,每个对象的向量均为稠密有值的,因此可以度量任意对象之间的语义相似程度。**而基于独热表示的图算法,由于受到大规模知识图谱稀疏特性的影响,往往无法有效计算很多对象之间的语义相似度。**另一方面,将大量对象投影到统一空间的过程,也能够将高频对象的语义信息用于帮助低频对象的语义表示,提高低频对象的语义表示准确性。 -3. **实现异质信息融合**:不同来源的异质信息需要融合为整体,才能够得到有效应用。大量实体和关系在不同知识库中的名称不同,如何实现多知识库的有机融合,对知识库应用具有重要意义。如果基于独热表示和网络表示,该任务只能通过设计合理的表示学习模型,将不同来源的对象投影到同一个语义空间中,就能够建立统一的表示空间,实现多知识库的信息融合。此外,当我们在信息检索或自然语言处理中应用知识库时,往往需要计算查询词、句子、文档和知识库实体之间的复杂语义关联。由于这些对象的异质性,计算它们的语义关联往往是棘手问题。而表示学习亦能为异质对象提供统一表示空间,轻而易举实现异质 对象之间的语义关联计算。 - -### 1.2 研究现状 - -知识表示学习的代表模型: - -1. 距离模型 -2. 单层神经网络模型 -3. 能量模型 -4. 双线性模型 -5. 张量神经网络模型 -6. 矩阵分解模型 -7. 翻译模型 -8. 图表示学习模型 - -以上【1-7】模型的具体说明,可以去看参考文献【1】,图表示学习模型请阅读文献【2】【3】。 - -## 二. 常见面试题 - -### 2.1 Q: 知识表示相对于one-hot表示的优势是什么? - -A:**独热表示**的问题在于,需要设计专门的图算法计算实体键的语义和推理关系,**计算复杂度高、可扩展性差,**同时在大规模语料的建模中,会出现**数据稀疏**的问题。而知识表示学习实现了对实体和关系的分布式表示,它具有以下主要优点: - -1. **显著提升计算效率**:知识表示学习得到的分布式表示,则**能够高效地实现语义相似度计算等操作**,显著提升计算效率。 -2. **有效缓解数据稀疏**:由于**表示学习将对象投影到统一的低维空间**中,使每个对象均对应一个稠密向量,从而有效缓解数据稀疏问题,这主要体现在2个方面。一方面,每个对象的向量均为稠密有值的,因此可以度量任意对象之间的语义相似程度。**而基于独热表示的图算法,由于受到大规模知识图谱稀疏特性的影响,往往无法有效计算很多对象之间的语义相似度。**另一方面,将大量对象投影到统一空间的过程,也能够将高频对象的语义信息用于帮助低频对象的语义表示,提高低频对象的语义表示准确性。 -3. **实现异质信息融合**:不同来源的异质信息需要融合为整体,才能够得到有效应用。大量实体和关系在不同知识库中的名称不同,如何实现多知识库的有机融合,对知识库应用具有重要意义。如果基于独热表示和网络表示,该任务只能通过设计合理的表示学习模型,将不同来源的对象投影到同一个语义空间中,就能够建立统一的表示空间,实现多知识库的信息融合。此外,当我们在信息检索或自然语言处理中应用知识库时,往往需要计算查询词、句子、文档和知识库实体之间的复杂语义关联。由于这些对象的异质性,计算它们的语义关联往往是棘手问题。而表示学习亦能为异质对象提供统一表示空间,轻而易举实现异质 对象之间的语义关联计算。 - -### 2.2 Q:有哪些文本表示模型?它们各有什么优缺点? - -A: - -(1)词袋模型和**N-gram**模型 - -最基础的文本表示模型是词袋模型。顾名思义,就是将每篇文章看成一袋子词,并忽略每个词出现的顺序。具体地说,就是将整段文本以词为单位切分开, 然后每篇文章可以表示成一个长向量,向量中的每一维代表一个单词,而该维对应的权重则反映了这个词在原文章中的重要程度。常用TF-IDF来计算权重,公式为 -$$ -TF-IDF(t, d) = TF(t, d) \times IDF(t) -$$ -其中TF(*t*,*d*)为单词*t*在文档*d*中出现的频率,IDF(*t*)是逆文档频率,用来衡量单词*t*对表达语义所起的重要性,表示为 -$$ -IDF(t) = log(\frac{文章总数}{包含单词t的文章总数+1}) -$$ -直观的解释是,如果一个单词在非常多的文章里面都出现,那么它可能是一个比较通用的词汇,对于区分某篇文章特殊语义的贡献较小,因此对权重做一定惩罚。 - -将文章进行单词级别的划分有时候并不是一种好的做法,比如英文中的natural language processing(自然语言处理)一词,如果将natural,language,processing这 3个词拆分开来,所表达的含义与三个词连续出现时大相径庭。通常,可以将连续 出现的*n*个词(*n*≤*N*)组成的词组(N-gram)也作为一个单独的特征放到向量表示 中去,构成N-gram模型。另外,同一个词可能有多种词性变化,却具有相似的含义。在实际应用中,一般会对单词进行词干抽取(Word Stemming)处理,即将不 同词性的单词统一成为同一词干的形式。 - -(2)主题模型 - -基于词袋模型或N-gram模型的文本表示模型有一个明显的缺陷,就是无法识 别出两个不同的词或词组具有相同的主题。因此,需要一种技术能够将具有相同 主题的词或词组映射到同一维度上去,于是产生了主题模型。主题模型是一种特 殊的概率图模型。想象一下我们如何判定两个不同的词具有相同的主题呢?这两 个词可能有更高的概率同时出现在同一篇文档中;换句话说,给定某一主题,这 两个词的产生概率都是比较高的,而另一些不太相关的词汇产生的概率则是较低 的。假设有*K*个主题,我们就把任意文章表示成一个*K*维的主题向量,其中向量的 每一维代表一个主题,权重代表这篇文章属于这个特定主题的概率。主题模型所 解决的事情,就是从文本库中发现有代表性的主题(得到每个主题上面词的分 布),并且计算出每篇文章对应着哪些主题。常见的主题模型有:pLSA(Probabilistic Latent Semantic Analysis),LDA(Latent Dirichlet Allocation)。 - -(3)词嵌入与深度学习模型 - -词嵌入是一类将词向量化的模型的统称,核心思想是将每个词都映射成低维 空间(通常*K*=50~300维)上的一个稠密向量(Dense Vector)。*K*维空间的每一维也可以看作一个隐含的主题,只不过不像主题模型中的主题那样直观。 - -由于词嵌入将每个词映射成一个*K*维的向量,如果一篇文档有*N*个词,就可以用一个*N*×*K*维的矩阵来表示这篇文档,但是这样的表示过于底层。在实际应用中,如果仅仅把这个矩阵作为原文本的表示特征输入到机器学习模型中,通常很 难得到令人满意的结果。因此,还需要在此基础之上加工出更高层的特征。在传统的浅层机器学习模型中,一个好的特征工程往往可以带来算法效果的显著提升。而深度学习模型正好为我们提供了一种自动地进行特征工程的方式,模型中的每个隐层都可以认为对应着不同抽象层次的特征。从这个角度来讲,深度学习模型能够打败浅层模型也就顺理成章了。卷积神经网络和循环神经网络的结构在文本表示中取得了很好的效果,主要是由于它们能够更好地对文本进行建模,抽取出一些高层的语义特征。与全连接的网络结构相比,卷积神经网络和循环神经网络一方面很好地抓住了文本的特性,另一方面又减少了网络中待学习的参数, 提高了训练速度,并且降低了过拟合的风险。 - -### 2.3 Q:word2vec与LDA模型之间的区别和联系? - -A:首先,LDA是利用**文档中单词的共现关系**来对单词按主题聚类,也可以理解为对“文档-单词”矩阵进行分解,得到“文档- 主题”和“主题-单词”两个概率分布。而Word2Vec其实是对“上下文-单词”矩阵进行 学习,其中上下文由周围的几个单词组成,由此得到的词向量表示更多地融入了 上下文共现的特征。也就是说,如果两个单词所对应的Word2Vec向量相似度较高,那么它们很可能经常在同样的上下文中出现。需要说明的是,上述分析的是 LDA与Word2Vec的不同,不应该作为主题模型和词嵌入两类方法的主要差异。主题模型通过一定的结构调整可以基于“上下文-单词”矩阵进行主题推理。同样地,词嵌入方法也可以根据“文档-单词”矩阵学习出词的隐含向量表示。主题模型和词嵌入两类方法最大的不同其实在于模型本身,主题模型是一种基于概率图模型的生成式模型,其似然函数可以写成若干条件概率连乘的形式,其中包括需要推测的隐含变量(即主题);而词嵌入模型一般表达为神经网络的形式,似然函数定义在网络的输出之上,需要通过学习网络的权重以得到单词的稠密向量表示。 - -### 2.4 Q:介绍下词向量空间中的平移不变现象? - -表示学习在自然语言处理领域受到广泛关注起源于Mikolov等人与2013年提出的word2vec词表示学习模型和工具包,利用该模型,Mikolov等人发现词向量空间中的平移不变现象,例如: -$$ -C(KING)-C(QUEEN) \approx C(MAN)-C(WOMAN) -$$ -这里的$c(w)$表示利用word2vec学习得到的单词$w$的词向量。也就是说,词向量能够捕捉到单词KING和QUEEN之间、MAN和WOMAN之间的某种相同的隐含语义关系。Mikolov等人通过类比推理实验【4, 5】发现,这种平移不变现象普遍存在于词汇的语义关系和句法关系中。 - -### 2.5 Q:简要介绍下TransE模型的思想及优点? - -A:受到词向量空间平移不变现象的启发,Bordes等人提出了TransE模型【6】,将知识库中的关系看做实体间的某种平移向量。对于每个三元组(h, r, t),TransE模型用关系r的向量$l_r$作为头实体向量$l_h$和尾实体向量$l_t$之间的平移。我们也可以将$l_r$看作从$l_h$到$l_t$的翻译,因此TransE也被称为翻译模型。 - -对于每个三元组(h, r, t),TransE希望 -$$ -l_h +l_r \approx l_t -$$ -TransE模型定义了如下损失函数: -$$ -f_r(h, t) = |l_h + l_r - l_t|_{L_1/L_2} -$$ -即向量$l_h+l_r$和$l_t$的$L_1$或$L_2$距离。 - -与以往模型相比,TransE模型参数较少,计算复杂度较低,却能直接建立实体和关系之间的复杂语义联系。实验表明,TransE的性能较以往模型有显著提升,特别是在大规模稀疏知识图谱上,TransE的性能尤其惊人。 - -### 2.6 Q:解释一下为什么TransE模型用于复杂关系建模时的性能较差? - -A:主要原因是因为模型过于简单,在对1-N、N-1、N-N等复杂关系进行建模时,我们可以推出以下结论:如果关系r是N-1关系,我们将会得到 -$$ -l_{h_0} \approx l_{h_1} \approx ... \approx l_{h_m} -$$ -同样的,这样的问题在关系r是N-1关系时也会发生,得到 -$$ -l_{t_0} \approx l_{t_1} \approx ... \approx l_{t_m} -$$ -具体来说,例如在知识库中有两个三元组,分别是(美国, 总统, 奥巴马)和(美国, 总统, 布什)。这里的关系“总统”是典型的1-N负责关系,如果用TransE模型从这两个三元组学习知识表示,将会使奥巴马和布什的向量变得相同,这显然不符合事实。 - -### 2.7 Q:简述TransH、TransR和TransD模型的思想 - -为了解决TransE模型在处理1-N、N-1、N-N等复杂关系时的局限性,TransH模型【8】提出让一个实体在不同的关系下拥有不同的表示。对于关系r,TransH模型同时使用平移向量$l_r$和超平面法向量$w_r$来表示它。对于一个三元组(h, r, t),TransH首先将头实体向量$l_h$和尾实体向量$l_t$延法线$w_r$投影到关系r对应的超平面上,用$l_{h_r}$ 和 $l_{t_r}$表示如下: -$$ -l_{h_r} = l_h - w_r^Tl_hw_r -$$ - -$$ -l_{t_r} = l_t - w_r^Tl_tw_r -$$ - -因此,TransH定义了如下损失函数: -$$ -f_r(h, t) = ||l_{h_r}+l_r-l_{t_r}||_{L_1/L_2} -$$ -需要主要的是,由于关系r可能存在无限个超平面,TransH简单地令$l_r$与$w_r$正交来选取一个超平面。 - -虽然TransH模型使每个实体在不同关系下拥有了不同的表示,但它仍然建设实体和关系处于相同的语义空间中,这在一定程度上限制了TransH的表示能力。TransR模型【9】则认为,一个实体是多种属性的综合体,不同关系关注实体的不同属性,而不同的关系拥有不同的语义空间。TransR模型在两个不同的空间,即**实体空间**和**多个关系空间**(关系特定的实体空间)中建模实体和关系,并在对应的关系空间中进行转换,因此命名为TrandR。 - -虽然TransR模型交TransE和TransH有了显著的改进,它仍然拥有很多缺点: - -(1)在同一个关系r下,头、尾实体共享相同的投影矩阵,然而,一个关系的头、尾实体的类型或属性可能差异巨大。 - -(2)从实体空间到关系空间的投影是实体和关系之间的交互过程,因此TransR让投影矩阵仅与关系有关是不合理的。 - -(3)与TransE和TransH相比,TransR由于引入了空间投影,是的TransR模型参数急剧增加,计算复杂度大大提高。 - -为了解决这些问题,Ji等人提出了TransD模型【10】。TransD模型设置了两个投影矩阵,分别将头实体和尾实体投影到关系空间,显然这两个投影矩阵与关系和实体都有关,这样就解决了上述问题(1)(2)。而且,只利用两个投影向量构建投影矩阵,这也解决了上述问题(3)中的参数过多的现象。 - -### 2.8 Q:简述deepwalk和node2vec模型的思想及其优点 - -A:DeepWalk算法【2】借鉴了word2vec算法的思想,word2vec是NLP中一种常用的word embedding方法,word2vec通过语料库中的句子序列来描述词与词的共现关系,进而学习到词语的向量表示。DeepWalk算法与word2vec类似,使用图中节点与节点的共现关系来学习节点的向量表示。在DeepWalk中通过使用随机游走(RandomWalk)的方式在图中进行节点采样来模拟语料库中的预料,进而使用word2vec的方式学习出节点的共现关系。 - -具体来说,DeepWalk 通过将节点视为单词并生成短随机游走作为句子来弥补网络嵌入和单词嵌入之间的差距。然后,可以将诸如 Skip-gram 之类的神经语言模型应用于这些随机游走以获得网络嵌入。其优点是首先其可以按需生成随机游走。由于 Skip-gram 模型也针对每个样本进行了优化,因此随机游走和 Skip-gram 的组合使 DeepWalk 成为在线算法。其次,DeepWalk 是可扩展的,生成随机游走和优化 Skip-gram 模型的过程都是高效且平凡的并行化。最重要的是,DeepWalk 引入了深度学习图形的范例。 - -node2vec模型【3】是在DeepWalk的架构上,优化了随机游走的序列抽取策略。node2vec采用有偏随机游走,在广度优先(bfs)和深度优先(dfs)图搜索之间进行权衡,从而产生比DeepWalk更高质量和更多信息量的嵌入。 - -### 2.9 Q:简述Line模型的思想 - -A:LINE【7】也是一种基于邻域相似假设的方法,只不过与DeepWalk使用DFS构造邻域不同的是,LINE可以看作是一种使用BFS构造邻域的算法。此外,LINE还可以应用在带权图中(DeepWalk仅能用于无权图)。 - -LINE适用于任意类型的信息网络:无向、有向和无权、有权。该方法优化了精心设计的目标函数,能够保留局部和全局网络结构。此外,LINE中还提出了边缘采样算法,解决了经典随机梯度下降的局限性,提高了算法的有效性和效率。具体来说,LINE明确定义了两个函数,分别用于一阶和二阶近似,并最小化了这两个函数的组合。一阶邻近函数与图分解(GF)相似,都是为了保持嵌入的邻接矩阵和点积接近。区别在于GF通过直接最小化两者的差异来实现这一点。相反,LINE为每对顶点定义了两个联合概率分布,一个使用邻接矩阵,另一个使用嵌入。然后,LINE最小化了这两个分布的Kullback–Leibler(KL)散度。 - -## 参考文献 - -- 【1】刘知远, 孙茂松, 林衍凯, 等. 知识表示学习研究进展[J]. 计算机研究与发展, 2016, 53(2): 247. -- 【2】Perozzi B, Al-Rfou R, Skiena S. Deepwalk: Online learning of social representations[C]//Proceedings of the 20th ACM SIGKDD international conference on Knowledge discovery and data mining. 2014: 701-710. -- 【3】Grover A, Leskovec J. node2vec: Scalable feature learning for networks[C]//Proceedings of the 22nd ACM SIGKDD international conference on Knowledge discovery and data mining. 2016: 855-864 -- 【4】Mikolov T, Sutskever I, Chen K, et al. Distributed representations of words and phrases and their compositionality[J]. arXiv preprint arXiv:1310.4546, 2013. -- 【5】Mikolov T, Chen K, Corrado G, et al. Efficient estimation of word representations in vector space[J]. arXiv preprint arXiv:1301.3781, 2013. -- 【6】Bordes A, Usunier N, Garcia-Duran A, et al. Translating embeddings for modeling multi-relational data[C]//Neural Information Processing Systems (NIPS). 2013: 1-9. -- 【7】Tang J, Qu M, Wang M, et al. Line: Large-scale information network embedding[C]//Proceedings of the 24th international conference on world wide web. 2015: 1067-1077 -- 【8】Wang Z, Zhang J, Feng J, et al. Knowledge graph embedding by translating on hyperplanes[C]//Proceedings of the AAAI Conference on Artificial Intelligence. 2014, 28(1). -- 【9】Lin Y, Liu Z, Sun M, et al. Learning entity and relation embeddings for knowledge graph completion[C]//Proceedings of the AAAI Conference on Artificial Intelligence. 2015, 29(1). -- 【10】Ji G, He S, Xu L, et al. Knowledge graph embedding via dynamic mapping matrix[C]//Proceedings of the 53rd annual meeting of the association for computational linguistics and the 7th international joint conference on natural language processing (volume 1: Long papers). 2015: 687-696. -- 【11】《百面机器学习》 \ No newline at end of file diff --git a/NLPinterview/PreTraining/bert/bertCode1_modeling.md b/NLPinterview/PreTraining/bert/bertCode1_modeling.md deleted file mode 100644 index 634daea..0000000 --- a/NLPinterview/PreTraining/bert/bertCode1_modeling.md +++ /dev/null @@ -1,919 +0,0 @@ -# 【关于 Bert 源码解析I 之 主体篇 】 那些你不知道的事 - -> 作者:杨夕 -> -> 论文链接:https://arxiv.org/pdf/1810.04805.pdf -> -> 本文链接:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210210200236.png) - -## 一、动机 - -之前给 小伙伴们 写过 一篇 【[【关于Bert】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/tree/master/bert_study/T1_bert)】后,有一些小伙伴联系我,说对 [【Bert】](https://arxiv.org/abs/1810.04805) 里面的很多细节性问题都没看懂,不清楚他怎么实现的。针对该问题,小菜鸡的我 也 意识到自己的不足,所以就 想 研读一下 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码,并针对 之前小伙伴 的一些 问题 进行 回答和解释,能力有限,希望对大家有帮助。 - - -## 二、本文框架 - -本文 将 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码分成以下模块: - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md)【本章】 -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md) -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md) - -分模块 进行解读。 - -## 三、前言 - -本文 主要 解读 Bert 模型的 主体代码 modeling.py。 - -## 四、配置类 BertConfig - -首先,解读一下 Bert 的 BertConfig 配置类,该类定义了 模型的一些默认参数,以及一些处理函数,代码如下: - -```s -class BertConfig(object): - """ 配置类 BertConfig """ - def __init__(self, - vocab_size, - hidden_size=768, - num_hidden_layers=12, - num_attention_heads=12, - intermediate_size=3072, - hidden_act="gelu", - hidden_dropout_prob=0.1, - attention_probs_dropout_prob=0.1, - max_position_embeddings=512, - type_vocab_size=16, - initializer_range=0.02): - """Constructs BertConfig. - Args: - vocab_size: 词表大小 - hidden_size: 隐藏层神经元 - num_hidden_layers: Transformer encoder中的隐藏层数 - num_attention_heads: multi-head attention 的head数 - intermediate_size: encoder的“中间”隐层神经元数(例如feed-forward layer) - hidden_act: 隐藏层激活函数 - hidden_dropout_prob: 隐层dropout率 - attention_probs_dropout_prob: 注意力部分的dropout - max_position_embeddings: 最大位置编码 - type_vocab_size: token_type_ids 的词典大小 - initializer_range: truncated_normal_initializer初始化方法的 stdev - """ - self.vocab_size = vocab_size - self.hidden_size = hidden_size - self.num_hidden_layers = num_hidden_layers - self.num_attention_heads = num_attention_heads - self.hidden_act = hidden_act - self.intermediate_size = intermediate_size - self.hidden_dropout_prob = hidden_dropout_prob - self.attention_probs_dropout_prob = attention_probs_dropout_prob - self.max_position_embeddings = max_position_embeddings - self.type_vocab_size = type_vocab_size - self.initializer_range = initializer_range - - # 功能:从 Python 词典中加载 配置参数 - @classmethod - def from_dict(cls, json_object): - """Constructs a `BertConfig` from a Python dictionary of parameters.""" - config = BertConfig(vocab_size=None) - for (key, value) in six.iteritems(json_object): - config.__dict__[key] = value - return config - - # 功能:从 Json 文件中加载 配置参数 - @classmethod - def from_json_file(cls, json_file): - """Constructs a `BertConfig` from a json file of parameters.""" - with tf.gfile.GFile(json_file, "r") as reader: - text = reader.read() - return cls.from_dict(json.loads(text)) - - def to_dict(self): - """Serializes this instance to a Python dictionary.""" - output = copy.deepcopy(self.__dict__) - return output - - def to_json_string(self): - """Serializes this instance to a JSON string.""" - return json.dumps(self.to_dict(), indent=2, sort_keys=True) + "\n" -``` - -## 五、获取 词向量 (Embedding_lookup) - -```s -def embedding_lookup(input_ids, - vocab_size, - embedding_size=128, - initializer_range=0.02, - word_embedding_name="word_embeddings", - use_one_hot_embeddings=False): - """Looks up words embeddings for id tensor. - - Args: - input_ids: 输入序列 的 id, int32 Tensor of shape [batch_size, seq_length] containing word - ids. - vocab_size: embedding词表, int. Size of the embedding vocabulary. - embedding_size: embedding维度, int. Width of the word embeddings. - initializer_range: embedding初始化范围, float. Embedding initialization range. - word_embedding_name: embeddding table命名,string. Name of the embedding table. - use_one_hot_embeddings: 是否使用one-hotembedding, bool. - If True, use one-hot method for word embeddings. - If False, use `tf.nn.embedding_lookup()`. One hot is better for TPUs. - Returns: - float Tensor of shape [batch_size, seq_length, embedding_size]. - """ - # 该函数默认输入的形状为【batch_size, seq_length, input_num】 - # - # 如果输入为2D的【batch_size, seq_length】,则扩展到【batch_size, seq_length, 1】 - if input_ids.shape.ndims == 2: - input_ids = tf.expand_dims(input_ids, axis=[-1]) - - embedding_table = tf.get_variable( - name=word_embedding_name, - shape=[vocab_size, embedding_size], - initializer=create_initializer(initializer_range)) - - if use_one_hot_embeddings: # one-hotembedding 取值 - flat_input_ids = tf.reshape(input_ids, [-1]) - one_hot_input_ids = tf.one_hot(flat_input_ids, depth=vocab_size) - output = tf.matmul(one_hot_input_ids, embedding_table) - else: # 按索引取值 - output = tf.nn.embedding_lookup(embedding_table, input_ids) - - input_shape = get_shape_list(input_ids) - - output = tf.reshape(output, - input_shape[0:-1] + [input_shape[-1] * embedding_size]) - return (output, embedding_table) -``` - -## 六、词向量 的后处理 (embedding_postprocessor) - -### 6.1 介绍 - -Bert 模型的输入主要分三部分: -- Token embedding; -- Segment embedding; -- Position embedding; - -![](img/20200701082543.png) - -### 6.2 特点 - -- 在30000个词上使用了WordPiece嵌入,把拆分的词片段(word pieces)用"##"标注; - - eg:在图中"playing"-"play ##ing"; -- 最大长度:使用了学习过的位置嵌入,支持序列长度达512的 Token; -- 特殊分类嵌入([CLS]):位于句首,在最终的隐藏层中(也就是转换器的输出)对应的是分类任务中序列标识的聚合表征。非分类任务中这一标记将被忽略; -- 区分句子对在 序列 中位置的方式: - - s1:用特殊词块([SEP])将它们分开; - - s2:给第一句的每一个标记添加一个学习到的句子 A 的嵌入,给第二句的每个标记添加一个学习到的句子 B 的嵌入; -- 对于单句输入,我们只使用句子A嵌入 - -### 6.3 代码实现 - -```s -def embedding_postprocessor(input_tensor, - use_token_type=False, - token_type_ids=None, - token_type_vocab_size=16, - token_type_embedding_name="token_type_embeddings", - use_position_embeddings=True, - position_embedding_name="position_embeddings", - initializer_range=0.02, - max_position_embeddings=512, - dropout_prob=0.1): - """Performs various post-processing on a word embedding tensor. - - Args: - input_tensor: float Tensor of shape [batch_size, seq_length, - embedding_size]. - use_token_type: bool. Whether to add embeddings for `token_type_ids`. - token_type_ids: (optional) int32 Tensor of shape [batch_size, seq_length]. Must be specified if `use_token_type` is True. - token_type_vocab_size: token_type_ids 的词典大小, int. The vocabulary size of `token_type_ids`. - token_type_embedding_name: token_type_embedding 名称,string. The name of the embedding table variable for token type ids. - use_position_embeddings: 是否使用 position embedding,bool. Whether to add position embeddings for the position of each token in the sequence. - position_embedding_name: position embedding 名称, string. The name of the embedding table variable for positional embeddings. - initializer_range: embedding初始化范围, float. Range of the weight initialization. - max_position_embeddings: 最大位置编码,必须大于等于max_seq_len, int. Maximum sequence length that might ever be used with this model. This can be longer than the sequence length of input_tensor, but cannot be shorter. - dropout_prob: float. Dropout probability applied to the final output tensor. - - Returns: - float tensor with same shape as `input_tensor`. - - Raises: - ValueError: One of the tensor shapes or input values is invalid. - """ - input_shape = get_shape_list(input_tensor, expected_rank=3) # 【batch_size,seq_length,embedding_size】 - batch_size = input_shape[0] - seq_length = input_shape[1] - width = input_shape[2] - - output = input_tensor - # Token embedding 信息 - if use_token_type: - if token_type_ids is None: - raise ValueError("`token_type_ids` must be specified if" - "`use_token_type` is True.") - # Token 定义 - token_type_table = tf.get_variable( - name=token_type_embedding_name, # token 变量的名称 - shape=[token_type_vocab_size, width], # token 变量的维度 - initializer=create_initializer(initializer_range)) # token 初始化的方式 - # 由于token-type-table比较小,所以这里采用one-hot的embedding方式加速 - flat_token_type_ids = tf.reshape(token_type_ids, [-1]) - one_hot_ids = tf.one_hot(flat_token_type_ids, depth=token_type_vocab_size) - token_type_embeddings = tf.matmul(one_hot_ids, token_type_table) - token_type_embeddings = tf.reshape(token_type_embeddings, - [batch_size, seq_length, width]) - output += token_type_embeddings - - # Position embedding 信息 - if use_position_embeddings: - # 确保seq_length小于等于max_position_embeddings - assert_op = tf.assert_less_equal(seq_length, max_position_embeddings) - with tf.control_dependencies([assert_op]): - full_position_embeddings = tf.get_variable( - name=position_embedding_name, - shape=[max_position_embeddings, width], - initializer=create_initializer(initializer_range)) - - # 这里position embedding是可学习的参数,[max_position_embeddings, width] - # 但是通常实际输入序列没有达到max_position_embeddings - # 所以为了提高训练速度,使用tf.slice取出句子长度的embedding - - # for position [0, 1, 2, ..., max_position_embeddings-1], and the current - # sequence has positions [0, 1, 2, ... seq_length-1], so we can just - # perform a slice. - position_embeddings = tf.slice(full_position_embeddings, [0, 0], - [seq_length, -1]) - num_dims = len(output.shape.as_list()) - - # word embedding之后的tensor是[batch_size, seq_length, width] - # 因为位置编码是与输入内容无关,它的shape总是[seq_length, width] - # 我们无法把位置Embedding加到word embedding上 - # 因此我们需要扩展位置编码为[1, seq_length, width] - # 然后就能通过broadcasting加上去了。 - position_broadcast_shape = [] - for _ in range(num_dims - 2): - position_broadcast_shape.append(1) - position_broadcast_shape.extend([seq_length, width]) - position_embeddings = tf.reshape(position_embeddings, - position_broadcast_shape) - output += position_embeddings - - output = layer_norm_and_dropout(output, dropout_prob) - return output - -``` - -## 七、创建 attention mask (attention_mask) - -### 7.1 作用 - -由于每个已经 padding 的样本 在 进行 self-attention 时,padding 部分 会 attend到其他部分上,所以 需要 构造attention可视域的attention_mask,避免该问题。 - -### 7.2 代码 - -```s -def create_attention_mask_from_input_mask(from_tensor, to_mask): - """Create 3D attention mask from a 2D tensor mask. - - Args: - from_tensor: padding 好的 input_ids,2D or 3D Tensor of shape [batch_size, from_seq_length, ...]. - to_mask: mask 标记向量,int32 Tensor of shape [batch_size, to_seq_length]. - - Returns: - float Tensor of shape [batch_size, from_seq_length, to_seq_length]. - """ - from_shape = get_shape_list(from_tensor, expected_rank=[2, 3]) - batch_size = from_shape[0] - from_seq_length = from_shape[1] - - to_shape = get_shape_list(to_mask, expected_rank=2) - to_seq_length = to_shape[1] - - to_mask = tf.cast( - tf.reshape(to_mask, [batch_size, 1, to_seq_length]), tf.float32) - - # We don't assume that `from_tensor` is a mask (although it could be). We - # don't actually care if we attend *from* padding tokens (only *to* padding) - # tokens so we create a tensor of all ones. - # - # `broadcast_ones` = [batch_size, from_seq_length, 1] - broadcast_ones = tf.ones( - shape=[batch_size, from_seq_length, 1], dtype=tf.float32) - - # Here we broadcast along two dimensions to create the mask. - mask = broadcast_ones * to_mask - - return mask -``` - -## 八、注意力层(attention layer) - -### 8.1 自注意力层(self-attention) -#### 8.1.1 动机 -- CNN 所存在的长距离依赖问题; -- RNN 所存在的无法并行化问题【虽然能够在一定长度上缓解 长距离依赖问题】; -#### 8.1.2 传统 Attention -- 方法:基于源端和目标端的隐向量计算Attention, -- 结果:源端每个词与目标端每个词间的依赖关系 【源端->目标端】 -- 问题:忽略了 远端或目标端 词与词间 的依赖关系 -#### 8.1.3 核心思想 -- 介绍: self-attention的结构在计算每个token时,总是会考虑整个序列其他token的表达; -- 举例:“我爱中国”这个序列,在计算"我"这个词的时候,不但会考虑词本身的embedding,也同时会考虑其他词对这个词的影响 -#### 8.1.4 目的 -学习句子内部的词依赖关系,捕获句子的内部结构。 -#### 8.1.5 公式 -![](img/20200624084515.png) -![](img/微信截图_20200625082324.png) -#### 8.1.6 步骤 -> 建议阅读 [Transformer#self-attention-长怎么样](https://github.com/km1994/nlp_paper_study/tree/master/transformer_study/Transformer#self-attention-长怎么样) - -### 8.2 多头自注意力 (Multi-Headed Attention) - -#### 8.2.1 思路 -- 相当于 $h$ 个 不同的 self-attention 的集成 -- 就是把self-attention做 n 次,取决于 head 的个数;论文里面是做了8次。 -#### 8.2.2 步骤 -- step 1 : 初始化 N 组 $Q,K,V$矩阵(论文为 8组); -- step 2 : 每组 分别 进行 self-attention; -- step 3: - - 问题:多个 self-attention 会得到 多个 矩阵,但是前馈神经网络没法输入8个矩阵; - - 目标:把8个矩阵降为1个 - - 步骤: - - 每次self-attention都会得到一个 Z 矩阵,把每个 Z 矩阵拼接起来, - - 再乘以一个Wo矩阵, - - 得到一个最终的矩阵,即 multi-head Attention 的结果; -![](img/微信截图_20200625101800.png) - -### 8.3 代码讲解 - -下面代码主要介绍 multi-head attention的实现。考虑key-query-value形式的attention,输入的from_tensor当做是query, to_tensor当做是key和value,当两者相同的时候即为self-attention。 - -```s -def attention_layer(from_tensor, - to_tensor, - attention_mask=None, - num_attention_heads=1, - size_per_head=512, - query_act=None, - key_act=None, - value_act=None, - attention_probs_dropout_prob=0.0, - initializer_range=0.02, - do_return_2d_tensor=False, - batch_size=None, - from_seq_length=None, - to_seq_length=None): - """Performs multi-headed attention from `from_tensor` to `to_tensor`. - - This function first projects `from_tensor` into a "query" tensor and - `to_tensor` into "key" and "value" tensors. These are (effectively) a list - of tensors of length `num_attention_heads`, where each tensor is of shape - [batch_size, seq_length, size_per_head]. - - Then, the query and key tensors are dot-producted and scaled. These are - softmaxed to obtain attention probabilities. The value tensors are then - interpolated by these probabilities, then concatenated back to a single - tensor and returned. - - In practice, the multi-headed attention are done with transposes and - reshapes rather than actual separate tensors. - - Args: - from_tensor: float Tensor of shape [batch_size, from_seq_length, from_width]. - to_tensor: float Tensor of shape [batch_size, to_seq_length, to_width]. - attention_mask: (optional) int32 Tensor of shape [batch_size, from_seq_length, to_seq_length]. The values should be 1 or 0. The attention scores will effectively be set to -infinity for any positions in the mask that are 0, and will be unchanged for positions that are 1. - num_attention_heads: 自注意力的数量, int. Number of attention heads. - size_per_head: int. 每个 head 的大小, Size of each attention head. - query_act: query变换的激活函数,(optional) Activation function for the query transform. - key_act: key变换的激活函数,(optional) Activation function for the key transform. - value_act: value变换的激活函数,(optional) Activation function for the value transform. - attention_probs_dropout_prob: attention层的dropout,(optional) float. Dropout probability of the attention probabilities. - initializer_range: 初始化取值范围,float. Range of the weight initializer. - do_return_2d_tensor:是否返回2d张量 bool. - 如果True,输出形状【batch_size*from_seq_length,num_attention_heads*size_per_head】 - 如果False,输出形状【batch_size, from_seq_length, num_attention_heads*size_per_head】 - batch_size: (Optional) int. - If the input is 2D, this might be the batch size of the 3D version of the `from_tensor` and `to_tensor`. - from_seq_length: (Optional) If the input is 2D, this might be the seq length - of the 3D version of the `from_tensor`. - to_seq_length: (Optional) If the input is 2D, this might be the seq length - of the 3D version of the `to_tensor`. - - Returns: - float Tensor of shape [batch_size, from_seq_length, - num_attention_heads * size_per_head]. (If `do_return_2d_tensor` is - true, this will be of shape [batch_size * from_seq_length, - num_attention_heads * size_per_head]). - - Raises: - ValueError: Any of the arguments or tensor shapes are invalid. - """ - # 转化成 multi-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 - - from_shape = get_shape_list(from_tensor, expected_rank=[2, 3]) - to_shape = get_shape_list(to_tensor, expected_rank=[2, 3]) - - if len(from_shape) != len(to_shape): - raise ValueError( - "The rank of `from_tensor` must match the rank of `to_tensor`.") - # step 1:对输入的tensor进行形状校验,提取batch_size、from_seq_length 、to_seq_length; - if len(from_shape) == 3: - batch_size = from_shape[0] - from_seq_length = from_shape[1] - to_seq_length = to_shape[1] - elif len(from_shape) == 2: - if (batch_size is None or from_seq_length is None or to_seq_length is None): - raise ValueError( - "When passing in rank 2 tensors to attention_layer, the values " - "for `batch_size`, `from_seq_length`, and `to_seq_length` " - "must all be specified.") - - # 为了方便备注shape,采用以下简写: - # B = batch size (number of sequences) - # F = `from_tensor` sequence length - # T = `to_tensor` sequence length - # N = `num_attention_heads` - # H = `size_per_head` - - # step 2:把from_tensor和to_tensor压缩成2D张量,经过一层全连接层后得到query_layer、key_layer 、value_layer - from_tensor_2d = reshape_to_matrix(from_tensor) # 【B*F, hidden_size】 - to_tensor_2d = reshape_to_matrix(to_tensor) # 【B*T, hidden_size】 - - # step 3:from_tensor作为query, to_tensor作为key和value - # 将from_tensor输入全连接层得到query_layer - # `query_layer` = [B*F, N*H] - 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)) - - # 将from_tensor输入全连接层得到query_layer - # `key_layer` = [B*T, N*H] - 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)) - - # 将from_tensor输入全连接层得到value_layer - # `value_layer` = [B*T, N*H] - 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)) - - # step 4:将上述张量通过transpose_for_scores转化成multi-head - # query_layer转成多头:[B*F, N*H]==>[B, F, N, H]==>[B, N, F, H] - query_layer = transpose_for_scores(query_layer, batch_size, - num_attention_heads, from_seq_length, - size_per_head) - - - # key_layer转成多头:[B*T, N*H] ==> [B, T, N, H] ==> [B, N, T, H] - key_layer = transpose_for_scores(key_layer, batch_size, num_attention_heads, - to_seq_length, size_per_head) - - # step 5:根据论文公式计算attention_score以及attention_probs - # 将query与key做点积,然后做一个scale,公式可以参见原始论文 - # `attention_scores` = [B, N, F, T] - 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))) - # attention mask 操作 - if attention_mask is not None: - # `attention_mask` = [B, 1, F, T] - attention_mask = tf.expand_dims(attention_mask, axis=[1]) - - # 如果attention_mask里的元素为1,则通过下面运算有(1-1)*-10000,adder就是0 - # 如果attention_mask里的元素为0,则通过下面运算有(1-0)*-10000,adder就是-10000 - adder = (1.0 - tf.cast(attention_mask, tf.float32)) * -10000.0 - - # 我们最终得到的attention_score一般不会很大, - # 所以上述操作对mask为0的地方得到的score可以认为是负无穷 - attention_scores += adder - - # 负无穷经过softmax之后为0,就相当于mask为0的位置不计算attention_score - # `attention_probs` = [B, N, F, T] - attention_probs = tf.nn.softmax(attention_scores) - - # 对attention_probs进行dropout,这虽然有点奇怪,但是Transforme原始论文就是这么做的 - attention_probs = dropout(attention_probs, attention_probs_dropout_prob) - - # `value_layer` = [B, T, N, H] - value_layer = tf.reshape( - value_layer, - [batch_size, to_seq_length, num_attention_heads, size_per_head]) - - # `value_layer` = [B, N, T, H] - value_layer = tf.transpose(value_layer, [0, 2, 1, 3]) - - # `context_layer` = [B, N, F, H] - context_layer = tf.matmul(attention_probs, value_layer) - - # `context_layer` = [B, F, N, H] - context_layer = tf.transpose(context_layer, [0, 2, 1, 3]) - - # step 6:将得到的attention_probs与value相乘,返回2D或3D张量 - if do_return_2d_tensor: - # `context_layer` = [B*F, N*V] - context_layer = tf.reshape( - context_layer, - [batch_size * from_seq_length, num_attention_heads * size_per_head]) - else: - # `context_layer` = [B, F, N*V] - context_layer = tf.reshape( - context_layer, - [batch_size, from_seq_length, num_attention_heads * size_per_head]) - - return context_layer - -``` - -### 8.4 代码流程总结 - -- step 1:对输入的tensor进行形状校验,提取batch_size、from_seq_length 、to_seq_length; -- step 2:输入如果是3d张量则转化成2d矩阵; -- step 3:from_tensor作为query, to_tensor作为key和value,经过一层全连接层后得到query_layer、key_layer 、value_layer; -- step 4:将上述张量通过transpose_for_scores转化成multi-head; -- step 5:根据论文公式计算attention_score以及attention_probs; -- step 6:将得到的attention_probs与value相乘,返回2D或3D张量 - -### 8.5 对比总结 - -上述代码与 之前介绍的 [【关于 Transformer 代码实战(文本摘要任务篇)】 那些你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/transformer_study/Transformer/code.md) 里面的 Attention 有所区别: - -1. 缺少scale的操作; -2. 没有Causality mask,个人猜测主要是bert没有decoder的操作,所以对角矩阵mask是不需要的,从另一方面来说正好体现了双向transformer的特点; -3. 没有query mask。跟(2)理由类似,encoder都是self attention,query和key相同所以只需要一次key mask就够了 -4. 没有query的Residual层和normalize - - - -## 九、Transformer - -### 9.1 介绍 - -Bert 模型只用到 Transformer 模型的 Encoder 层,其结果 如下图: - -![Encoder 层](img/20200624080740.png) - -### 9.2 模型实现 - -```s -def transformer_model(input_tensor, - attention_mask=None, - hidden_size=768, - num_hidden_layers=12, - num_attention_heads=12, - intermediate_size=3072, - intermediate_act_fn=gelu, - hidden_dropout_prob=0.1, - attention_probs_dropout_prob=0.1, - initializer_range=0.02, - do_return_all_layers=False): - """Multi-headed, multi-layer Transformer from "Attention is All You Need". - - This is almost an exact implementation of the original Transformer encoder. - - See the original paper: - https://arxiv.org/abs/1706.03762 - - Also see: - https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/models/transformer.py - - Args: - input_tensor: float Tensor of shape [batch_size, seq_length, hidden_size]. - attention_mask: (optional) int32 Tensor of shape [batch_size, seq_length, seq_length], with 1 for positions that can be attended to and 0 in positions that should not be. - hidden_size: int. Hidden size of the Transformer. - num_hidden_layers: int. Number of layers (blocks) in the Transformer. - num_attention_heads: int. Number of attention heads in the Transformer. - intermediate_size: int. The size of the "intermediate" (a.k.a., feed forward) layer. - intermediate_act_fn: feed-forward层的激活函数,function. The non-linear activation function to apply to the output of the intermediate/feed-forward layer. - hidden_dropout_prob: float. Dropout probability for the hidden layers. - attention_probs_dropout_prob: float. Dropout probability of the attention probabilities. - initializer_range: float. Range of the initializer (stddev of truncated normal). - do_return_all_layers: Whether to also return all layers or just the final layer. - - Returns: - float Tensor of shape [batch_size, seq_length, hidden_size], the final - hidden layer of the Transformer. - - Raises: - ValueError: A Tensor shape or parameter is invalid. - """ - # 这里注意,因为最终要输出hidden_size, 我们有num_attention_head个区域, - # 每个head区域有size_per_head多的隐层 - # 所以有 hidden_size = num_attention_head * size_per_head - if hidden_size % num_attention_heads != 0: - raise ValueError( - "The hidden size (%d) is not a multiple of the number of attention " - "heads (%d)" % (hidden_size, num_attention_heads)) - - attention_head_size = int(hidden_size / num_attention_heads) - input_shape = get_shape_list(input_tensor, expected_rank=3) - batch_size = input_shape[0] - seq_length = input_shape[1] - input_width = input_shape[2] - - # 因为encoder中有残差操作,所以需要shape相同 - if input_width != hidden_size: - raise ValueError("The width of the input tensor (%d) != hidden size (%d)" % - (input_width, hidden_size)) - - # reshape操作在CPU/GPU上很快,但是在TPU上很不友好 - # 所以为了避免2D和3D之间的频繁reshape,我们把所有的3D张量用2D矩阵表示 - prev_output = reshape_to_matrix(input_tensor) - - all_layer_outputs = [] - for layer_idx in range(num_hidden_layers): - with tf.variable_scope("layer_%d" % layer_idx): - layer_input = prev_output - # step 1:多头自注意力 - with tf.variable_scope("attention"): - attention_heads = [] - with tf.variable_scope("self"): - attention_head = attention_layer( - from_tensor=layer_input, - to_tensor=layer_input, - attention_mask=attention_mask, - num_attention_heads=num_attention_heads, - size_per_head=attention_head_size, - attention_probs_dropout_prob=attention_probs_dropout_prob, - initializer_range=initializer_range, - do_return_2d_tensor=True, - batch_size=batch_size, - from_seq_length=seq_length, - to_seq_length=seq_length) - attention_heads.append(attention_head) - - attention_output = None - if len(attention_heads) == 1: - attention_output = attention_heads[0] - else: - # 如果有多个head,将他们拼接起来 - attention_output = tf.concat(attention_heads, axis=-1) - - # step 2:对attention的输出进行线性映射, 目的是将shape变成与input一致 - # 然后dropout+residual+norm - 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) - #Layer Norml - attention_output = layer_norm(attention_output + layer_input) - - # step 3:feed-forward - # The activation is only applied to the "intermediate" hidden layer. - with tf.variable_scope("intermediate"): - intermediate_output = tf.layers.dense( - attention_output, - intermediate_size, - activation=intermediate_act_fn, - kernel_initializer=create_initializer(initializer_range)) - - # step 4:对 feed-forward 层的输出使用线性变换变回‘hidden_size’ - # 然后dropout + residual + norm - with tf.variable_scope("output"): - layer_output = tf.layers.dense( - intermediate_output, - hidden_size, - kernel_initializer=create_initializer(initializer_range)) - layer_output = dropout(layer_output, hidden_dropout_prob) - # step 5:Layer Norml - layer_output = layer_norm(layer_output + attention_output) - prev_output = layer_output - all_layer_outputs.append(layer_output) - - if do_return_all_layers: - final_outputs = [] - for layer_output in all_layer_outputs: - final_output = reshape_from_matrix(layer_output, input_shape) - final_outputs.append(final_output) - return final_outputs - else: - final_output = reshape_from_matrix(prev_output, input_shape) - return final_output -``` - -### 9.3 思路分析 - -1. 计算attention_head_size,attention_head_size = int(hidden_size / num_attention_heads)即将隐层的输出等分给各个attention头。然后将input_tensor转换成2D矩阵; -2. 对input_tensor进行多头attention操作,再做:线性投影——dropout——layer norm——intermediate线性投影——线性投影——dropout——attention_output的residual——layer norm,其中intermediate线性投影的hidden_size可以自行指定,其他层的线性投影hidden_size需要统一,目的是为了对齐。 -3. 如此循环计算若干次,且保存每一次的输出,最后返回所有层的输出或者最后一层的输出。 - -## 十、入口函数 BertModel() - -### 10.1 模型实现 - -```s -class BertModel(object): - """BERT model ("Bidirectional Embedding Representations from a Transformer"). - - Example usage: - - python - # Already been converted into WordPiece token ids - input_ids = tf.constant([[31, 51, 99], [15, 5, 0]]) - input_mask = tf.constant([[1, 1, 1], [1, 1, 0]]) - token_type_ids = tf.constant([[0, 0, 1], [0, 2, 0]]) - - config = modeling.BertConfig(vocab_size=32000, hidden_size=512, - num_hidden_layers=8, num_attention_heads=6, intermediate_size=1024) - - model = modeling.BertModel(config=config, is_training=True, - input_ids=input_ids, input_mask=input_mask, token_type_ids=token_type_ids) - - label_embeddings = tf.get_variable(...) - pooled_output = model.get_pooled_output() - logits = tf.matmul(pooled_output, label_embeddings) - ... - - """ - - def __init__(self, - config, - is_training, - input_ids, - input_mask=None, - token_type_ids=None, - use_one_hot_embeddings=True, - scope=None): - """Constructor for BertModel. - - Args: - config: `BertConfig` instance. - is_training: bool. rue for training model, false for eval model. Controls - whether dropout will be applied. - input_ids: int32 Tensor of shape [batch_size, seq_length]. - input_mask: (optional) int32 Tensor of shape [batch_size, seq_length]. - token_type_ids: (optional) int32 Tensor of shape [batch_size, seq_length]. - use_one_hot_embeddings: (optional) bool. Whether to use one-hot word - embeddings or tf.embedding_lookup() for the word embeddings. On the TPU, - it is must faster if this is True, on the CPU or GPU, it is faster if - this is False. - scope: (optional) variable scope. Defaults to "bert". - - Raises: - ValueError: The config is invalid or one of the input tensor shapes - is invalid. - """ - config = copy.deepcopy(config) - if not is_training: - config.hidden_dropout_prob = 0.0 - config.attention_probs_dropout_prob = 0.0 - - input_shape = get_shape_list(input_ids, expected_rank=2) - batch_size = input_shape[0] - seq_length = input_shape[1] - - if input_mask is None: - input_mask = tf.ones(shape=[batch_size, seq_length], dtype=tf.int32) - - if token_type_ids is None: - token_type_ids = tf.zeros(shape=[batch_size, seq_length], dtype=tf.int32) - - with tf.variable_scope(scope, default_name="bert"): - with tf.variable_scope("embeddings"): - # Perform embedding lookup on the word ids. - (self.embedding_output, self.embedding_table) = embedding_lookup( - input_ids=input_ids, - vocab_size=config.vocab_size, - embedding_size=config.hidden_size, - initializer_range=config.initializer_range, - word_embedding_name="word_embeddings", - use_one_hot_embeddings=use_one_hot_embeddings) - - # Add positional embeddings and token type embeddings, then layer - # normalize and perform dropout. - self.embedding_output = embedding_postprocessor( - input_tensor=self.embedding_output, - use_token_type=True, - token_type_ids=token_type_ids, - token_type_vocab_size=config.type_vocab_size, - token_type_embedding_name="token_type_embeddings", - use_position_embeddings=True, - position_embedding_name="position_embeddings", - initializer_range=config.initializer_range, - max_position_embeddings=config.max_position_embeddings, - dropout_prob=config.hidden_dropout_prob) - - with tf.variable_scope("encoder"): - # This converts a 2D mask of shape [batch_size, seq_length] to a 3D - # mask of shape [batch_size, seq_length, seq_length] which is used - # for the attention scores. - attention_mask = create_attention_mask_from_input_mask( - input_ids, input_mask) - - # Run the stacked transformer. - # `sequence_output` shape = [batch_size, seq_length, hidden_size]. - self.all_encoder_layers = transformer_model( - input_tensor=self.embedding_output, - attention_mask=attention_mask, - hidden_size=config.hidden_size, - num_hidden_layers=config.num_hidden_layers, - num_attention_heads=config.num_attention_heads, - intermediate_size=config.intermediate_size, - intermediate_act_fn=get_activation(config.hidden_act), - hidden_dropout_prob=config.hidden_dropout_prob, - attention_probs_dropout_prob=config.attention_probs_dropout_prob, - initializer_range=config.initializer_range, - do_return_all_layers=True) - - self.sequence_output = self.all_encoder_layers[-1] - # The "pooler" converts the encoded sequence tensor of shape - # [batch_size, seq_length, hidden_size] to a tensor of shape - # [batch_size, hidden_size]. This is necessary for segment-level - # (or segment-pair-level) classification tasks where we need a fixed - # dimensional representation of the segment. - with tf.variable_scope("pooler"): - # We "pool" the model by simply taking the hidden state corresponding - # to the first token. We assume that this has been pre-trained - first_token_tensor = tf.squeeze(self.sequence_output[:, 0:1, :], axis=1) - self.pooled_output = tf.layers.dense( - first_token_tensor, - config.hidden_size, - activation=tf.tanh, - kernel_initializer=create_initializer(config.initializer_range)) - - def get_pooled_output(self): - return self.pooled_output - - def get_sequence_output(self): - """Gets final hidden layer of encoder. - - Returns: - float Tensor of shape [batch_size, seq_length, hidden_size] corresponding - to the final hidden of the transformer encoder. - """ - return self.sequence_output - - def get_all_encoder_layers(self): - return self.all_encoder_layers - - def get_embedding_output(self): - """Gets output of the embedding lookup (i.e., input to the transformer). - - Returns: - float Tensor of shape [batch_size, seq_length, hidden_size] corresponding - to the output of the embedding layer, after summing the word - embeddings with the positional embeddings and the token type embeddings, - then performing layer normalization. This is the input to the transformer. - """ - return self.embedding_output - - def get_embedding_table(self): - return self.embedding_table - -``` - -### 10.2 流程介绍 - -1. 设置各种参数,如果input_mask为None的话,就指定所有input_mask值为1,即不进行过滤;如果token_type_ids是None的话,就指定所有token_type_ids值为0; -2. 对输入的input_ids进行embedding操作,再embedding_postprocessor操作,前面我们说了。主要是加入位置和token_type信息到词向量里面; -3. 转换attention_mask 后,通过调用transformer_model进行encoder操作; -4. 获取最后一层的输出sequence_output和pooled_output,pooled_output是取sequence_output的第一个切片然后线性投影获得(可以用于分类问题) - -## 十一、总结 - -1. bert主要流程是先embedding(包括位置和token_type的embedding),然后调用transformer得到输出结果,其中embedding、embedding_table、所有transformer层输出、最后transformer层输出以及pooled_output都可以获得,用于迁移学习的fine-tune和预测任务; -2. bert对于transformer的使用仅限于encoder,没有decoder的过程。这是因为模型存粹是为了预训练服务,而预训练是通过语言模型,不同于NLP其他特定任务。在做迁移学习时可以自行添加; -3. 正因为没有decoder的操作,所以在attention函数里面也相应地减少了很多不必要的功能。 - - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md)【本章】 -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md) -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md) - -分模块 进行解读。 -## 参考 - -1. [BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding](https://arxiv.org/abs/1810.04805) -2. [google-research](https://github.com/google-research/google-research) -3. [Bert系列(二)——源码解读之模型主体](https://www.jianshu.com/p/d7ce41b58801) -4. [BERT源码分析PART I](https://zhuanlan.zhihu.com/p/69106080) diff --git a/NLPinterview/PreTraining/bert/bertCode2_pretraining.md b/NLPinterview/PreTraining/bert/bertCode2_pretraining.md deleted file mode 100644 index 663bedd..0000000 --- a/NLPinterview/PreTraining/bert/bertCode2_pretraining.md +++ /dev/null @@ -1,908 +0,0 @@ -# 【关于 Bert 源码解析II 之 预训练篇 】 那些你不知道的事 - -> 作者:杨夕 -> -> 论文链接:https://arxiv.org/pdf/1810.04805.pdf -> -> 本文链接:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210210195755.png) - -## 一、动机 - -之前给 小伙伴们 写过 一篇 【[【关于Bert】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/tree/master/bert_study/T1_bert)】后,有一些小伙伴联系我,说对 [【Bert】](https://arxiv.org/abs/1810.04805) 里面的很多细节性问题都没看懂,不清楚他怎么实现的。针对该问题,小菜鸡的我 也 意识到自己的不足,所以就 想 研读一下 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码,并针对 之前小伙伴 的一些 问题 进行 回答和解释,能力有限,希望对大家有帮助。 - - -## 二、本文框架 - -本文 将 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码分成以下模块: - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md) -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md)【本章】 -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md) - - -分模块 进行解读。 - -## 三、前言 - -本文 主要 解读 Bert 模型的 预训练 模块代码: -- tokenization.py:主要用于对原始句子内容进行解析,分为 BasicTokenizer和WordpieceTokenizer 两种; -- create_pretraining_data.py:用于将 原始语料 转化为 模型 所需要的 训练格式; -- run_pretraining.py:模型预训练; - -## 四、原始语料 预处理模块 (tokenization.py) - -### 4.1 动机 - -由于 原始语料 可能多种多样,所以需要将 原始语料 转化为 Bert 所需要的训练数据格式。 - -### 4.2 类别 - -预处理模块主要分为: -- BasicTokenizer -- WordpieceTokenizer - -### 4.3 BasicTokenizer - -- 动机:对原始语料进行处理 -- 处理操作:unicode转换、标点符号分割、小写转换、中文字符分割、去除重音符号等操作,最后返回的是关于词的数组(中文是字的数组); - -- 代码解析 - -```s -class BasicTokenizer(object): - """Runs basic tokenization (punctuation splitting, lower casing, etc.).""" - - def __init__(self, do_lower_case=True): - """Constructs a BasicTokenizer. - - Args: - do_lower_case: 是否将 query 字母都转化为小写 - """ - self.do_lower_case = do_lower_case - - def tokenize(self, text): - """Tokenizes a piece of text.""" - # step 1:将 text 从 Unicode 转化为 utf-8 - text = convert_to_unicode(text) - # step 2:去除无意义字符以及空格 - text = self._clean_text(text) - # step 3:增加中文支持 - text = self._tokenize_chinese_chars(text) - # step 4:在一段文本上运行基本的空格清除和拆分 - orig_tokens = whitespace_tokenize(text) - # step 5:用标点切分 - split_tokens = [] - for token in orig_tokens: - # 是否转小写 - if self.do_lower_case: - token = token.lower() - # 对text进行归一化 - token = self._run_strip_accents(token) - # 用标点切分 - split_tokens.extend(self._run_split_on_punc(token)) - # step 5:在一段文本上运行基本的空格清除和拆分 - output_tokens = whitespace_tokenize(" ".join(split_tokens)) - return output_tokens - - def _run_strip_accents(self, text): - """这个函数去除掉text中的非间距字符""" - # step 1: 对text进行归一化 - # 标准化对于任何需要以一致的方式处理Unicode文本的程序都是非常重要的。 - # 当处理来自用户输入的字符串而你很难去控制编码的时候尤其如此。 - # normalize() 将文本标准化,第一个参数指定字符串标准化的方式,NFD表示字符应该分解为多个组合字符表示 - text = unicodedata.normalize("NFD", text) - output = [] - for char in text: - # # category() 返回字符在UNICODE里分类的类型 - cat = unicodedata.category(char) - # 判断cat 是否为 Mn,Mark, Nonspacing 指示字符是非间距字符,这指示基字符的修改。 - if cat == "Mn": - continue - output.append(char) - return "".join(output) - - def _run_split_on_punc(self, text): - """用标点对 文本 进行切分,返回list""" - chars = list(text) - i = 0 - start_new_word = True - output = [] - while i < len(chars): - char = chars[i] - if _is_punctuation(char): - output.append([char]) - start_new_word = True - else: - if start_new_word: - output.append([]) - start_new_word = False - output[-1].append(char) - i += 1 - - return ["".join(x) for x in output] - - def _tokenize_chinese_chars(self, text): - """ 按字切分中文,实现就是在字两侧添加空格 - Adds whitespace around any CJK character. """ - output = [] - for char in text: - cp = ord(char) - if self._is_chinese_char(cp): - output.append(" ") - output.append(char) - output.append(" ") - else: - output.append(char) - return "".join(output) - - def _is_chinese_char(self, cp): - """ 判断是否是汉字 - Checks whether CP is the codepoint of a CJK character.""" - # This defines a "chinese character" as anything in the CJK Unicode block: - # https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block) - # - # Note that the CJK Unicode block is NOT all Japanese and Korean characters, - # despite its name. The modern Korean Hangul alphabet is a different block, - # as is Japanese Hiragana and Katakana. Those alphabets are used to write - # space-separated words, so they are not treated specially and handled - # like the all of the other languages. - if ((cp >= 0x4E00 and cp <= 0x9FFF) or # - (cp >= 0x3400 and cp <= 0x4DBF) or # - (cp >= 0x20000 and cp <= 0x2A6DF) or # - (cp >= 0x2A700 and cp <= 0x2B73F) or # - (cp >= 0x2B740 and cp <= 0x2B81F) or # - (cp >= 0x2B820 and cp <= 0x2CEAF) or - (cp >= 0xF900 and cp <= 0xFAFF) or # - (cp >= 0x2F800 and cp <= 0x2FA1F)): # - return True - - return False - - def _clean_text(self, text): - """ - 去除无意义字符以及空格 - Performs invalid character removal and whitespace cleanup on text. - """ - output = [] - for char in text: - cp = ord(char) - if cp == 0 or cp == 0xfffd or _is_control(char): - continue - if _is_whitespace(char): - output.append(" ") - else: - output.append(char) - return "".join(output) -``` - -### 4.4 WordpieceTokenizer - -- 动机:对于 词中 可能是 未登录词、时态问题等; -- 操作:将BasicTokenizer的结果进一步做更细粒度的切分,将合成词分解成类似词根一样的词片。例如将"unwanted"分解成["un", "##want", "##ed"] -- 目的:去除未登录词对模型效果的影响。防止因为词的过于生僻没有被收录进词典最后只能以[UNK]代替的局面,因为英语当中这样的合成词非常多,词典不可能全部收录。 -- 代码讲解 -```s -class WordpieceTokenizer(object): - """Runs WordPiece tokenziation.""" - - def __init__(self, vocab, unk_token="[UNK]", max_input_chars_per_word=200): - self.vocab = vocab - self.unk_token = unk_token - self.max_input_chars_per_word = max_input_chars_per_word - - def tokenize(self, text): - """使用贪心的最大正向匹配算法 - 例如: - For example: - input = \"unaffable\" - output = [\"un\", \"##aff\", \"##able\"] - Args: - text: A single token or whitespace separated tokens. This should have - already been passed through `BasicTokenizer. - - Returns: - A list of wordpiece tokens. - """ - # step 1:将 text 从 Unicode 转化为 utf-8 - text = convert_to_unicode(text) - - output_tokens = [] - for token in whitespace_tokenize(text): - chars = list(token) - if len(chars) > self.max_input_chars_per_word: - output_tokens.append(self.unk_token) - continue - - is_bad = False - start = 0 - sub_tokens = [] - while start < len(chars): - end = len(chars) - cur_substr = None - while start < end: - substr = "".join(chars[start:end]) - if start > 0: - substr = "##" + substr - if substr in self.vocab: - cur_substr = substr - break - end -= 1 - if cur_substr is None: - is_bad = True - break - sub_tokens.append(cur_substr) - start = end - - if is_bad: - output_tokens.append(self.unk_token) - else: - output_tokens.extend(sub_tokens) - return output_tokens - -``` -> 举例说明:
-> 假设输入是”unaffable”。
-> 我们跳到while循环部分,这是start=0,end=len(chars)=9,也就是先看看unaffable在不在词典里,如果在,那么直接作为一个WordPiece,如果不再,那么end-=1,也就是看unaffabl在不在词典里,最终发现”un”在词典里,把un加到结果里。
-> 接着start=2,看affable在不在,不在再看affabl,…,最后发现 ##aff 在词典里。注意:##表示这个词是接着前面的,这样使得WordPiece切分是可逆的——我们可以恢复出“真正”的词。
- -### 4.5 FullTokenizer - -- 功能:对一个文本段进行以上两种解析,最后返回词(字)的数组,同时还提供token到id的索引以及id到token的索引。这里的token可以理解为文本段处理过后的最小单元。 -- 代码讲解 -```s -class FullTokenizer(object): - """Runs end-to-end tokenziation.""" - - def __init__(self, vocab_file, do_lower_case=True): - # 加载词表文件为字典形式 - self.vocab = load_vocab(vocab_file) - self.inv_vocab = {v: k for k, v in self.vocab.items()} - self.basic_tokenizer = BasicTokenizer(do_lower_case=do_lower_case) - self.wordpiece_tokenizer = WordpieceTokenizer(vocab=self.vocab) - - def tokenize(self, text): - split_tokens = [] - # 调用BasicTokenizer粗粒度分词 - for token in self.basic_tokenizer.tokenize(text): - # 调用WordpieceTokenizer细粒度分词 - for sub_token in self.wordpiece_tokenizer.tokenize(token): - split_tokens.append(sub_token) - - return split_tokens - - def convert_tokens_to_ids(self, tokens): - return convert_by_vocab(self.vocab, tokens) - - def convert_ids_to_tokens(self, ids): - return convert_by_vocab(self.inv_vocab, ids) -``` - -## 五、训练数据生成(create_pretraining_data.py) - -### 5.1 作用 - -将原始输入语料转换成模型预训练所需要的数据格式TFRecoed。 - -### 5.2 参数设置 - -```s -flags.DEFINE_string("input_file", None, - "Input raw text file (or comma-separated list of files).") -flags.DEFINE_string( - "output_file", None, - "Output TF example file (or comma-separated list of files).") -flags.DEFINE_string("vocab_file", None, - "The vocabulary file that the BERT model was trained on.") -flags.DEFINE_bool( - "do_lower_case", True, - "Whether to lower case the input text. Should be True for uncased " - "models and False for cased models.") -flags.DEFINE_integer("max_seq_length", 128, "Maximum sequence length.") -flags.DEFINE_integer("max_predictions_per_seq", 20, - "Maximum number of masked LM predictions per sequence.") -flags.DEFINE_integer("random_seed", 12345, "Random seed for data generation.") -flags.DEFINE_integer( - "dupe_factor", 10, - "Number of times to duplicate the input data (with different masks).") -flags.DEFINE_float("masked_lm_prob", 0.15, "Masked LM probability.") -flags.DEFINE_float( - "short_seq_prob", 0.1, - "Probability of creating sequences which are shorter than the " - "maximum length.") -``` -- 参数介绍 - - input_file::代表输入的源语料文件地址 - - output_file :代表处理过的预料文件地址 - - do_lower_case:是否全部转为小写字母 - - vocab_file:词典文件 - - max_seq_length:最大序列长度 - - dupe_factor: 重复参数,默认重复10次,目的是可以生成不同情况的masks;举例:对于同一个句子,我们可以设置不同位置的【MASK】次数。比如对于句子Hello world, this is bert.,为了充分利用数据,第一次可以mask成Hello [MASK], this is bert.,第二次可以变成Hello world, this is [MASK]. - - max_predictions_per_seq: 一个句子里最多有多少个[MASK]标记 - - masked_lm_prob: 多少比例的Token被MASK掉 - - short_seq_prob: 长度小于“max_seq_length”的样本比例。因为在fine-tune过程里面输入的target_seq_length是可变的(小于等于max_seq_length),那么为了防止过拟合也需要在pre-train的过程当中构造一些短的样本。 - -### 5.3 main 入口 - -- 思路: -1. 构造tokenizer,构造tokenizer对输入语料进行分词处理 ; -2. 构造instances,经过create_training_instances函数构造训练instance; -3. 保存instances,调用write_instance_to_example_files函数以TFRecord格式保存数据 -; - -- 代码讲解 -```s -def main(_): - tf.logging.set_verbosity(tf.logging.INFO) - # step 1:构造tokenizer,构造tokenizer对输入语料进行分词处理 ; - tokenizer = tokenization.FullTokenizer( - vocab_file=FLAGS.vocab_file, do_lower_case=FLAGS.do_lower_case) - - input_files = [] - for input_pattern in FLAGS.input_file.split(","): - input_files.extend(tf.gfile.Glob(input_pattern)) - - tf.logging.info("*** Reading from input files ***") - for input_file in input_files: - tf.logging.info(" %s", input_file) - - # step 2:构造instances,经过create_training_instances函数构造训练instance; - rng = random.Random(FLAGS.random_seed) - instances = create_training_instances( - input_files, tokenizer, FLAGS.max_seq_length, FLAGS.dupe_factor, - FLAGS.short_seq_prob, FLAGS.masked_lm_prob, FLAGS.max_predictions_per_seq, - rng) - - output_files = FLAGS.output_file.split(",") - tf.logging.info("*** Writing to output files ***") - for output_file in output_files: - tf.logging.info(" %s", output_file) - # step 3:保存instances,调用write_instance_to_example_files函数以TFRecord格式保存数据 -; - write_instance_to_example_files(instances, tokenizer, FLAGS.max_seq_length, - FLAGS.max_predictions_per_seq, output_files) -``` - -### 5.4 定义训练样本类 (TrainingInstance) - -- 作用:构建训练样本 -- 代码讲解: - -```s -class TrainingInstance(object): - """A single training instance (sentence pair).""" - - def __init__(self, tokens, segment_ids, masked_lm_positions, masked_lm_labels, - is_random_next): - self.tokens = tokens - self.segment_ids = segment_ids # 指的形式为[0,0,0...1,1,111] 0的个数为i+1个,1的个数为max_seq_length - (i+1) 对应到模型输入就是token_type - self.is_random_next = is_random_next # 其实就是上图的Label,0.5的概率为True(和当只有一个segment的时候),如果为True则B和A不属于同一document。剩下的情况为False,则B为A同一document的后续句子。 - self.masked_lm_positions = masked_lm_positions # 序列里被[MASK]的位置; - self.masked_lm_labels = masked_lm_labels # 序列里被[MASK]的token - - def __str__(self): - s = "" - s += "tokens: %s\n" % (" ".join( - [tokenization.printable_text(x) for x in self.tokens])) - s += "segment_ids: %s\n" % (" ".join([str(x) for x in self.segment_ids])) - s += "is_random_next: %s\n" % self.is_random_next - s += "masked_lm_positions: %s\n" % (" ".join( - [str(x) for x in self.masked_lm_positions])) - s += "masked_lm_labels: %s\n" % (" ".join( - [tokenization.printable_text(x) for x in self.masked_lm_labels])) - s += "\n" - return s - - def __repr__(self): - return self.__str__() -``` - -### 5.5 构建训练实例 (create_training_instances) - -- 功能:读取数据,并构建实例 -- 训练样本输入格式说明(sample_text.txt): -```s -This text is included to make sure Unicode is handled properly: 力加勝北区ᴵᴺᵀᵃছজটডণত -Text should be one-sentence-per-line, with empty lines between documents. -This sample text is public domain and was randomly selected from Project Guttenberg. - -The rain had only ceased with the gray streaks of morning at Blazing Star, and the settlement awoke to a moral sense of cleanliness, and the finding of forgotten knives, tin cups, and smaller camp utensils, where the heavy showers had washed away the debris and dust heaps before the cabin doors. -Indeed, it was recorded in Blazing Star that a fortunate early riser had once picked up on the highway a solid chunk of gold quartz which the rain had freed from its incumbering soil, and washed into immediate and glittering popularity. -... -``` -- 说明: - - 不同句子 用 换行符 分割,也就是一个句子一行; - - 不同 文档 中间 用 两个换行符 分割; - - 同一篇文档的上下句 之间 操作关系; -- 代码讲解: -```s -def create_training_instances(input_files, tokenizer, max_seq_length, - dupe_factor, short_seq_prob, masked_lm_prob, - max_predictions_per_seq, rng): - """Create `TrainingInstance`s from raw text.""" - all_documents = [[]] - # step 1:加载数据 - # Input file format: - # (1) 每行一句话。理想情况下,这些应该是实际句子,而不是整个段落或文本的任意跨度。 (因为我们将句子边界用于“下一句预测”任务)。 - # (2) 文档之间的空白行。需要文档边界,以便“下一个句子预测”任务不会跨越文档之间。 - for input_file in input_files: - with tf.gfile.GFile(input_file, "r") as reader: - while True: - line = tokenization.convert_to_unicode(reader.readline()) - if not line: - break - line = line.strip() - - # Empty lines are used as document delimiters - if not line: - all_documents.append([]) - tokens = tokenizer.tokenize(line) - if tokens: - all_documents[-1].append(tokens) - - # step 2:清除 空文档 - all_documents = [x for x in all_documents if x] - rng.shuffle(all_documents) - - vocab_words = list(tokenizer.vocab.keys()) - instances = [] - # step 3:重复dupe_factor次,目的是可以生成不同情况的masks - for _ in range(dupe_factor): - for document_index in range(len(all_documents)): - instances.extend( - create_instances_from_document( - all_documents, document_index, max_seq_length, short_seq_prob, - masked_lm_prob, max_predictions_per_seq, vocab_words, rng)) - # step 4:数据打乱 - rng.shuffle(instances) - return instances - -``` - -### 5.6 从 document 中抽取 实例(create_instances_from_document) -#### 5.6.1 作用 -- 作用:实现从一个文档中抽取多个训练样本 -#### 5.6.2 代码讲解 -```s -def create_instances_from_document( - all_documents, document_index, max_seq_length, short_seq_prob, - masked_lm_prob, max_predictions_per_seq, vocab_words, rng): - """Creates `TrainingInstance`s for a single document.""" - document = all_documents[document_index] - - # step 1:为[CLS], [SEP], [SEP]预留三个空位 - max_num_tokens = max_seq_length - 3 - - # step 2:以short_seq_prob的概率随机生成(2~max_num_tokens)的长度 - # 我们*通常*想要填充整个序列,因为无论如何我们都要填充到“ max_seq_length”,因此短序列通常会浪费计算量。但是,我们有时*(即short_seq_prob == 0.1 == 10%的时间)希望使用较短的序列来最大程度地减少预训练和微调之间的不匹配。但是,“ target_seq_length”只是一个粗略的目标,而“ max_seq_length”是一个硬限制。 - target_seq_length = max_num_tokens - if rng.random() < short_seq_prob: - target_seq_length = rng.randint(2, max_num_tokens) - - # step 3:根据用户输入提供的实际“句子”将输入分为“ A”和“ B”两段 - # 我们不只是将文档中的所有标记连接成一个较长的序列,并选择一个任意的分割点,因为这会使下一个句子的预测任务变得太容易了。相反,我们根据用户输入提供的实际“句子”将输入分为“ A”和“ B”两段。 - instances = [] - current_chunk = [] - current_length = 0 - i = 0 - while i < len(document): - segment = document[i] - current_chunk.append(segment) - current_length += len(segment) - # 将句子依次加入current_chunk中,直到加完或者达到限制的最大长度 - if i == len(document) - 1 or current_length >= target_seq_length: - if current_chunk: - # `a_end`是第一个句子A结束的下标 - a_end = 1 - # 随机选取切分边界 - if len(current_chunk) >= 2: - a_end = rng.randint(1, len(current_chunk) - 1) - - tokens_a = [] - for j in range(a_end): - tokens_a.extend(current_chunk[j]) - - # step 4:构建 NSP 任务 - tokens_b = [] - # 是否随机next - is_random_next = False - # 构建随机的下一句 - if len(current_chunk) == 1 or rng.random() < 0.5: - is_random_next = True - target_b_length = target_seq_length - len(tokens_a) - - # 随机的挑选另外一篇文档的随机开始的句子 - # 但是理论上有可能随机到的文档就是当前文档,因此需要一个while循环 - # 这里只while循环10次,理论上还是有重复的可能性,但是我们忽略 - for _ in range(10): - random_document_index = rng.randint(0, len(all_documents) - 1) - if random_document_index != document_index: - break - - random_document = all_documents[random_document_index] - random_start = rng.randint(0, len(random_document) - 1) - for j in range(random_start, len(random_document)): - tokens_b.extend(random_document[j]) - if len(tokens_b) >= target_b_length: - break - # 对于上述构建的随机下一句,我们并没有真正地使用它们 - # 所以为了避免数据浪费,我们将其“放回” - num_unused_segments = len(current_chunk) - a_end - i -= num_unused_segments - # 构建真实的下一句 - else: - is_random_next = False - for j in range(a_end, len(current_chunk)): - tokens_b.extend(current_chunk[j]) - # 如果太多了,随机去掉一些 - truncate_seq_pair(tokens_a, tokens_b, max_num_tokens, rng) - - assert len(tokens_a) >= 1 - assert len(tokens_b) >= 1 - - tokens = [] - segment_ids = [] - # 处理句子A - tokens.append("[CLS]") - segment_ids.append(0) - for token in tokens_a: - tokens.append(token) - segment_ids.append(0) - # 句子A结束,加上【SEP】 - tokens.append("[SEP]") - segment_ids.append(0) - # 处理句子B - for token in tokens_b: - tokens.append(token) - segment_ids.append(1) - # 句子B结束,加上【SEP】 - tokens.append("[SEP]") - segment_ids.append(1) - - # step 5:构建 MLN 任务 - # 调用 create_masked_lm_predictions 来随机对某些Token进行mask - (tokens, masked_lm_positions, - masked_lm_labels) = create_masked_lm_predictions( - tokens, masked_lm_prob, max_predictions_per_seq, vocab_words, rng) - instance = TrainingInstance( - tokens=tokens, - segment_ids=segment_ids, - is_random_next=is_random_next, - masked_lm_positions=masked_lm_positions, - masked_lm_labels=masked_lm_labels) - instances.append(instance) - current_chunk = [] - current_length = 0 - i += 1 - - return instances -``` -#### 5.6.3 流程 - -1. 算法首先会维护一个chunk,不断加入document中的元素,也就是句子(segment),直到加载完或者chunk中token数大于等于最大限制,这样做的目的是使得padding的尽量少,训练效率更高。 -2. 现在chunk建立完毕之后,假设包括了前三个句子,算法会随机选择一个切分点,比如2。接下来构建predict next判断: - 1. 如果是正样本,前两个句子当成是句子A,后一个句子当成是句子B; - 2. 如果是负样本,前两个句子当成是句子A,无关的句子从其他文档中随机抽取 -3. 得到句子A和句子B之后,对其填充tokens和segment_ids,这里会加入特殊的[CLS]和[SEP]标记 -- 模板 -> [CLS] A [SEP] B [SEP]
-> A = [token_0, token_1, ..., token_i]
-> B = [token_i+1, token_i+2, ... , token_n-1]
-> 其中:
-> 2<= n < max_seq_length - 3 (in short_seq_prob)
-> n=max_seq_length - 3 (in 1-short_seq_prob)
- -- 结果举例 -> Input = [CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP]
-> Label = IsNext
->
-> Input = [CLS] the man [MASK] to the store [SEP] he penguin [MASK] are flight ##less birds [SEP]
-> Label = NotNext
- -4. 在create_masked_lm_predictions函数里,一个序列在指定MASK数量之后,有80%被真正MASK,10%还是保留原来token,10%被随机替换成其他token。 - -### 5.7 随机MASK(create_masked_lm_predictions) - -#### 5.7.1 介绍 - -- 创新点:对Tokens进行随机mask -- 原因:为了防止模型在双向循环训练的过程中“预见自身”; -- 文章中选取的策略是对输入序列中15%的词使用[MASK]标记掩盖掉,然后通过上下文去预测这些被mask的token。但是为了防止模型过拟合地学习到【MASK】这个标记,对15%mask掉的词进一步优化。 -- 操作 - -> 原始句子:the man went to a store, he bought a gallon milk.
-> 对于 句子中 15% 的 Token,采用以下一种方式优化:
-> 1. 以80%的概率用[MASK]替换:
-> the man went to a [MASK], he bought a gallon milk.
-> 2. 以10%的概率随机替换:
-> the man went to a shop, he bought a gallon milk.
-> 3. 以10%的概率保持原状:
-> the man went to a store, he bought a gallon milk.
- -#### 5.7.2 代码解析 - -```s -def create_masked_lm_predictions(tokens, masked_lm_prob, - max_predictions_per_seq, vocab_words, rng): - """Creates the predictions for the masked LM objective.""" - - cand_indexes = [] - # step 1:[CLS]和[SEP]不能用于MASK - for (i, token) in enumerate(tokens): - if token == "[CLS]" or token == "[SEP]": - continue - # Whole Word Masking means that if we mask all of the wordpieces - # corresponding to an original word. When a word has been split into - # WordPieces, the first token does not have any marker and any subsequence - # tokens are prefixed with ##. So whenever we see the ## token, we - # append it to the previous set of word indexes. - # - # Note that Whole Word Masking does *not* change the training code - # at all -- we still predict each WordPiece independently, softmaxed - # over the entire vocabulary. - if (FLAGS.do_whole_word_mask and len(cand_indexes) >= 1 and - token.startswith("##")): - cand_indexes[-1].append(i) - else: - cand_indexes.append([i]) - - rng.shuffle(cand_indexes) - - output_tokens = list(tokens) - - num_to_predict = min(max_predictions_per_seq, - max(1, int(round(len(tokens) * masked_lm_prob)))) - # step 2 : mask 操作 - masked_lms = [] - covered_indexes = set() - for index_set in cand_indexes: - if len(masked_lms) >= num_to_predict: - break - # If adding a whole-word mask would exceed the maximum number of - # predictions, then just skip this candidate. - if len(masked_lms) + len(index_set) > num_to_predict: - continue - is_any_index_covered = False - for index in index_set: - if index in covered_indexes: - is_any_index_covered = True - break - if is_any_index_covered: - continue - for index in index_set: - covered_indexes.add(index) - - masked_token = None - # 80% of the time, replace with [MASK] - if rng.random() < 0.8: - masked_token = "[MASK]" - else: - # 10% of the time, keep original - if rng.random() < 0.5: - masked_token = tokens[index] - # 10% of the time, replace with random word - else: - masked_token = vocab_words[rng.randint(0, len(vocab_words) - 1)] - - output_tokens[index] = masked_token - - masked_lms.append(MaskedLmInstance(index=index, label=tokens[index])) - assert len(masked_lms) <= num_to_predict - # step 3:按照下标重排,保证是原来句子中出现的顺序 - masked_lms = sorted(masked_lms, key=lambda x: x.index) - - masked_lm_positions = [] - masked_lm_labels = [] - for p in masked_lms: - masked_lm_positions.append(p.index) - masked_lm_labels.append(p.label) - - return (output_tokens, masked_lm_positions, masked_lm_labels) -``` - - -### 5.8 保存instance(write_instance_to_example_files) - -- 代码讲解 -```s -def write_instance_to_example_files(instances, tokenizer, max_seq_length, - max_predictions_per_seq, output_files): - - writers = [] - for output_file in output_files: - writers.append(tf.python_io.TFRecordWriter(output_file)) - - writer_index = 0 - - total_written = 0 - for (inst_index, instance) in enumerate(instances): - # 将输入转成word-ids - input_ids = tokenizer.convert_tokens_to_ids(instance.tokens) - # 记录实际句子长度 - input_mask = [1] * len(input_ids) - segment_ids = list(instance.segment_ids) - assert len(input_ids) <= max_seq_length - - # padding - while len(input_ids) < max_seq_length: - input_ids.append(0) - input_mask.append(0) - segment_ids.append(0) - - assert len(input_ids) == max_seq_length - assert len(input_mask) == max_seq_length - assert len(segment_ids) == max_seq_length - - masked_lm_positions = list(instance.masked_lm_positions) - masked_lm_ids = tokenizer.convert_tokens_to_ids(instance.masked_lm_labels) - masked_lm_weights = [1.0] * len(masked_lm_ids) - - while len(masked_lm_positions) < max_predictions_per_seq: - masked_lm_positions.append(0) - masked_lm_ids.append(0) - masked_lm_weights.append(0.0) - - next_sentence_label = 1 if instance.is_random_next else 0 - - features = collections.OrderedDict() - features["input_ids"] = create_int_feature(input_ids) - features["input_mask"] = create_int_feature(input_mask) - features["segment_ids"] = create_int_feature(segment_ids) - features["masked_lm_positions"] = create_int_feature(masked_lm_positions) - features["masked_lm_ids"] = create_int_feature(masked_lm_ids) - features["masked_lm_weights"] = create_float_feature(masked_lm_weights) - features["next_sentence_labels"] = create_int_feature([next_sentence_label]) - - # 生成训练样本 - tf_example = tf.train.Example(features=tf.train.Features(feature=features)) - - # 输出到文件 - writers[writer_index].write(tf_example.SerializeToString()) - writer_index = (writer_index + 1) % len(writers) - - total_written += 1 - - # 打印前20个样本 - if inst_index < 20: - tf.logging.info("*** Example ***") - tf.logging.info("tokens: %s" % " ".join( - [tokenization.printable_text(x) for x in instance.tokens])) - - for feature_name in features.keys(): - feature = features[feature_name] - values = [] - if feature.int64_list.value: - values = feature.int64_list.value - elif feature.float_list.value: - values = feature.float_list.value - tf.logging.info( - "%s: %s" % (feature_name, " ".join([str(x) for x in values]))) - - for writer in writers: - writer.close() - - tf.logging.info("Wrote %d total instances", total_written) -``` - -## 六、预训练 - -### 6.1 Masked LM 训练 (get_masked_lm_output) - -- 作用:针对的是语言模型对MASK起来的标签的预测,即上下文语境预测当前词,并计算 MLM 的 训练 loss - -```s -def get_masked_lm_output( - bert_config, # bert 配置 - input_tensor, # BertModel的最后一层sequence_output输出([batch_size, seq_length, hidden_size]) - output_weights, # embedding_table,用来反embedding,这样就映射到token的学习了 - positions, - label_ids, - label_weights): - """ 获取 MLM 的 loss 和 log probs - Get loss and log probs for the masked LM. - """ - # step 1:在一个小批量的特定位置收集向量。 - input_tensor = gather_indexes(input_tensor, positions) - - with tf.variable_scope("cls/predictions"): - # step 2:在输出之前添加一个非线性变换,只在预训练阶段起作用 - 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) - - # step 3:output_weights是和传入的word embedding一样的 - # 但是在输出中有一个对应每个 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) - - # step 4:label_ids表示mask掉的Token的id - label_ids = tf.reshape(label_ids, [-1]) - label_weights = tf.reshape(label_weights, [-1]) - # step 5:关于 label 的一些格式处理,处理完之后把 label 转化成 one hot 类型的输出。 - one_hot_labels = tf.one_hot( - label_ids, depth=bert_config.vocab_size, dtype=tf.float32) - - # step 6:`positions` tensor可以补零(如果序列太短而无法获得最大预测数)。 对于每个真实的预测,`label_weights` tensor 的值为1.0,对于填充预测,其值为0.0。 - # 但是由于实际MASK的可能不到20,比如只MASK18,那么label_ids有2个0(padding) - # 而label_weights=[1, 1, ...., 0, 0],说明后面两个label_id是padding的,计算loss要去掉。 - 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) -``` -### 6.2 获取 next sentence prediction(下一句预测) 部分的 loss 以及 log probs (get_next_sentence_output) - -- 作用:用于计算 NSP 的训练loss - -```s -def get_next_sentence_output(bert_config, input_tensor, labels): - """获取 NSP 的 loss 和 log probs""" - - # 二分类任务 - # 0 is "next sentence" and 1 is "random sentence". - # 这个分类器的参数在实际Fine-tuning阶段会丢弃掉 - with tf.variable_scope("cls/seq_relationship"): - output_weights = tf.get_variable( - "output_weights", - shape=[2, bert_config.hidden_size], - initializer=modeling.create_initializer(bert_config.initializer_range)) - output_bias = tf.get_variable( - "output_bias", shape=[2], 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) - labels = tf.reshape(labels, [-1]) - one_hot_labels = tf.one_hot(labels, depth=2, dtype=tf.float32) - per_example_loss = -tf.reduce_sum(one_hot_labels * log_probs, axis=-1) - loss = tf.reduce_mean(per_example_loss) - return (loss, per_example_loss, log_probs) -``` - -## 七、测试 - -```s -python create_pretraining_data.py \ - --input_file=./sample_text_zh.txt \ - --output_file=/tmp/tf_examples.tfrecord \ - --vocab_file=$BERT_BASE_DIR/vocab.txt \ - --do_lower_case=True \ - --max_seq_length=128 \ - --max_predictions_per_seq=20 \ - --masked_lm_prob=0.15 \ - --random_seed=12345 \ - --dupe_factor=5 -``` -## 八、总结 - -本章 主要介绍了 利用 Bert fineturn,代码比较简单。 - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md) -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md)【本章】 -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md) - -分模块 进行解读。 -## 参考文档 - -1. [Bert系列(三)——源码解读之Pre-train](https://www.jianshu.com/p/22e462f01d8c) -2. [BERT源码分析PART II](https://zhuanlan.zhihu.com/p/70230267) \ No newline at end of file diff --git a/NLPinterview/PreTraining/bert/bertCode3_fineTune.md b/NLPinterview/PreTraining/bert/bertCode3_fineTune.md deleted file mode 100644 index 1b2d701..0000000 --- a/NLPinterview/PreTraining/bert/bertCode3_fineTune.md +++ /dev/null @@ -1,811 +0,0 @@ -# 【关于 Bert 源码解析III 之 微调 篇 】 那些你不知道的事 - -> 作者:杨夕 -> -> 论文链接:https://arxiv.org/pdf/1810.04805.pdf -> -> 本文链接:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210210195339.png) - -## 一、动机 - -之前给 小伙伴们 写过 一篇 【[【关于Bert】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/tree/master/bert_study/T1_bert)】后,有一些小伙伴联系我,说对 [【Bert】](https://arxiv.org/abs/1810.04805) 里面的很多细节性问题都没看懂,不清楚他怎么实现的。针对该问题,小菜鸡的我 也 意识到自己的不足,所以就 想 研读一下 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码,并针对 之前小伙伴 的一些 问题 进行 回答和解释,能力有限,希望对大家有帮助。 - -## 二、本文框架 - -本文 将 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码分成以下模块: - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md) -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md) -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md)【本章】 -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md) - -分模块 进行解读。 - -## 三、前言 - -本文 主要 解读 Bert 模型的 微调 模块代码: -- run_classifier.py:主要用于 文本分类 任务的微调 - -## 四、参数解析 - -```s -flags = tf.flags -FLAGS = flags.FLAGS -''' - 必要参数 -''' -# 数据地址 -flags.DEFINE_string( - "data_dir", None, - "The input data dir. Should contain the .tsv files (or other data files) " - "for the task.") -# Bert 配置文件地址 -flags.DEFINE_string( - "bert_config_file", None, - "The config json file corresponding to the pre-trained BERT model. " - "This specifies the model architecture.") -# 训练任务 -flags.DEFINE_string("task_name", None, "The name of the task to train.") -# Bert 词库 -flags.DEFINE_string("vocab_file", None, - "The vocabulary file that the BERT model was trained on.") -# 训练输出 地址 -flags.DEFINE_string( - "output_dir", None, - "The output directory where the model checkpoints will be written.") -''' - 其他参数 -''' -# 预训练 Bert 模型 -flags.DEFINE_string( - "init_checkpoint", None, - "Initial checkpoint (usually from a pre-trained BERT model).") -# 是否小写 -flags.DEFINE_bool( - "do_lower_case", True, - "Whether to lower case the input text. Should be True for uncased " - "models and False for cased models.") -# 指定WordPiece tokenization 之后的sequence的最大长度,要求小于等于预训练模型的最大sequence长度。当输入的数据长度小于max_seq_length时用0补齐,如果长度大于max_seq_length则truncate处理; -flags.DEFINE_integer( - "max_seq_length", 128, - "The maximum total input sequence length after WordPiece tokenization. " - "Sequences longer than this will be truncated, and sequences shorter " - "than this will be padded.") -# 训练 -flags.DEFINE_bool("do_train", False, "Whether to run training.") -# 验证 -flags.DEFINE_bool("do_eval", False, "Whether to run eval on the dev set.") -# 预测 -flags.DEFINE_bool( - "do_predict", False, - "Whether to run the model in inference mode on the test set.") -# 训练 Batch 大小 -flags.DEFINE_integer("train_batch_size", 32, "Total batch size for training.") -# 评测 Batch 大小 -flags.DEFINE_integer("eval_batch_size", 8, "Total batch size for eval.") -# 预测 Batch 大小 -flags.DEFINE_integer("predict_batch_size", 8, "Total batch size for predict.") -# 学习率 -flags.DEFINE_float("learning_rate", 5e-5, "The initial learning rate for Adam.") -# 训练 epochs -flags.DEFINE_float("num_train_epochs", 3.0, - "Total number of training epochs to perform.") -# 进行线性学习率预热的训练比例。 -flags.DEFINE_float( - "warmup_proportion", 0.1, - "Proportion of training to perform linear learning rate warmup for. " - "E.g., 0.1 = 10% of training.") -# 保存模型 步长 -flags.DEFINE_integer("save_checkpoints_steps", 1000, - "How often to save the model checkpoint.") -# 每个 estimator call 调用中要执行多少步 -flags.DEFINE_integer("iterations_per_loop", 1000, - "How many steps to make in each estimator call.") -# 是否 使用 TPU -flags.DEFINE_bool("use_tpu", False, "Whether to use TPU or GPU/CPU.") -# TPU 名称 -tf.flags.DEFINE_string( - "tpu_name", None, - "The Cloud TPU to use for training. This should be either the name " - "used when creating the Cloud TPU, or a grpc://ip.address.of.tpu:8470 " - "url.") - -tf.flags.DEFINE_string( - "tpu_zone", None, - "[Optional] GCE zone where the Cloud TPU is located in. If not " - "specified, we will attempt to automatically detect the GCE project from " - "metadata.") - -tf.flags.DEFINE_string( - "gcp_project", None, - "[Optional] Project name for the Cloud TPU-enabled project. If not " - "specified, we will attempt to automatically detect the GCE project from " - "metadata.") - -tf.flags.DEFINE_string("master", None, "[Optional] TensorFlow master URL.") - -flags.DEFINE_integer( - "num_tpu_cores", 8, - "Only used if `use_tpu` is True. Total number of TPU cores to use.") -``` - -## 五、输入数据实例 - -```s -class InputExample(object): - """A single training/test example for simple sequence classification.""" - - def __init__(self, guid, text_a, text_b=None, label=None): - """Constructs a InputExample. - - Args: - guid: 实例 唯一 id - text_a: string. 第一个序列的未标记文本。 对于单序列任务,仅必须指定此序列。 - text_b: (Optional) string. 第二个序列的未标记文本。 仅必须为序列对任务指定。 - label: (Optional) string. 实例的标签。 应该为train和dev实例指定此名称,但不为测试实例指定,如果是test数据集则label统一为0。 - """ - self.guid = guid - self.text_a = text_a - self.text_b = text_b - self.label = label -``` - -## 六、特定任务数据处理 - -### 6.1 数据处理 接口 - -- 作用:数据预处理 接口 -- -```s -class DataProcessor(object): - """Base class for data converters for sequence classification data sets.""" - - def get_train_examples(self, data_dir): - """Gets a collection of `InputExample`s for the train set.""" - raise NotImplementedError() - - def get_dev_examples(self, data_dir): - """Gets a collection of `InputExample`s for the dev set.""" - raise NotImplementedError() - - def get_test_examples(self, data_dir): - """Gets a collection of `InputExample`s for prediction.""" - raise NotImplementedError() - - def get_labels(self): - """Gets the list of labels for this data set.""" - raise NotImplementedError() - - @classmethod - def _read_tsv(cls, input_file, quotechar=None): - """Reads a tab separated value file.""" - with tf.gfile.Open(input_file, "r") as f: - reader = csv.reader(f, delimiter="\t", quotechar=quotechar) - lines = [] - for line in reader: - lines.append(line) - return lines -``` - -### 6.2 推理任务 数据集处理 - -- 目标:读取两句话,并判定两者间的关系是否为“蕴含”(Entailment)、“矛盾”(Contradict)或“中性”(Neutral) -- 具体任务数据介绍:[FAIR重磅发布大规模语料库XNLI:支持15种语言,解决跨语言理解难题](https://www.infoq.cn/article/XNLI-evaluating-cross-lingual-sentence-representations) -```s -class XnliProcessor(DataProcessor): - """Processor for the XNLI data set.""" - - def __init__(self): - self.language = "zh" - - def get_train_examples(self, data_dir): - """See base class.""" - lines = self._read_tsv( - os.path.join(data_dir, "multinli", - "multinli.train.%s.tsv" % self.language)) - examples = [] - for (i, line) in enumerate(lines): - if i == 0: - continue - guid = "train-%d" % (i) - text_a = tokenization.convert_to_unicode(line[0]) - text_b = tokenization.convert_to_unicode(line[1]) - label = tokenization.convert_to_unicode(line[2]) - if label == tokenization.convert_to_unicode("contradictory"): - label = tokenization.convert_to_unicode("contradiction") - examples.append( - InputExample(guid=guid, text_a=text_a, text_b=text_b, label=label)) - return examples - - def get_dev_examples(self, data_dir): - """See base class.""" - lines = self._read_tsv(os.path.join(data_dir, "xnli.dev.tsv")) - examples = [] - for (i, line) in enumerate(lines): - if i == 0: - continue - guid = "dev-%d" % (i) - language = tokenization.convert_to_unicode(line[0]) - if language != tokenization.convert_to_unicode(self.language): - continue - text_a = tokenization.convert_to_unicode(line[6]) - text_b = tokenization.convert_to_unicode(line[7]) - label = tokenization.convert_to_unicode(line[1]) - examples.append( - InputExample(guid=guid, text_a=text_a, text_b=text_b, label=label)) - return examples - - def get_labels(self): - """See base class.""" - return ["contradiction", "entailment", "neutral"] - -``` - -### 6.3 二分类任务 数据集处理 - -```s -class ColaProcessor(DataProcessor): - """Processor for the CoLA data set (GLUE version).""" - - def get_train_examples(self, data_dir): - """See base class.""" - return self._create_examples( - self._read_tsv(os.path.join(data_dir, "train.tsv")), "train") - - def get_dev_examples(self, data_dir): - """See base class.""" - return self._create_examples( - self._read_tsv(os.path.join(data_dir, "dev.tsv")), "dev") - - def get_test_examples(self, data_dir): - """See base class.""" - return self._create_examples( - self._read_tsv(os.path.join(data_dir, "test.tsv")), "test") - - def get_labels(self): - """See base class.""" - return ["0", "1"] - - def _create_examples(self, lines, set_type): - """Creates examples for the training and dev sets.""" - examples = [] - for (i, line) in enumerate(lines): - # Only the test set has a header - if set_type == "test" and i == 0: - continue - guid = "%s-%s" % (set_type, i) - if set_type == "test": - text_a = tokenization.convert_to_unicode(line[1]) - label = "0" - else: - text_a = tokenization.convert_to_unicode(line[3]) - label = tokenization.convert_to_unicode(line[1]) - examples.append( - InputExample(guid=guid, text_a=text_a, text_b=None, label=label)) - return examples - -``` - -## 七、examples转换成features (file_based_convert_examples_to_features) - -### 7.1 单例转化 - -- 作用:将单个InputExample转换为单个InputFeatures。 -- 流程: - - step 1:判断 example 是否是 PaddingInputExample - - step 2:构建 label map - - step 3:text_a 序列化 - - step 4:text_b 序列化 - - step 5:训练 长度修改 - - step 6:输入数据 转化未 Bert 所要求类型数据 - - step 7:输入数据 转化为 id 系列 - - step 8:Mask 数据 - - step 9:利用 0 填充 - - step 10:标签 处理 - - step 11:构建 InputExample -```s -def convert_single_example( - ex_index, - example, - label_list, - max_seq_length, - tokenizer): - """将单个 InputExample 转换为单个InputFeatures。""" - # step 1:判断 example 是否是 PaddingInputExample - if isinstance(example, PaddingInputExample): - return InputFeatures( - input_ids=[0] * max_seq_length, - input_mask=[0] * max_seq_length, - segment_ids=[0] * max_seq_length, - label_id=0, - is_real_example=False) - # step 2:构建 label map - label_map = {} - for (i, label) in enumerate(label_list): - label_map[label] = i - # step 3:text_a 序列化 - tokens_a = tokenizer.tokenize(example.text_a) - # step 4:text_b 序列化 - tokens_b = None - if example.text_b: - tokens_b = tokenizer.tokenize(example.text_b) - # step 5:训练 长度修改 - if tokens_b: - # 在适当位置修改`tokens_a`和`tokens_b`,以使总长度小于指定长度。 - # Account for [CLS], [SEP], [SEP] with "- 3" - _truncate_seq_pair(tokens_a, tokens_b, max_seq_length - 3) - else: - # Account for [CLS] and [SEP] with "- 2" - if len(tokens_a) > max_seq_length - 2: - tokens_a = tokens_a[0:(max_seq_length - 2)] - - # step 6:输入数据 转化未 Bert 所要求类型数据 - # The convention in BERT is: - # (a) For sequence pairs: - # tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] - # type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 - # (b) For single sequences: - # tokens: [CLS] the dog is hairy . [SEP] - # type_ids: 0 0 0 0 0 0 0 - # - # Where "type_ids" are used to indicate whether this is the first sequence or the second sequence. The embedding vectors for `type=0` and `type=1` were learned during pre-training and are added to the wordpiece embedding vector (and position vector). This is not *strictly* necessary since the [SEP] token unambiguously separates the sequences, but it makes it easier for the model to learn the concept of sequences. - # - # For classification tasks, the first vector (corresponding to [CLS]) is used as the "sentence vector". Note that this only makes sense because the entire model is fine-tuned. - tokens = [] - segment_ids = [] - tokens.append("[CLS]") - segment_ids.append(0) - for token in tokens_a: - tokens.append(token) - segment_ids.append(0) - tokens.append("[SEP]") - segment_ids.append(0) - - if tokens_b: - for token in tokens_b: - tokens.append(token) - segment_ids.append(1) - tokens.append("[SEP]") - segment_ids.append(1) - - # step 7:输入数据 转化为 id 系列 - input_ids = tokenizer.convert_tokens_to_ids(tokens) - - # step 8:Mask 数据 - # The mask has 1 for real tokens and 0 for padding tokens. Only real - # tokens are attended to. - input_mask = [1] * len(input_ids) - - # step 9:利用 0 填充 - # Zero-pad up to the sequence length. - while len(input_ids) < max_seq_length: - input_ids.append(0) - input_mask.append(0) - segment_ids.append(0) - - assert len(input_ids) == max_seq_length - assert len(input_mask) == max_seq_length - assert len(segment_ids) == max_seq_length - # step 10:标签 处理 - label_id = label_map[example.label] - if ex_index < 5: - tf.logging.info("*** Example ***") - tf.logging.info("guid: %s" % (example.guid)) - tf.logging.info("tokens: %s" % " ".join( - [tokenization.printable_text(x) for x in tokens])) - tf.logging.info("input_ids: %s" % " ".join([str(x) for x in input_ids])) - tf.logging.info("input_mask: %s" % " ".join([str(x) for x in input_mask])) - tf.logging.info("segment_ids: %s" % " ".join([str(x) for x in segment_ids])) - tf.logging.info("label: %s (id = %d)" % (example.label, label_id)) - # step 11:构建 InputFeatures 实例 - feature = InputFeatures( - input_ids=input_ids, - input_mask=input_mask, - segment_ids=segment_ids, - label_id=label_id, - is_real_example=True) - return feature - -``` - -### 7.2 单例转化 - -```s -def file_based_convert_examples_to_features( - examples, label_list, max_seq_length, tokenizer, output_file): - """Convert a set of `InputExample`s to a TFRecord file.""" - - writer = tf.python_io.TFRecordWriter(output_file) - - for (ex_index, example) in enumerate(examples): - if ex_index % 10000 == 0: - tf.logging.info("Writing example %d of %d" % (ex_index, len(examples))) - - feature = convert_single_example(ex_index, example, label_list, - max_seq_length, tokenizer) - - def create_int_feature(values): - f = tf.train.Feature(int64_list=tf.train.Int64List(value=list(values))) - return f - - features = collections.OrderedDict() - features["input_ids"] = create_int_feature(feature.input_ids) - features["input_mask"] = create_int_feature(feature.input_mask) - features["segment_ids"] = create_int_feature(feature.segment_ids) - features["label_ids"] = create_int_feature([feature.label_id]) - features["is_real_example"] = create_int_feature( - [int(feature.is_real_example)]) - - tf_example = tf.train.Example(features=tf.train.Features(feature=features)) - writer.write(tf_example.SerializeToString()) - writer.close() - -``` - -## 八、创建模型 - -### 8.1 create_model 创建 分类模型 - -```s -def create_model(bert_config, is_training, input_ids, input_mask, segment_ids, - labels, num_labels, use_one_hot_embeddings): - """创建 分类模型""" - model = modeling.BertModel( - config=bert_config, - is_training=is_training, - input_ids=input_ids, - input_mask=input_mask, - token_type_ids=segment_ids, - use_one_hot_embeddings=use_one_hot_embeddings) - - # In the demo, we are doing a simple classification task on the entire segment. - # - # If you want to use the token-level output, use model.get_sequence_output() instead. - output_layer = model.get_pooled_output() - - hidden_size = output_layer.shape[-1].value - - output_weights = tf.get_variable( - "output_weights", [num_labels, hidden_size], - initializer=tf.truncated_normal_initializer(stddev=0.02)) - - output_bias = tf.get_variable( - "output_bias", [num_labels], initializer=tf.zeros_initializer()) - # 计算损失函数 - with tf.variable_scope("loss"): - if is_training: - # I.e., 0.1 dropout - output_layer = tf.nn.dropout(output_layer, keep_prob=0.9) - - logits = tf.matmul(output_layer, output_weights, transpose_b=True) - logits = tf.nn.bias_add(logits, output_bias) - probabilities = tf.nn.softmax(logits, axis=-1) - log_probs = tf.nn.log_softmax(logits, axis=-1) - - one_hot_labels = tf.one_hot(labels, depth=num_labels, dtype=tf.float32) - - per_example_loss = -tf.reduce_sum(one_hot_labels * log_probs, axis=-1) - loss = tf.reduce_mean(per_example_loss) - - return (loss, per_example_loss, logits, probabilities) -``` -### 8.2 model_fn_builder - -- 作用: -```s -def model_fn_builder(bert_config, num_labels, init_checkpoint, learning_rate, - num_train_steps, num_warmup_steps, use_tpu, - use_one_hot_embeddings): - """Returns `model_fn` closure for TPUEstimator.""" - - def model_fn(features, labels, mode, params): # pylint: disable=unused-argument - """The `model_fn` for TPUEstimator.""" - - tf.logging.info("*** Features ***") - for name in sorted(features.keys()): - tf.logging.info(" name = %s, shape = %s" % (name, features[name].shape)) - - input_ids = features["input_ids"] - input_mask = features["input_mask"] - segment_ids = features["segment_ids"] - label_ids = features["label_ids"] - is_real_example = None - if "is_real_example" in features: - is_real_example = tf.cast(features["is_real_example"], dtype=tf.float32) - else: - is_real_example = tf.ones(tf.shape(label_ids), dtype=tf.float32) - - is_training = (mode == tf.estimator.ModeKeys.TRAIN) - - # 总的损失定义为两者之和 - (total_loss, per_example_loss, logits, probabilities) = create_model( - bert_config, is_training, input_ids, input_mask, segment_ids, label_ids, - num_labels, use_one_hot_embeddings) - # 获取所有变量 - tvars = tf.trainable_variables() - initialized_variable_names = {} - scaffold_fn = None - # 如果有之前保存的模型,则进行恢复 - if init_checkpoint: - (assignment_map, initialized_variable_names - ) = modeling.get_assignment_map_from_checkpoint(tvars, init_checkpoint) - if use_tpu: - - def tpu_scaffold(): - tf.train.init_from_checkpoint(init_checkpoint, assignment_map) - return tf.train.Scaffold() - - scaffold_fn = tpu_scaffold - else: - tf.train.init_from_checkpoint(init_checkpoint, assignment_map) - - tf.logging.info("**** Trainable Variables ****") - for var in tvars: - init_string = "" - if var.name in initialized_variable_names: - init_string = ", *INIT_FROM_CKPT*" - tf.logging.info(" name = %s, shape = %s%s", var.name, var.shape, - init_string) - # 训练过程,获得spec - output_spec = None - if mode == tf.estimator.ModeKeys.TRAIN: - - train_op = optimization.create_optimizer( - total_loss, learning_rate, num_train_steps, num_warmup_steps, use_tpu) - - output_spec = tf.contrib.tpu.TPUEstimatorSpec( - mode=mode, - loss=total_loss, - train_op=train_op, - scaffold_fn=scaffold_fn) - # 验证过程spec - elif mode == tf.estimator.ModeKeys.EVAL: - - def metric_fn(per_example_loss, label_ids, logits, is_real_example): - predictions = tf.argmax(logits, axis=-1, output_type=tf.int32) - accuracy = tf.metrics.accuracy( - labels=label_ids, predictions=predictions, weights=is_real_example) - loss = tf.metrics.mean(values=per_example_loss, weights=is_real_example) - return { - "eval_accuracy": accuracy, - "eval_loss": loss, - } - - eval_metrics = (metric_fn, - [per_example_loss, label_ids, logits, is_real_example]) - output_spec = tf.contrib.tpu.TPUEstimatorSpec( - mode=mode, - loss=total_loss, - eval_metrics=eval_metrics, - scaffold_fn=scaffold_fn) - # 预测过程spec - else: - output_spec = tf.contrib.tpu.TPUEstimatorSpec( - mode=mode, - predictions={"probabilities": probabilities}, - scaffold_fn=scaffold_fn) - return output_spec - - return model_fn - -``` - -## 九、主入口 - -```s -def main(_): - tf.logging.set_verbosity(tf.logging.INFO) - # 任务处理器 映射表 - processors = { - "cola": ColaProcessor, - "mnli": MnliProcessor, - "mrpc": MrpcProcessor, - "xnli": XnliProcessor, - } - - tokenization.validate_case_matches_checkpoint(FLAGS.do_lower_case, - FLAGS.init_checkpoint) - - if not FLAGS.do_train and not FLAGS.do_eval and not FLAGS.do_predict: - raise ValueError( - "At least one of `do_train`, `do_eval` or `do_predict' must be True.") - # 加载 Bert 配置 - bert_config = modeling.BertConfig.from_json_file(FLAGS.bert_config_file) - - if FLAGS.max_seq_length > bert_config.max_position_embeddings: - raise ValueError( - "Cannot use sequence length %d because the BERT model " - "was only trained up to sequence length %d" % - (FLAGS.max_seq_length, bert_config.max_position_embeddings)) - - tf.gfile.MakeDirs(FLAGS.output_dir) - - task_name = FLAGS.task_name.lower() - - if task_name not in processors: - raise ValueError("Task not found: %s" % (task_name)) - # 定义任务处理器 - processor = processors[task_name]() - # 获取标签项 - label_list = processor.get_labels() - # 数据预处理 - tokenizer = tokenization.FullTokenizer( - vocab_file=FLAGS.vocab_file, do_lower_case=FLAGS.do_lower_case) - - tpu_cluster_resolver = None - if FLAGS.use_tpu and FLAGS.tpu_name: - tpu_cluster_resolver = tf.contrib.cluster_resolver.TPUClusterResolver( - FLAGS.tpu_name, zone=FLAGS.tpu_zone, project=FLAGS.gcp_project) - - is_per_host = tf.contrib.tpu.InputPipelineConfig.PER_HOST_V2 - run_config = tf.contrib.tpu.RunConfig( - cluster=tpu_cluster_resolver, - master=FLAGS.master, - model_dir=FLAGS.output_dir, - save_checkpoints_steps=FLAGS.save_checkpoints_steps, - tpu_config=tf.contrib.tpu.TPUConfig( - iterations_per_loop=FLAGS.iterations_per_loop, - num_shards=FLAGS.num_tpu_cores, - per_host_input_for_training=is_per_host)) - - train_examples = None - num_train_steps = None - num_warmup_steps = None - # 模型训练 数据加载 - if FLAGS.do_train: - # 加载训练数据 - train_examples = processor.get_train_examples(FLAGS.data_dir) - num_train_steps = int( - len(train_examples) / FLAGS.train_batch_size * FLAGS.num_train_epochs) - num_warmup_steps = int(num_train_steps * FLAGS.warmup_proportion) - # 自定义模型用于estimator训练 - model_fn = model_fn_builder( - bert_config=bert_config, - num_labels=len(label_list), - init_checkpoint=FLAGS.init_checkpoint, - learning_rate=FLAGS.learning_rate, - num_train_steps=num_train_steps, - num_warmup_steps=num_warmup_steps, - use_tpu=FLAGS.use_tpu, - use_one_hot_embeddings=FLAGS.use_tpu) - - # 如果没有TPU,会自动转为CPU/GPU的Estimator - estimator = tf.contrib.tpu.TPUEstimator( - use_tpu=FLAGS.use_tpu, - model_fn=model_fn, - config=run_config, - train_batch_size=FLAGS.train_batch_size, - eval_batch_size=FLAGS.eval_batch_size, - predict_batch_size=FLAGS.predict_batch_size) - # 模型 训练 - if FLAGS.do_train: - train_file = os.path.join(FLAGS.output_dir, "train.tf_record") - file_based_convert_examples_to_features( - train_examples, label_list, FLAGS.max_seq_length, tokenizer, train_file) - tf.logging.info("***** Running training *****") - tf.logging.info(" Num examples = %d", len(train_examples)) - tf.logging.info(" Batch size = %d", FLAGS.train_batch_size) - tf.logging.info(" Num steps = %d", num_train_steps) - train_input_fn = file_based_input_fn_builder( - input_file=train_file, - seq_length=FLAGS.max_seq_length, - is_training=True, - drop_remainder=True) - estimator.train(input_fn=train_input_fn, max_steps=num_train_steps) - # 模型 验证 数据加载 - if FLAGS.do_eval: - eval_examples = processor.get_dev_examples(FLAGS.data_dir) - num_actual_eval_examples = len(eval_examples) - if FLAGS.use_tpu: - # TPU requires a fixed batch size for all batches, therefore the number - # of examples must be a multiple of the batch size, or else examples - # will get dropped. So we pad with fake examples which are ignored - # later on. These do NOT count towards the metric (all tf.metrics - # support a per-instance weight, and these get a weight of 0.0). - while len(eval_examples) % FLAGS.eval_batch_size != 0: - eval_examples.append(PaddingInputExample()) - - eval_file = os.path.join(FLAGS.output_dir, "eval.tf_record") - file_based_convert_examples_to_features( - eval_examples, label_list, FLAGS.max_seq_length, tokenizer, eval_file) - - tf.logging.info("***** Running evaluation *****") - tf.logging.info(" Num examples = %d (%d actual, %d padding)", - len(eval_examples), num_actual_eval_examples, - len(eval_examples) - num_actual_eval_examples) - tf.logging.info(" Batch size = %d", FLAGS.eval_batch_size) - - # This tells the estimator to run through the entire set. - eval_steps = None - # However, if running eval on the TPU, you will need to specify the - # number of steps. - if FLAGS.use_tpu: - assert len(eval_examples) % FLAGS.eval_batch_size == 0 - eval_steps = int(len(eval_examples) // FLAGS.eval_batch_size) - - eval_drop_remainder = True if FLAGS.use_tpu else False - eval_input_fn = file_based_input_fn_builder( - input_file=eval_file, - seq_length=FLAGS.max_seq_length, - is_training=False, - drop_remainder=eval_drop_remainder) - - result = estimator.evaluate(input_fn=eval_input_fn, steps=eval_steps) - - output_eval_file = os.path.join(FLAGS.output_dir, "eval_results.txt") - with tf.gfile.GFile(output_eval_file, "w") as writer: - tf.logging.info("***** Eval results *****") - for key in sorted(result.keys()): - tf.logging.info(" %s = %s", key, str(result[key])) - writer.write("%s = %s\n" % (key, str(result[key]))) - # 模型预测 - if FLAGS.do_predict: - predict_examples = processor.get_test_examples(FLAGS.data_dir) - num_actual_predict_examples = len(predict_examples) - if FLAGS.use_tpu: - # TPU requires a fixed batch size for all batches, therefore the number - # of examples must be a multiple of the batch size, or else examples - # will get dropped. So we pad with fake examples which are ignored - # later on. - while len(predict_examples) % FLAGS.predict_batch_size != 0: - predict_examples.append(PaddingInputExample()) - - predict_file = os.path.join(FLAGS.output_dir, "predict.tf_record") - file_based_convert_examples_to_features(predict_examples, label_list, - FLAGS.max_seq_length, tokenizer, - predict_file) - - tf.logging.info("***** Running prediction*****") - tf.logging.info(" Num examples = %d (%d actual, %d padding)", - len(predict_examples), num_actual_predict_examples, - len(predict_examples) - num_actual_predict_examples) - tf.logging.info(" Batch size = %d", FLAGS.predict_batch_size) - - predict_drop_remainder = True if FLAGS.use_tpu else False - predict_input_fn = file_based_input_fn_builder( - input_file=predict_file, - seq_length=FLAGS.max_seq_length, - is_training=False, - drop_remainder=predict_drop_remainder) - - result = estimator.predict(input_fn=predict_input_fn) - - output_predict_file = os.path.join(FLAGS.output_dir, "test_results.tsv") - with tf.gfile.GFile(output_predict_file, "w") as writer: - num_written_lines = 0 - tf.logging.info("***** Predict results *****") - for (i, prediction) in enumerate(result): - probabilities = prediction["probabilities"] - if i >= num_actual_predict_examples: - break - output_line = "\t".join( - str(class_probability) - for class_probability in probabilities) + "\n" - writer.write(output_line) - num_written_lines += 1 - assert num_written_lines == num_actual_predict_examples -``` - -## 十、总结 - -本章 主要介绍了 利用 Bert fineturn,代码比较简单。 - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md) -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md) -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md)【本章】 -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md) - -分模块 进行解读。 - -## 参考文档 - -1. [Bert系列(四)——源码解读之Fine-tune](https://www.jianshu.com/p/116bfdb9119a) -2. [BERT源码分析PART III](https://zhuanlan.zhihu.com/p/71406864) \ No newline at end of file diff --git a/NLPinterview/PreTraining/bert/bertCode4_word2embedding.md b/NLPinterview/PreTraining/bert/bertCode4_word2embedding.md deleted file mode 100644 index 6ad9302..0000000 --- a/NLPinterview/PreTraining/bert/bertCode4_word2embedding.md +++ /dev/null @@ -1,445 +0,0 @@ -# 【关于 Bert 源码解析IV 之 句向量生成篇 】 那些你不知道的事 - -> 作者:杨夕 -> -> 论文链接:https://arxiv.org/pdf/1810.04805.pdf -> -> 本文链接:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210210194740.png) - -## 一、动机 - -之前给 小伙伴们 写过 一篇 【[【关于Bert】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/tree/master/bert_study/T1_bert)】后,有一些小伙伴联系我,说对 [【Bert】](https://arxiv.org/abs/1810.04805) 里面的很多细节性问题都没看懂,不清楚他怎么实现的。针对该问题,小菜鸡的我 也 意识到自己的不足,所以就 想 研读一下 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码,并针对 之前小伙伴 的一些 问题 进行 回答和解释,能力有限,希望对大家有帮助。 - -## 二、本文框架 - -本文 将 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码分成以下模块: - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md) -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md) -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) 【本章】 -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md) - -分模块 进行解读。 - -## 三、前言 - -本文 主要 解读 Bert 模型的 微调 模块代码: -- extract_feature.py:主要用于 生成 Bert 句向量 - -## 四、配置类 (Config) - -该类主要包含 一些 Bert 模型地址,和一些采用配置信息 - -```s -import os -import tensorflow as tf -class Config(): - def __init__(self): - tf.logging.set_verbosity(tf.logging.INFO) - self.file_path = os.path.dirname(__file__) - # Bert 模型 的 路径 - self.model_dir = os.path.join(self.file_path, 'F:/document/datasets/nlpData/bert/chinese_L-12_H-768_A-12/') - # Bert 模型 配置 - self.config_name = os.path.join(self.model_dir, 'bert_config.json') - # Bert 模型 文件 - self.ckpt_name = os.path.join(self.model_dir, 'bert_model.ckpt') - # Bert 输出 - self.output_dir = os.path.join("", 'output/') - # Bert 词库 - self.vocab_file = os.path.join(self.model_dir, 'vocab.txt') - # 训练数据地址 - self.data_dir = os.path.join("", 'data/') - # 训练 epochs - self.num_train_epochs = 10 - # 训练 batch_size - self.batch_size = 128 - self.learning_rate = 0.00005 - # gpu使用率 - self.gpu_memory_fraction = 0.8 - # 默认取倒数第二层的输出值作为句向量 - self.layer_indexes = [-2] - # 序列的最大程度,单文本建议把该值调小 - self.max_seq_len = 32 -``` - -## 五、特征实例类 (InputExample) - -```s -class InputExample(object): - def __init__(self, unique_id, text_a, text_b): - self.unique_id = unique_id - self.text_a = text_a - self.text_b = text_b - -class InputFeatures(object): - """A single set of features of data.""" - def __init__(self, unique_id, tokens, input_ids, input_mask, input_type_ids): - self.unique_id = unique_id - self.tokens = tokens - self.input_ids = input_ids - self.input_mask = input_mask - self.input_type_ids = input_type_ids -``` - -## 六、Bert 句向量 类 (BertVector) - -这一个 是 生成 Bert 句向量的 类,流程: -1. 模型加载 (get_estimator); -2. predict input 预处理 (queue_predict_input_fn); - 1. 将 实例(examples) 转化为 特征(features)(convert_examples_to_features); -3. encode sentence (encode); - -```s -class BertVector: - def __init__(self, batch_size=32): - """ - init BertVector - :param batch_size: Depending on your memory default is 32 - """ - self.max_seq_length = args.max_seq_len - self.layer_indexes = args.layer_indexes - self.gpu_memory_fraction = 1 - self.graph_path = optimize_graph() - self.tokenizer = tokenization.FullTokenizer(vocab_file=args.vocab_file, do_lower_case=True) - self.batch_size = batch_size - # 获取 estimator - self.estimator = self.get_estimator() - # 输入 队列 - self.input_queue = Queue(maxsize=1) - # 输出 队列 - self.output_queue = Queue(maxsize=1) - # 预测 线程 - self.predict_thread = Thread(target=self.predict_from_queue, daemon=True) - self.predict_thread.start() - self.sentence_len = 0 - # 获取 estimator - def get_estimator(self): - from tensorflow.python.estimator.estimator import Estimator - from tensorflow.python.estimator.run_config import RunConfig - from tensorflow.python.estimator.model_fn import EstimatorSpec - - def model_fn(features, labels, mode, params): - with tf.gfile.GFile(self.graph_path, 'rb') as f: - graph_def = tf.GraphDef() - graph_def.ParseFromString(f.read()) - - input_names = ['input_ids', 'input_mask', 'input_type_ids'] - - output = tf.import_graph_def( - graph_def, - input_map={k + ':0': features[k] for k in input_names},return_elements=['final_encodes:0'] - ) - return EstimatorSpec(mode=mode, predictions={ - 'encodes': output[0] - }) - # GPU 配置信息 - config = tf.ConfigProto() - config.gpu_options.allow_growth = True - config.gpu_options.per_process_gpu_memory_fraction = self.gpu_memory_fraction - config.log_device_placement = False - config.graph_options.optimizer_options.global_jit_level = tf.OptimizerOptions.ON_1 - return Estimator( - model_fn=model_fn, - config=RunConfig(session_config=config), - params={'batch_size': self.batch_size} - ) - # 预测 - def predict_from_queue(self): - prediction = self.estimator.predict(input_fn=self.queue_predict_input_fn, yield_single_examples=False) - for i in prediction: - self.output_queue.put(i) - # encode sentence - def encode(self, sentence): - self.sentence_len = len(sentence) - self.input_queue.put(sentence) - prediction = self.output_queue.get()['encodes'] - return prediction - # 预测 input 生成 - def queue_predict_input_fn(self): - return ( - tf.data.Dataset.from_generator( - self.generate_from_queue, - output_types={ - 'unique_ids': tf.int32, - 'input_ids': tf.int32, - 'input_mask': tf.int32, - 'input_type_ids': tf.int32 - }, - output_shapes={ - 'unique_ids': (self.sentence_len,), - 'input_ids': (None, self.max_seq_length), - 'input_mask': (None, self.max_seq_length), - 'input_type_ids': (None, self.max_seq_length) - } - ).prefetch(10)) - - def generate_from_queue(self): - while True: - features = list(self.convert_examples_to_features(seq_length=self.max_seq_length, tokenizer=self.tokenizer)) - yield { - 'unique_ids': [f.unique_id for f in features], - 'input_ids': [f.input_ids for f in features], - 'input_mask': [f.input_mask for f in features], - 'input_type_ids': [f.input_type_ids for f in features] - } - - def input_fn_builder(self, features, seq_length): - """Creates an `input_fn` closure to be passed to Estimator.""" - - all_unique_ids = [] - all_input_ids = [] - all_input_mask = [] - all_input_type_ids = [] - - for feature in features: - all_unique_ids.append(feature.unique_id) - all_input_ids.append(feature.input_ids) - all_input_mask.append(feature.input_mask) - all_input_type_ids.append(feature.input_type_ids) - - def input_fn(params): - """The actual input function.""" - batch_size = params["batch_size"] - - num_examples = len(features) - - # This is for demo purposes and does NOT scale to large data sets. We do - # not use Dataset.from_generator() because that uses tf.py_func which is - # not TPU compatible. The right way to load data is with TFRecordReader. - d = tf.data.Dataset.from_tensor_slices({ - "unique_ids": - tf.constant(all_unique_ids, shape=[num_examples], dtype=tf.int32), - "input_ids": - tf.constant( - all_input_ids, shape=[num_examples, seq_length], - dtype=tf.int32), - "input_mask": - tf.constant( - all_input_mask, - shape=[num_examples, seq_length], - dtype=tf.int32), - "input_type_ids": - tf.constant( - all_input_type_ids, - shape=[num_examples, seq_length], - dtype=tf.int32), - }) - - d = d.batch(batch_size=batch_size, drop_remainder=False) - return d - - return input_fn - - def model_fn_builder(self, bert_config, init_checkpoint, layer_indexes): - """Returns `model_fn` closure for TPUEstimator.""" - - def model_fn(features, labels, mode, params): # pylint: disable=unused-argument - """The `model_fn` for TPUEstimator.""" - - unique_ids = features["unique_ids"] - input_ids = features["input_ids"] - input_mask = features["input_mask"] - input_type_ids = features["input_type_ids"] - - jit_scope = tf.contrib.compiler.jit.experimental_jit_scope - - with jit_scope(): - model = modeling.BertModel( - config=bert_config, - is_training=False, - input_ids=input_ids, - input_mask=input_mask, - token_type_ids=input_type_ids) - - if mode != tf.estimator.ModeKeys.PREDICT: - raise ValueError("Only PREDICT modes are supported: %s" % (mode)) - - tvars = tf.trainable_variables() - - (assignment_map, initialized_variable_names) = modeling.get_assignment_map_from_checkpoint(tvars, init_checkpoint) - - tf.logging.info("**** Trainable Variables ****") - for var in tvars: - init_string = "" - if var.name in initialized_variable_names: - init_string = ", *INIT_FROM_CKPT*" - tf.logging.info(" name = %s, shape = %s%s", var.name, var.shape, init_string) - - all_layers = model.get_all_encoder_layers() - - predictions = { - "unique_id": unique_ids, - } - - for (i, layer_index) in enumerate(layer_indexes): - predictions["layer_output_%d" % i] = all_layers[layer_index] - - from tensorflow.python.estimator.model_fn import EstimatorSpec - - output_spec = EstimatorSpec(mode=mode, predictions=predictions) - return output_spec - - return model_fn - - def convert_examples_to_features(self, seq_length, tokenizer): - """将数据文件加载到 “InputBatch” 队列中 【这一部分 之前介绍过】""" - - features = [] - input_masks = [] - examples = self._to_example(self.input_queue.get()) - for (ex_index, example) in enumerate(examples): - tokens_a = tokenizer.tokenize(example.text_a) - - # 如果 句子 长度 大于 seq_len,只取 左边句子 - if len(tokens_a) > seq_length - 2: - tokens_a = tokens_a[0:(seq_length - 2)] - - # The convention in BERT is: - # (a) For sequence pairs: - # tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] - # type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 - # (b) For single sequences: - # tokens: [CLS] the dog is hairy . [SEP] - # type_ids: 0 0 0 0 0 0 0 - # - # Where "type_ids" are used to indicate whether this is the first sequence or the second sequence. The embedding vectors for `type=0` and `type=1` were learned during pre-training and are added to the wordpiece embedding vector (and position vector). This is not *strictly* necessary since the [SEP] token unambiguously separates the sequences, but it makes it easier for the model to learn the concept of sequences. - # - # For classification tasks, the first vector (corresponding to [CLS]) is used as as the "sentence vector". Note that this only makes sense because - # the entire model is fine-tuned. - tokens = [] - input_type_ids = [] - tokens.append("[CLS]") - input_type_ids.append(0) - for token in tokens_a: - tokens.append(token) - input_type_ids.append(0) - tokens.append("[SEP]") - input_type_ids.append(0) - - # Where "input_ids" are tokens's index in vocabulary - input_ids = tokenizer.convert_tokens_to_ids(tokens) - - # The mask has 1 for real tokens and 0 for padding tokens. Only real - # tokens are attended to. - input_mask = [1] * len(input_ids) - input_masks.append(input_mask) - # Zero-pad up to the sequence length. - while len(input_ids) < seq_length: - input_ids.append(0) - input_mask.append(0) - input_type_ids.append(0) - - assert len(input_ids) == seq_length - assert len(input_mask) == seq_length - assert len(input_type_ids) == seq_length - - if ex_index < 5: - tf.logging.info("*** Example ***") - tf.logging.info("unique_id: %s" % (example.unique_id)) - tf.logging.info("tokens: %s" % " ".join( - [tokenization.printable_text(x) for x in tokens])) - tf.logging.info("input_ids: %s" % " ".join([str(x) for x in input_ids])) - tf.logging.info("input_mask: %s" % " ".join([str(x) for x in input_mask])) - tf.logging.info( - "input_type_ids: %s" % " ".join([str(x) for x in input_type_ids])) - - yield InputFeatures( - unique_id=example.unique_id, - tokens=tokens, - input_ids=input_ids, - input_mask=input_mask, - input_type_ids=input_type_ids) - - def _truncate_seq_pair(self, tokens_a, tokens_b, max_length): - """将序列对截断到最大长度""" - - # 这是一个简单的启发式方法,它总是一次一个 token 地截断较长的序列。这比从每个 token 中截取相等百分比的 token 更有意义,因为如果一个序列非常短,那么每个被截断的 token 可能包含比较长序列更多的信息。 - # This is a simple heuristic which will always truncate the longer sequence one token at a time. This makes more sense than truncating an equal percent of tokens from each, since if one sequence is very short then each token that's truncated likely contains more information than a longer sequence. - while True: - total_length = len(tokens_a) + len(tokens_b) - if total_length <= max_length: - break - if len(tokens_a) > len(tokens_b): - tokens_a.pop() - else: - tokens_b.pop() - - # sentences 转 InputExamples - @staticmethod - def _to_example(sentences): - import re - """ - sentences to InputExample - :param sentences: list of strings - :return: list of InputExample - """ - unique_id = 0 - for ss in sentences: - line = tokenization.convert_to_unicode(ss) - if not line: - continue - line = line.strip() - text_a = None - text_b = None - m = re.match(r"^(.*) \|\|\| (.*)$", line) - if m is None: - text_a = line - else: - text_a = m.group(1) - text_b = m.group(2) - yield InputExample(unique_id=unique_id, text_a=text_a, text_b=text_b) - unique_id += 1 -``` - -## 七、Bert 句向量 生成 实例 - -```s -if __name__ == "__main__": - bert = BertVector() - # while True: - # question = input('question: ') - vectors = bert.encode(['你好', '哈哈']) - print(str(vectors)) ->>> -INFO:tensorflow:*** Example *** -INFO:tensorflow:unique_id: 0 -INFO:tensorflow:tokens: [CLS] 你 好 , be ##rt ! [SEP] -INFO:tensorflow:input_ids: 101 872 1962 8024 8815 8716 8013 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -INFO:tensorflow:input_mask: 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -INFO:tensorflow:input_type_ids: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -INFO:tensorflow:*** Example *** -INFO:tensorflow:unique_id: 1 -INFO:tensorflow:tokens: [CLS] 这 是 一 个 例 子 [SEP] -INFO:tensorflow:input_ids: 101 6821 3221 671 702 891 2094 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -INFO:tensorflow:input_mask: 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -INFO:tensorflow:input_type_ids: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -[[ 0.77314675 0.00324035 0.35886183 ... -0.00801571 0.6570408 - 0.3012028 ] - [-0.26962122 0.49693802 0.33362615 ... 0.42230296 0.5397997 - -0.47371814]] -``` - -## 八、总结 - -本章 主要介绍了 利用 Bert 生成 句向量,代码比较简单。 - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md) -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md) -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) 【本章】 -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md) - -分模块 进行解读。 - -## 参考资料 - -1. 【[【关于Bert】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/tree/master/bert_study/T1_bert)】 -2. [【Bert】论文](https://arxiv.org/abs/1810.04805) -3. [【Bert】源码](https://github.com/google-research/bert/blob/master/) \ No newline at end of file diff --git a/NLPinterview/PreTraining/bert/bertCode5_similarity.md b/NLPinterview/PreTraining/bert/bertCode5_similarity.md deleted file mode 100644 index 1757170..0000000 --- a/NLPinterview/PreTraining/bert/bertCode5_similarity.md +++ /dev/null @@ -1,799 +0,0 @@ -# 【关于 Bert 源码解析V 之 文本相似度 篇 】 那些你不知道的事 - -> 作者:杨夕 -> -> 论文链接:https://arxiv.org/pdf/1810.04805.pdf -> -> 本文链接:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210210195051.png) - -## 一、动机 - -之前给 小伙伴们 写过 一篇 【[【关于Bert】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/tree/master/bert_study/T1_bert)】后,有一些小伙伴联系我,说对 [【Bert】](https://arxiv.org/abs/1810.04805) 里面的很多细节性问题都没看懂,不清楚他怎么实现的。针对该问题,小菜鸡的我 也 意识到自己的不足,所以就 想 研读一下 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码,并针对 之前小伙伴 的一些 问题 进行 回答和解释,能力有限,希望对大家有帮助。 - -## 二、本文框架 - -本文 将 [【Bert】](https://github.com/google-research/bert/blob/master/) 的 源码分成以下模块: - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md) -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md) -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md)【本章】 - -分模块 进行解读。 - -## 三、前言 - -本文 主要 解读 Bert 模型的 微调 模块代码: -- similarity.py:主要用于 计算文本相似度 - -## 四、配置类 (Config) - -该类主要包含 一些 Bert 模型地址,和一些采用配置信息 - -```s -import os -import tensorflow as tf -class Config(): - def __init__(self): - tf.logging.set_verbosity(tf.logging.INFO) - self.file_path = os.path.dirname(__file__) - # Bert 模型 的 路径 - self.model_dir = os.path.join(self.file_path, 'F:/document/datasets/nlpData/bert/chinese_L-12_H-768_A-12/') - # Bert 模型 配置 - self.config_name = os.path.join(self.model_dir, 'bert_config.json') - # Bert 模型 文件 - self.ckpt_name = os.path.join(self.model_dir, 'bert_model.ckpt') - # Bert 输出 - self.output_dir = os.path.join("", 'output/') - # Bert 词库 - self.vocab_file = os.path.join(self.model_dir, 'vocab.txt') - # 训练数据地址 - self.data_dir = os.path.join("", 'data/') - # 训练 epochs - self.num_train_epochs = 10 - # 训练 batch_size - self.batch_size = 128 - self.learning_rate = 0.00005 - # gpu使用率 - self.gpu_memory_fraction = 0.8 - # 默认取倒数第二层的输出值作为句向量 - self.layer_indexes = [-2] - # 序列的最大程度,单文本建议把该值调小 - self.max_seq_len = 32 -``` - -## 五、特征实例类 (InputExample) - -这部分 代码在 [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) 有做过详细介绍,此处不展开重新介绍 - -```s -class InputExample(object): - def __init__(self, unique_id, text_a, text_b): - self.unique_id = unique_id - self.text_a = text_a - self.text_b = text_b - -class InputFeatures(object): - """A single set of features of data.""" - def __init__(self, unique_id, tokens, input_ids, input_mask, input_type_ids): - self.unique_id = unique_id - self.tokens = tokens - self.input_ids = input_ids - self.input_mask = input_mask - self.input_type_ids = input_type_ids -``` -## 六、数据预处理类 - -### 6.1 DataProcessor - -```s -class DataProcessor(object): - """Base class for data converters for sequence classification data sets.""" - - def get_train_examples(self, data_dir): - """Gets a collection of `InputExample`s for the train set.""" - raise NotImplementedError() - - def get_dev_examples(self, data_dir): - """Gets a collection of `InputExample`s for the dev set.""" - raise NotImplementedError() - - def get_test_examples(self, data_dir): - """Gets a collection of `InputExample`s for prediction.""" - raise NotImplementedError() - - def get_labels(self): - """Gets the list of labels for this data set.""" - raise NotImplementedError() -``` - -### 6.2 文本相似度任务 文本预处理 (SimProcessor) - -#### 6.2.1 数据格式 - -```s -query,reply,label -可以组合贷吗?,可以的,1 -... -``` - -从上面实例中可以看出,每一行有query,reply,label组成,该任务主要是 判别 query 与 reply 是否存在关系,当 label 为 1 时,表示存在关系,为 0 时,表示无关系; - -#### 6.2.2 数据预处理类 - -```s -class SimProcessor(DataProcessor): - # 加载 训练数据 - def get_train_examples(self, data_dir): - file_path = os.path.join(data_dir, 'train.csv') - train_df = pd.read_csv(file_path, encoding='utf-8') - train_data = [] - for index, train in enumerate(train_df.values): - guid = 'train-%d' % index - text_a = tokenization.convert_to_unicode(str(train[0])) - text_b = tokenization.convert_to_unicode(str(train[1])) - label = str(train[2]) - train_data.append(InputExample(guid=guid, text_a=text_a, text_b=text_b, label=label)) - random.shuffle(train_data) - return train_data - # 加载 验证数据 - def get_dev_examples(self, data_dir): - file_path = os.path.join(data_dir, 'dev.csv') - dev_df = pd.read_csv(file_path, encoding='utf-8') - dev_data = [] - for index, dev in enumerate(dev_df.values): - guid = 'test-%d' % index - text_a = tokenization.convert_to_unicode(str(dev[0])) - text_b = tokenization.convert_to_unicode(str(dev[1])) - label = str(dev[2]) - dev_data.append(InputExample(guid=guid, text_a=text_a, text_b=text_b, label=label)) - random.shuffle(dev_data) - return dev_data - - def get_test_examples(self, data_dir): - file_path = os.path.join(data_dir, 'test.csv') - test_df = pd.read_csv(file_path, encoding='utf-8') - test_data = [] - for index, test in enumerate(test_df.values): - test_data.append([str(test[0]),str(test[1])]) - return test_data - - def get_sentence_examples(self, questions): - for index, data in enumerate(questions): - guid = 'test-%d' % index - text_a = tokenization.convert_to_unicode(str(data[0])) - text_b = tokenization.convert_to_unicode(str(data[1])) - label = str(0) - yield InputExample(guid=guid, text_a=text_a, text_b=text_b, label=label) - # 获取标签 - def get_labels(self): - return ['0', '1'] -``` - -## 七、基于 Bert 的 文本相似度 模型 - -这部分代码,很多方法都未作修改, 与 [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) 一样, - -```s -class BertSim: - def __init__(self, batch_size=args.batch_size): - self.mode = None - self.max_seq_length = args.max_seq_len - self.tokenizer = tokenization.FullTokenizer(vocab_file=args.vocab_file, do_lower_case=True) - self.batch_size = batch_size - self.estimator = None - self.processor = SimProcessor() - tf.logging.set_verbosity(tf.logging.INFO) - # 选择模式 - def set_mode(self, mode): - self.mode = mode - self.estimator = self.get_estimator() - if mode == tf.estimator.ModeKeys.PREDICT: - self.input_queue = Queue(maxsize=1) - self.output_queue = Queue(maxsize=1) - self.predict_thread = Thread(target=self.predict_from_queue, daemon=True) - self.predict_thread.start() - if mode == "test": - self.input_queue = Queue(maxsize=1) - self.output_queue = Queue(maxsize=1) - self.predict_thread = Thread(target=self.predict_from_queue, daemon=True) - self.predict_thread.start() - # 构建模型 - @staticmethod - def create_model(bert_config, is_training, input_ids, input_mask, segment_ids, - labels, num_labels, use_one_hot_embeddings): - """Creates a classification model.""" - model = modeling.BertModel( - config=bert_config, - is_training=is_training, - input_ids=input_ids, - input_mask=input_mask, - token_type_ids=segment_ids, - use_one_hot_embeddings=use_one_hot_embeddings) - - # In the demo, we are doing a simple classification task on the entire - # segment. - # - # If you want to use the token-level output, use model.get_sequence_output() - # instead. - output_layer = model.get_pooled_output() - - hidden_size = output_layer.shape[-1].value - - output_weights = tf.get_variable( - "output_weights", [num_labels, hidden_size], - initializer=tf.truncated_normal_initializer(stddev=0.02)) - - output_bias = tf.get_variable( - "output_bias", [num_labels], initializer=tf.zeros_initializer()) - - with tf.variable_scope("loss"): - if is_training: - # I.e., 0.1 dropout - output_layer = tf.nn.dropout(output_layer, keep_prob=0.9) - - logits = tf.matmul(output_layer, output_weights, transpose_b=True) - logits = tf.nn.bias_add(logits, output_bias) - probabilities = tf.nn.softmax(logits, axis=-1) - log_probs = tf.nn.log_softmax(logits, axis=-1) - - one_hot_labels = tf.one_hot(labels, depth=num_labels, dtype=tf.float32) - - per_example_loss = -tf.reduce_sum(one_hot_labels * log_probs, axis=-1) - loss = tf.reduce_mean(per_example_loss) - - return (loss, per_example_loss, logits, probabilities) - - def model_fn_builder(self, bert_config, num_labels, init_checkpoint, learning_rate, - num_train_steps, num_warmup_steps, - use_one_hot_embeddings): - """Returns `model_fn` closurimport_tfe for TPUEstimator.""" - - def model_fn(features, labels, mode, params): # pylint: disable=unused-argument - from tensorflow.python.estimator.model_fn import EstimatorSpec - - tf.logging.info("*** Features ***") - for name in sorted(features.keys()): - tf.logging.info(" name = %s, shape = %s" % (name, features[name].shape)) - - input_ids = features["input_ids"] - input_mask = features["input_mask"] - segment_ids = features["segment_ids"] - label_ids = features["label_ids"] - - is_training = (mode == tf.estimator.ModeKeys.TRAIN) - - (total_loss, per_example_loss, logits, probabilities) = BertSim.create_model( - bert_config, is_training, input_ids, input_mask, segment_ids, label_ids, - num_labels, use_one_hot_embeddings) - - tvars = tf.trainable_variables() - initialized_variable_names = {} - - if init_checkpoint: - (assignment_map, initialized_variable_names) \ - = modeling.get_assignment_map_from_checkpoint(tvars, init_checkpoint) - tf.train.init_from_checkpoint(init_checkpoint, assignment_map) - - tf.logging.info("**** Trainable Variables ****") - for var in tvars: - init_string = "" - if var.name in initialized_variable_names: - init_string = ", *INIT_FROM_CKPT*" - tf.logging.info(" name = %s, shape = %s%s", var.name, var.shape, - init_string) - - if mode == tf.estimator.ModeKeys.TRAIN: - - train_op = optimization.create_optimizer( - total_loss, learning_rate, num_train_steps, num_warmup_steps, False) - - output_spec = EstimatorSpec( - mode=mode, - loss=total_loss, - train_op=train_op) - elif mode == tf.estimator.ModeKeys.EVAL: - - def metric_fn(per_example_loss, label_ids, logits): - predictions = tf.argmax(logits, axis=-1, output_type=tf.int32) - accuracy = tf.metrics.accuracy(label_ids, predictions) - auc = tf.metrics.auc(label_ids, predictions) - loss = tf.metrics.mean(per_example_loss) - return { - "eval_accuracy": accuracy, - "eval_auc": auc, - "eval_loss": loss, - } - - eval_metrics = metric_fn(per_example_loss, label_ids, logits) - output_spec = EstimatorSpec( - mode=mode, - loss=total_loss, - eval_metric_ops=eval_metrics) - else: - output_spec = EstimatorSpec(mode=mode, predictions=probabilities) - return output_spec - return model_fn - - def get_estimator(self): - - from tensorflow.python.estimator.estimator import Estimator - from tensorflow.python.estimator.run_config import RunConfig - - bert_config = modeling.BertConfig.from_json_file(args.config_name) - label_list = self.processor.get_labels() - train_examples = self.processor.get_train_examples(args.data_dir) - num_train_steps = int( - len(train_examples) / self.batch_size * args.num_train_epochs) - num_warmup_steps = int(num_train_steps * 0.1) - - if self.mode == tf.estimator.ModeKeys.TRAIN: - init_checkpoint = args.ckpt_name - else: - init_checkpoint = args.output_dir - - model_fn = self.model_fn_builder( - bert_config=bert_config, - num_labels=len(label_list), - init_checkpoint=init_checkpoint, - learning_rate=args.learning_rate, - num_train_steps=num_train_steps, - num_warmup_steps=num_warmup_steps, - use_one_hot_embeddings=False) - - config = tf.ConfigProto() - config.gpu_options.allow_growth = True - config.gpu_options.per_process_gpu_memory_fraction = args.gpu_memory_fraction - config.log_device_placement = False - - return Estimator(model_fn=model_fn, config=RunConfig(session_config=config), model_dir=args.output_dir, - params={'batch_size': self.batch_size}) - - def predict_from_queue(self): - for i in self.estimator.predict(input_fn=self.queue_predict_input_fn, yield_single_examples=False): - self.output_queue.put(i) - - def queue_predict_input_fn(self): - return (tf.data.Dataset.from_generator( - self.generate_from_queue, - output_types={ - 'input_ids': tf.int32, - 'input_mask': tf.int32, - 'segment_ids': tf.int32, - 'label_ids': tf.int32}, - output_shapes={ - 'input_ids': (None, self.max_seq_length), - 'input_mask': (None, self.max_seq_length), - 'segment_ids': (None, self.max_seq_length), - 'label_ids': (1,)}).prefetch(10)) - - def convert_examples_to_features(self, examples, label_list, max_seq_length, tokenizer): - """Convert a set of `InputExample`s to a list of `InputFeatures`.""" - - for (ex_index, example) in enumerate(examples): - label_map = {} - for (i, label) in enumerate(label_list): - label_map[label] = i - - tokens_a = tokenizer.tokenize(example.text_a) - tokens_b = None - if example.text_b: - tokens_b = tokenizer.tokenize(example.text_b) - - if tokens_b: - # Modifies `tokens_a` and `tokens_b` in place so that the total - # length is less than the specified length. - # Account for [CLS], [SEP], [SEP] with "- 3" - self._truncate_seq_pair(tokens_a, tokens_b, max_seq_length - 3) - else: - # Account for [CLS] and [SEP] with "- 2" - if len(tokens_a) > max_seq_length - 2: - tokens_a = tokens_a[0:(max_seq_length - 2)] - - # The convention in BERT is: - # (a) For sequence pairs: - # tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] - # type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 - # (b) For single sequences: - # tokens: [CLS] the dog is hairy . [SEP] - # type_ids: 0 0 0 0 0 0 0 - # - # Where "type_ids" are used to indicate whether this is the first - # sequence or the second sequence. The embedding vectors for `type=0` and - # `type=1` were learned during pre-training and are added to the wordpiece - # embedding vector (and position vector). This is not *strictly* necessary - # since the [SEP] token unambiguously separates the sequences, but it makes - # it easier for the model to learn the concept of sequences. - # - # For classification tasks, the first vector (corresponding to [CLS]) is - # used as as the "sentence vector". Note that this only makes sense because - # the entire model is fine-tuned. - tokens = [] - segment_ids = [] - tokens.append("[CLS]") - segment_ids.append(0) - for token in tokens_a: - tokens.append(token) - segment_ids.append(0) - tokens.append("[SEP]") - segment_ids.append(0) - - if tokens_b: - for token in tokens_b: - tokens.append(token) - segment_ids.append(1) - tokens.append("[SEP]") - segment_ids.append(1) - - input_ids = tokenizer.convert_tokens_to_ids(tokens) - - # The mask has 1 for real tokens and 0 for padding tokens. Only real - # tokens are attended to. - input_mask = [1] * len(input_ids) - - # Zero-pad up to the sequence length. - while len(input_ids) < max_seq_length: - input_ids.append(0) - input_mask.append(0) - segment_ids.append(0) - - assert len(input_ids) == max_seq_length - assert len(input_mask) == max_seq_length - assert len(segment_ids) == max_seq_length - - label_id = label_map[example.label] - if ex_index < 5 and self.mode!="test": - tf.logging.info("*** Example ***") - tf.logging.info("guid: %s" % (example.guid)) - tf.logging.info("tokens: %s" % " ".join( - [tokenization.printable_text(x) for x in tokens])) - tf.logging.info("input_ids: %s" % " ".join([str(x) for x in input_ids])) - tf.logging.info("input_mask: %s" % " ".join([str(x) for x in input_mask])) - tf.logging.info("segment_ids: %s" % " ".join([str(x) for x in segment_ids])) - tf.logging.info("label: %s (id = %d)" % (example.label, label_id)) - - feature = InputFeatures( - input_ids=input_ids, - input_mask=input_mask, - segment_ids=segment_ids, - label_id=label_id) - - yield feature - - def generate_from_queue(self): - while True: - predict_examples = self.processor.get_sentence_examples(self.input_queue.get()) - features = list(self.convert_examples_to_features(predict_examples, self.processor.get_labels(), - args.max_seq_len, self.tokenizer)) - yield { - 'input_ids': [f.input_ids for f in features], - 'input_mask': [f.input_mask for f in features], - 'segment_ids': [f.segment_ids for f in features], - 'label_ids': [f.label_id for f in features] - } - - def _truncate_seq_pair(self, tokens_a, tokens_b, max_length): - """Truncates a sequence pair in place to the maximum length.""" - - # This is a simple heuristic which will always truncate the longer sequence - # one token at a time. This makes more sense than truncating an equal percent - # of tokens from each, since if one sequence is very short then each token - # that's truncated likely contains more information than a longer sequence. - while True: - total_length = len(tokens_a) + len(tokens_b) - if total_length <= max_length: - break - if len(tokens_a) > len(tokens_b): - tokens_a.pop() - else: - tokens_b.pop() - - def convert_single_example(self, ex_index, example, label_list, max_seq_length, tokenizer): - """Converts a single `InputExample` into a single `InputFeatures`.""" - label_map = {} - for (i, label) in enumerate(label_list): - label_map[label] = i - - tokens_a = tokenizer.tokenize(example.text_a) - tokens_b = None - if example.text_b: - tokens_b = tokenizer.tokenize(example.text_b) - - if tokens_b: - # Modifies `tokens_a` and `tokens_b` in place so that the total - # length is less than the specified length. - # Account for [CLS], [SEP], [SEP] with "- 3" - self._truncate_seq_pair(tokens_a, tokens_b, max_seq_length - 3) - else: - # Account for [CLS] and [SEP] with "- 2" - if len(tokens_a) > max_seq_length - 2: - tokens_a = tokens_a[0:(max_seq_length - 2)] - - # The convention in BERT is: - # (a) For sequence pairs: - # tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] - # type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1 - # (b) For single sequences: - # tokens: [CLS] the dog is hairy . [SEP] - # type_ids: 0 0 0 0 0 0 0 - # - # Where "type_ids" are used to indicate whether this is the first - # sequence or the second sequence. The embedding vectors for `type=0` and - # `type=1` were learned during pre-training and are added to the wordpiece - # embedding vector (and position vector). This is not *strictly* necessary - # since the [SEP] token unambiguously separates the sequences, but it makes - # it easier for the model to learn the concept of sequences. - # - # For classification tasks, the first vector (corresponding to [CLS]) is - # used as as the "sentence vector". Note that this only makes sense because - # the entire model is fine-tuned. - tokens = [] - segment_ids = [] - tokens.append("[CLS]") - segment_ids.append(0) - for token in tokens_a: - tokens.append(token) - segment_ids.append(0) - tokens.append("[SEP]") - segment_ids.append(0) - - if tokens_b: - for token in tokens_b: - tokens.append(token) - segment_ids.append(1) - tokens.append("[SEP]") - segment_ids.append(1) - - input_ids = tokenizer.convert_tokens_to_ids(tokens) - - # The mask has 1 for real tokens and 0 for padding tokens. Only real - # tokens are attended to. - input_mask = [1] * len(input_ids) - - # Zero-pad up to the sequence length. - while len(input_ids) < max_seq_length: - input_ids.append(0) - input_mask.append(0) - segment_ids.append(0) - - assert len(input_ids) == max_seq_length - assert len(input_mask) == max_seq_length - assert len(segment_ids) == max_seq_length - - label_id = label_map[example.label] - if ex_index < 5: - tf.logging.info("*** Example ***") - tf.logging.info("guid: %s" % (example.guid)) - tf.logging.info("tokens: %s" % " ".join( - [tokenization.printable_text(x) for x in tokens])) - tf.logging.info("input_ids: %s" % " ".join([str(x) for x in input_ids])) - tf.logging.info("input_mask: %s" % " ".join([str(x) for x in input_mask])) - tf.logging.info("segment_ids: %s" % " ".join([str(x) for x in segment_ids])) - tf.logging.info("label: %s (id = %d)" % (example.label, label_id)) - - feature = InputFeatures( - input_ids=input_ids, - input_mask=input_mask, - segment_ids=segment_ids, - label_id=label_id) - return feature - - def file_based_convert_examples_to_features(self, examples, label_list, max_seq_length, tokenizer, output_file): - """Convert a set of `InputExample`s to a TFRecord file.""" - - writer = tf.python_io.TFRecordWriter(output_file) - - for (ex_index, example) in enumerate(examples): - if ex_index % 10000 == 0: - tf.logging.info("Writing example %d of %d" % (ex_index, len(examples))) - - feature = self.convert_single_example(ex_index, example, label_list, - max_seq_length, tokenizer) - - def create_int_feature(values): - f = tf.train.Feature(int64_list=tf.train.Int64List(value=list(values))) - return f - - features = collections.OrderedDict() - features["input_ids"] = create_int_feature(feature.input_ids) - features["input_mask"] = create_int_feature(feature.input_mask) - features["segment_ids"] = create_int_feature(feature.segment_ids) - features["label_ids"] = create_int_feature([feature.label_id]) - - tf_example = tf.train.Example(features=tf.train.Features(feature=features)) - writer.write(tf_example.SerializeToString()) - - def file_based_input_fn_builder(self, input_file, seq_length, is_training, drop_remainder): - """Creates an `input_fn` closure to be passed to TPUEstimator.""" - - name_to_features = { - "input_ids": tf.FixedLenFeature([seq_length], tf.int64), - "input_mask": tf.FixedLenFeature([seq_length], tf.int64), - "segment_ids": tf.FixedLenFeature([seq_length], tf.int64), - "label_ids": tf.FixedLenFeature([], tf.int64), - } - - def _decode_record(record, name_to_features): - """Decodes a record to a TensorFlow example.""" - example = tf.parse_single_example(record, name_to_features) - - # tf.Example only supports tf.int64, but the TPU only supports tf.int32. - # So cast all int64 to int32. - for name in list(example.keys()): - t = example[name] - if t.dtype == tf.int64: - t = tf.to_int32(t) - example[name] = t - - return example - - def input_fn(params): - """The actual input function.""" - batch_size = params["batch_size"] - - # For training, we want a lot of parallel reading and shuffling. - # For eval, we want no shuffling and parallel reading doesn't matter. - d = tf.data.TFRecordDataset(input_file) - if is_training: - d = d.repeat() - d = d.shuffle(buffer_size=100) - - d = d.apply( - tf.contrib.data.map_and_batch( - lambda record: _decode_record(record, name_to_features), - batch_size=batch_size, - drop_remainder=drop_remainder)) - - return d - - return input_fn - - def train(self): - if self.mode is None: - raise ValueError("Please set the 'mode' parameter") - - bert_config = modeling.BertConfig.from_json_file(args.config_name) - - if args.max_seq_len > bert_config.max_position_embeddings: - raise ValueError( - "Cannot use sequence length %d because the BERT model " - "was only trained up to sequence length %d" % - (args.max_seq_len, bert_config.max_position_embeddings)) - - tf.gfile.MakeDirs(args.output_dir) - - label_list = self.processor.get_labels() - - train_examples = self.processor.get_train_examples(args.data_dir) - num_train_steps = int(len(train_examples) / args.batch_size * args.num_train_epochs) - - estimator = self.get_estimator() - - train_file = os.path.join(args.output_dir, "train.tf_record") - self.file_based_convert_examples_to_features(train_examples, label_list, args.max_seq_len, self.tokenizer, - train_file) - tf.logging.info("***** Running training *****") - tf.logging.info(" Num examples = %d", len(train_examples)) - tf.logging.info(" Batch size = %d", args.batch_size) - tf.logging.info(" Num steps = %d", num_train_steps) - train_input_fn = self.file_based_input_fn_builder(input_file=train_file, seq_length=args.max_seq_len, - is_training=True, - drop_remainder=True) - - # early_stopping = tf.contrib.estimator.stop_if_no_decrease_hook( - # estimator, - # metric_name='loss', - # max_steps_without_decrease=10, - # min_steps=num_train_steps) - - # estimator.train(input_fn=train_input_fn, hooks=[early_stopping]) - estimator.train(input_fn=train_input_fn, max_steps=num_train_steps) - - def eval(self): - if self.mode is None: - raise ValueError("Please set the 'mode' parameter") - eval_examples = self.processor.get_dev_examples(args.data_dir) - eval_file = os.path.join(args.output_dir, "eval.tf_record") - label_list = self.processor.get_labels() - self.file_based_convert_examples_to_features( - eval_examples, label_list, args.max_seq_len, self.tokenizer, eval_file) - - tf.logging.info("***** Running evaluation *****") - tf.logging.info(" Num examples = %d", len(eval_examples)) - tf.logging.info(" Batch size = %d", self.batch_size) - - eval_input_fn = self.file_based_input_fn_builder( - input_file=eval_file, - seq_length=args.max_seq_len, - is_training=False, - drop_remainder=False) - - estimator = self.get_estimator() - result = estimator.evaluate(input_fn=eval_input_fn, steps=None) - - output_eval_file = os.path.join(args.output_dir, "eval_results.txt") - with tf.gfile.GFile(output_eval_file, "w") as writer: - tf.logging.info("***** Eval results *****") - for key in sorted(result.keys()): - tf.logging.info(" %s = %s", key, str(result[key])) - writer.write("%s = %s\n" % (key, str(result[key]))) - - def predict(self, sentence1, sentence2): - if self.mode is None: - raise ValueError("Please set the 'mode' parameter") - self.input_queue.put([(sentence1, sentence2)]) - prediction = self.output_queue.get() - return prediction - - def test(self): - if self.mode is None: - raise ValueError("Please set the 'mode' parameter") - test_examples = self.processor.get_test_examples(args.data_dir) - output_eval_file = os.path.join(args.output_dir, "test_results.txt") - with tf.gfile.GFile(output_eval_file, "w") as writer: - for sentenceItem in test_examples: - self.input_queue.put([(sentenceItem[0], sentenceItem[1])]) - prediction = self.output_queue.get() - writer.write("%s,%s,%s\n" % (sentenceItem[0], sentenceItem[1],prediction[0][1])) -``` - - - -## 八、Bert 相似度 模型 使用 - -- 训练 -```s - sim = BertSim() - sim.set_mode(tf.estimator.ModeKeys.TRAIN) - sim.train() -``` -- 验证 -```s - sim = BertSim() - sim.set_mode(tf.estimator.ModeKeys.EVAL) - sim.eval() -``` -- 测试 -```s - sim = BertSim() - sim.set_mode("test") - sim.test() -``` -- 预测 -```s - sim = BertSim() - sim.set_mode(tf.estimator.ModeKeys.PREDICT) - while True: - sentence1 = input('sentence1: ') - sentence2 = input('sentence2: ') - import time - s = time.time() - predict = sim.predict(sentence1, sentence2) - print(time.time() - s) - print(f'similarity:{predict[0][1]}') -``` - -## 九、总结 - -本章 主要介绍了 利用 Bert 生成 句向量,代码比较简单。 - -1. [【关于 Bert 源码解析 之 主体篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode1_modeling.md) -2. [【关于 Bert 源码解析 之 预训练篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode2_pretraining.md) -3. [【关于 Bert 源码解析 之 微调篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode3_fineTune.md) -4. [【关于 Bert 源码解析IV 之 句向量生成篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode4_word2embedding.md) -5. [【关于 Bert 源码解析V 之 文本相似度篇 】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/bert_study/T1_bert/bertCode5_similarity.md)【本章】 - -分模块 进行解读。 - -## 参考资料 - -1. 【[【关于Bert】 那些的你不知道的事](https://github.com/km1994/nlp_paper_study/tree/master/bert_study/T1_bert)】 -2. [【Bert】论文](https://arxiv.org/abs/1810.04805) -3. [【Bert】源码](https://github.com/google-research/bert/blob/master/) \ No newline at end of file diff --git a/NLPinterview/PreTraining/bert/img/20200528133755.png b/NLPinterview/PreTraining/bert/img/20200528133755.png deleted file mode 100644 index 84f73eb..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200528133755.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200624080740.png b/NLPinterview/PreTraining/bert/img/20200624080740.png deleted file mode 100644 index ceb9a79..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200624080740.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200624084515.png b/NLPinterview/PreTraining/bert/img/20200624084515.png deleted file mode 100644 index 4a76dd4..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200624084515.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200629083749.png b/NLPinterview/PreTraining/bert/img/20200629083749.png deleted file mode 100644 index 20c17cf..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200629083749.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200629084400.png b/NLPinterview/PreTraining/bert/img/20200629084400.png deleted file mode 100644 index ed0194b..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200629084400.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200629085428.png b/NLPinterview/PreTraining/bert/img/20200629085428.png deleted file mode 100644 index dcf8e13..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200629085428.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200629085533.png b/NLPinterview/PreTraining/bert/img/20200629085533.png deleted file mode 100644 index 04abda4..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200629085533.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200629085712.png b/NLPinterview/PreTraining/bert/img/20200629085712.png deleted file mode 100644 index def3a6c..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200629085712.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200629085906.png b/NLPinterview/PreTraining/bert/img/20200629085906.png deleted file mode 100644 index 78b158d..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200629085906.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200629092209.png b/NLPinterview/PreTraining/bert/img/20200629092209.png deleted file mode 100644 index ce443d5..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200629092209.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200629203527.png b/NLPinterview/PreTraining/bert/img/20200629203527.png deleted file mode 100644 index 4937838..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200629203527.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200630084746.png b/NLPinterview/PreTraining/bert/img/20200630084746.png deleted file mode 100644 index 5ed6dc5..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200630084746.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200701082543.png b/NLPinterview/PreTraining/bert/img/20200701082543.png deleted file mode 100644 index adace01..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200701082543.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200701091112.png b/NLPinterview/PreTraining/bert/img/20200701091112.png deleted file mode 100644 index cb79bfd..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200701091112.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200809105640.png b/NLPinterview/PreTraining/bert/img/20200809105640.png deleted file mode 100644 index 070a974..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200809105640.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20200809110034.png b/NLPinterview/PreTraining/bert/img/20200809110034.png deleted file mode 100644 index b6d7e1f..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20200809110034.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20201130205012.png b/NLPinterview/PreTraining/bert/img/20201130205012.png deleted file mode 100644 index 2a3687f..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20201130205012.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20201130205229.png b/NLPinterview/PreTraining/bert/img/20201130205229.png deleted file mode 100644 index 59030ac..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20201130205229.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20201130205325.png b/NLPinterview/PreTraining/bert/img/20201130205325.png deleted file mode 100644 index 827f6ba..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20201130205325.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/20201130205357.png b/NLPinterview/PreTraining/bert/img/20201130205357.png deleted file mode 100644 index d9cf973..0000000 Binary files a/NLPinterview/PreTraining/bert/img/20201130205357.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/Bert.png b/NLPinterview/PreTraining/bert/img/Bert.png deleted file mode 100644 index d6ea4ea..0000000 Binary files a/NLPinterview/PreTraining/bert/img/Bert.png and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/QQ\346\210\252\345\233\27620201226230858.png" "b/NLPinterview/PreTraining/bert/img/QQ\346\210\252\345\233\27620201226230858.png" deleted file mode 100644 index 1a6bf15..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/QQ\346\210\252\345\233\27620201226230858.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/QQ\346\210\252\345\233\27620201226231023.png" "b/NLPinterview/PreTraining/bert/img/QQ\346\210\252\345\233\27620201226231023.png" deleted file mode 100644 index fc6f9de..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/QQ\346\210\252\345\233\27620201226231023.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg b/NLPinterview/PreTraining/bert/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg deleted file mode 100644 index c6d83d3..0000000 Binary files a/NLPinterview/PreTraining/bert/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/img/zg.png b/NLPinterview/PreTraining/bert/img/zg.png deleted file mode 100644 index 16068e1..0000000 Binary files a/NLPinterview/PreTraining/bert/img/zg.png and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" deleted file mode 100644 index bba4c4e..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" deleted file mode 100644 index 0073695..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" deleted file mode 100644 index 680268b..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" deleted file mode 100644 index 88c6211..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" deleted file mode 100644 index 2e542fa..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" deleted file mode 100644 index d4568e1..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120203732.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120203732.png" deleted file mode 100644 index 8a50a1b..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120203732.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120203746.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120203746.png" deleted file mode 100644 index 428628d..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120203746.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204305.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204305.png" deleted file mode 100644 index 09c76af..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204305.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204418.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204418.png" deleted file mode 100644 index 2c72644..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204418.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204506.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204506.png" deleted file mode 100644 index 956a9a4..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120204506.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210194740.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210194740.png" deleted file mode 100644 index 327fbd3..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210194740.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195051.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195051.png" deleted file mode 100644 index 3953413..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195051.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195339.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195339.png" deleted file mode 100644 index a352ab1..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195339.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195755.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195755.png" deleted file mode 100644 index f74f200..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210195755.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200236.png" "b/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200236.png" deleted file mode 100644 index 6c8a2f8..0000000 Binary files "a/NLPinterview/PreTraining/bert/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200236.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/bert/readme.md b/NLPinterview/PreTraining/bert/readme.md deleted file mode 100644 index 978c3eb..0000000 --- a/NLPinterview/PreTraining/bert/readme.md +++ /dev/null @@ -1,253 +0,0 @@ -# 【关于Bert】 那些的你不知道的事 - -> 作者:杨夕 -> -> NLP 论文读书笔记:https://github.com/km1994/nlp_paper_study -> -> 面经:https://github.com/km1994/NLP-Interview-Notes/blob/main/NLPinterview/PreTraining/bert/readme.md -> -> 论文链接:https://arxiv.org/pdf/1810.04805.pdf -> -> 代码链接:https://github.com/google-research/bert -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/bert.png) - -## 一、动机篇 - -### 1.1 【演变史】one-hot 存在问题? - -- 问题: - - 维度灾难:容易受维数灾难的困扰,每个词语的维度就是语料库字典的长度; - - 离散、稀疏问题:因为 one-Hot 中,句子向量,如果词出现则为1,没出现则为0,但是由于维度远大于句子长度,所以句子中的1远小于0的个数; - - 维度鸿沟问题:词语的编码往往是随机的,导致不能很好地刻画词与词之间的相似性。 - -### 1.2【演变史】wordvec 存在问题? - -- 多义词问题 - - 因为 word2vec 为静态方式,即训练好后,每个词表达固定; - -### 1.3【演变史】fastText 存在问题? - -- 多义词问题 - - 因为 word2vec 为静态方式,即训练好后,每个词表达固定; - -### 1.4【演变史】elmo 存在问题? - -- 问题: - - 在做序列编码任务时,使用 LSTM; - - ELMo 采用双向拼接的融合特征,比Bert一体化融合特征方式弱; - -## 二、Bert 篇 - -### 2.1 Bert 介绍篇 - -#### 2.1.1【BERT】Bert 是什么? - -BERT(Bidirectional Encoder Representations from Transformers)是一种T**ransformer的双向编码器**,旨在**通过在左右上下文中共有的条件计算来预先训练来自无标号文本的深度双向表示**。因此,经过预先训练的BERT模型只需一个额外的输出层就可以进行微调,从而为各种自然语言处理任务生成最新模型。 - -这个也是我们常说的 **【预训练】+【微调】** - -#### 2.1.2【BERT】Bert 三个关键点? - -- 基于 transformer 结构 -- 大量语料预训练: - - 介绍:在包含整个维基百科的无标签号文本的大语料库中(足足有25亿字!) 和图书语料库(有8亿字)中进行预训练; - - 优点:大语料 能够 覆盖 更多 的 信息; -- 双向模型: - - BERT是一个“深度双向”的模型。双向意味着BERT在训练阶段从所选文本的左右上下文中汲取信息 - - 举例 - - > BERT同时捕获左右上下文 - - 问题: - - 如果仅取左上下文或右上下文来预测单词“bank”的性质,那么在两个给定示例中,至少有一个会出错; - - 解决方法: - - 在做出预测之前同时考虑左上下文和右上下文 - -![](img/20200630084746.png) - -### 2.2 Bert 输入输出表征篇 - -#### 2.2.1 【BERT】Bert 输入输出表征长啥样? - -- input 组成: - - Token embedding 字向量: BERT模型通过查询字向量表将文本中的每个字转换为一维向量,作为模型输入; - - Segment embedding 文本向量: 该向量的取值在模型训练过程中自动学习,用于刻画文本的全局语义信息,并与单字/词的语义信息相融合; - - Position embedding 位置向量:由于出现在文本不同位置的字/词所携带的语义信息存在差异(比如:“我爱你”和“你爱我”),因此,BERT模型对不同位置的字/词分别附加一个不同的向量以作区分 -- output 组成:输入各字对应的融合全文语义信息后的向量表示 - -![](img/20200701082543.png) - -- 特点: - - 在30000个词上使用了WordPiece嵌入,把拆分的词片段(word pieces)用"##"标注; - - eg:在图中"playing"-"play ##ing"; - - 最大长度:使用了学习过的位置嵌入,支持序列长度达512的 Token; - - 特殊分类嵌入([CLS]):位于句首,在最终的隐藏层中(也就是转换器的输出)对应的是分类任务中序列标识的**聚合表征**。非分类任务中这一标记将被忽略; - - 区分句子对在 序列 中位置的方式: - - s1:用特殊词块([SEP])将它们分开; - - s2:给第一句的每一个标记添加一个学习到的句子 A 的嵌入,给第二句的每个标记添加一个学习到的句子 B 的嵌入; - - 对于单句输入,我们只使用句子A嵌入 - -### 2.3 【BERT】Bert 预训练篇 - -#### 2.3.1 【BERT】Bert 预训练任务介绍 - -- 预训练 包含 两个 Task: - - Task 1:Masked LM - - Task 2:Next Sentence Prediction - -#### 2.3.2 【BERT】Bert 预训练任务 之 Masked LM 篇 - -##### 2.3.2.1 【BERT】 Bert 为什么需要预训练任务 Masked LM ? - -- 普通的自注意力模块允许一个位置看到它左右侧单词的信息,使得 每个词 都能 通过多层 上下文 “看到自己”; - -##### 2.3.2.2 【BERT】 Bert 预训练任务 Masked LM 怎么做? - -- 做法: - - s1:随机遮蔽输入词块的某些部分; - - s2:仅预测那些被遮蔽词块; - - s3:被遮盖的标记对应的最终的隐藏向量被当作softmax的关于该词的一个输出,和其他标准语言模型中相同 - -##### 2.3.2.3 【BERT】 Bert 预训练任务 Masked LM 存在问题? - -- 预训练和微调之间的不匹配: - - 解释:在微调期间从未看到[MASK]词块 -- 收敛速度慢问题: - - 原因:每 batch 中只预测了15%的词块,导致 收敛速度慢 - -##### 2.3.2.4 【BERT】 预训练和微调之间的不匹配的解决方法? - - - 以一定概率用 [MASK] 词块替换“遮蔽”单词,论文采用 15% 的概率 随机选择 词块 - - 举例: - - 句子:我的狗是毛茸茸的 - - 操作: - - 80%的概率:用[MASK]词块替换单词,例如,我的狗是毛茸茸的!我的狗是[MASK]; - - 10%的概率:用随机词替换遮蔽词,例如,我的狗是毛茸茸的!我的狗是苹果; - - 10%的概率:保持单词不变,例如,我的狗是毛茸茸的!我的狗毛茸茸的。 - - 目的:是将该表征偏向于实际观察到的单词 - - 目的:模型需要学习每个输入词块的分布式语境表征 - -#### 2.3.3 【BERT】Bert 预训练任务 之 Next Sentence Prediction 篇 - -##### 2.3.3.1 【BERT】Bert 为什么需要预训练任务 Next Sentence Prediction ? - -- 动机:很多重要的下游任务,例如问答(QA)和自然语言推理(NLI),都是基于对两个文本句子间关系的理解,而这种关系并非通过语言建模直接获得 - -##### 2.3.3.2 【BERT】 Bert 预训练任务 Next Sentence Prediction 怎么做? - -- 方法: - - 预训练 一个 二值化 NSP 任务 学习 句子间关系; -- 操作: - - 选择句子A和B作为预训练样本:B有50%的可能是A的下一句,也有50%的可能是来自语料库的随机句子 - - 举例: - -> 输入=[CLS]男子去[MASK]商店[SEP]他买了一加仑[MASK]牛奶[SEP]
-> Label= IsNext
-> 输入=[CLS]男人[面具]到商店[SEP]企鹅[面具]是飞行##少鸟[SEP]
-> Label= NotNext
- -### 2.4 【BERT】 fine-turning 篇? - -#### 2.4.1 【BERT】为什么 Bert 需要 fine-turning? - -- 动机:获得输入序列的固定维度池化表征 - -#### 2.4.2 【BERT】 Bert 如何 fine-turning? - -- 对该输入第一个词块采取最终隐藏状态(例如,该变换器输出),通过对应于特殊[CLS]词嵌入来构造。我们将该向量表示为$C∈R^H$。 -- 微调期间添加的唯一新参数是分类层向量$W∈R^{KxH}$,其中K是分类器标签的数量。 -- 该标签概率$P∈R^K$用标准softmax函数,P=softmax(CWT)计算。BERT和W的所有参数都经过联动地微调,以最大化正确标签的对数概率 - -### 2.5 【BERT】 Bert 损失函数篇? - -#### 2.5.1 【BERT】BERT的两个预训练任务对应的损失函数是什么(用公式形式展示)? - -- Bert 损失函数组成: - - 第一部分是来自 Mask-LM 的单词级别分类任务; - - 另一部分是句子级别的分类任务; -- 优点:通过这两个任务的联合学习,可以使得 BERT 学习到的表征既有 token 级别信息,同时也包含了句子级别的语义信息。 -- 损失函数 - -![](img/20201130205012.png) - -> 注:
-> θ:BERT 中 Encoder 部分的参数;
-> θ1:是 Mask-LM 任务中在 Encoder 上所接的输出层中的参数;
-> θ2:是句子预测任务中在 Encoder 接上的分类器参数;
- -- 在第一部分的损失函数中,如果被 mask 的词集合为 M,因为它是一个词典大小 |V| 上的多分类问题,所用的损失函数叫做负对数似然函数(且是最小化,等价于最大化对数似然函数),那么具体说来有: - -![](img/20201130205229.png) - -- 在第二部分的损失函数中,在句子预测任务中,也是一个分类问题的损失函数: - -![](img/20201130205325.png) - -- 两个任务联合学习的损失函数是: - -![](img/20201130205357.png) - -## 三、 对比篇? - -### 3.1 【对比】多义词问题是什么? - -- 问题:什么是多义词? - - 一个单词在不同场景下意思不同 - - 举例: - - 单词 Bank,有“银行”、“河岸”两个含义 - -### 3.2 【对比】word2vec 为什么解决不了多义词问题? - -- 由于 word2vec 采用静态方式, - - 第一阶段:训练结束后,每个单词 只对应 一个固定的词向量; - - 第二阶段:在使用时, 该词向量 不会 根据上下文场景 而变化 -- 因此 word2vec 解决不了 多义词 问题 - -### 3.3 【对比】GPT和BERT有什么不同? - -![](img/QQ截图20201226230858.png) - -- 模块选择: - - GPT-2 是使用「transformer 解码器模块」构建的 - - BERT 则是通过「transformer 编码器」模块构建的。 - -![](img/微信截图_20210120203746.png) -> Transformer 编码层 - -![](img/微信截图_20210120203732.png) -> Transformer 解码层 - -- 方向性: - - GPT是单向的:然后体现? 解码层 有一个 Masked Self-Attention 层,它将后面的单词掩盖掉了。但并不像 BERT 一样将它们替换成特殊定义的单词,而是在自注意力计算的时候屏蔽了来自当前计算位置右边所有单词的信息。 - - Bert 是双向的; - -![](img/微信截图_20210120204418.png) -> GPT是单向的体现:如果我们重点关注位置单词及其前续路径,模型只允许注意当前计算的单词以及之前的单词: - -![](img/微信截图_20210120204506.png) -> Bert是双向的体现:Bert的自注意力模块允许一个位置看到它左右侧单词的信息,为了 避免 当前位置经过多层之后看到自己,所以 引入了 [MLP 任务](#232-bertbert-预训练任务-之-masked-lm-篇)【见上面介绍】; - - -- 机制: - - GPT-2 自回归(auto-regression):效果好因为是在每个新单词产生后,该单词就被添加在之前生成的单词序列后面,这个序列会成为模型下一步的新输入 - - Bert 自编码(auto-encoder):获得了结合单词前后的上下文信息的能力,从而取得了更好的效果 -- BERT在训练中加入了下一个句子预测任务,所以它也有 segment嵌入; - -![](img/QQ截图20201226231023.png) - -### 3.4 【对比】为什么 elmo、GPT、Bert能够解决多义词问题?(以 elmo 为例) - -- elmo 的 解决方式: - - 预训练时,使用语言模型学习一个单词的emb(**多义词无法解决**); - - 使用时,单词间具有特定上下文,可根据上下文单词语义调整单词的emb表示(**可解决多义词问题**) - - 理解:因为预训练过程中,**emlo 中 的 lstm 能够学习到 每个词 对应的 上下文信息**,并保存在网络中,在 fine-turning 时,**下游任务 能够对 该 网络进行 fine-turning,使其 学习到新特征**; - - 因此 elmo能够解决 多义词 问题(GPT、Bert 采用 的 是 transformer) - -## 参考 - -1. [CS224n](http://web.stanford.edu/class/cs224n/index.html) -2. [关于BERT的若干问题整理记录](https://zhuanlan.zhihu.com/p/95594311) -3. [完全图解GPT-2:看完这篇就够了(一)](https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=2247522366&idx=4&sn=7d49958abf158875bb8ceab2ed688437&chksm=ebb7a0eadcc029fc77ad3f3a3edbc8545d6b91da4955d86d6a8389a91bf100ad82fb7b3f1847&mpshare=1&scene=22&srcid=0120jmuqnbHH6yG3kNqlZKZ4&sharer_sharetime=1611116751597&sharer_shareid=da84f0d2d31380d783922b9e26cacfe2#rd) -4. [完全图解GPT-2:看完这篇就够了(二)](https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=2247522366&idx=5&sn=53ca90dfb791e8b1bbf22710b6e675b4&chksm=ebb7a0eadcc029fc3688aae44af144e8d8fa7a80cd7f4ad387a4b317d6939017e2829b68719f&mpshare=1&scene=22&srcid=0120zi6UD58buvsh3QUhyUla&sharer_sharetime=1611116758797&sharer_shareid=da84f0d2d31380d783922b9e26cacfe2#rd) - diff --git a/NLPinterview/PreTraining/bert_big/img/20201015170627.png b/NLPinterview/PreTraining/bert_big/img/20201015170627.png deleted file mode 100644 index 7baa5bd..0000000 Binary files a/NLPinterview/PreTraining/bert_big/img/20201015170627.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_big/img/20201026153603.png b/NLPinterview/PreTraining/bert_big/img/20201026153603.png deleted file mode 100644 index 9c041cf..0000000 Binary files a/NLPinterview/PreTraining/bert_big/img/20201026153603.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_big/img/20201026153725.png b/NLPinterview/PreTraining/bert_big/img/20201026153725.png deleted file mode 100644 index 8e6ea9d..0000000 Binary files a/NLPinterview/PreTraining/bert_big/img/20201026153725.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_big/img/20201026154010.png b/NLPinterview/PreTraining/bert_big/img/20201026154010.png deleted file mode 100644 index 8ecd314..0000000 Binary files a/NLPinterview/PreTraining/bert_big/img/20201026154010.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_big/img/20201026154623.png b/NLPinterview/PreTraining/bert_big/img/20201026154623.png deleted file mode 100644 index 503c6b0..0000000 Binary files a/NLPinterview/PreTraining/bert_big/img/20201026154623.png and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120211554.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120211554.png" deleted file mode 100644 index c118ecd..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120211554.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120211800.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120211800.png" deleted file mode 100644 index 9878db0..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120211800.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120212518.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120212518.png" deleted file mode 100644 index c28608d..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120212518.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120213008.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120213008.png" deleted file mode 100644 index 679e6f6..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210120213008.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206164501.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206164501.png" deleted file mode 100644 index 50456d2..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206164501.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210808214524.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210808214524.png" deleted file mode 100644 index 721147d..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210808214524.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210322.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210322.png" deleted file mode 100644 index 79c7d75..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210322.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210729.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210729.png" deleted file mode 100644 index 533508b..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210729.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210907.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210907.png" deleted file mode 100644 index 0b51776..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910210907.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910211607.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910211607.png" deleted file mode 100644 index 2dcc65a..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910211607.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212046.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212046.png" deleted file mode 100644 index 7fa03fa..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212046.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212205.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212205.png" deleted file mode 100644 index 13e7d66..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212205.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212307.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212307.png" deleted file mode 100644 index f0630d1..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910212307.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213336.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213336.png" deleted file mode 100644 index 8eee64c..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213336.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213420.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213420.png" deleted file mode 100644 index 334ffe4..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213420.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213837.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213837.png" deleted file mode 100644 index 64ee3a6..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210910213837.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220121111042.png" "b/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220121111042.png" deleted file mode 100644 index 9b4237d..0000000 Binary files "a/NLPinterview/PreTraining/bert_big/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220121111042.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_big/readme.md b/NLPinterview/PreTraining/bert_big/readme.md deleted file mode 100644 index f00b0ca..0000000 --- a/NLPinterview/PreTraining/bert_big/readme.md +++ /dev/null @@ -1,666 +0,0 @@ -# 【关于 Bert 越大越精序列 】那些的你不知道的事 - -> 作者:杨夕 -> -> 介绍:本项目是作者们根据个人面试和经验总结出的搜索引擎(search engine) 面试准备的学习笔记与资料,该资料目前包含 搜索引擎各领域的 面试题积累。 -> -> NLP 百面百搭 地址:https://github.com/km1994/NLP-Interview-Notes -> -> 推荐系统 百面百搭 地址:https://github.com/km1994/RES-Interview-Notes -> -> **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** -> -> 搜索引擎 百面百搭 地址:https://github.com/km1994/search-engine-Interview-Notes 【编写ing】 -> -> NLP论文学习笔记:https://github.com/km1994/nlp_paper_study -> -> 推荐系统论文学习笔记:https://github.com/km1994/RS_paper_study -> -> GCN 论文学习笔记:https://github.com/km1994/GCN_study -> -> 关注公众号 **【关于NLP那些你不知道的事】** 加入 【NLP && 推荐学习群】一起学习!!! - -> 注:github 网页版 看起来不舒服,可以看 **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** - -## 目录 - -- [【关于 Bert 越大越精序列 】那些的你不知道的事](#关于-bert-越大越精序列-那些的你不知道的事) - - [目录](#目录) - - [总结](#总结) - - [一、Bert](#一bert) - - [1.1 【BERT】介绍](#11-bert介绍) - - [1.2 【BERT】Bert 预训练任务?](#12-bertbert-预训练任务) - - [1.2.1 【BERT】任务介绍](#121-bert任务介绍) - - [1.2.2 【MLM】Bert 预训练任务 Masked LM 怎么做?](#122-mlmbert-预训练任务-masked-lm-怎么做) - - [1.2.2.1【MLM】动机](#1221mlm动机) - - [1.2.2.2【MLM】做法](#1222mlm做法) - - [1.2.3【NSP】Bert 预训练任务 Next Sentence Prediction 怎么做?](#123nspbert-预训练任务-next-sentence-prediction-怎么做) - - [1.2.3.1 【NSP】动机](#1231-nsp动机) - - [1.2.3.2 【NSP】方法](#1232-nsp方法) - - [1.2.3.3【NSP】操作](#1233nsp操作) - - [1.3 【Bert】问题](#13-bert问题) - - [1.3.1 【Bert】问题 1:预训练和微调之间的不匹配](#131-bert问题-1预训练和微调之间的不匹配) - - [1.3.2 【Bert】问题2:收敛速度慢问题](#132-bert问题2收敛速度慢问题) - - [二、XLNet](#二xlnet) - - [2.1 【XLNet】 介绍](#21-xlnet-介绍) - - [2.2 【XLNet】动机](#22-xlnet动机) - - [2.3 【XLNet】AR vs AE](#23-xlnetar-vs-ae) - - [2.4 【XLNet】 预训练](#24-xlnet-预训练) - - [2.4.1 【XLNet】Permutation Language Modeling](#241-xlnetpermutation-language-modeling) - - [2.4.2 【XLNet】 Two-Stream Self-Attention for Target-Aware Representations](#242-xlnet-two-stream-self-attention-for-target-aware-representations) - - [2.4.2.1 介绍](#2421-介绍) - - [2.4.2.2 计算两个self-attention](#2422-计算两个self-attention) - - [2.4.2.3 Transformer-XL](#2423-transformer-xl) - - [三、RoBERTa](#三roberta) - - [3.1 【RoBERTa】动机](#31-roberta动机) - - [3.2 【RoBERTa】工作](#32-roberta工作) - - [3.3 【RoBERTa】预训练](#33-roberta预训练) - - [3.3.1 动态掩码](#331-动态掩码) - - [3.3.2 去掉NSP任务](#332-去掉nsp任务) - - [3.3.3 更大的数据量](#333-更大的数据量) - - [3.3.4 更大的batch_size](#334-更大的batch_size) - - [3.3.5 Byte-level BPE编码](#335-byte-level-bpe编码) - - [四、ELECTRA](#四electra) - - [4.1 【ELECTRA】动机](#41-electra动机) - - [4.2 【ELECTRA】介绍](#42-electra介绍) - - [4.3 【ELECTRA】核心任务](#43-electra核心任务) - - [4.4 【ELECTRA】判别器 & 生成器](#44-electra判别器--生成器) - - [4.5 【ELECTRA】算法流程](#45-electra算法流程) - - [五、ERNIE 1.0](#五ernie-10) - - [5.1 【ERNIE 1.0】动机](#51-ernie-10动机) - - [5.2 【ERNIE 1.0】预训练](#52-ernie-10预训练) - - [5.2.1 Knowledge Integration](#521-knowledge-integration) - - [5.2.2 Dialogue Language Model(DLM)](#522-dialogue-language-modeldlm) - - [六、ERNIE 2.0](#六ernie-20) - - [6.1 【ERNIE 2.0】动机](#61-ernie-20动机) - - [6.2 【ERNIE 2.0】架构](#62-ernie-20架构) - - [6.3 【ERNIE 2.0】预训练](#63-ernie-20预训练) - - [6.3.1 预训练连续学习](#631-预训练连续学习) - - [6.3.2 更多的无监督预训练任务](#632-更多的无监督预训练任务) - - [七、ERNIE-T](#七ernie-t) - - [7.1 【ERNIE-T】动机](#71-ernie-t动机) - - [7.2 【ERNIE-T】架构](#72-ernie-t架构) - - [7.3 【ERNIE-T】预训练](#73-ernie-t预训练) - - [7.3.1 引入知识图谱](#731-引入知识图谱) - - [7.3.2 异构信息融合](#732-异构信息融合) - - [7.3.3 dAE](#733-dae) - - [八、ChineseBERT](#八chinesebert) - - [8.1 【ChineseBERT】动机](#81-chinesebert动机) - - [8.2 【ChineseBERT】方法介绍](#82-chinesebert方法介绍) - - [8.2.1 模型整体架构介绍](#821-模型整体架构介绍) - - [8.2.2 模型改进点介绍](#822-模型改进点介绍) - - [8.3 【ChineseBERT】预训练](#83-chinesebert预训练) - - [九、SpanBERT](#九spanbert) - - [9.1 【SpanBERT】动机](#91-spanbert动机) - - [9.2 【SpanBERT】预训练](#92-spanbert预训练) - - [9.3 【SpanBERT】微调](#93-spanbert微调) - - [9.4 【SpanBERT】效果](#94-spanbert效果) - - [十、MacBERT](#十macbert) - - [10.1 【MacBERT】动机](#101-macbert动机) - - [10.2 【MacBERT】预训练](#102-macbert预训练) - - [10.2.1 MLM](#1021-mlm) - - [10.2.2 NSP](#1022-nsp) - - [10.3 【MacBERT】微调](#103-macbert微调) - - [10.4 【MacBERT】效果](#104-macbert效果) - - [参考](#参考) - -## 总结 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称介绍动机预训练方法微调问题
BertTransformer的双向编码器多义词问题 && GPT 单向 TransformerTask 1:Masked LM && Task 2:Next Sentence Prediction直接利用 特定任务数据 微调1. [MASK]预训练和微调之间的不匹配
2. Max Len 为 512
XLNet广义自回归预训练方法1. Bert 预训练和微调之间的不匹配
2. Bert 的 Max Len 为 512
(1) Permutation Language Modeling【解决Bert 预训练和微调之间的不匹配】
(2)Two-Stream Self-Attention for Target-Aware Representations【解决PLM出现的目标预测歧义】
(3)XLNet将最先进的自回归模型Transformer-XL的思想整合到预训练中【解决 Bert 的 Max Len 为 512】
直接利用 特定任务数据 微调问题
RoBERTaA Robustly Optimized BERT Pretraining Approach 1. 确定方法的哪些方面贡献最大可能是具有挑战性的
2. 训练在计算上是昂贵的的,限制了可能完成的调整量
1. 去掉下一句预测(NSP)任务
2. 动态掩码
3. 文本编码
4. 更大的数据量
5. 更大的batch_size
直接利用 特定任务数据 微调问题
ELECTRA判别器 & 生成器1. 只有15%的输入上是会有loss利用一个基于MLM的Generator来替换example中的某些个token,然后丢给Discriminator来判别直接利用 特定任务数据 微调问题
ERNIE 1.0ERNIE: Enhanced Representation through Knowledge Integration随机【MASK】会让模型不能充分学习到语义信息1. Knowledge Integration
2. Dialogue Language Model(DLM)
--问题
ERNIE 2.0ERNIE 2.0: A Continual Pre-Training Framework for Language Understanding之前的工作主要**通过词或句子的共现信号,构建语言模型任务进行模型预训练**。**除了语言共现信息之外,语料中还包含词法、语法、语义等更多有价值的信息**。1. 预训练连续学习
2. 更多的无监督预训练任务
--问题
ERNIE-TERNIE: Enhanced Language Representation with Informative Entities引入外部图谱1. 引入知识图谱
2. 异构信息融合
2. dAE
--问题
ChineseBERTChineseBERT: Chinese Pretraining Enhanced by Glyph and Pinyin Information引入 字形 和 拼音1. Masking 操作
2. Packed Input 与 Single Input 之间交替训练
----
SpanBERTSpanBERT: Improving Pre-training by Representing and Predicting Spans旨在更好地表示和预测文本的 span1. Span Mask
2. Span Boundary Objective (SBO)
训练目标 Single-Sequence Training
----
MacBERTRevisiting Pre-trained Models for Chinese Natural Language Processing为了解决与训练阶段和微调阶段存在的差异性1. 使用Whole Word Masking、N-gram Masking
2. 使用相似的word进行替换[MASK]
3. 采用ALBERT提出的SOP替换NSP
----
- - -## 一、Bert - -> 论文名称:《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》
-> 论文:https://arxiv.org/pdf/1810.04805.pdf
-> 代码:https://github.com/google-research/bert
- -### 1.1 【BERT】介绍 - -BERT(Bidirectional Encoder Representations from Transformers)是一种Transformer的双向编码器,旨在通过在左右上下文中共有的条件计算来预先训练来自无标号文本的深度双向表示。因此,经过预先训练的BERT模型只需一个额外的输出层就可以进行微调,从而为各种自然语言处理任务生成最新模型。 - -### 1.2 【BERT】Bert 预训练任务? - -#### 1.2.1 【BERT】任务介绍 - -- 预训练 包含 两个 Task: - - Task 1:Masked LM - - Task 2:Next Sentence Prediction - -#### 1.2.2 【MLM】Bert 预训练任务 Masked LM 怎么做? - -##### 1.2.2.1【MLM】动机 -- 双向模型 由于 可以分别 从左到右 和 从右到左 训练,使得 每个词 都能 通过多层 上下文 “看到自己”; - -##### 1.2.2.2【MLM】做法 -- s1:随机遮蔽输入词块的某些部分; -- s2:仅预测那些被遮蔽词块; -- s3:被遮盖的标记对应的最终的隐藏向量被当作softmax的关于该词的一个输出,和其他标准语言模型中相同 - -#### 1.2.3【NSP】Bert 预训练任务 Next Sentence Prediction 怎么做? - -##### 1.2.3.1 【NSP】动机 - -很多重要的下游任务,例如问答(QA)和自然语言推理(NLI),都是基于对两个文本句子间关系的理解,而这种关系并非通过语言建模直接获得 - -##### 1.2.3.2 【NSP】方法 - -预训练 一个 二值化 NSP 任务 学习 句子间关系; - -##### 1.2.3.3【NSP】操作 -- 选择句子A和B作为预训练样本:B有50%的可能是A的下一句,也有50%的可能是来自语料库的随机句子 -> 举例:
-> - 输入=[CLS]男子去[MASK]商店[SEP]他买了一加仑[MASK]牛奶[SEP]
-> - Label= IsNext
-> - 输入=[CLS]男人[面具]到商店[SEP]企鹅[面具]是飞行##少鸟[SEP]
-> - Label= NotNext
- -### 1.3 【Bert】问题 - -#### 1.3.1 【Bert】问题 1:预训练和微调之间的不匹配 -1. 解释:在微调期间从未看到[MASK]词块 -2. 解决方法: -- 以一定概率用 [MASK] 词块替换“遮蔽”单词,论文采用 15% 的概率 随机选择 词块 -- 目的:模型需要学习每个输入词块的分布式语境表征 -- 举例: - -> 句子:我的狗是毛茸茸的
-> 操作:
-> - 80%的概率:用[MASK]词块替换单词,例如,我的狗是毛茸茸的!我的狗是[MASK];
-> - 10%的概率:用随机词替换遮蔽词,例如,我的狗是毛茸茸的!我的狗是苹果;
-> - 10%的概率:保持单词不变,例如,我的狗是毛茸茸的!我的狗毛茸茸的。【目的:是将该表征偏向于实际观察到的单词】
- -#### 1.3.2 【Bert】问题2:收敛速度慢问题 -1. 原因:每 batch 中只预测了15%的词块,导致 收敛速度慢 - -## 二、XLNet - -> 论文名称:《XLNet: Generalized Autoregressive Pretraining for Language Understanding》
-> 论文:https://arxiv.org/abs/1906.08237
-> 代码:https://github.com/zihangdai/xlnet
- -### 2.1 【XLNet】 介绍 - -本文结合AR LM和AE LM,在Transformer-XL的基础上提出generalized autoregressive method,XLNet。 - -- 所有的分解序列作为一个集合,从中采样一个序列,XLNet按照AR LM的计算方式最大化有关序列所有可能的因式分解的排列的对数似然函数的期望。通常,当前token的上文包含left和right的tokens:比如原始序列为1-2-3-4,分解序列中采样一个为2-4-1-3,那么如果当前token为3,XLNet的方式就可以看到所有的信息,当然这也是理想情况。 -- 引入Transformer-XL的segment recurrence mechanism和relative encoding scheme。 -- 引入Masked Two-Stream Self-Attention解决PLM出现的目标预测歧义【the ambiguity in target prediction】问题。举个例子,比如分解序列中采样一个为2-4-6-1-3-5的序列,假设要预测[1]的token,按照经典的Transformer来计算next-token的概率分布,位置[1]token的概率就是通过[2,4,6]位置上的tokens来计算softmax,不会把[1]作为输入来计算的。但是如果以这种方式去预测next-token,这对[3,5]的预测就会产生影响,因为如果[1]的预测出现错误会把错误传给后面。对后面每一个token的预测,需要建立在之前token都已知的条件下。因此本文计算了两个self-attention计算方式,一个mask当前词,attention值记为$g$;一个已知当前词,attention值记为$h$。最后假设self-attention一共有$M$层,用第$M$层、$t$时刻的$g_t$,去预测词$x_t$。 - -### 2.2 【XLNet】动机 - -1. Bert 预训练和微调之间的不匹配 -2. Bert 的 Max Len 为 512 - -### 2.3 【XLNet】AR vs AE - -文章从AR(autoregressive,自回归)和AE(autoencoding,自编码)的角度出发,解释论文动机。 - -AR LM,即自回归语言模型。具体而言,给定一个序列,当前token时刻只知道前面的信息,而不知道后面的信息,即使分成正向和反向计算当前token时刻的概率分布,也是同样的原则,ELMo、GPT是属于这个范畴。对于一些自然语言理解任务而言,是给定上下文的,即使ELMo把两个的方向计算的信息concat,但也是独立计算,对上下文的编码是有缺陷的。 - -AE LM,即自编码语言模型。BERT通过预测原始数据里MASK掉的token来预训练语言模型,预测[MASK]使用了上下文信息,弥补了AR LM的缺陷。但是[MASK]只在预训练的时候用到,finetune的时候是不用的,这使得pretrain/train不一致。并且,BERT假定每个[MASK]与其他[MASK]是相互独立的,不能计算序列、长期依赖的联合概率。即使BERT的NSP预训练任务一定程度上给了模型建模句间关系的能力,但是还是对长文本不敏感。 - -### 2.4 【XLNet】 预训练 - -#### 2.4.1 【XLNet】Permutation Language Modeling - -首先代码会根据输入序列的长度采样一个排列,然后用Transformer中attention mask的方式实现排列,如果原始序列长度为T,那么理论上一共有T的阶乘种情况。PLM的目标函数就是所有排列情况(论文里设定:统共T种)的期望最大: - -![](img/20201026153603.png) - -这样pretrain和finetune阶段就一样了,输入都是原始序列,通过attention mask实现随机产生的排列。下图是排列语言模型的表现形式: - -![](img/20201026153725.png) - -> 注:假设要预测t=3的词,按照不同的排列顺序,h_3的上文都不一样,用attention-mask的方式得到t=3的上文。 - -#### 2.4.2 【XLNet】 Two-Stream Self-Attention for Target-Aware Representations - -##### 2.4.2.1 介绍 - -上面是构造输入,这里就是自回归地得到每一时刻的概率分布,示意图如下: - -![](img/20201026154010.png) - -##### 2.4.2.2 计算两个self-attention - -- (a) 代表context stream self-attention,以[1,t]时刻的词作为K、V,t时刻的词作为Q计算当前词的信息,把排列之后的原始序列信息用h记忆起来。 -- (b) 代表query stream self-attention,mask掉当前词,以[1,t-1]时刻的词作为K、V,t时刻的词作为Q预测当前词,得到概率分布。 -- (c) 代表通过多层的masked two-stream attention,最后用t时刻的$g_t$来预测x_t。 - -![](img/20201026154623.png) - -##### 2.4.2.3 Transformer-XL - -确定好目标函数之后,框架确定为Transformer-XL自回归语言模型。特点是relative positional encoding scheme和segment recurrence mechanism,更好地处理长文本,提升计算效率。具体不介绍了,详见参考文献[2]。 - -## 三、RoBERTa - -> 论文名称:《RoBERTa: A Robustly Optimized BERT Pretraining Approach》
-> 论文:https://arxiv.org/pdf/1907.11692.pdf
-> 代码:https://github.com/pytorch/fairseq
- -### 3.1 【RoBERTa】动机 - -- Bert 序列模型的问题 -> 确定方法的哪些方面贡献最大可能是具有挑战性的; -> -> 训练在计算上是昂贵的的,限制了可能完成的调整量 - -### 3.2 【RoBERTa】工作 - -- 更大的模型参数量(论文提供的训练时间来看,模型使用 1024 块 V100 GPU 训练了 1 天的时间) -- 更大bacth size。RoBERTa 在训练过程中使用了更大的bacth size。尝试过从 256 到 8000 不等的bacth size。 -- 更多的训练数据(包括:CC-NEWS 等在内的 160GB 纯文本。而最初的BERT使用16GB BookCorpus数据集和英语维基百科进行训练) -另外,RoBERTa在训练方法上有以下改进: - -### 3.3 【RoBERTa】预训练 - -#### 3.3.1 动态掩码 - -- 动态掩码。BERT 依赖随机掩码和预测 token。原版的 BERT 实现在数据预处理期间执行一次掩码,得到一个静态掩码。 而 RoBERTa 使用了动态掩码:每次向模型输入一个序列时都会生成新的掩码模式。这样,在大量数据不断输入的过程中,模型会逐渐适应不同的掩码策略,学习不同的语言表征。 - -#### 3.3.2 去掉NSP任务 - -- 动机:虽然是句子对输入,但其实一个句子不只有一句,而是文章里面的连续片段,可以包含多句。 -- 操作:采用去掉NSP而且一个样本是从同一个文档里面进行采样 - -#### 3.3.3 更大的数据量 - -在BERT采用的数据BOOKCORPUS + English WIKIPEDIA(共16G)基础上 - -- 增加 CC-NEWS(76GB) -- 增加 OPENWEBTEXT(38GB) -- 增加 STORIES(31GB) - -也就是RoBERTa一共用了160GB语料进行预训练。 - -#### 3.3.4 更大的batch_size - -BERT的batch_size是256,一共训练了1M步,实验证明,采用更大的batch_size以及训练更多步,可以提高性能。最后RoBERTa采用的batch_size是8K。 - -#### 3.3.5 Byte-level BPE编码 - -- BERT:采用的是基于character level的Byte-Pair Encoding(BPE)编码,词表大小是30K; -- RoBERTa:文本编码。Byte-Pair Encoding(BPE)是字符级和词级别表征的混合,支持处理自然语言语料库中的众多常见词汇。原版的 BERT 实现使用字符级别的 BPE 词汇,大小为 30K,是在利用启发式分词规则对输入进行预处理之后学得的。Facebook 研究者没有采用这种方式,而是考虑用更大的 byte 级别 BPE 词汇表来训练 BERT,这一词汇表包含 50K 的 subword 单元,且没有对输入作任何额外的预处理或分词。 - -## 四、ELECTRA - -> 论文名称:《ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generator》
-> 论文:https://arxiv.org/abs/2003.10555
-> 代码:https://github.com/google-research/electra
- -### 4.1 【ELECTRA】动机 - -- Bert MLM 方式: 在训练Bert的时候,在输入上操作把15%的词语给替换成Mask,然后这其中有80%是Mask,有10%是替换成其他词语,最后剩下10%保持原来的词语。 -- 问题: 可以看到,Bert的训练中,每次相当于**只有15%的输入上是会有loss**的,而其他位置是没有的,这就导致了每一步的训练并没有被完全利用上,导致了训练速度慢。换句话说,就是模型只学习到 15%的 token 信息; - -### 4.2 【ELECTRA】介绍 - -提出了一种更有效的样本预训练任务,称为替换令牌检测。我们的方法不是掩盖输入,而是通过使用从 small generator network 采样的合理替代物替换一些令牌来破坏输入。然后,我们训练一个判别模型,该模型预测损坏的输入中的每个标记是否被生成器采样器代替,而不是训练一个预测损坏的令牌的原始身份的模型。 - -### 4.3 【ELECTRA】核心任务 - -- 核心:将生成式的Masked language model(MLM)预训练任务改成了判别式的Replaced token detection(RTD)任务,判断当前token是否被语言模型替换过; -- 思路:利用一个基于MLM的Generator来替换example中的某些个token,然后丢给Discriminator来判别 - -### 4.4 【ELECTRA】判别器 & 生成器 - -如下图所示,首先会训练一个生成器来生成假样本,然后Electra去判断每个token是不是被替换了。 - -![](img/20201015170627.png) - -### 4.5 【ELECTRA】算法流程 - -1. Generator G: - 1. 输入经过随机选择设置为[MASK]; - 2. 输入给 G,G 负责把[MASK]变成替换过的词; -2. Discriminator D: - 1. 预测 输入的句子 每个位置上的词语是否被替换过; - -> 注:
-> -> 1. Discriminator是训练完之后我们得到的预训练模型,Generator在训练完之后就没有用了 - -## 五、ERNIE 1.0 - -> 论文名称:《ERNIE: Enhanced Representation through Knowledge Integration》
-> 论文:https://arxiv.org/pdf/1904.09223.pdf
-> 代码:https://github.com/PaddlePaddle/ERNIE/tree/develop/ERNIE
- -### 5.1 【ERNIE 1.0】动机 - -原生BERT是采用随机【MASK】会让模型不能充分学习到语义信息,降低学习难度。 - -![](img/微信截图_20210910210322.png) -> 注:Harry Potter的Harry被【MASK】掉,这时候让模型去预测被【MASK】掉的token,这种情况下,模型很可能是根据Potter从而预测Harry(毕竟Harry Potter在语料中共同出现频率的比较高),在这种情况下,模型也许并不是根据Harry Potter和J.K.Rowling的关系来预测出Harry的,换个角度,这样BERT学到的是规则,而并非语义信息。 - -### 5.2 【ERNIE 1.0】预训练 - -#### 5.2.1 Knowledge Integration - -针对 MASK 存在问题,ERNIE 1.0 将 MASK 分为三部分: - -- Basic-level Masking:与BERT一样; -- Entity-level Masking:把实体作为一个整体【MASK】,例如 J.K.Rowling 这个词作为一个实体,被一起【MASK】; -- Phrase-Level Masking:把短语作为一个整体【MASK】,如 a series of 作为一个短语整体,被一起【MASK】。 - -![](img/微信截图_20210910210729.png) - -#### 5.2.2 Dialogue Language Model(DLM) - -在 Bert 已有的预训练任务中,加入了 Dialogue Language Model 任务: - -- 作用:ERNIE 1.0 通过引入 多轮问答数据,使 ERNIE 学习到对话中的隐含关系,增加模型的语义表达能力。 -- 具体操作:把里面的单个token、实体、短语【MASK】掉,然后预测它们,另外在生成预训练数据的时候,有一定几率用另外的句子替代里面的问题和答案,所以模型还要预测是否是真实的问答对。 - -![](img/微信截图_20210910210907.png) - -> 注:注意看Segment Embedding被Dialogue Embedding代替了,但其它结构跟MLM模型是一样的,所以DLM任务可以和MLM任务联合训练,即Dialogue Embedding只会跟随DLM任务更新,Segment Embedding指挥跟随MLM任务跟新,而模型其它参数是随着DLM任务和MLM任务一起更新。 - -## 六、ERNIE 2.0 - -> 论文名称:《ERNIE 2.0: A Continual Pre-Training Framework for Language Understanding》
-> 论文:https://ojs.aaai.org//index.php/AAAI/article/view/6428
-> 代码:https://github.com/PaddlePaddle/ERNIE
- -### 6.1 【ERNIE 2.0】动机 - -近两年,以 BERT、XLNet 为代表的无监督预训练技术在多个自然语言处理任务上取得了技术突破。基于大规模数据的无监督预训练技术在自然语言处理领域变得至关重要。 - -百度发现,之前的工作主要**通过词或句子的共现信号,构建语言模型任务进行模型预训练**。例如,**BERT 通过掩码语言模型和下一句预测任务进行预训练**。**XLNet 构建了全排列的语言模型,并通过自回归的方式进行预训练**。 - -然而,**除了语言共现信息之外,语料中还包含词法、语法、语义等更多有价值的信息**。例如,人名、地名、机构名等词语概念知识,句子间顺序和距离关系等结构知识,文本语义相似度和语言逻辑关系等语义知识。那么如果持续地学习各类任务,模型的效果能否进一步提升?这就是 ERNIE 2.0 希望探索的。 - -### 6.2 【ERNIE 2.0】架构 - -![](img/微信截图_20210910211607.png) - -ERNIE 2.0 中有一个很重要的概念便是连续学习(Continual Learning),**连续学习的目的是在一个模型中顺序训练多个不同的任务以便在学习下个任务当中可以记住前一个学习任务学习到的结果**。通过使用连续学习,可以不断积累新的知识,模型在新任务当中可以用历史任务学习到参数进行初始化,一般来说比直接开始新任务的学习会获得更好的效果 - -### 6.3 【ERNIE 2.0】预训练 - -#### 6.3.1 预训练连续学习 - -ERNIE 2.0 提出三种策略来让模型同时学习3个任务: - -- 策略一:**Multi-task Learning**,就是让模型同时学这3个任务,具体的让这3个任务的损失函数权重双加,然后一起反向传播更新参数; -- 策略二:**Continual Learning**,先训练任务1,再训练任务2,再训练任务3,这种策略的缺点是容易遗忘前面任务的训练结果,最后训练出的模型容易对最后一个任务过拟合; -- 策略三:**Sequential Multi-task Learning**,连续多任务学习,即第一轮的时候,先训练任务1,但不完全让它收敛训练完,第二轮,一起训练任务1和任务2,同样不让模型收敛完,第三轮,一起训练三个任务,直到模型收敛完。 - -![](img/微信截图_20210910212046.png) - -论文采用策略三的思想。具体的,如下图所示,每个任务有独立的损失函数,句子级别的任务可以和词级别的任务一起训练,相信做过联合训练的同学并不陌生。 - -![](img/微信截图_20210910212205.png) - -#### 6.3.2 更多的无监督预训练任务 - -由于是多任务学习,模型输入的时候额外多了一个Task embedding。 - -![](img/微信截图_20210910212307.png) - -具体的三种类型的无监督训练任务是哪三种呢?每种里面又包括什么任务呢? - -1. 任务一:词法级别预训练任务 - -- Knowledge Masking Task:这任务同ERNIE 1.0一样,把一些字、短语、实体【MASK】掉,预测【MASK】词语; -- Capitalization Prediction Task:预测单词是大写还是小写; -- Token-Document Relation Prediction Task:预测在段落A中出现的token,是否在文档的段落B中出现。 - -2. 任务二:语言结构级别预训练任务 - -- Sentence Reordering Task:把文档中的句子打乱,预测正确顺序; -- Sentence Distance Task:分类句子间的距离(0:相连的句子,1:同一文档中不相连的句子,2:两篇文档间的句子)。 - -1. 任务三:语句级别预训练任务 - -- Discourse Relation Task:计算两句间的语义和修辞关系; -- IR Relevance Task:短文本信息检索关系,搜索数据(0:搜索并点击,1:搜素并展现,2:无关)。 - -## 七、ERNIE-T - -> 论文名称:《ERNIE: Enhanced Language Representation with Informative Entities》
-> 论文:https://arxiv.org/pdf/1905.07129.pdf
-> 代码:https://github.com/thunlp/ERNIE
- -### 7.1 【ERNIE-T】动机 - -例如下面的句子,我们的任务目标是对“Bob Dylan”进行实体类别识别(Entity Typing)。所谓Entity Typing,是指给定一个实体指代(entity mention),根据实体的上下文信息来对实体的具体语义类别进行预测。例如在示例1中,Bob Dylan的entity typing的值为“songwriter”和“writer”,因为“Blowin' in the wind”是一首歌,“Chronicies:Volume One”是一本书。对于BERT来说,仅仅通过上下文是很难预测出正确的结果的,因为它没有关于这两个作品类别的信息。 - -但是如果我们引入了实体额外的知识图谱呢,如图1。根据图谱提供的信息,我们知道了Blowin' in the wind”是一首歌以及“Chronicies:Volume One”是一本书,那么我们再对“Boby Dylan”进行实体类别识别时就容易多了。 - -![](img/微信截图_20210910213336.png) -> 示例1: Bob Dylan wrote Blowin' in the Wind in 1962, and wrote Chronicies: Volume One in 2004. - -### 7.2 【ERNIE-T】架构 - -![](img/微信截图_20210910213420.png) - -### 7.3 【ERNIE-T】预训练 - -#### 7.3.1 引入知识图谱 - -ERNIE-T 引入知识图谱来增强预训练模型的语义表达能力,其实预训练时就是在原来bert的基础上增加了一个实体对齐的任务。 - -#### 7.3.2 异构信息融合 - -因为词向量和实体的知识图谱是两个异构的信息,那么如何设计一个网络来融合这两个信息则是我们需要解决的首要问题。如图2所示,ERNIE-T由两个模块组成,它们是底层文本编码器(underlying textual encoder,T-Encoder)和上层知识编码器(upper knowledge encoder,K-Encoder)。 - -#### 7.3.3 dAE - -提出了随机mask tokens-entity中的entity,然后去预测该位置对应的entity,本质上和MLM(mask language model)任务一致,都属于去噪自编码。具体mask的细节: - -1. 5%的tokens-entity对采用随机用其他的entity来替换,这主要是引入噪声,因为在实际的任务中也存在这种情况。 -2. 15%的tokens-entity对采用随机maskentity,然后来预测这个entity。 -3. 80%保持正常。 - -这篇论文主要的工作就是增加了这个任务,另外也提出了在实体类型和关系抽取两个任务上新的预训练方式,具体如下图: - -![](img/微信截图_20210910213837.png) - -就是引入了一些特殊的token来表明另外一些特殊token的身份。因为引入了实体对齐任务,因此该模型在一些和知识图谱相关的下游任务上要优于bert。 - -## 八、ChineseBERT - -> 论文名称:ChineseBERT: Chinese Pretraining Enhanced by Glyph and Pinyin Information
-> 论文:https://arxiv.org/abs/2106.16038
-> 代码:https://github.com/ShannonAI/ChineseBert
- -### 8.1 【ChineseBERT】动机 - -1. 中文与英文不同,其包含 字形 和 拼音: - -- 字形:在 汉字中 字形 包含一些特殊的语义信息,而这些语义信息能够增强 中文自然语言处理任务模型的表达能力。 - -> eg:“液”、“河”和“湖”都有“氵”,表示这些字符都与“水”的语义相关; - -- 拼音:利用 拼音 的 方式表示 汉字发音,在建模语义和语法信息是至关重要的; - -> 同样的汉字在不同的读音下,有着不同的涵义。例如: “乐”字,读“yuè”时表示音乐,读“lè” 时表示快乐;
-> 形近字发音类似。例如:“博” 和 “搏” 等; - -### 8.2 【ChineseBERT】方法介绍 - -#### 8.2.1 模型整体架构介绍 - -![](img/微信截图_20210808214524.png) - -1. embedding 层:将 字符嵌入(char embedding)、字形嵌入(glyph embedding)和拼音嵌入(pinyin embedding) 做拼接; -2. Fusion Layer 层:将 拼接后的 embedding 向量 做 Fusion 得到 一个 d 维的 Fusion embedding; -3. 位置拼接:将 Fusion embedding 和 位置嵌入(position embedding)、片段嵌入(segment embedding)相加; -4. Transformer-Encoder层 - -#### 8.2.2 模型改进点介绍 - -1. 在底层的融合层(Fusion Layer)融合了除字嵌入(Char Embedding)之外的字形嵌入(Glyph Embedding)和拼音嵌入(Pinyin Embedding),得到融合嵌入(Fusion Embedding),再与位置嵌入相加,就形成模型的输入; -2. 抛弃预训练任务中的NSP任务。 由于预训练时没有使用NSP任务,因此模型结构图省略了片段嵌入(segment embedding)。实际上下游任务输入为多个段落时(例如:文本匹配、阅读理解等任务),是采用了segment embedding; - -### 8.3 【ChineseBERT】预训练 - -1. Masking 操作。预训练的一大关键步骤是确定如何掩码(Masking)输入文本。ChineseBERT 综合使用两种掩码策略:全词掩码(Whole Word Masking, WWM)与字掩码(Char Masking, CM)。 - -- 字掩码(Char Masking, CM):最简洁最直观的掩码方法,以单个汉字为单位进行掩码。 -- 全词掩码(Whole Word Masking, WWM):以词为单位,将词中的所有字掩码。注意基本的输入单元依然是字,只是一个词包含的所有汉字都被掩码。比如,“我喜欢紫禁城”在掩码词“紫禁城”之后就是“我喜欢[M][M][M]”,而非“我喜欢[M]”。 - -使用两种掩码方式易于模型从不同的角度融合字、字形、拼音及上下文信息。 - -2. Packed Input 与 Single Input 之间交替训练。 为了习得短期上下文与长期上下文,ChineseBERT 在 Packed Input 与 Single Input 之间交替训练: - -- Packed Input 是将模型的输入扩展到最大长度 512,作为输入的概率为 0.9; -- Single Input 则将单个句子作为输入,Single Input 作为输入的概率是 0.1。 - -## 九、SpanBERT - -> 论文名称:SpanBERT: Improving Pre-training by Representing and Predicting Spans
-> 论文:https://arxiv.org/abs/1907.10529
-> 代码:https://github.com/facebookresearch/SpanBERT
- -### 9.1 【SpanBERT】动机 - -- 动机:旨在更好地表示和预测文本的 span; - -### 9.2 【SpanBERT】预训练 - -- 论文方法->扩展了BERT: - - (1)Span Mask。屏蔽连续的随机跨度,而不是随机标记; - - (2)Span Boundary Objective (SBO) 训练目标。训练跨度边界表示来预测屏蔽跨度的整个内容,而不依赖其中的单个标记表示。 - - (3) Single-Sequence Training。弃用 Next Sentence Prediction (NSP) 任务,改用 Single-Sequence Training - - 原因:(a)更长的语境对模型更有利,模型可以获得更长上下文(类似 XLNet 的一部分效果;(b)加入另一个文本的语境信息会给MLM 语言模型带来噪音。 - -![](img/微信截图_20220121111042.png) - -### 9.3 【SpanBERT】微调 - - -### 9.4 【SpanBERT】效果 - -在 TACRED 关系抽取任务中的表现也超过了基线,获得 70.8% 的 F1 score,在 GLUE 数据集上的表现也有所提升 - -## 十、MacBERT - -> 论文名称:Revisiting Pre-trained Models for Chinese Natural Language Processing
-> 论文:https://arxiv.org/abs/2004.13922
-> 代码:https://github.com/ymcui/MacBERT
- -### 10.1 【MacBERT】动机 - -- 主要为了解决与训练阶段和微调阶段存在的差异性 - -### 10.2 【MacBERT】预训练 - -#### 10.2.1 MLM - -1. 使用Whole Word Masking、N-gram Masking:single token、2-gram、3-gram、4-gram分别对应比例为0.4、0.3、0.2、0.1; -2. 由于finetuning时从未见过[MASK]token,因此使用相似的word进行替换。使用工具Synonyms toolkit 获得相似的词。如果被选中的N-gram存在相似的词,则随机选择相似的词进行替换,否则随机选择任意词替换; -3. 对于一个输入文本,15%的词进行masking。其中80%的使用相似的词进行替换,10%使用完全随机替换,10%保持不变。 - -### 10.2.2 NSP - -采用ALBERT提出的SOP替换NSP - -### 10.3 【MacBERT】微调 - - -### 10.4 【MacBERT】效果 - - - -## 参考 - -1. [《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》](https://arxiv.org/pdf/1810.04805.pdf) -2. [《XLNet: Generalized Autoregressive Pretraining for Language Understanding》](https://arxiv.org/abs/1906.08237) -3. [《RoBERTa: A Robustly Optimized BERT Pretraining Approach》](https://arxiv.org/pdf/1907.11692.pdf) -4. [《ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generator》](https://arxiv.org/abs/2003.10555) -5. [《ERNIE: Enhanced Representation through Knowledge Integration》](https://arxiv.org/pdf/1904.09223.pdf) -6. [《ERNIE 2.0: A Continual Pre-Training Framework for Language Understanding》](https://ojs.aaai.org//index.php/AAAI/article/view/6428) -7. [《ERNIE: Enhanced Language Representation with Informative Entities》](https://arxiv.org/pdf/1905.07129.pdf) \ No newline at end of file diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122170950.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122170950.png" deleted file mode 100644 index d05cead..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122170950.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122171023.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122171023.png" deleted file mode 100644 index 9c6d961..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122171023.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122172500.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122172500.png" deleted file mode 100644 index 7decdea..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122172500.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122183547.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122183547.png" deleted file mode 100644 index 18d2010..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20211122183547.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120094526.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120094526.png" deleted file mode 100644 index 6741567..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120094526.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120094806.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120094806.png" deleted file mode 100644 index ea2fd58..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120094806.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120095126.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120095126.png" deleted file mode 100644 index 8026013..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120095126.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100138.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100138.png" deleted file mode 100644 index 4f97188..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100138.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100330.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100330.png" deleted file mode 100644 index 66cf19c..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100330.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100533.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100533.png" deleted file mode 100644 index f79e5cd..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100533.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100841.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100841.png" deleted file mode 100644 index 3ac801b..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120100841.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120101534.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120101534.png" deleted file mode 100644 index a07a0a5..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120101534.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120105718.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120105718.png" deleted file mode 100644 index 51b5563..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120105718.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120110645.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120110645.png" deleted file mode 100644 index 3017e2f..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120110645.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120112533.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120112533.png" deleted file mode 100644 index dfcdc3b..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120112533.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120112812.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120112812.png" deleted file mode 100644 index 717a49d..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220120112812.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220121103152.png" "b/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220121103152.png" deleted file mode 100644 index 12ef9c2..0000000 Binary files "a/NLPinterview/PreTraining/bert_generative/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220121103152.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_generative/readme.md b/NLPinterview/PreTraining/bert_generative/readme.md deleted file mode 100644 index 8ce0b84..0000000 --- a/NLPinterview/PreTraining/bert_generative/readme.md +++ /dev/null @@ -1,424 +0,0 @@ -# 【关于 GPT->GPT2-> ... 】那些的你不知道的事 - -> 作者:杨夕 -> -> 介绍:本项目是作者们根据个人面试和经验总结出的搜索引擎(search engine) 面试准备的学习笔记与资料,该资料目前包含 搜索引擎各领域的 面试题积累。 -> -> NLP 百面百搭 地址:https://github.com/km1994/NLP-Interview-Notes -> -> 推荐系统 百面百搭 地址:https://github.com/km1994/RES-Interview-Notes -> -> **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** -> -> 搜索引擎 百面百搭 地址:https://github.com/km1994/search-engine-Interview-Notes 【编写ing】 -> -> NLP论文学习笔记:https://github.com/km1994/nlp_paper_study -> -> 推荐系统论文学习笔记:https://github.com/km1994/RS_paper_study -> -> GCN 论文学习笔记:https://github.com/km1994/GCN_study -> -> 关注公众号 **【关于NLP那些你不知道的事】** 加入 【NLP && 推荐学习群】一起学习!!! - -> 注:github 网页版 看起来不舒服,可以看 **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** - -## 目录 - -- [【关于 GPT->GPT2-> ... 】那些的你不知道的事](#关于-gpt-gpt2---那些的你不知道的事) - - [目录](#目录) - - [总结](#总结) - - [一、Generative Pre-trained Transformer(GPT)](#一generative-pre-trained-transformergpt) - - [1.1 动机](#11-动机) - - [1.2 GPT 思想](#12-gpt-思想) - - [1.3 GPT 处理的 有监督任务有哪些?](#13-gpt-处理的-有监督任务有哪些) - - [1.4 GPT 训练](#14-gpt-训练) - - [1.4.1 无监督预训练](#141-无监督预训练) - - [1.4.2 有监督微调](#142-有监督微调) - - [1.5 优点](#15-优点) - - [1.6 缺点](#16-缺点) - - [1.7 主要贡献](#17-主要贡献) - - [二、Generative Pre-trained Transformer 2(GPT-2)](#二generative-pre-trained-transformer-2gpt-2) - - [2.1 动机](#21-动机) - - [2.2 GPT-2 核心思想](#22-gpt-2-核心思想) - - [三、MASS](#三mass) - - [3.1 动机](#31-动机) - - [3.2 MASS 核心思想](#32-mass-核心思想) - - [3.2.1 预训练阶段](#321-预训练阶段) - - [3.2.2 微调阶段](#322-微调阶段) - - [3.3 优点](#33-优点) - - [四、UniLM 1.0](#四unilm-10) - - [4.1 动机](#41-动机) - - [4.2 方向性语言模型](#42-方向性语言模型) - - [4.3 UniLM 1.0 核心思路](#43-unilm-10-核心思路) - - [4.3.1 预训练阶段](#431-预训练阶段) - - [4.3.2 微调阶段](#432-微调阶段) - - [4.4 UniLM 1.0 优点](#44-unilm-10-优点) - - [五、Bart](#五bart) - - [5.1 动机](#51-动机) - - [5.2 Bart 思路](#52-bart-思路) - - [5.3 BART 预训练](#53-bart-预训练) - - [5.4 BART 微调](#54-bart-微调) - - [5.4.1 Sequence Classification Task 序列分类任务](#541-sequence-classification-task-序列分类任务) - - [5.4.2 Token Classification Task 序列分类任务](#542-token-classification-task-序列分类任务) - - [5.4.3 Sequence Generation Task 序列生成任务](#543-sequence-generation-task-序列生成任务) - - [5.4.4 Machine Translation 机器翻译](#544-machine-translation-机器翻译) - - [六、T5](#六t5) - - [6.1 动机](#61-动机) - - [6.2 T5 的基本思想](#62-t5-的基本思想) - - [6.3 T5 预训练任务](#63-t5-预训练任务) - - [6.3.1 T5 预训练任务介绍](#631-t5-预训练任务介绍) - - [6.3.2 T5 预训练任务——无监督训练](#632-t5-预训练任务无监督训练) - - [6.3.3 T5 预训练任务——有监督训练](#633-t5-预训练任务有监督训练) - - [6.4 T5 微调任务](#64-t5-微调任务) - - [参考](#参考) - -## 总结 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称介绍动机预训练方法微调优点问题
GPTGenerative Pre-trained Transformer标注数据昂贵 && 根据一个任务训练的模型很难泛化到其它任务中利用无监督语料对 GPT 模型进行预训练,学习得到一个生成式的语言模型根据特定热任务对 生成式的语言模型 进行微调GPT-1的模型要比基于LSTM的模型稳定泛化能力远远低于经过微调的有监督任务&在 NLU 任务性能低下
GPT-2Generative Pre-trained Transformer 2GPT-1 能力不够问题GPT-2 利用 更大的语料进行预训练根据特定热任务对 生成式的语言模型 进行微调 & 增大其网络参数NLG 能力提升在 NLU 任务性能低下
MASSMasked Sequence to Sequence Pre-training for Language GenerationBert 只适用于 NLU 类型任务,无法直接用于 生成式任务(eg:翻译、摘要等)利用 encoder 信息和 decoder 信息,预测 被 mask 的 连续 k 个词————MASS 在 机器翻译上 取得了 新的SOTA
mask掉连续的token,可以得到更好的语言建模能力
只让decoder从encoder侧获取信息,得到的模型效果更好
————
UniLM 1.0Unified Language Model Pre-training for Natural Language Understanding and GenerationELMO 和 GPT 无法同时利用上下文 && Bert 在 NLG 效果低下 && [MASK] 标记问题 混合训练方式 && masking 方式 && Attention 控制对于NLU类型的任务UNILM和BERT相同。对于NLG类型的任务,UNILM随机mask decoder中的一些词,然后再预测它们1. 预训练阶段 同时训练 双向(bidirectional)语言模型、seq-to-seq语言模型、两种单向学习的语言模型
2. 预训练阶段 使用 mask 方法 解决 self-attention 中约束问题
3. 在 NLU 和 NLG 任务上都取得不错效果
在GLUE上首次不加外部数据打赢了BERT
————
BartDenoising sequence-to-sequence pre-training for natural language generation, translation, and comprehensionBERT 较难用于生成任务
GPT 仅基于左侧上下文预测单词,无法学习双向交互
通过破坏文档再优化重建损失不同任务微调方式不同————————
T5Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer Money is All you Need!!!增大训练数据
转化为 seq2seq 任务进行训练
Multi-task————————
- - -## 一、Generative Pre-trained Transformer(GPT) - -### 1.1 动机 - -在 GPT 之前,传统的NLP模型往往需要使用标注数据对有监督模型进行任务相关的模型训练,这种训练方式存在两个问题: - -1. 需要大量标准数据; -2. 根据一个任务训练的模型很难泛化到其它任务中。 - -### 1.2 GPT 思想 - -1. 利用无监督语料对 GPT 模型进行预训练,学习得到一个生成式的语言模型; -2. 根据特定热任务对 生成式的语言模型 进行微调; - -### 1.3 GPT 处理的 有监督任务有哪些? - -1. 自然语言推理(Natural Language Inference 或者 Textual Entailment):判断两个句子是包含关系(entailment),矛盾关系(contradiction),或者中立关系(neutral); -2. 问答和常识推理(Question answering and commonsense reasoning):类似于多选题,输入一个文章,一个问题以及若干个候选答案,输出为每个答案的预测概率; -3. 语义相似度(Semantic Similarity):判断两个句子是否语义上市是相关的; -4. 分类(Classification):判断输入文本是指定的哪个类别。 - -![](img/微信截图_20220120101534.png) - -### 1.4 GPT 训练 - -#### 1.4.1 无监督预训练 - -- 思路:给定一个未标注序列 U={u1,u2,...,un} , 利用 语言模型进行训练,目标函数为: - -![](img/微信截图_20220120094526.png) - -- GPT 模型框架: 利用 12个 transformers 的 block 作为 decoder,每个 transformers 的 block 是一个多头的自注意力机制,然后通过全连接得到输出的概率分布。 - -![](img/微信截图_20220120094806.png) - -![](img/微信截图_20220120095126.png) - -#### 1.4.2 有监督微调 - -在 第一阶段预训练之后,我们只是得到了 一个预训练模型,当遇到具体有监督任务时,需要利用标注数据集 C 输入到 训练好的预训练模型中,得到最终的特征向量 h,然后通过 全连接层得到 预测结果 y: - -![](img/微信截图_20220120100330.png) - -目标函数为: - -![](img/微信截图_20220120100533.png) - -论文 并没有直接使用 L2 ,而向其中加入了 L1 ,目标函数为: - -![](img/微信截图_20220120100841.png) - -### 1.5 优点 - -GPT-1的模型要比基于LSTM的模型稳定,且随着训练次数的增加,GPT-1的性能也逐渐提升,表明GPT-1有非常强的泛化能力,能够用到和有监督任务无关的其它NLP任务中。GPT-1证明了transformer对学习词向量的强大能力,在GPT-1得到的词向量基础上进行下游任务的学习,能够让下游任务取得更好的泛化能力。对于下游任务的训练,GPT-1往往只需要简单的微调便能取得非常好的效果。 - -### 1.6 缺点 - -GPT-1在未经微调的任务上虽然也有一定效果,但是其泛化能力远远低于经过微调的有监督任务,说明了GPT-1只是一个简单的领域专家,而非通用的语言学家。 - -### 1.7 主要贡献 - -- 验证了Transformer在Unsupervised Pretraining中的有效性。 -- 验证了更大的模型效果更好: 6 --> 12 层。 -- 为下游任务引入了通用的求解框架,不再为任务做模型定制。 - -## 二、Generative Pre-trained Transformer 2(GPT-2) - -### 2.1 动机 - -GPT-1 能力不够问题 - -### 2.2 GPT-2 核心思想 - -1. GPT-2 利用 更大的语料进行预训练; -2. GPT-2把GPT中12层的Transformer提升到48层,增大其网络参数; - -GPT-2的核心思想概括为:任何有监督任务都是语言模型的一个子集,当模型的容量非常大且数据量足够丰富时,仅仅靠训练语言模型的学习便可以完成其他有监督学习的任务。 - -## 三、MASS - -### 3.1 动机 - -1. Bert 只适用于 NLU 类型任务,无法直接用于 生成式任务(eg:翻译、摘要等); - -### 3.2 MASS 核心思想 - -#### 3.2.1 预训练阶段 - -MASS 的 结构还是 encoder2decoder 结构,如下图: - -1. encoder 模块:随机 mask 掉 输入句子中的连续 k 个词; -2. decoder 模块:将 被 encoder mask 的 k-1 个词 放在 decoder 模块中的对应位置; -3. MASS 目标:利用 encoder 信息和 decoder 信息,预测 被 mask 的 连续 k 个词; - -![](img/微信截图_20220120105718.png) - -目标函数 - -![](img/微信截图_20220120110645.png) - -#### 3.2.2 微调阶段 - -### 3.3 优点 - -1. MASS 在 机器翻译上 取得了 新的SOTA; -2. mask掉连续的token,可以得到更好的语言建模能力; -3. 只让decoder从encoder侧获取信息,得到的模型效果更好; - -## 四、UniLM 1.0 - -### 4.1 动机 - -1. ELMO 通过双向都做AR 模型,然后进行拼接,但从结果来看,效果并不是太好; -2. GPT 的 等效性结构 使其无法同时利用上下文; -3. Bert 的 双向性结构 限制了 其在 NLG 问题上的应用; -4. Bert 由于训练中采用了 [MASK] 标记,导致预训练与微调阶段不一致的问题 - -### 4.2 方向性语言模型 - -1. 单向训练语言模型,mask词的语境就是其单侧的words,左边或者右边; -2. 双向训练语言模型,mask词的语境就是左右两侧的words; -3. Seq-to-Seq语言模型,左边的seq我们称source sequence,右边的seq我们称为target sequence,我们要预测的就是target sequence,所以其语境就是所有的source sequence和其左侧已经预测出来的target sequence. - -![](img/微信截图_20220120112533.png) - -### 4.3 UniLM 1.0 核心思路 - -#### 4.3.1 预训练阶段 - -1. 混合训练方式。对于同一个batch,采用以下不同方式进行训练: - 1. 1/3时间采用双向(bidirectional)语言模型的目标; - 2. 1/3的时间采用seq-to-seq语言模型目标; - 3. 最后1/3平均分配给两种单向学习的语言模型,也就是left-to-right和right-to-left方式各占1/6时间 -2. masking 方式。和 Bert 一样,对其中 15% ,采用以下方式进行处理: - 1. 80%的情况下直接用[MASK]替代; - 2. 10%的情况下随机选择一个词替代; - 3. 最后10%的情况用真实值。还有就是80%的情况是每次只mask一个词,另外20%的情况是mask掉bigram或者trigram; -3. Attention 控制:不同的训练方式,其关注的语境是不一样的,上面也有介绍,如上图所示,灰色的方格就是不能看到的信息,白色的就是需要attention的信息。如何实现这种控制呢?不让当前预测词看掉的信息就采用掩码隐藏掉,只留下能让当前词可看的信息,换句话说,论文使用了掩码来控制在计算基于上下文的表征时 token 应该关注的上下文的量。 - -![](img/微信截图_20220120112812.png) -> 模型架构 - -#### 4.3.2 微调阶段 - -对于NLU类型的任务UNILM和BERT相同。对于NLG类型的任务,UNILM随机mask decoder中的一些词,然后再预测它们。 - -### 4.4 UniLM 1.0 优点 - -1. 预训练阶段 同时训练 双向(bidirectional)语言模型、seq-to-seq语言模型、两种单向学习的语言模型; -2. 预训练阶段 使用 mask 方法 解决 self-attention 中约束问题; -3. 在 NLU 和 NLG 任务上都取得不错效果; -4. 在GLUE上首次不加外部数据打赢了BERT - -## 五、Bart - -### 5.1 动机 - -1. BERT:用掩码替换随机 token,双向编码文档。由于缺失 token 被单独预测,因此 BERT 较难用于生成任务; - -![](img/微信截图_20211122170950.png) - -2. GPT:使用自回归方式预测 token,这意味着 GPT 可用于生成任务。但是,该模型仅基于左侧上下文预测单词,无法学习双向交互 - -![](img/微信截图_20211122171023.png) - -### 5.2 Bart 思路 - -BART:编码器输入与解码器输出无需对齐,即允许任意噪声变换。使用掩码符号替换文本段,从而破坏文本。使用双向模型编码被破坏的文本(左),然后使用自回归解码器计算原始文档的似然(右)。至于微调,未被破坏的文档是编码器和解码器的输入,研究者使用来自解码器最终隐藏状态的表征。 - -![](img/微信截图_20211122172500.png) - -### 5.3 BART 预训练 - -BART 是**通过破坏文档再优化重建损失**(即解码器输出和原始文档之间的交叉熵)训练得到的。 - -与目前仅适合特定噪声机制的去噪自编码器不同,BART 可应用于任意类型的文档破坏。极端情况下,当源文本信息全部缺失时,BART 也等同于语言模型。 - -- 破坏原始文本的噪声方法: - - Token Masking(token 掩码):按照 BERT 模型,BART 采样随机 token,并用 [MASK]标记 替换它们; - - Sentence Permutation(句子排列变换):按句号将文档分割成多个句子,然后以随机顺序打乱这些句子; - - Document Rotation(文档旋转):随机均匀地选择 token,旋转文档使文档从该 token 开始。该任务的目的是训练模型识别文档开头; - - Token Deletion(token 删除):从输入中随机删除 token。与 token 掩码不同,模型必须确定缺失输入的位置; - - Text Infilling(文本填充):采样多个文本段,文本段长度取决于泊松分布 (λ = 3)。用单个掩码 token 替换每个文本段。长度为 0 的文本段对应掩码 token 的插入; - -### 5.4 BART 微调 - -#### 5.4.1 Sequence Classification Task 序列分类任务 - -对于序列分类任务,将相同的输入,输入到encoder和decoder中,最后将decoder的最后一个隐藏节点作为输出,输入到分类层(全连接层)中,获取最终的分类的结果。 - -![](img/微信截图_20211122182304.png) - -> 注:其中,decoder的最后一个隐藏节点是一个特殊标记,相当于BERT模型中的[CLS]。 - -#### 5.4.2 Token Classification Task 序列分类任务 - -对于 token 分类任务,将完整文档输入到编码器和解码器中,使用解码器最上方的隐藏状态作为每个单词的表征。该表征的用途是分类 token。 - -#### 5.4.3 Sequence Generation Task 序列生成任务 - -由于 BART 具备自回归解码器,因此它可以针对序列生成任务进行直接微调,如抽象问答和摘要。在这两项任务中,信息复制自输入但是经过了处理,这与去噪预训练目标紧密相关。这里,编码器的输入是输入序列,解码器以自回归的方式生成输出。 - -#### 5.4.4 Machine Translation 机器翻译 - -将BART的encoder端的embedding层替换成randomly initialized encoder,新的encoder也可以用不同的vocabulary。通过新加的Encoder,我们可以将新的语言映射到BART能解码到English(假设BART是在English的语料上进行的预训练)的空间。具体的finetune过程分两阶段: - -1. 第一步只更新randomly initialized encoder + BART positional embedding + BART的encoder第一层的self-attention 输入映射矩阵。 -2. 第二步更新全部参数,但是只训练很少的几轮。 - -![](img/微信截图_20211122183547.png) - -## 六、T5 - -### 6.1 动机 - -Money is All you Need!!! - -### 6.2 T5 的基本思想 - -将每个 NLP 问题都视为“text-to-text”问题,即将文本作为输入并生成新的文本作为输出,这允许将相同的模型、目标、训练步骤和解码过程,直接应用于每个任务。 - -### 6.3 T5 预训练任务 - -#### 6.3.1 T5 预训练任务介绍 - -T5 的 预训练任务可以分为:无监督训练 和 有监督训练 两个; - -![](img/微信截图_20220121103152.png) - -#### 6.3.2 T5 预训练任务——无监督训练 - -- 预训练语料: 800G 的语料(论文称之为 C4); -- 训练目标:与 Bert 类似,只是改成 seq2seq()可视为 升级版完形填空任务 - -```s - 输入:明月几时有,[M0] 问青天,不知 [M1],今夕是何年。我欲[M2]归去,唯恐琼楼玉宇,高处 [M3];起舞 [M4] 清影,何似在人间。 - - 输出:[M0] 把酒 [M1] 天上宫阙 [M2] 乘风 [M3] 不胜寒 [M4] 弄 -``` - -#### 6.3.3 T5 预训练任务——有监督训练 - -- 预训练数据:各种 NLP 标注数据; -- 训练方式:转化为 seq2seq 任务进行训练: - -> 文本分类任务 -```s - 输入:识别该句子的情感倾向:这趟北京之旅我感觉很不错。 - 输出:正面 -``` - -> 主题分类 -```s - 输入:下面是一则什么新闻?八个月了,终于又能在赛场上看到女排姑娘们了。 - 输出:体育 -``` - -> 阅读理解 -```s - 输入:阅读理解:特朗普与拜登共同竞选下一任美国总统。根据上述信息回答问题:特朗普是哪国人? - 输出:美国 -``` - -### 6.4 T5 微调任务 - -- 也是Multi-task,将所有GLUE/SuperGLUE的数据拼在一起变成精调一个task,减少过拟合,但同时也会牺牲一些精度 -- batch size减小到8 -- 其实最后同时进行了多任务精调和单独精调,根据dev集选择最好的结果 - - -## 参考 - -1. [Radford, A., Narasimhan, K., Salimans, T. and Sutskever, I., 2018. Improving language understanding by generative pre-training](https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf) -2. [词向量之GPT-1,GPT-2和GPT-3](https://zhuanlan.zhihu.com/p/350017443) -3. [《MASS: Masked Sequence to Sequence Pre-training for Language Generation》](https://arxiv.org/abs/1905.02450) -4. [BERT生成式之MASS解读](https://zhuanlan.zhihu.com/p/67687640) -5. [UniLM(Unified Language Model Pre-training for Natural Language Understanding and Generation)](https://arxiv.org/abs/1905.03197) 【[github](https://github.com/microsoft/unilm)】 -6. [paper阅读:UniLM(Unified Language Model Pre-training for Natural Language Understanding and Generation)](https://www.cnblogs.com/gczr/p/12113434.html) -7. [BERT时代与后时代的NLP](https://zhuanlan.zhihu.com/p/66676144) -8. [Lewis, Mike, et al. "Bart: Denoising sequence-to-sequence pre-training for natural language generation, translation, and comprehension." arXiv preprint arXiv:1910.13461 (2019)](https://arxiv.org/abs/1910.13461) -9. [Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer](https://arxiv.org/abs/1910.10683) 【[github 源码](https://github.com/google-research/text-to-text-transfer-transformer)】 diff --git a/NLPinterview/PreTraining/bert_zip/img/20200731202733.png b/NLPinterview/PreTraining/bert_zip/img/20200731202733.png deleted file mode 100644 index 018f9ba..0000000 Binary files a/NLPinterview/PreTraining/bert_zip/img/20200731202733.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_zip/img/20200801191212.png b/NLPinterview/PreTraining/bert_zip/img/20200801191212.png deleted file mode 100644 index 5fac0c5..0000000 Binary files a/NLPinterview/PreTraining/bert_zip/img/20200801191212.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_zip/img/20200801191434.png b/NLPinterview/PreTraining/bert_zip/img/20200801191434.png deleted file mode 100644 index ee80d46..0000000 Binary files a/NLPinterview/PreTraining/bert_zip/img/20200801191434.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_zip/img/20200927153839.png b/NLPinterview/PreTraining/bert_zip/img/20200927153839.png deleted file mode 100644 index 428b900..0000000 Binary files a/NLPinterview/PreTraining/bert_zip/img/20200927153839.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_zip/img/20200927154643.png b/NLPinterview/PreTraining/bert_zip/img/20200927154643.png deleted file mode 100644 index f17aed7..0000000 Binary files a/NLPinterview/PreTraining/bert_zip/img/20200927154643.png and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_zip/img/20200927191946.png b/NLPinterview/PreTraining/bert_zip/img/20200927191946.png deleted file mode 100644 index 331f53d..0000000 Binary files a/NLPinterview/PreTraining/bert_zip/img/20200927191946.png and /dev/null differ diff --git "a/NLPinterview/PreTraining/bert_zip/img/Bert\345\216\213\347\274\251.png" "b/NLPinterview/PreTraining/bert_zip/img/Bert\345\216\213\347\274\251.png" deleted file mode 100644 index 06795bd..0000000 Binary files "a/NLPinterview/PreTraining/bert_zip/img/Bert\345\216\213\347\274\251.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/bert_zip/readme.md b/NLPinterview/PreTraining/bert_zip/readme.md deleted file mode 100644 index 5be4543..0000000 --- a/NLPinterview/PreTraining/bert_zip/readme.md +++ /dev/null @@ -1,273 +0,0 @@ -# 【关于 Bert 压缩】 那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/Bert压缩.png) - -## 一、Bert 模型压缩 动机篇 - -- Bert 优点: - - 对下游任务进行微调后,显著提高了模型的表现; -- Bert 缺点: - - 内存占用; - - 功耗过高; - - 带来很高的延迟; - - 限制了 Bert 系列模型在移动和物联网等嵌入式设备上的部署; - -## 二、Bert 模型压缩对比表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
论文剪枝低秩因式分解知识蒸馏参数共享量化预训练微调
ALBERT: A Lite Bert for self-supervisedLearning of Language Representations111
Q-BERT: Hessian Based Ultra Low Precision Quantization of BERT111
Extreme Language Model Compression withOptimal Subwords and Shared Projections11
DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter11
FastBERT: a Self-distilling BERT with Adaptive Inference Time11
TinyBERT: Distilling BERT for Natural Language Understanding111
- -## 三、 Bert 模型压缩方法介绍 - -### 3.1 Bert 模型压缩方法 之 低秩因式分解&跨层参数共享 - -#### 3.1.1 什么是低秩因式分解? - -- 低秩因式分解:在输入层和输出层使用嵌入大小远小于原生Bert的嵌入大小,再使用简单的映射矩阵使得输入层的输出或者最后一层隐藏层的输出可以通过映射矩阵输入到第一层的隐藏层或者输出层; - -#### 3.1.2 什么是跨层参数共享? - -- 跨层参数共享:隐藏层中的每一层都使用相同的参数,用多种方式共享参数,例如只共享每层的前馈网络参数或者只共享每层的注意力子层参数。默认情况是共享每层的所有参数; - -#### 3.1.3 ALBERT 所所用的方法? - -- 论文名称:ALBERT: A Lite Bert for self-supervisedLearning of Language Representations【低秩因式分解 + 跨层参数共享】 -- 论文地址:https://openreview.net/forum?id=H1eA7AEtvS -- 论文源码:https://github.com/google-research/ALBERT -- 收录期刊:ICLR 2020 spotlight presentation收录 -- 模型压缩方法:低秩因式分解 + 跨层参数共享 -- 模型压缩方法介绍: - - 低秩因式分解: - - 动机:Bert的参数量大部分集中于模型的隐藏层架构上,在嵌入层中只有30,000词块,其所占据的参数量只占据整个模型参数量的小部分; - - 方法:将输入层和输出层的权重矩阵分解为两个更小的参数矩阵; - - 思路:在输入层和输出层使用嵌入大小远小于原生Bert的嵌入大小,再使用简单的映射矩阵使得输入层的输出或者最后一层隐藏层的输出可以通过映射矩阵输入到第一层的隐藏层或者输出层; - - 优点:在不显著增加词嵌入大小的情况下能够更容易增加隐藏层大小; - - 参数共享【跨层参数共享】: - - 动机:隐藏层 参数 大小 一致; - - 方法:隐藏层中的每一层都使用相同的参数,用多种方式共享参数,例如只共享每层的前馈网络参数或者只共享每层的注意力子层参数。默认情况是共享每层的所有参数; - - 优点:防止参数随着网络深度的增加而增大; -- 其他改进策略: - - **句子顺序预测损失(SOP)**代替**Bert中的下一句预测损失(NSP)**: - - 动机:通过实验证明,Bert中的下一句预测损失(NSP) 作用不大; - - 介绍:用预测两个句子是否连续出现在原文中替换为两个连续的句子是正序或是逆序,用于进一步提高下游任务的表现 -- 优点:参数量上有所降低; -- 缺点:其加速指标仅展示了训练过程,由于ALBERT的隐藏层架构**采用跨层参数共享策略并未减少训练过程的计算量**,加速效果更多来源于低维的嵌入层; - -### 3.2 Bert 模型压缩方法 之 蒸馏 - -#### 3.2.1 什么是蒸馏? - -- 蒸馏:用一个学生模型来学习大模型的知识,不仅要学logits,还要学attention score; - -#### 3.2.2 使用 模型蒸馏 的论文? - -##### 3.2.2.1 Extreme Language Model Compression withOptimal Subwords and Shared Projections 【蒸馏】 - -![](img/20200927154643.png) - -- 论文地址:https://openreview.net/forum?id=S1x6ueSKPr -- 模型压缩方法:知识蒸馏 -- 模型压缩方法介绍: - - 减少学生模型的词汇表中词块的数量: - - 动机:训练词汇量过大; - - 方法:使学生模型在蒸馏的过程中学习到一个更小的词汇表; - - 思路: - - 对偶训练:在蒸馏过程中,对于给定的输入到教师模型的训练序列,该工作混合使用教师词汇表和学生词汇表。通过从序列中随机选择部分单词,使用学生词汇表来分割,对于其它单词使用教师词汇表来分割,这鼓励根据老师和学生的词汇表来对齐同一单词的表示形式。这也是通过掩码语言建模任务来实现的该策略的效果。需要注意的是我们仅对教师模型执行对偶训练。在使用掩码语言建模训练时,模型针对老师和学生的词汇表使用不同的softmax层,具体取决于需预测的单词使用了哪一个词汇表来分割。 - - 减少隐藏层大小: - - 动机:尽量不损害模型性能,仅仅依靠教师模型的输出去训练学生模型并不具备高泛化能力; - - 思路: - - 共享映射:将教师模型和隐藏层大小较小的学生模型的参数投影到相同的空间再最小化两者的信息损失。详细地,该工作将教师模型的每一层中的每个可训练变量投影为与学生模型中相应变量相同的形状,记为向下映射,并计算2-范式损失,相似地,将学生模型的每一层中的每个可训练变量投影为与教师模型中相应变量相同的形状,记为向上映射,并计算2-范式损失,最后将损失相加作为目标函数的一部分,另外一部分为掩码语言建模预测损失。 - -##### 3.2.2.2 DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter 【蒸馏】 - -![](img/20200927154643.png) - -- 论文地址:https://arxiv.org/abs/1910.01108 -- 模型压缩方法:知识蒸馏 -- 模型压缩方法介绍: - - 通过知识蒸馏(在 logits,hidden_states 上计算学生与教师的 loss)训练一个小(主要是层数)模型实现和大模型类似的效果; -- 损失函数 - -![](img/20200801191212.png) - -> $t_i$ 老师的概率估计 -> $s_i$ 学生的概率估计 - -- 使用了 softmax-temperature: - -![](img/20200801191434.png) - -> T 控制输出分布的平滑程度,推理时设置为 1 变为标准的 Softmax; -> $z_i$ 表示类别 i 的分数。 - -最终的损失函数是 Lce 和 masked language modeling loss Lmlm 的线性组合,另外作者发现添加余弦嵌入损失(Lcos)有利于使学生和教师隐藏状态向量的方向一致。 - -- 学生架构 - - 具有和老师一般的体系结构; - - 移除了 Token type embedding 和 pooler; - - 层数减少为 1/2:作者调查发现改变隐层维度对计算效率的影响比其他因素的变化要小(比如层数)。 - -从老师的两层中选择一层来初始化学生。蒸馏应用了Liu et al. [2019] 提出的 BERT 模型训练最佳实践。语料和 Bert 使用的一致。 - -##### 3.2.2.3 FastBERT: a Self-distilling BERT with Adaptive Inference Time 【蒸馏】 - -![](img/20200731202733.png) - -- 论文地址:https://arxiv.org/pdf/2004.02178 -- 模型压缩方法:知识蒸馏 -- 模型压缩方法介绍: - - 样本自适应机制(Sample-wise adaptive mechanism) - - 思路: - - 在每层Transformer后都去预测样本标签,如果某样本预测结果的置信度很高,就不用继续计算了,就是自适应调整每个样本的计算量,容易的样本通过一两层就可以预测出来,较难的样本则需要走完全程。 - - 操作: - - 给每层后面接一个分类器,毕竟分类器比Transformer需要的成本小多了 - - 自蒸馏(Self-distillation) - - 思路: - - 在预训练和精调阶段都只更新主干参数; - - 精调完后freeze主干参数,用分支分类器(图中的student)蒸馏主干分类器(图中的teacher)的概率分布 - - 优点: - - 非蒸馏的结果没有蒸馏要好 - - 不再依赖于标注数据。蒸馏的效果可以通过源源不断的无标签数据来提升 - -##### 3.2.2.4 TinyBERT: Distilling BERT for Natural Language Understanding 【蒸馏】 - -![](img/20200927191946.png) - -- 论文地址:https://arxiv.org/pdf/1909.10351.pdf -- 模型压缩方法:知识蒸馏 -- tinybert的创新点:学习了teacher Bert中更多的层数的特征表示; -- 模型压缩方法介绍: - - 基于transformer的知识蒸馏模型压缩 - - 学习了teacher Bert中更多的层数的特征表示; - - 特征表示: - - 词向量层的输出; - - Transformer layer的输出以及注意力矩阵; - - 预测层输出(仅在微调阶段使用); - - bert知识蒸馏的过程 - - 左图:整体概括了知识蒸馏的过程 - - 左边:Teacher BERT; - - 右边:Student TinyBERT - - 目标:将Teacher BERT学习到的知识迁移到TinyBERT中 - - 右图:描述了知识迁移的细节; - - 在训练过程中选用Teacher BERT中每一层transformer layer的attention矩阵和输出作为监督信息 - -### 3.3 Bert 模型压缩方法 之 量化 - -#### 3.3.1 什么是量化? - -- 量化:把FP32改成FP16或者INT8; - -#### 3.3.2 Q-BERT: Hessian Based Ultra Low Precision Quantization of BERT 【量化】 - -- 论文地址:https://arxiv.org/abs/1909.05840 -- 论文源码: -- 收录期刊:AAAI 2020 收录 -- 模型压缩方法:量化 - -> 量化技术介绍:通过减少用于表示每个权重值的精度来压缩模型。例如模型使用float32标准定义参数的精度进行训练,然后我们可以使用量化技术选择float16,甚至int8表示参数的精度用于压缩模型。 - -- 模型压缩方法介绍: - - 混合精确量化: - - 介绍:由于不同的编码器层负责不同的语义表示,预计他们表现出不同的灵敏度。因此该工作为更敏感的层分配更高的精度以保证模型表现。通过海森关注量化(HAWQ)计算每一层参数的海森频谱(例如特征值),具有更高海森频谱的网络层是对量化更敏感的,需要更高的精度; - - 思路: - - step 1:在执行海森关注量化时对于不同的训练数据获得每一层的平均最大特征值和其方差作为指标来决定每一层的量化精度; - - step 2:然后根据所选的精度设置执行量化包括每一层的参数和激活函数,并微调模型 - - 分组量化: - - 介绍:在编码器层中的每一个自注意力头有四个参数矩阵,即和输出权重矩阵。将此四个矩阵作为一个具有相同量化范围的整体直接量化会显著降低模型准确性。该工作将每个自注意力头对应的四个权重矩阵作为一个组,所以有12个组(12个自注意力头)。此外,在每一组中,将顺序的输出神经元分组,比如每一自注意力子层有4*12*64=3072个神经元,其中64为输出神经元,每6个输出神经元为一个子组,所以总共有12×64/6= 128个子组,每个子组可以有自己的量化范围。分层量化以及分组量化可由下图阐述。 - -![](img/20200927153839.png) - - -### 3.4 Bert 模型压缩方法 之 剪枝 - -#### 3.4.1 什么是剪枝? - -- 剪枝:剪掉多余的连接、多余的注意力头、甚至LayerDrop[1]直接砍掉一半Transformer层 - -## 四、模型压缩存在问题? - -- 精度的下降 - - 低秩因式分解 and 跨层参数共享 计算量并没有下降; - - 剪枝会直接降低模型的拟合能力; - - 量化虽然有提升但也有瓶颈; - - 蒸馏的不确定性最大,很难预知你的BERT教出来怎样的学生; - -## 参考 - -1. [关于BERT的模型压缩简介](https://zhuanlan.zhihu.com/p/110934513) diff --git a/NLPinterview/PreTraining/elmo/img/20200528133755.png b/NLPinterview/PreTraining/elmo/img/20200528133755.png deleted file mode 100644 index 84f73eb..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200528133755.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200624080740.png b/NLPinterview/PreTraining/elmo/img/20200624080740.png deleted file mode 100644 index ceb9a79..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200624080740.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200624084515.png b/NLPinterview/PreTraining/elmo/img/20200624084515.png deleted file mode 100644 index 4a76dd4..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200624084515.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200629083749.png b/NLPinterview/PreTraining/elmo/img/20200629083749.png deleted file mode 100644 index 20c17cf..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200629083749.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200629084400.png b/NLPinterview/PreTraining/elmo/img/20200629084400.png deleted file mode 100644 index ed0194b..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200629084400.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200629085428.png b/NLPinterview/PreTraining/elmo/img/20200629085428.png deleted file mode 100644 index dcf8e13..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200629085428.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200629085533.png b/NLPinterview/PreTraining/elmo/img/20200629085533.png deleted file mode 100644 index 04abda4..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200629085533.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200629085712.png b/NLPinterview/PreTraining/elmo/img/20200629085712.png deleted file mode 100644 index def3a6c..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200629085712.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200629085906.png b/NLPinterview/PreTraining/elmo/img/20200629085906.png deleted file mode 100644 index 78b158d..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200629085906.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200629092209.png b/NLPinterview/PreTraining/elmo/img/20200629092209.png deleted file mode 100644 index ce443d5..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200629092209.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200629203527.png b/NLPinterview/PreTraining/elmo/img/20200629203527.png deleted file mode 100644 index 4937838..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200629203527.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200630084746.png b/NLPinterview/PreTraining/elmo/img/20200630084746.png deleted file mode 100644 index 5ed6dc5..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200630084746.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200701082543.png b/NLPinterview/PreTraining/elmo/img/20200701082543.png deleted file mode 100644 index adace01..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200701082543.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200701091112.png b/NLPinterview/PreTraining/elmo/img/20200701091112.png deleted file mode 100644 index cb79bfd..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200701091112.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200809105640.png b/NLPinterview/PreTraining/elmo/img/20200809105640.png deleted file mode 100644 index 070a974..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200809105640.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20200809110034.png b/NLPinterview/PreTraining/elmo/img/20200809110034.png deleted file mode 100644 index b6d7e1f..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20200809110034.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20201130205012.png b/NLPinterview/PreTraining/elmo/img/20201130205012.png deleted file mode 100644 index 2a3687f..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20201130205012.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20201130205229.png b/NLPinterview/PreTraining/elmo/img/20201130205229.png deleted file mode 100644 index 59030ac..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20201130205229.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20201130205325.png b/NLPinterview/PreTraining/elmo/img/20201130205325.png deleted file mode 100644 index 827f6ba..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20201130205325.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/20201130205357.png b/NLPinterview/PreTraining/elmo/img/20201130205357.png deleted file mode 100644 index d9cf973..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/20201130205357.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/Elmo.png b/NLPinterview/PreTraining/elmo/img/Elmo.png deleted file mode 100644 index cc6498e..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/Elmo.png and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg b/NLPinterview/PreTraining/elmo/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg deleted file mode 100644 index c6d83d3..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/img/zg.png b/NLPinterview/PreTraining/elmo/img/zg.png deleted file mode 100644 index 16068e1..0000000 Binary files a/NLPinterview/PreTraining/elmo/img/zg.png and /dev/null differ diff --git "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" "b/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" deleted file mode 100644 index bba4c4e..0000000 Binary files "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" "b/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" deleted file mode 100644 index 0073695..0000000 Binary files "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" "b/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" deleted file mode 100644 index 680268b..0000000 Binary files "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" "b/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" deleted file mode 100644 index 88c6211..0000000 Binary files "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" "b/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" deleted file mode 100644 index 2e542fa..0000000 Binary files "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" "b/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" deleted file mode 100644 index d4568e1..0000000 Binary files "a/NLPinterview/PreTraining/elmo/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/elmo/readme.md b/NLPinterview/PreTraining/elmo/readme.md deleted file mode 100644 index 59b26a8..0000000 --- a/NLPinterview/PreTraining/elmo/readme.md +++ /dev/null @@ -1,47 +0,0 @@ -# 【关于 Elmo】 那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人论文读书笔记:https://github.com/km1994/nlp_paper_study -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/Elmo.png) - -## 一、Elmo 动机篇 - -### 1.1 为什么会有 Elmo? - -- 多义词问题: - - 因为 one-hot、word2vec、fastText 为静态方式,即训练好后,每个词表达固定; -- 单向性: - - 因为 one-hot、word2vec、fastText 都是 从左向右 学习,导致该方法 不能 同时考虑 两边信息; - -## 二、Elmo 介绍篇 - -### 2.1 Elmo 的 特点? - -基于特征融合 的 word emb - -### 2.2 Elmo 的 思想是什么? - -- 预训练时,使用语言模型学习一个单词的emb(**多义词无法解决**); -- 使用时,单词间具有特定上下文,可根据上下文单词语义调整单词的emb表示(**可解决多义词问题**) - - 理解:因为预训练过程中,emlo 中 的 lstm 能够学习到 每个词 对应的 上下文信息,并保存在网络中,在 fine-turning 时,下游任务 能够对 该 网络进行 fine-turning,使其 学习到新特征; - -![](img/20200629092209.png) - -## 三、Elmo 问题篇 - -### 3.1 Elmo 存在的问题是什么? - -1. 在做序列编码任务时,使用 LSTM; -2. ELMo 采用双向拼接的融合特征,比Bert一体化融合特征方式弱; - - -## 参考资料 - -1. [神经网路语言模型(NNLM)的理解](https://blog.csdn.net/lilong117194/article/details/82018008) -3. [NLP 面试题(一)和答案,附有参考URL](https://www.jianshu.com/p/fbb6d5e75059) \ No newline at end of file diff --git a/NLPinterview/PreTraining/fasttext/img/20200528133755.png b/NLPinterview/PreTraining/fasttext/img/20200528133755.png deleted file mode 100644 index 84f73eb..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200528133755.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200624080740.png b/NLPinterview/PreTraining/fasttext/img/20200624080740.png deleted file mode 100644 index ceb9a79..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200624080740.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200624084515.png b/NLPinterview/PreTraining/fasttext/img/20200624084515.png deleted file mode 100644 index 4a76dd4..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200624084515.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200629083749.png b/NLPinterview/PreTraining/fasttext/img/20200629083749.png deleted file mode 100644 index 20c17cf..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200629083749.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200629084400.png b/NLPinterview/PreTraining/fasttext/img/20200629084400.png deleted file mode 100644 index ed0194b..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200629084400.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200629085428.png b/NLPinterview/PreTraining/fasttext/img/20200629085428.png deleted file mode 100644 index dcf8e13..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200629085428.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200629085533.png b/NLPinterview/PreTraining/fasttext/img/20200629085533.png deleted file mode 100644 index 04abda4..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200629085533.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200629085712.png b/NLPinterview/PreTraining/fasttext/img/20200629085712.png deleted file mode 100644 index def3a6c..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200629085712.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200629085906.png b/NLPinterview/PreTraining/fasttext/img/20200629085906.png deleted file mode 100644 index 78b158d..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200629085906.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200629092209.png b/NLPinterview/PreTraining/fasttext/img/20200629092209.png deleted file mode 100644 index ce443d5..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200629092209.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200629203527.png b/NLPinterview/PreTraining/fasttext/img/20200629203527.png deleted file mode 100644 index 4937838..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200629203527.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200630084746.png b/NLPinterview/PreTraining/fasttext/img/20200630084746.png deleted file mode 100644 index 5ed6dc5..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200630084746.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200701082543.png b/NLPinterview/PreTraining/fasttext/img/20200701082543.png deleted file mode 100644 index adace01..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200701082543.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200701091112.png b/NLPinterview/PreTraining/fasttext/img/20200701091112.png deleted file mode 100644 index cb79bfd..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200701091112.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200809105640.png b/NLPinterview/PreTraining/fasttext/img/20200809105640.png deleted file mode 100644 index 070a974..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200809105640.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20200809110034.png b/NLPinterview/PreTraining/fasttext/img/20200809110034.png deleted file mode 100644 index b6d7e1f..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20200809110034.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20201130205012.png b/NLPinterview/PreTraining/fasttext/img/20201130205012.png deleted file mode 100644 index 2a3687f..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20201130205012.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20201130205229.png b/NLPinterview/PreTraining/fasttext/img/20201130205229.png deleted file mode 100644 index 59030ac..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20201130205229.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20201130205325.png b/NLPinterview/PreTraining/fasttext/img/20201130205325.png deleted file mode 100644 index 827f6ba..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20201130205325.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/20201130205357.png b/NLPinterview/PreTraining/fasttext/img/20201130205357.png deleted file mode 100644 index d9cf973..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/20201130205357.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/fastText.png b/NLPinterview/PreTraining/fasttext/img/fastText.png deleted file mode 100644 index 8f7e117..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/fastText.png and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg b/NLPinterview/PreTraining/fasttext/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg deleted file mode 100644 index c6d83d3..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/img/zg.png b/NLPinterview/PreTraining/fasttext/img/zg.png deleted file mode 100644 index 16068e1..0000000 Binary files a/NLPinterview/PreTraining/fasttext/img/zg.png and /dev/null differ diff --git "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" "b/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" deleted file mode 100644 index bba4c4e..0000000 Binary files "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" "b/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" deleted file mode 100644 index 0073695..0000000 Binary files "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" "b/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" deleted file mode 100644 index 680268b..0000000 Binary files "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" "b/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" deleted file mode 100644 index 88c6211..0000000 Binary files "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" "b/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" deleted file mode 100644 index 2e542fa..0000000 Binary files "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" "b/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" deleted file mode 100644 index d4568e1..0000000 Binary files "a/NLPinterview/PreTraining/fasttext/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/fasttext/readme.md b/NLPinterview/PreTraining/fasttext/readme.md deleted file mode 100644 index 09db667..0000000 --- a/NLPinterview/PreTraining/fasttext/readme.md +++ /dev/null @@ -1,166 +0,0 @@ -# 【关于 fastText】 那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人论文读书笔记:https://github.com/km1994/nlp_paper_study -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/fastText.png) - -## 一、fastText 动机篇 - -### 1.1 word-level Model 是什么? - -- 介绍:基于word单词作为基本单位的,这种方式虽然能够很好的对词库中每一个词进行向量表示 - -### 1.2 word-level Model 存在什么问题? - -- OOV 问题 - - 问题描述:容易出现单词不存在于词汇库中的情况; - - 解决方法:最佳语料规模,使系统能够获得更多的词汇量; -- 误拼障碍 - - 问题描述:如果遇到了不正式的拼写, 系统很难进行处理; - - 解决方法:矫正或加规则约束; -- 做翻译问题时, 音译姓名比较难做到 - -### 1.3 Character-Level Model 是什么? - -- 介绍:基于 Character 作为基本单位的,这种方式虽然能够很好的对字库中每一个 Char 进行向量表示 - -### 1.4 Character-Level Model 优点? - -- 能够解决 Word-level 所存在的 OOV 问题; -- 拼写类似的单词 具有类似的 embedding; - -### 1.5 Character-Level Model 存在问题? - -- Character-level 的输入句子变长; -- 数据变得稀疏; -- 对于远距离的依赖难以学到; -- 训练速度降低; - -### 1.6 Character-Level Model 问题的解决方法? - -- Lee 等 提出了利用多层 conv 和 pooling 和 highway layer 的方式来解决该问题,其结构如下所示: - - 输入的字符首先需要经过 Character embedding 层,并被转化为 character embeddings 表示; - - 采用 不同窗口大小的卷积核对输入字符的 character embeddings 表示进行卷积操作,论文中采用的窗口的大小分别为 3、4、5 ,也就是说学习 Character-level 的 3-gram、4-gram、5-gram; - - 对不同卷积层的卷积结果进行 max-pooling 操作,即捕获其最显著特征生成 segment embedding; - - segment embedding 经过 Highway Network (有些类似于Residual network,方便深层网络中信息的流通,不过加入了一些控制信息流量的gate); - - 输出结果 再经过 单层 BiGRU,得到最终 的 encoder output; - - 之后,decoder再利用Attention机制以及character level GRU进行decode -- 通过这种方式不仅能够解决 Word-level 所存在的 OOV 问题,而且能够捕获 句子的 3-gram、4-gram、5-gram 信息,这个也是 后期 FastText 的想法雏形; - -![](img/20200629203527.png) - - -## 二、 词内的n-gram信息(subword n-gram information) 介绍篇 - -### 2.1 引言 - -在前面,我们已经介绍和比较了 word-level 和 character-level 的优缺点,并根据其特点,提出一种介于 word-level Model 和 Character-level 之间的 Model —— Subword Model。 - -那么,我们可不可以采取类似于上面的subword的思路来产生更好的word embedding呢? - -FAIR的FastText就是利用subword将word2vec扩充,有效的构建embedding。 - -### 2.2 fastText 是什么? - -将每个 word 表示成 bag of character n-gram 以及单词本身的集合,例如对于where这个单词和n=3的情况,它可以表示为 , ,其中"<",">"为代表单词开始与结束的特殊标记。 - -假设对于word $w$ ,其n-gram集合用 $G_w$ 表示,每个 n-gram 的矢量表示为![](img/zg.png),则每个单词可以表示成其所有n-gram的矢量和的形式,而center word $w$ 与context word $c$ 的分数就可表示成 - -![](img/20200528133755.png) - -之后就可以按照经典的word2vec算法训练得到这些特征向量。 - -这种方式既保持了word2vec计算速度快的优点,又解决了遇到training data中没见过的oov word的表示问题,可谓一举两得。 - -### 2.3 fastText 的结构是什么样? - -- 每个单词通过嵌入层可以得到词向量; -- 然后将所有词向量平均可以得到文本的向量表达; -- 在输入分类器,使用softmax计算各个类别的概率; - -![](img/20200629084400.png) - -### 2.4 为什么 fastText 要使用词内的n-gram信息(subword n-gram information)? - -- 之前方法: - - 以词汇表中的独立单词作为基本单元来进行训练学习的 - - 存在问题: - - 低频词、罕见词:由于在语料中本身出现的次数就少,得不到足够的训练,效果不佳 - - 未登录词:如果出现了一些在词典中都没有出现过的词,或者带有某些拼写错误的词,传统模型更加无能为力 - -### 2.5 fastText 词内的n-gram信息(subword n-gram information) 介绍? - -- s1. 将一个单词打散到字符级别; -- s2. 利用字符级别的n-gram信息来捕捉字符间的顺序关系 - - 目的:以此丰富单词内部更细微的语义 -- 举例: - - 对于一个单词“google”,为了表达单词前后边界,我们加入<>两个字符,即变形为“”; - - 抽取所有的tri-gram信息:G = { }; - - 通过这种方式:原始的一个单词google,就被一个字符级别的n-gram集合所表达; - -### 2.6 fastText 词内的n-gram信息 的 训练过程? - -- s1:每个n-gram都会对应训练一个向量; -- s2:原来完整单词的词向量就由它对应的所有n-gram的向量求和得到; -- s3:所有的单词向量以及字符级别的n-gram向量会同时相加求平均作为训练模型的输入; - -### 2.7 fastText 词内的n-gram信息 存在问题? - -- 由于需要估计的参数多,模型可能会比较膨胀 -- 压缩模型的建议: - - 采用hash-trick:由于n-gram原始的空间太大,可以用某种hash函数将其映射到固定大小的buckets中去,从而实现内存可控; - - 采用quantize命令:对生成的模型进行参数量化和压缩; - - 减小最终向量的维度。 - -## 三、 层次化Softmax回归(Hierarchical Softmax) 介绍篇 - -### 3.1 为什么要用 层次化Softmax回归(Hierarchical Softmax) ? - -- 传统 softmax - - 介绍: - - 以隐藏层的输出h为输入,经过线性和指数变换后,再进行全局的归一化处理,找到概率最大的输出项; - - 问题: - - 当词汇数量V较大时(一般会到几十万量级),Softmax计算代价很大,是O(V)量级。 - -### 3.2 层次化Softmax回归(Hierarchical Softmax) 的思想是什么? - -- 将一个全局多分类的问题,转化成为了若干个二元分类问题,从而将计算复杂度从O(V)降到O(logV); -- 每个二元分类问题,由一个基本的逻辑回归单元来实现 - -### 3.3 层次化Softmax回归(Hierarchical Softmax) 的步骤? - -![](img/20200629085428.png) -- 步骤: - - 从根结点开始,每个中间结点(标记成灰色)都是一个逻辑回归单元,根据它的输出来选择下一步是向左走还是向右走; - - 上图示例中实际上走了一条“左-左-右”的路线,从而找到单词w₂。而最终输出单词w₂的概率,等于中间若干逻辑回归单元输出概率的连乘积; - -![](img/20200629085533.png) - -## 四、fastText 存在问题? - -![](img/20200629085712.png) - -- 如何构造每个逻辑回归单元的输入 - - 特殊函数 ⟦x⟧ - - 如果下一步需要向左走其函数值定义为1,向右则取-1。在训练时,我们知道最终输出叶子结点,并且从根结点到叶子结点的每一步的路径也是确定的。 - - 每个内部结点(逻辑回归单元)对应的一个向量 v' - - 以在训练过程中学习和更新 - - h 是网络中隐藏层的输出 - - 如何建立这棵用于判断的树形结构? - - 霍夫曼树的构造 - - 处理机制:将字符信息编码成为0/1二进制串 - - 结构介绍:给出现频繁的字符较短的编码,出现较少的字符以较长的编码,是最经济的方案 - - 构造步骤: - -![](img/20200629085906.png) - -## 参考资料 - -1. [神经网路语言模型(NNLM)的理解](https://blog.csdn.net/lilong117194/article/details/82018008) -2. [NLP 面试题(一)和答案,附有参考URL](https://www.jianshu.com/p/fbb6d5e75059) \ No newline at end of file diff --git a/NLPinterview/PreTraining/tfidf/img/20200528133755.png b/NLPinterview/PreTraining/tfidf/img/20200528133755.png deleted file mode 100644 index 84f73eb..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200528133755.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200624080740.png b/NLPinterview/PreTraining/tfidf/img/20200624080740.png deleted file mode 100644 index ceb9a79..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200624080740.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200624084515.png b/NLPinterview/PreTraining/tfidf/img/20200624084515.png deleted file mode 100644 index 4a76dd4..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200624084515.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200629083749.png b/NLPinterview/PreTraining/tfidf/img/20200629083749.png deleted file mode 100644 index 20c17cf..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200629083749.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200629084400.png b/NLPinterview/PreTraining/tfidf/img/20200629084400.png deleted file mode 100644 index ed0194b..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200629084400.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200629085428.png b/NLPinterview/PreTraining/tfidf/img/20200629085428.png deleted file mode 100644 index dcf8e13..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200629085428.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200629085533.png b/NLPinterview/PreTraining/tfidf/img/20200629085533.png deleted file mode 100644 index 04abda4..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200629085533.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200629085712.png b/NLPinterview/PreTraining/tfidf/img/20200629085712.png deleted file mode 100644 index def3a6c..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200629085712.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200629085906.png b/NLPinterview/PreTraining/tfidf/img/20200629085906.png deleted file mode 100644 index 78b158d..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200629085906.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200629092209.png b/NLPinterview/PreTraining/tfidf/img/20200629092209.png deleted file mode 100644 index ce443d5..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200629092209.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200629203527.png b/NLPinterview/PreTraining/tfidf/img/20200629203527.png deleted file mode 100644 index 4937838..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200629203527.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200630084746.png b/NLPinterview/PreTraining/tfidf/img/20200630084746.png deleted file mode 100644 index 5ed6dc5..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200630084746.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200701082543.png b/NLPinterview/PreTraining/tfidf/img/20200701082543.png deleted file mode 100644 index adace01..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200701082543.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200701091112.png b/NLPinterview/PreTraining/tfidf/img/20200701091112.png deleted file mode 100644 index cb79bfd..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200701091112.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200809105640.png b/NLPinterview/PreTraining/tfidf/img/20200809105640.png deleted file mode 100644 index 070a974..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200809105640.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20200809110034.png b/NLPinterview/PreTraining/tfidf/img/20200809110034.png deleted file mode 100644 index b6d7e1f..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20200809110034.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20201130205012.png b/NLPinterview/PreTraining/tfidf/img/20201130205012.png deleted file mode 100644 index 2a3687f..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20201130205012.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20201130205229.png b/NLPinterview/PreTraining/tfidf/img/20201130205229.png deleted file mode 100644 index 59030ac..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20201130205229.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20201130205325.png b/NLPinterview/PreTraining/tfidf/img/20201130205325.png deleted file mode 100644 index 827f6ba..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20201130205325.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/20201130205357.png b/NLPinterview/PreTraining/tfidf/img/20201130205357.png deleted file mode 100644 index d9cf973..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/20201130205357.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/TF-idf.png b/NLPinterview/PreTraining/tfidf/img/TF-idf.png deleted file mode 100644 index 2fc6114..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/TF-idf.png and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg b/NLPinterview/PreTraining/tfidf/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg deleted file mode 100644 index c6d83d3..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/img/zg.png b/NLPinterview/PreTraining/tfidf/img/zg.png deleted file mode 100644 index 16068e1..0000000 Binary files a/NLPinterview/PreTraining/tfidf/img/zg.png and /dev/null differ diff --git "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" "b/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" deleted file mode 100644 index bba4c4e..0000000 Binary files "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" "b/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" deleted file mode 100644 index 0073695..0000000 Binary files "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" "b/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" deleted file mode 100644 index 680268b..0000000 Binary files "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" "b/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" deleted file mode 100644 index 88c6211..0000000 Binary files "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" "b/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" deleted file mode 100644 index 2e542fa..0000000 Binary files "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" "b/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" deleted file mode 100644 index d4568e1..0000000 Binary files "a/NLPinterview/PreTraining/tfidf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/tfidf/readme.md b/NLPinterview/PreTraining/tfidf/readme.md deleted file mode 100644 index 3030b16..0000000 --- a/NLPinterview/PreTraining/tfidf/readme.md +++ /dev/null @@ -1,92 +0,0 @@ -# 【关于 TF-idf】 那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人论文读书笔记:https://github.com/km1994/nlp_paper_study -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/TF-idf.png) - -## 一、one-hot 篇 - -### 1.1 为什么有 one-hot ? - -由于计算机无法识别 文本语言,所以需要将文本数字化,one-hot 方法最早的一种将 文本数字化的方法。 - -### 1.2 one-hot 是什么? - -用一个很长的向量来表示一个词,向量长度为词典的大小N,每个向量只有一个维度为1,其余维度全部为0,为1的位置表示该词语在词典的位置。 - -### 1.3 one-hot 有什么特点? - -- 维度长:向量的维度为 **词典大小**; -- 一一其零:每个向量**只有一个维度为1**,其余维度全部为0,**为1的位置表示该词语在词典的位置**; - -### 1.4 one-hot 存在哪些问题? - -- 维度灾难:容易受维数灾难的困扰,每个词语的维度就是语料库字典的长度; -- 离散、稀疏问题:因为 one-Hot 中,句子向量,如果词出现则为1,没出现则为0,但是由于维度远大于句子长度,所以句子中的1远小于0的个数; -- 维度鸿沟问题:词语的编码往往是随机的,导致不能很好地刻画词与词之间的相似性。 - -## 二、TF-IDF 篇 - -### 2.1 什么是 TF-IDF? - -TF-IDF 是一种统计方法,用以评估句子中的某一个词(字)对于整个文档的重要程度。 - -### 2.2 TF-IDF 如何评估词的重要程度? - -- 对于 句子中的某一个词(字)随着其在整个句子中的出现次数的增加,其重要性也随着增加;(正比关系)【体现词在句子中频繁性】 -- 对于 句子中的某一个词(字)随着其在整个文档中的出现频率的增加,其重要性也随着减少;(反比关系)【体现词在文档中的唯一性】 - -### 2.3 TF-IDF 的思想是什么? - -如果某个单词在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类; - -### 2.4 TF-IDF 的计算公式是什么? - -- 词频 (Term Frequency,TF) - - 介绍:体现 词 在 句子 中出现的频率; - - 问题: - - 当一个句子长度的增加,句子中 每一个 出现的次数 也会随之增加,导致该值容易偏向长句子; - - 解决方法: - - 需要做归一化(词频除以句子总字数) - - 公式 - -![](img/20200809105640.png) - -- 逆文本频率(Inverse Document Frequency,IDF) - - 介绍:体现 词 在文档 中出现的频率 - - 方式:某一特定词语的IDF,可以由总句子数目除以包含该词语的句子的数目,再将得到的商取对数得到; - - 作用:如果包含词条t的文档越少, IDF越大,则说明词条具有很好的类别区分能力 - - 公式: - -![](img/20200809110034.png) - -### 2.5 TF-IDF 怎么描述? - -某一特定句子内的高词语频率,以及该词语在整个文档集合中的低文档频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。 - -### 2.6 TF-IDF 的优点是什么? - -- 容易理解; -- 容易实现; - -### 2.7 TF-IDF 的缺点是什么? - -其简单结构并没有考虑词语的语义信息,无法处理一词多义与一义多词的情况。 - -### 2.8 TF-IDF 的应用? - -- 搜索引擎; -- 关键词提取; -- 文本相似性; -- 文本摘要 - -## 参考资料 - -1. [神经网路语言模型(NNLM)的理解](https://blog.csdn.net/lilong117194/article/details/82018008) -2. [NLP 面试题(一)和答案,附有参考URL](https://www.jianshu.com/p/fbb6d5e75059) \ No newline at end of file diff --git a/NLPinterview/PreTraining/word2vec/img/20200528133755.png b/NLPinterview/PreTraining/word2vec/img/20200528133755.png deleted file mode 100644 index 84f73eb..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200528133755.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200624080740.png b/NLPinterview/PreTraining/word2vec/img/20200624080740.png deleted file mode 100644 index ceb9a79..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200624080740.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200624084515.png b/NLPinterview/PreTraining/word2vec/img/20200624084515.png deleted file mode 100644 index 4a76dd4..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200624084515.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200629083749.png b/NLPinterview/PreTraining/word2vec/img/20200629083749.png deleted file mode 100644 index 20c17cf..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200629083749.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200629084400.png b/NLPinterview/PreTraining/word2vec/img/20200629084400.png deleted file mode 100644 index ed0194b..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200629084400.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200629085428.png b/NLPinterview/PreTraining/word2vec/img/20200629085428.png deleted file mode 100644 index dcf8e13..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200629085428.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200629085533.png b/NLPinterview/PreTraining/word2vec/img/20200629085533.png deleted file mode 100644 index 04abda4..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200629085533.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200629085712.png b/NLPinterview/PreTraining/word2vec/img/20200629085712.png deleted file mode 100644 index def3a6c..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200629085712.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200629085906.png b/NLPinterview/PreTraining/word2vec/img/20200629085906.png deleted file mode 100644 index 78b158d..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200629085906.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200629092209.png b/NLPinterview/PreTraining/word2vec/img/20200629092209.png deleted file mode 100644 index ce443d5..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200629092209.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200629203527.png b/NLPinterview/PreTraining/word2vec/img/20200629203527.png deleted file mode 100644 index 4937838..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200629203527.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200630084746.png b/NLPinterview/PreTraining/word2vec/img/20200630084746.png deleted file mode 100644 index 5ed6dc5..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200630084746.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200701082543.png b/NLPinterview/PreTraining/word2vec/img/20200701082543.png deleted file mode 100644 index adace01..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200701082543.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200701091112.png b/NLPinterview/PreTraining/word2vec/img/20200701091112.png deleted file mode 100644 index cb79bfd..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200701091112.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200809105640.png b/NLPinterview/PreTraining/word2vec/img/20200809105640.png deleted file mode 100644 index 070a974..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200809105640.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20200809110034.png b/NLPinterview/PreTraining/word2vec/img/20200809110034.png deleted file mode 100644 index b6d7e1f..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20200809110034.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20201130205012.png b/NLPinterview/PreTraining/word2vec/img/20201130205012.png deleted file mode 100644 index 2a3687f..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20201130205012.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20201130205229.png b/NLPinterview/PreTraining/word2vec/img/20201130205229.png deleted file mode 100644 index 59030ac..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20201130205229.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20201130205325.png b/NLPinterview/PreTraining/word2vec/img/20201130205325.png deleted file mode 100644 index 827f6ba..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20201130205325.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/20201130205357.png b/NLPinterview/PreTraining/word2vec/img/20201130205357.png deleted file mode 100644 index d9cf973..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/20201130205357.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/Word2vec.png b/NLPinterview/PreTraining/word2vec/img/Word2vec.png deleted file mode 100644 index 9da15fa..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/Word2vec.png and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg b/NLPinterview/PreTraining/word2vec/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg deleted file mode 100644 index c6d83d3..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/v2-02f5f0a3a2bc5c8a0931e677df2a78a6_r.jpg and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/img/zg.png b/NLPinterview/PreTraining/word2vec/img/zg.png deleted file mode 100644 index 16068e1..0000000 Binary files a/NLPinterview/PreTraining/word2vec/img/zg.png and /dev/null differ diff --git "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" "b/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" deleted file mode 100644 index bba4c4e..0000000 Binary files "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625082324.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" "b/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" deleted file mode 100644 index 0073695..0000000 Binary files "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20200625101800.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" "b/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" deleted file mode 100644 index 680268b..0000000 Binary files "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201128130050.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" "b/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" deleted file mode 100644 index 88c6211..0000000 Binary files "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211731.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" "b/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" deleted file mode 100644 index 2e542fa..0000000 Binary files "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224211840.png" and /dev/null differ diff --git "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" "b/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" deleted file mode 100644 index d4568e1..0000000 Binary files "a/NLPinterview/PreTraining/word2vec/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201224212421.png" and /dev/null differ diff --git a/NLPinterview/PreTraining/word2vec/readme.md b/NLPinterview/PreTraining/word2vec/readme.md deleted file mode 100644 index 8defdc8..0000000 --- a/NLPinterview/PreTraining/word2vec/readme.md +++ /dev/null @@ -1,138 +0,0 @@ -# 【关于 Word2vec】 那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人论文读书笔记:https://github.com/km1994/nlp_paper_study -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/Word2vec.png) - -## 一、Wordvec 介绍篇 - -### 1.1 Wordvec 指什么? - -- 介绍:word2vec是一个把词语转化为对应向量的形式。word2vec中建模并不是最终的目的,其目的是获取建模的参数,这个过程称为fake task。 -- 双剑客 - - CBOW vs Skip-gram - -### 1.2 Wordvec 中 CBOW 指什么? - -- CBOW - - 思想:用周围词预测中心词 - - 输入输出介绍:输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量 - - ![](img/20200701091112.png) - -### 1.3 Wordvec 中 Skip-gram 指什么? - -- Skip-gram - - 思想:用中心词预测周围词 - - 输入输出介绍:输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量 - - ![](img/20200629083749.png) - -### 1.4 CBOW vs Skip-gram 哪一个好? - -- CBOW 可以理解为 一个老师教多个学生;(高等教育) -- Skip-gram 可以理解为 一个学生被多个老师教;(补习班) -- 那问题来了? - - 最后 哪个学生 成绩 会更好? - -## 二、Wordvec 优化篇 - -### 2.1 Word2vec 中 霍夫曼树 是什么? - -HS用哈夫曼树,把预测one-hot编码改成预测一组01编码,进行层次分类。 -- 输入输出: - - 输入:权值为(w1,w2,...wn)的n个节点 - - 输出:对应的霍夫曼树 -- 步骤: - 1. 将(w1,w2,...wn)看做是有n棵树的森林,每个树仅有一个节点。 - 2. 在森林中选择根节点权值最小的两棵树进行合并,得到一个新的树,这两颗树分布作为新树的左右子树。新树的根节点权重为左右子树的根节点权重之和。 - 3. 将之前的根节点权值最小的两棵树从森林删除,并把新树加入森林。 - 4. 重复步骤2)和3)直到森林里只有一棵树为止。 -- 举例说明: -     -下面我们用一个具体的例子来说明霍夫曼树建立的过程,我们有(a,b,c,d,e,f)共6个节点,节点的权值分布是(20,4,8,6,16,3)。 - -首先是最小的b和f合并,得到的新树根节点权重是7.此时森林里5棵树,根节点权重分别是20,8,6,16,7。此时根节点权重最小的6,7合并,得到新子树,依次类推,最终得到下面的霍夫曼树。 - -![](img/微信截图_20201224212421.png) - -### 2.2 Word2vec 中 为什么要使用 霍夫曼树? - -一般得到霍夫曼树后我们会对叶子节点进行霍夫曼编码,由于权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样我们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,也符合我们的信息论,即我们希望越常用的词拥有更短的编码。如何编码呢?一般对于一个霍夫曼树的节点(根节点除外),可以约定左子树编码为0,右子树编码为1.如上图,则可以得到c的编码是00。 - -在word2vec中,约定编码方式和上面的例子相反,即约定左子树编码为1,右子树编码为0,同时约定左子树的权重不小于右子树的权重。 - -### 2.3 Word2vec 中使用 霍夫曼树 的好处? - -1. 由于是二叉树,之前计算量为V,现在变成了log2V; -2. 由于使用霍夫曼树是高频的词靠近树根,这样高频词需要更少的时间会被找到,这符合我们的贪心优化思想。 - -### 2.4 为什么 Word2vec 中会用到 负采样? - -- 动机:使用霍夫曼树来代替传统的神经网络,可以提高模型训练的效率。但是如果我们的训练样本里的中心词w是一个很生僻的词,那么就得在霍夫曼树中辛苦的向下走很久了; -- 介绍:一种概率采样的方式,可以根据词频进行随机抽样,倾向于选择词频较大的负样本; -- 优点: - - 用来提高训练速度并且改善所得到词向量的质量的一种方法; - - 不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。 - -### 2.5 Word2vec 中会用到 负采样 是什么样? - -因为使用softmax时,分母需要将中心词与语料库总所有词做点乘,代价太大: - -![](img/微信截图_20201224211731.png) - -所以负采样方法将softmax函数换成sigmoid函数。 - -选取K个负样本,即窗口之外的样本,计算中心词与负样本的点乘,最小化该结果。计算中心词与窗口内单词的点乘,最大化该结果,目标函数为: - -![](img/微信截图_20201224211840.png) - -### 2.6 Word2vec 中 负采样 的采样方式? - -NS是一种概率采样的方式,可以根据词频进行随机抽样,我们倾向于选择词频比较大的负样本,比如“的”,这种词语其实是对我们的目标单词没有很大贡献的。 - -Word2vec则在词频基础上取了0.75次幂,减小词频之间差异过大所带来的影响,使得词频比较小的负样本也有机会被采到。 - -极大化正样本出现的概率,同时极小化负样本出现的概率,以sigmoid来代替softmax,相当于进行二分类,判断这个样本到底是不是正样本。 - -## 三、Wordvec 对比篇 - -### 3.1 word2vec和NNLM对比有什么区别?(word2vec vs NNLM) -- NNLM:是神经网络语言模型,使用前 n - 1 个单词预测第 n 个单词; -- word2vec :使用第 n - 1 个单词预测第 n 个单词的神经网络模型。但是 word2vec 更专注于它的中间产物词向量,所以在计算上做了大量的优化。优化如下: -1. 对输入的词向量直接按列求和,再按列求平均。这样的话,输入的多个词向量就变成了一个词向量。 -2. 采用分层的 softmax(hierarchical softmax),实质上是一棵哈夫曼树。 -3. 采用负采样,从所有的单词中采样出指定数量的单词,而不需要使用全部的单词 - -### 3.2 word2vec和tf-idf 在相似度计算时的区别? - -1. word2vec 是稠密的向量,而 tf-idf 则是稀疏的向量; -2. word2vec 的向量维度一般远比 tf-idf 的向量维度小得多,故而在计算时更快; -3. word2vec 的向量可以表达语义信息,但是 tf-idf 的向量不可以; -4. word2vec 可以通过计算余弦相似度来得出两个向量的相似度,但是 tf-idf 不可以; - -## 四、word2vec 实战篇 - -### 4.1 word2vec训练trick,window设置多大? - -- window设置: - - 比较大,会提取更多的topic信息 - - 设置比较小的话会更加关注于词本身。 -- 默认参数是5,但是在有些任务中window为2效果最好,比如某些英语语料的短文本任务(并非越大越好) - -### 4.1 word2vec训练trick,词向量纬度,大与小有什么影响,还有其他参数? - -词向量维度代表了词语的特征,特征越多能够更准确的将词与词区分,就好像一个人特征越多越容易与他人区分开来。但是在实际应用中维度太多训练出来的模型会越大,虽然维度越多能够更好区分,但是词与词之间的关系也就会被淡化,这与我们训练词向量的目的是相反的,我们训练词向量是希望能够通过统计来找出词与词之间的联系,维度太高了会淡化词之间的关系,但是维度太低了又不能将词区分,所以词向量的维度选择依赖于你的实际应用场景,这样才能继续后面的工作。一般说来200-400维是比较常见的。 - - -## 参考资料 - -1. [word2vec原理(一) CBOW与Skip-Gram模型基础](https://www.cnblogs.com/pinard/p/7160330.html) -2. [word2vec原理(二) 基于Hierarchical Softmax的模型](https://www.cnblogs.com/pinard/p/7243513.html) -3. [word2vec原理(三) 基于Negative Sampling的模型](https://www.cnblogs.com/pinard/p/7249903.html) -4. [神经网路语言模型(NNLM)的理解](https://blog.csdn.net/lilong117194/article/details/82018008) -5. [NLP 面试题(一)和答案,附有参考URL](https://www.jianshu.com/p/fbb6d5e75059) \ No newline at end of file diff --git a/NLPinterview/QA/FAQ/img/20200904112045.png b/NLPinterview/QA/FAQ/img/20200904112045.png deleted file mode 100644 index dcba949..0000000 Binary files a/NLPinterview/QA/FAQ/img/20200904112045.png and /dev/null differ diff --git a/NLPinterview/QA/FAQ/img/20200904114741.png b/NLPinterview/QA/FAQ/img/20200904114741.png deleted file mode 100644 index 9403b5b..0000000 Binary files a/NLPinterview/QA/FAQ/img/20200904114741.png and /dev/null differ diff --git a/NLPinterview/QA/FAQ/img/20200904192633.png b/NLPinterview/QA/FAQ/img/20200904192633.png deleted file mode 100644 index 6f8ce34..0000000 Binary files a/NLPinterview/QA/FAQ/img/20200904192633.png and /dev/null differ diff --git a/NLPinterview/QA/FAQ/img/20200904192812.png b/NLPinterview/QA/FAQ/img/20200904192812.png deleted file mode 100644 index b4b3eed..0000000 Binary files a/NLPinterview/QA/FAQ/img/20200904192812.png and /dev/null differ diff --git a/NLPinterview/QA/FAQ/img/3c0a842e2e7046f3838a8bb3dff9b27d.png b/NLPinterview/QA/FAQ/img/3c0a842e2e7046f3838a8bb3dff9b27d.png deleted file mode 100644 index dca45c8..0000000 Binary files a/NLPinterview/QA/FAQ/img/3c0a842e2e7046f3838a8bb3dff9b27d.png and /dev/null differ diff --git "a/NLPinterview/QA/FAQ/img/EncoderDecoder\346\250\241\345\274\217.png" "b/NLPinterview/QA/FAQ/img/EncoderDecoder\346\250\241\345\274\217.png" deleted file mode 100644 index c78098e..0000000 Binary files "a/NLPinterview/QA/FAQ/img/EncoderDecoder\346\250\241\345\274\217.png" and /dev/null differ diff --git a/NLPinterview/QA/FAQ/img/FAQ.png b/NLPinterview/QA/FAQ/img/FAQ.png deleted file mode 100644 index 3b898d6..0000000 Binary files a/NLPinterview/QA/FAQ/img/FAQ.png and /dev/null differ diff --git "a/NLPinterview/QA/FAQ/img/FAQ\344\273\213\347\273\215.drawio" "b/NLPinterview/QA/FAQ/img/FAQ\344\273\213\347\273\215.drawio" deleted file mode 100644 index 4dbf4d8..0000000 --- "a/NLPinterview/QA/FAQ/img/FAQ\344\273\213\347\273\215.drawio" +++ /dev/null @@ -1 +0,0 @@ -7VpNc5swEP01mmkP7hiJzyPYuO1Me0k606Y3xchAC4jIIrbz6ysJYUycZJyZ1ISEiy3tamGfVnoPZAM0y7efGS6T7zQiGYDTaAvQHEDoOlB8SsNOG5BTG2KWRrXJaA2X6R3Rxqm2VmlE1p2BnNKMp2XXuKRFQZa8Y8OM0U132Ipm3buWOCZHhsslzo6tP9OIJxoFdFr7F5LGSXNnw/ZqT46bwRrJOsER3RyYUAjQjFHK61a+nZFMzl0zL3Xc4hHvPjFGCn5KwFW5+rk2C+f3/KJ0ftxdbJyv5cTVufFdA5hEAr/uUsYTGtMCZ2FrDRitiojIq05Frx3zjdJSGA1h/EM43+li4opTYUp4nmkv2ab8lwz/ZOne1YFnvtVXVp1d0yk42x0Eye7Voa8NU70mrsYnQT06bdq0phVbkifmqll+mMWEPzEO7osrNgWhORH5iDhGMszT224eWC/PeD+uraBo6CI+o6D6urc4q/SdALQzkW4QpbedSts3lVx6wYoWfLLCeZqJOfOBXEU2zks1dwiZ4lvsrTXNRKr3HWrw7OGQiqWECVdBNo/H5bSg6xKLaYd1saYqm7VaOTIXwyy3e1+WFmSS6N2mvJ70NkBEK9bfCrC4cPEg4mu8/BurVTxZ0oyy+mIsvv4ALWuf2732xwduFDrAM4HvgtAGrgsCQQrTm4rIMtYpiBLWWXQzE2ZVjcZ6bwt2N9gmSTm5VJOE5htBst3NpOtNGCfbp5f48ZLUAdDUFKU52nB1f9MyntHQWHLAdk3ci69ib6Slk2kJnkhLqE9agiMtDQvw6+NaG3iCZR3VmAF/Jtk38IE/lRZ/Dnz0TNYdBBdDq28ubp7EXz8ZvyCpohNJ1eyTVNFIqsMC/BpJ1TWBuwChBbwABCEIXeAvgGtLi3ik9YO3SKoI9k6qxtGkvH1SNU8kVatPUjVHUh0W4BHUGZQizK9JFKVFLMdJjTDUsYcDfFM+hL+ERgxDOXo/GjHgO1QO60TlsPtUDmtUjmEBHkGd5R1DvVH4cxAKqfCA66lXi4U6wVFvHV74fvTD7P84B71D/bBP1A+nT/2wR/0YFuAR1BsFdQZRtOSbk+dLdQwcKZDnFMVBSKXV+yGdMxLysACPoEZQwwF1BpXxgCfEJZQNHwKvPrGbyz8tyd/MDfkLjxAgN5QaVAuQZ59dd4ahRt7/UyPRbf8GqnwH/6VF4T8= \ No newline at end of file diff --git a/NLPinterview/QA/FAQ/img/ab1b2a4bf5db0f0cf89503df2a9e5e14.png b/NLPinterview/QA/FAQ/img/ab1b2a4bf5db0f0cf89503df2a9e5e14.png deleted file mode 100644 index 5305ffb..0000000 Binary files a/NLPinterview/QA/FAQ/img/ab1b2a4bf5db0f0cf89503df2a9e5e14.png and /dev/null differ diff --git "a/NLPinterview/QA/FAQ/img/\344\273\273\345\212\241\345\236\213\345\257\274\345\220\221\345\257\271\350\257\235\347\263\273\347\273\237\347\232\204\344\274\240\347\273\237\344\274\240\351\200\222\351\200\224\345\276\204.png" "b/NLPinterview/QA/FAQ/img/\344\273\273\345\212\241\345\236\213\345\257\274\345\220\221\345\257\271\350\257\235\347\263\273\347\273\237\347\232\204\344\274\240\347\273\237\344\274\240\351\200\222\351\200\224\345\276\204.png" deleted file mode 100644 index 662b8c1..0000000 Binary files "a/NLPinterview/QA/FAQ/img/\344\273\273\345\212\241\345\236\213\345\257\274\345\220\221\345\257\271\350\257\235\347\263\273\347\273\237\347\232\204\344\274\240\347\273\237\344\274\240\351\200\222\351\200\224\345\276\204.png" and /dev/null differ diff --git "a/NLPinterview/QA/FAQ/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210116102726.png" "b/NLPinterview/QA/FAQ/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210116102726.png" deleted file mode 100644 index 3d64187..0000000 Binary files "a/NLPinterview/QA/FAQ/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210116102726.png" and /dev/null differ diff --git "a/NLPinterview/QA/FAQ/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206162253.png" "b/NLPinterview/QA/FAQ/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206162253.png" deleted file mode 100644 index 5f4129a..0000000 Binary files "a/NLPinterview/QA/FAQ/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206162253.png" and /dev/null differ diff --git "a/NLPinterview/QA/FAQ/img/\350\207\252\347\204\266\350\257\255\350\250\200\350\241\250\350\276\276\347\232\204\344\270\200\344\270\252\350\257\264\346\230\216\344\276\213\345\255\220.png" "b/NLPinterview/QA/FAQ/img/\350\207\252\347\204\266\350\257\255\350\250\200\350\241\250\350\276\276\347\232\204\344\270\200\344\270\252\350\257\264\346\230\216\344\276\213\345\255\220.png" deleted file mode 100644 index 421dd7d..0000000 Binary files "a/NLPinterview/QA/FAQ/img/\350\207\252\347\204\266\350\257\255\350\250\200\350\241\250\350\276\276\347\232\204\344\270\200\344\270\252\350\257\264\346\230\216\344\276\213\345\255\220.png" and /dev/null differ diff --git a/NLPinterview/QA/FAQ/readme.md b/NLPinterview/QA/FAQ/readme.md deleted file mode 100644 index 97571f6..0000000 --- a/NLPinterview/QA/FAQ/readme.md +++ /dev/null @@ -1,157 +0,0 @@ -# 【关于 FAQ 检索式问答系统】 那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人论文读书笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210206162253.png) - -## 一、动机 - -### 1.1 问答系统的动机? - -- 场景:假设 你有 一个 标准的问题库,此时 有一个 新 query 进来,你会做什么操作? - -- 灵魂三连问: - - 如何根据 这个 query,你怎么返回一个标准答案呢? - - 如何从 问题库 里面找 答案? - - 如何 判断 你 找到 答案 是 对的? - -### 1.2 问答系统 是什么? - -- 介绍:问答系统是信息检索的一种高级形式,能够更加准确地理解用户用自然语言提出的问题,并通过检索语料库、知识图谱或问答知识库返回简洁、准确的匹配答案。相较于搜索引擎,问答系统能更好地理解用户提问的真实意图, 进一步能更有效地满足用户的信息需求。 -- 目标对象:用户输入的 query 和 答案; -- 领域类型分类: - - 面向限定域的问答系统; - - 面向开放域的问答系统; - - 面向常用问题集的问答系统; -- 根据答案来源分类: - - 基于结构化数据的问答系统(eg:KBQA); - - 基于文本的问答系统(eg:阅读理解); - - 基于问答对的问答系统(eg:FAQ); -- 答案的反馈机制分类: - - 基于检索式的问答系统; - - 基于生成式的问答系统; - -## 二、FAQ 检索式问答系统介绍篇 - -### 2.1 FAQ 检索式问答系统 是 什么? - -- 名称:(Frequently asked Questions),是检索式问答系统 -- 目标:给定 标准问题库,匹配与用户输入 query 最相近的问题并返回答案; -- 流程: - - 分析 用户输入 的 query; - - 计算 与 query 最相近 的 标准问题; - - 做 Rank,并 取 Top1 的 标准问题; - - 返回 Top1 的 标准问题的答案; - -![](img/20200904112045.png) - -### 2.2 query 匹配标准 QA 的核心是什么? - -- 核心组成 - - 用户输入 的 query 和 标准问题 的 的相似度; - - 常用方法: - - 关键字匹配; - - TF-idf 相似度计算; - - 用户输入 的 query 和 标准答案 的 匹配度; - - 常用方法: - - DL 模型 相似度计算; - - Bert 句向量 语义相似度计算; - -## 三、FAQ 检索式问答系统 方案篇 - -### 3.1 常用 方案有哪些? - -- 方案一:QA 匹配:输入Query与候选的所有Answer 计算相似度,去找哪一个最合适 -- 方案二:QQ 匹配:输入Query与历史语料库里的Query去找哪一个最相似,然后把找到的query对应的Answer取出即可;【常用】 - -### 3.2 为什么 QQ 匹配比较常用? - -#### 3.2.1 QQ 匹配的优点有哪些? - -- 原因 1:语义空间 -- 原因 2:语料的稳定性 -- 原因 3:业务回答与算法模型的解耦 -- 原因 4:新问题发现与去重 -- 原因 5:新问题发现与去重 - -#### 3.2.2 QQ 匹配的语义空间是什么? - -- 介绍:**问题和问题的语义空间是一致的,而问题与回答的语义空间可能是不一致的。** -- 分析:假设对于一个 医疗FAQ系统,query 主要来自于患者的问题,而患者间对于问题的出发点和形式是一样的,但是 Answer 主要来自于 医生,而医生的回答相对于 专业化,所以在语义空间上就与用户的问题有着明显的不同。而这个语义空间的不一致性会极大影响算法的选择与学习。 -- 举例: - - 深度学习方法:句子相似度典型算法中以两侧向量相似度为目标和损失函数的孪生网络算法(Siamese network系列)就需要两边的语义空间一样,两边抽取特征的网络结构和参数也是共享的。而其他任务的匹配算法,如推理SLI任务往往就不是参数共享的,且往往需要额外的一个交互映射层来完成两边句子表示的语义映射关系。 - - 传统手工特征:那么句法树的解析出的中心节点是否相同,两句子的编辑距离大小,两句子的关键词overlap情况,这些特征在相似问题判断时会有更好的体现,且具有很高的可解释性(比如编辑距离越小,越可能是同一个意思)。而QA Match 在特征抽取上就会受限很多。 - -#### 3.2.3 QQ 匹配的语料的稳定性是什么? - -- 介绍:问题遵循一个固定的状态,而回答容易随着业务的发展发生变化,所以采用 QQ 效果更好 - -#### 3.2.4 QQ 匹配的业务回答与算法模型的解耦是什么? - -- 介绍:把问题与回答分离,只对问题建模,可以将算法模型的学习与业务方编辑的答案充分解耦,让不同问题与回答之间的映射比较随意可控; - -#### 3.2.5 QQ 匹配的新问题发现与去重是什么? - -- 介绍:FAQ的系统在构建好后,并不会是一成不变的,因为公司的业务需要也还是在不断发生变化和增长,用户会有新的频繁需要询问的问题,或者其实有些问题跟已有的问题其实是一致的,或者历史上配置的问题其实是不必要的。 - -#### 3.2.6 QQ 匹配的上线运行速度是什么? - -- 动机:如果使用QA Match的话,如果FAQ语料库的候选很大,即A有很多的话,那么在线上预测的时候,就会存在一个问题,进来的问题需要和那么多的A分别去做Match,(假设有1000条A,那么就需要执行QA Match模型1000次)虽然可以使用Batch机制来批量match,但始终整体的计算资源消耗和计算速度是比较大的。 -- 做法:如果使用问题与问题相似的思路,那么就可以提前把历史文本语料索引在Elastic search这样的搜索引擎中,或者可以把相似模型对于问题的建模稠密向量用Faiss或者annoy工具索引起来。当来了一个新问题的时候,就通过索引去搜索召回出历史语料中比较粗粒度的最相似TopK(这个时候TopK就可以降低到10或者20)问题即可,然后再用精细化的耗时的复杂语义模型去进一步匹配,就可以节约很多的计算资源和提高速度。 - -### 3.3 QQ 匹配一般处理流程是怎么样? 【假设 标准问题库 已处理好】 - -1. 数据清洗:用户 query 数据清洗; -2. 文本纠正:利用 纠错表 或 pycorrector 对 query 进行 纠错处理; -3. 意图识别:利用 意图分类模型 进行分类,确定 query 意图;【第一层粗召】 -4. Embedding 表示:文本等通过某种方式进行向量化表示(word2vec、doc2vec、elmo、bert等); -5. 语义召回:用户 query 特征向量进行索引(faiss/Milus) ,找到 一定数量 相似的 标准问题 ; -6. 多路召回: - 1. 关键词召回:可以利用 ES 计算 关键词相似度; - 2. ML 语义相似度召回:利用 TF-idf、ngram+TF-idf计算相似度; - 3. DL 语义相似度召回:DSSM、ESIM 等深度模型 计算相似度; -7. 问题答案获取:各相似度加权求和,精排,取 Top 作为 问题答案; - -![](img/FAQ.png) - -## 四、FAQ 标准问题库构建篇 - -### 4.1 如何发现 FAQ 中标准问题? - -- s1:对 问题库 中的问题进行预处理; -- s2:将 问题库 中的问题向量化; -- s3:对 问题库 进行聚类; -- s4:对比已有的FAQ,发现并补足未覆盖的知识点。将FAQ与知识点一一对应 - -### 4.2 FAQ 如何做拆分? - -- FAQ拆分:当一个FAQ里包含多个意图或者说多种情况的时候,需要对触达率较高的FAQ进行自动分析,聚类FAQ对应的问句,按照意图将其拆分开来; - -### 4.3 FAQ 如何做合并? - -- FAQ 的最终目标:用户的每一个意图都能对应到唯一的FAQ,这样用户每次提问的时候,可能会出现以下两种情况: - - 一一对应:后台能够根据意图对应的FAQ直接给出一个直接的回答; - - 模糊回复:当用户的提问,所对应的多个FAQ意思过于相近,那么当用户问到相关问题时,就不会出现一个直接的回答,而是多个意图相关的推荐问题,此时,需要用户选择比较符合的回答,后台需要对触达率较高的FAQ进行自动分析,分析哪一些问句总是被推荐相同的答案,将问句对应的意图合并。 - -### 4.4 FAQ 标准库如何实时更新? - -- 淘汰机制:后台需要定期分析历史日志,采用淘汰机制淘汰废弃知识点,如已下线业务知识点等。 - -## 五、FAQ 标准问题库答案优化篇 - -### 5.1 FAQ 标准问题库答案如何优化? - -- 挖掘对话,进行答案优化:如果机器人已经正确识别意图但最后仍然转人工,说明知识库的答案不对,需要进一步修正这一类知识点相对应的答案。 -- 分析头部场景,回答应用文本、图片、自动化解决方案等多元化方式:比如在电商场景中,经常会有查询发货到货时间、订单状态等的场景。利用图示指引、具体订单处理等方式让用户操作更便捷。 - -## 参考 - -1. [【FAQ 检索式问答系统】 那些你不知道的事](https://github.com/km1994/nlp_paper_study/blob/master/QA_study/FAQ.md) \ No newline at end of file diff --git "a/NLPinterview/QA/Faiss/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206162632.png" "b/NLPinterview/QA/Faiss/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206162632.png" deleted file mode 100644 index a59abea..0000000 Binary files "a/NLPinterview/QA/Faiss/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206162632.png" and /dev/null differ diff --git a/NLPinterview/QA/Faiss/readme.md b/NLPinterview/QA/Faiss/readme.md deleted file mode 100644 index 0965796..0000000 --- a/NLPinterview/QA/Faiss/readme.md +++ /dev/null @@ -1,439 +0,0 @@ -# 【关于 Faiss 】 那些你不知道的事 - -> 作者:杨夕 -> -> 本文链接:https://github.com/km1994/nlp_paper_study -> -> 论文名称:Billion-scale similarity search with GPUs -> -> 论文链接:https://arxiv.org/abs/1702.08734 -> -> 官方源码地址:https://github.com/facebookresearch/Faiss -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210206162632.png) - -## 一、动机篇 - -### 1.1 传统的相似度算法所存在的问题? - -1. 传统的相似度算法(欧几里得距离、曼哈顿距离、明可夫斯基距离、余弦相似度等[1])在计算向量相似度时,效率低下; -2. 传统的相似度算法(欧几里得距离、曼哈顿距离、明可夫斯基距离、余弦相似度等[1])在计算向量相似度时,不支持 GPU 计算; - -## 二、介绍篇 - -### 2.1 什么是 Faiss ? - -1. Faiss是针对稠密向量进行相似性搜索和聚类的一个高效类库。 -2. 它包含可搜索任意大小的向量集的算法,这些向量集的大小甚至都不适合RAM。 -3. 它还包含用于评估和参数调整的支持代码。 -4. Faiss用C ++编写,并且有python2与python3的封装代码。 -5. 一些最有用的算法在GPU上有实现。 -6. Faiss是由Facebook AI Research开发的。 - -### 2.2 Faiss 如何使用? - -Faiss 的使用方式可以分为三个步骤: - -1. 构建训练数据以矩阵的形式表示,比如我们现在经常使用的embedding,embedding出来的向量就是矩阵的一行。 -2. 为数据集选择合适的index,index是整个Faiss的核心部分,将第一步得到的训练数据add到index当中。 -3. search,或者说query,搜索到最终结果。 - -### 2.3 Faiss原理与核心算法 - -- Faiss的主要功能是对向量进行相似搜索。 -- 具体介绍:就是给定一个向量,在所有已知的向量库中找出与其相似度最高的一些向量; -- 本质:是一个KNN(K近邻)问题,比如google的以图找图功能。根据上面的描述不难看出,Faiss本质是一个向量(矢量)数据库,这个数据库在进行向量查询的时候有其独到之处,因此速度比较快,同时占用的空间也比较小。 - -## 三、Faiss 实战篇 - -### 3.1 Faiss 如何安装? - -```s - # 更新conda - conda update conda - # 先安装mkl - conda install mkl - # faiss提供gpu和cpu版,根据服务选择 - # cpu版本 - conda install faiss-cpu -c pytorch - # gpu版本 -- 记得根据自己安装的cuda版本安装对应的faiss版本,不然会出异常。使用命令:nvcc -V 查看 - conda install faiss-gpu cudatoolkit=8.0 -c pytorch # For CUDA8 - conda install faiss-gpu cudatoolkit=9.0 -c pytorch # For CUDA9 - conda install faiss-gpu cudatoolkit=10.0 -c pytorch # For CUDA10 - # 校验是否安装成功 - python -c "import faiss" -``` - -> 【注:这里小编尝试过多次 window 安装,最后都失败,最后Google了一下,发现Faiss不支持 window 系统!】 - -### 3.2 Faiss 的索引Index有哪些? - -- Faiss中最重要的是索引 Index - - 为什么要创建索引? - - Faiss 创建索引对向量预处理,提高查询效率 - - Faiss中的稠密向量各种索引都是基于 Index实现的,主要的索引方法包括: IndexFlatL2、IndexFlatIP、IndexHNSWFlat、IndexIVFFlat、IndexLSH、IndexScalarQuantizer、IndexPQ、IndexIVFScalarQuantizer、IndexIVFPQ、IndexIVFPQR等。每个方法的具体介绍见: - -![](img/微信截图_20210116102726.png) - -### 3.3 Faiss 的索引Index都怎么用? - -#### 3.3.1 数据预备 - -- 创建训练数据和测试数据 -- 代码: - -```s - import numpy as np - d = 64 # dimension - nb = 100000 # database size - nq = 10000 # nb of queries - np.random.seed(1234) # make reproducible - xb = np.random.random((nb, d)).astype('float32') - xb[:, 0] += np.arange(nb) / 1000. - xq = np.random.random((nq, d)).astype('float32') - xq[:, 0] += np.arange(nq) / 1000. -``` - -- 解析: - - 训练集 xb:[100000,64] - - 查询数据集 xq:[10000,64] - -#### 3.3.2 暴力美学 IndexFlatL2 - -- 介绍:暴力检索 L2 距离的索引; -- 方式:全量搜索 -- 流程: - -1. 创建索引 - -```s - import faiss # make faiss available - index = faiss.IndexFlatL2(d) # build the index - print(index.is_trained) -``` - -> 注:创建索引时必须指定向量的维度d。大部分索引需要训练的步骤。IndexFlatL2 跳过这一步。 - -当索引创建好并训练(如果需要)之后,我们就可以执行 add 方法,add方法一般添加训练时的样本; - -2. 添加 训练集 - -```s - index.add(xb) # add vectors to the index - print(index.ntotal) -``` - -3. 寻找相似相似向量 - -包含向量的索引后,就可以传入搜索向量查找相似向量,search就是寻找相似相似向量了。 - -```s - k = 4 # we want to see 4 nearest neighbors - D, I = index.search(xq, k) # actual search - print(I[:5]) # neighbors of the 5 first queries - print(D[-5:]) # neighbors of the 5 last queries - >>> - [[ 0 393 363 78] - [ 1 555 277 364] - [ 2 304 101 13] - [ 3 173 18 182] - [ 4 288 370 531]] - - [[ 0. 7.17517328 7.2076292 7.25116253] - [ 0. 6.32356453 6.6845808 6.79994535] - [ 0. 5.79640865 6.39173603 7.28151226] - [ 0. 7.27790546 7.52798653 7.66284657] - [ 0. 6.76380348 7.29512024 7.36881447]] -``` - -> 注:
-> D:numpy array对象,表示与相似向量的距离(distance),维度
-> I:numpy array对象,表示相似用户的ID
- -- 存在问题:虽然查询速度高于 传统相似度计算方法,但是速度还是太慢 - -#### 3.3.3 闪电侠 IndexIVFFlat - -- 引言:暴力美学 IndexFlatL2 查询速度太慢了 -- 介绍:IndexIVFFlat 是一种 加速索引方法,其所用的方法 为倒排法; -- 方式: -- 先聚类再搜索,可以加快检索速度,先将xb中的数据进行聚类(聚类的数目是超参) - - nlist: 聚类的数目; - - nprobe: 在多少个聚类中进行搜索,默认为1, nprobe越大,结果越精确,但是速度越慢 -- 流程: - - 使用K-means建立聚类中心; - - 然后通过查询最近的聚类中心; - - 最后比较聚类中的所有向量得到相似的向量 -- 代码: - -1. 定义索引 和 聚类簇数 - -```s - nlist = 100 #聚类中心的个数 - k = 4 - quantizer = faiss.IndexFlatL2(d) # the other index - index = faiss.IndexIVFFlat(quantizer, d, nlist, faiss.METRIC_L2) - # here we specify METRIC_L2, by default it performs inner-product search -``` -> 注:创建IndexIVFFlat时需要指定一个其他的索引作为量化器(quantizer)来计算距离或相似度。
-> 参数介绍:
-> faiss.METRIC_L2: faiss定义了两种衡量相似度的方法(metrics),分别为faiss.METRIC_L2、faiss.METRIC_INNER_PRODUCT。一个是欧式距离,一个是向量内积。
-> nlist:聚类中心的个数 - -2. 添加 训练集 - -```s - index.train(xb) - assert index.is_trained - - index.add(xb) # add may be a bit slower as well -``` -> 注:与 IndexFlatL2 对比,在 add 方法之前需要先训练 - -3. 寻找相似相似向量 - -包含向量的索引后,就可以传入搜索向量查找相似向量,search就是寻找相似相似向量了。 - -```s - D, I = index.search(xq, k) # actual search - print(I[-5:]) # neighbors of the 5 last queries - index.nprobe = 10 # default nprobe is 1, try a few more - D, I = index.search(xq, k) - print(I[-5:]) # neighbors of the 5 last queries -``` - -> 参数介绍:
-> k:查找最相似的k个向量
-> index.nprobe:查找聚类中心的个数,默认为1个。
- -#### 3.3.4 内存管家 IndexIVFPQ - -- 动机:索引IndexFlatL2和IndexIVFFlat都会全量存储所有的向量在内存中,如果数据量是海量级别的时候,怎么办呢? -- 介绍:IndexIVFPQ 基于Product Quantizer(乘积量化)的压缩算法编码向量大小到指定的字节数的索引算法,存储的向量时压缩过的,查询的距离也是近似的。关于乘积量化的算法可自行搜索。 -- 方式:基于乘积量化(product quantizers)对存储向量进行压缩,节省存储空间 - - m:乘积量化中,将原来的向量维度平均分成多少份,d必须为m的整数倍 - - bits: 每个子向量用多少个bits表示 -- 代码: - -1. 定义索引 和 聚类簇数 - -```s - nlist = 100 - m = 8 # number of bytes per vector - k = 4 - quantizer = faiss.IndexFlatL2(d) # this remains the same - index = faiss.IndexIVFPQ(quantizer, d, nlist, m, 8) - # 8 specifies that each sub-vector is encoded a -``` -> 注:之前我们定义的维度为d = 64,向量的数据类型为float32。这里压缩成了8个字节。所以压缩比率为 (64*32/8) / 8 = 32 - -2. 添加 训练集 - -```s - index.train(xb) - index.add(xb) -``` -> 注:与 IndexFlatL2 对比,在 add 方法之前需要先训练 - -3. 寻找相似相似向量 - -包含向量的索引后,就可以传入搜索向量查找相似向量,search就是寻找相似相似向量了。 - -```s - D, I = index.search(xb[:5], k) # sanity check - print(I) - print(D) - index.nprobe = 10 # make comparable with experiment above - D, I = index.search(xq, k) # search - print(I[-5:]) - >>> - [[ 0 608 220 228] - [ 1 1063 277 617] - [ 2 46 114 304] - [ 3 791 527 316] - [ 4 159 288 393]] - - [[ 1.40704751 6.19361687 6.34912491 6.35771513] - [ 1.49901485 5.66632462 5.94188499 6.29570007] - [ 1.63260388 6.04126883 6.18447495 6.26815748] - [ 1.5356375 6.33165455 6.64519501 6.86594009] - [ 1.46203303 6.5022912 6.62621975 6.63154221]] -``` - -### 3.4 Faiss 然后使用 GPU? - -> 注:并不是所有的索引都支持 GPU,所以在使用之前建议 查阅一下 [Basic indexes](https://github.com/facebookresearch/faiss/wiki/Faiss-indexes) - -- 可通过faiss.get_num_gpus()查询有多少个gpu - -```s - ngpus = faiss.get_num_gpus() - print("number of GPUs:", ngpus) -``` - -- 单 GPU - -```s - res = faiss.StandardGpuResources() # use a single GPU, 这个命令需要安装Faiss GPU 版本 - # build a flat (CPU) index - index_flat = faiss.IndexFlatL2(d) - # make it into a gpu index - gpu_index_flat = faiss.index_cpu_to_gpu(res, 0, index_flat) - gpu_index_flat.add(xb) # add vectors to the index - print(gpu_index_flat.ntotal) - - k = 4 # we want to see 4 nearest neighbors - D, I = gpu_index_flat.search(xq, k) # actual search - print(I[:5]) # neighbors of the 5 first queries - print(I[-5:]) # neighbors of the 5 last queries -``` - -- 多 GPU - -```s - ngpus = faiss.get_num_gpus() - print("number of GPUs:", ngpus) - cpu_index = faiss.IndexFlatL2(d) - gpu_index = faiss.index_cpu_to_all_gpus(cpu_index) # build the index - gpu_index.add(xb) # add vectors to the index - print(gpu_index.ntotal) - k = 4 # we want to see 4 nearest neighbors - D, I = gpu_index.search(xq, k) # actual search - print(I[:5]) # neighbors of the 5 first queries - print(I[-5:]) # neighbors of the 5 last queries -``` - -## 四、 Faiss 对比篇 - -### 4.1 sklearn cosine_similarity 和 Faiss 哪家强 - - -- 方法一:使用 sklearn 中的 cosine_similarity - -```s - # encoding utf8 - import pandas as pd - import csv - import numpy as np - import sys - from sklearn.metrics.pairwise import cosine_similarity - # sys.path.append('../') - # 自定义 包 - from tools.loader import loadDict,saveDict,dictCutBatchSave,dictLoadMerge - from tools.bert_tools import Bert_Class - bertModel = Bert_Class() - from tools.common_tools import timer - - commonPath = "data/" - inf = commonPath+"resource/" - dataType = "" - fileName = f"medQA.valid.txt" - QueAnsFileName = f"QueAns{dataType}" - query = "睡前练瑜伽好吗睡觉之前练习40分钟的瑜伽好吗、能起到瘦身的作用吗?" - topN = 20 - - # 使用 sklearn cosine_similarity 方法 计算相似度 - def use_sklearn_get_sim_query(query,training_vectors,topN): - # step 1:测试文本 转 bert sent - test_vecs = bertModel.get_vec_to_sent(query).astype('float32') - # step 2:计算 相似度 - print("------------sklearn-------------") - ag=cosine_similarity(test_vecs,training_vectors) - # step 3:排序 - fe=np.sort(ag,axis=1) - fe_index = np.argsort(ag,axis=1) - score_list = fe[0].tolist() - index_list = fe_index[0].tolist() - score_list.reverse() - index_list.reverse() - # step 4:取 Top N - return index_list[:topN],score_list[:topN] - - training_vectors = np.load(f"{inf}training_vectors.npy") - id2QusAns = loadDict(inf,QueAnsFileName) - index_list,score_list = use_sklearn_get_sim_query(query,training_vectors,topN) - - for index,score in zip(index_list,score_list): - print(f"index:{index} => query:{id2QusAns[index]}:{score}\n") -``` - -- 方法二:Faiss - -```s - # encoding utf8 - import pandas as pd - import csv - import numpy as np - import sys - import faiss - from faiss import normalize_L2 - # sys.path.append('../') - # 自定义 包 - from tools.loader import loadDict,saveDict,dictCutBatchSave,dictLoadMerge - from tools.bert_tools import Bert_Class - bertModel = Bert_Class() - from tools.common_tools import timer - - commonPath = "data/" - inf = commonPath+"resource/" - dataType = "" - fileName = f"medQA.valid.txt" - QueAnsFileName = f"QueAns{dataType}" - query = "睡前练瑜伽好吗睡觉之前练习40分钟的瑜伽好吗、能起到瘦身的作用吗?" - topN = 20 - - # 使用 sklearn cosine_similarity 方法 计算相似度 - def use_faiss_get_sim_query(query,training_vectors,topN,d=768): - # step 1:测试文本 转 bert sent - test_vecs = bertModel.get_vec_to_sent(query).astype('float32') - # step 2:计算 相似度 - print("------------faiss-------------") - print('normalize_L2') - normalize_L2(training_vectors) - normalize_L2(test_vecs) - print('IndexFlatIP') - index=faiss.IndexFlatIP(d) # the other index,需要以其他index作为基础 - index.train(training_vectors) - print(f"training_vectors.shape:{training_vectors.shape}") - print(index) - print('train') - print(index.is_trained) - print('add') - print(index) - index.add(training_vectors) - print('search') - print(f"test_vecs.shape:{test_vecs.shape}") - D, I =index.search(test_vecs, topN) - print(f"I:{I}") # 表示最相近的前5个的index - print(f"D:{D}") # 表示最相近的前5个的相似度的值 - # step 3:排序 - score_list = D.tolist()[0] - index_list = I.tolist()[0] - # step 4:取 Top N - return index_list,score_list - - training_vectors = np.load(f"{inf}training_vectors.npy") - id2QusAns = loadDict(inf,QueAnsFileName) - index_list,score_list = use_faiss_get_sim_query(query,training_vectors,topN) - - for index,score in zip(index_list,score_list): - print(f"index:{index} => query:{id2QusAns[index]}:{score}\n") - -``` - -- 分析: - - 从预测结果角度看,两者结果雷同; - - 从计算速度角度看:当 数据集 特别大时,Faiss 秒杀 sklearn cosine_similarity - - -## 参考资料 - -1. [常用的相似度计算方法原理及实现](https://blog.csdn.net/yixianfeng41/article/details/61917158) -2. [Faiss从入门到实战精通](https://blog.csdn.net/bitcarmanlee/article/details/106447629) -2. [Faiss 教程](https://zhuanlan.zhihu.com/p/320653340) -3. [Faiss 用法](https://zhuanlan.zhihu.com/p/40236865) -4. [Basic indexes](https://github.com/facebookresearch/faiss/wiki/Faiss-indexes) diff --git a/NLPinterview/QA/readme.md b/NLPinterview/QA/readme.md deleted file mode 100644 index e69de29..0000000 diff --git a/NLPinterview/TextMatch/ESIM/img/20181213150803869.png b/NLPinterview/TextMatch/ESIM/img/20181213150803869.png deleted file mode 100644 index 5abba48..0000000 Binary files a/NLPinterview/TextMatch/ESIM/img/20181213150803869.png and /dev/null differ diff --git a/NLPinterview/TextMatch/ESIM/img/20200819085245.png b/NLPinterview/TextMatch/ESIM/img/20200819085245.png deleted file mode 100644 index 0964072..0000000 Binary files a/NLPinterview/TextMatch/ESIM/img/20200819085245.png and /dev/null differ diff --git a/NLPinterview/TextMatch/ESIM/img/20200819085713.png b/NLPinterview/TextMatch/ESIM/img/20200819085713.png deleted file mode 100644 index 28382ce..0000000 Binary files a/NLPinterview/TextMatch/ESIM/img/20200819085713.png and /dev/null differ diff --git a/NLPinterview/TextMatch/ESIM/img/20200819085922.png b/NLPinterview/TextMatch/ESIM/img/20200819085922.png deleted file mode 100644 index d1c8b12..0000000 Binary files a/NLPinterview/TextMatch/ESIM/img/20200819085922.png and /dev/null differ diff --git a/NLPinterview/TextMatch/ESIM/img/20200819090200.png b/NLPinterview/TextMatch/ESIM/img/20200819090200.png deleted file mode 100644 index 5e00af1..0000000 Binary files a/NLPinterview/TextMatch/ESIM/img/20200819090200.png and /dev/null differ diff --git a/NLPinterview/TextMatch/ESIM/img/20200819090442.png b/NLPinterview/TextMatch/ESIM/img/20200819090442.png deleted file mode 100644 index 98eeb1e..0000000 Binary files a/NLPinterview/TextMatch/ESIM/img/20200819090442.png and /dev/null differ diff --git "a/NLPinterview/TextMatch/ESIM/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206164901.png" "b/NLPinterview/TextMatch/ESIM/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206164901.png" deleted file mode 100644 index 26d51d4..0000000 Binary files "a/NLPinterview/TextMatch/ESIM/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206164901.png" and /dev/null differ diff --git a/NLPinterview/TextMatch/ESIM/readme.md b/NLPinterview/TextMatch/ESIM/readme.md deleted file mode 100644 index 09420f1..0000000 --- a/NLPinterview/TextMatch/ESIM/readme.md +++ /dev/null @@ -1,207 +0,0 @@ -# 【关于 文本匹配模型 ESIM 】那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人论文读书笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 论文:Enhanced LSTM for Natural Language Inference -> -> 会议:TACL2017 -> -> 论文地址:https://arxiv.org/pdf/1609.06038.pdf - -![](img/微信截图_20210206164901.png) - -## 一、动机篇 - -- 自然语言推理(NLI: natural language inference)问题: - - 即判断能否从一个前提p中推导出假设h - - 简单来说,就是判断给定两个句子的三种关系:蕴含、矛盾或无关 - -在Query 扩召回项目中,通过各种手段挖掘出一批同义词,想对其进行流程化,所以考虑加上语义推断,作为竞赛神器 ESIM 模型,该模型在近两年横扫了好多比赛,算是 NLI (Natural Language Inference) 领域未来几年一个很难绕过的超强 baseline 了,单模型的效果可以达到 88.0% 的 Acc。 - -- 创新点 - - 精细的设计序列式的推断结构; - - 考虑局部推断和全局推断。 - -## 二、ESIM 模型篇 - -### 2.1 模型介绍 - -![](img/20181213150803869.png) -> 模型整体结构 - -- 模型结构图分为左右两边: -- 左侧就是 ESIM, -- 右侧是基于句法树的 tree-LSTM,两者合在一起交 HIM (Hybrid Inference Model)。 -- 整个模型从下往上看,分为三部分: - - input encoding; - - local inference modeling; - - inference composition; - - Prediction - -以 ESIM 为例 - -### 2.2 Input Encoding - -- step1 : 输入一般可以采用预训练好的词向量或者添加embedding层,这里介绍采用的是embedding层; -- step2 :采用一个双向的LSTM,起作用主要在于对输入值做encoding,也可以理解为在做特征提取, -- step3 :把其隐藏状态的值保留下来, - -![](img/20200819085245.png) -> BiLSTM 公式 - -> 其中i与j分别表示的是不同的时刻,a与b表示的是上文提到的p与h。 - -- 代码讲解 - -```s - def forward(self): - # step 1 : input encoding : embeding + BiLSTM - p_embedding = tf.nn.embedding_lookup(self.embedding, self.p) - h_embedding = tf.nn.embedding_lookup(self.embedding, self.h) - with tf.variable_scope("lstm_p", reuse=tf.AUTO_REUSE): - (p_f, p_b), _ = self.bilstm(p_embedding, self.config['embedding_hidden_size']) - with tf.variable_scope("lstm_p", reuse=tf.AUTO_REUSE): - (h_f, h_b), _ = self.bilstm(h_embedding, self.config['embedding_hidden_size']) - p = tf.concat([p_f, p_b], axis=2) - h = tf.concat([h_f, h_b], axis=2) - p = self.dropout(p) - h = self.dropout(h) - ... -``` - -### 2.3 Local Inference Modeling - -- 目标:将上一轮 所提取到的 特征值 做 差异值 计算; -- 所用方法: Attention -- 步骤 - - s1: 计算 Attention weight(如 图 1) - - s2: 根据attention weight计算出a与b的权重加权后的值(如 图 2)【作用:通过Attention的方式,以 a 为query向量,text_right中的所有单词的表征作为key向量和value向量,那么就可以计算得到text_left中单词 wa 基于text_right中单词的表征 a‘】 - - s3: 得到encoding值与加权encoding值之后,下一步是分别对这两个值做差异性计算,作者认为这样的操作有助于【强化每个单词的表征】,论文有两种计算方法: - - 对位相减 - - 对位相乘 - - s4: 把encoding两个状态的值与相减、相乘的值拼接起来(如 图 3) - -![](img/20200819085713.png) -> 图 1 - -![](img/20200819085922.png) -> 图 2 -> 注:计算 a 时,是与 b 做 加权,而非自身,b 同理 - -![](img/20200819090200.png) -> 图 3 - -- 代码 - -```s - def forward(self): - ... - # step 2 : local inference modeling - ## 2.1 首先计算两个句子 word 之间的相似度,得到2维的相似度矩阵,这里会用到 torch.matmul - e = tf.matmul(p, tf.transpose(h, perm=[0, 2, 1])) - ## 2.2 然后才进行两句话的 local inference。用之前得到的相似度矩阵,结合 a,b 两句话,互相生成彼此相似性加权后的句子,维度保持不变。 - a_attention = tf.nn.softmax(e) - b_attention = tf.transpose(tf.nn.softmax(tf.transpose(e, perm=[0, 2, 1])), perm=[0, 2, 1]) - a = tf.matmul(a_attention, h) - b = tf.matmul(b_attention, p) - ## 2.3 在 local inference 之后,进行 Enhancement of local inference information。这里的 enhancement 就是计算 a 和 align 之后的 a 的差和点积, 体现了一种差异性吧,更利用后面的学习。 - m_a = tf.concat((a, p, a - p, tf.multiply(a, p)), axis=2) - m_b = tf.concat((b, h, b - h, tf.multiply(b, h)), axis=2) - ... -``` - -### 2.4 Inference Composition - -在这一层中,把之前的值再一次送到了BiLSTM中,这里的BiLSTM的作用和之前的并不一样,这里主要是用于捕获局部推理信息 $m_a$ 和 $m_b$ 及其上下文,以便进行推理组合。 - -最后把BiLSTM得到的值进行池化操作,分别是最大池化与平均池化,并把池化之后的值再一次的拼接起来。 - -![](img/20200819090442.png) - -- 代码 - -```s - def forward(self): - ... - # step 3 : inference composition - ## 3.1 用 BiLSTM 提取上下文信息 - with tf.variable_scope("lstm_a", reuse=tf.AUTO_REUSE): - (a_f, a_b), _ = self.bilstm(m_a, self.config['context_hidden_size']) - with tf.variable_scope("lstm_b", reuse=tf.AUTO_REUSE): - (b_f, b_b), _ = self.bilstm(m_b, self.config['context_hidden_size']) - a = tf.concat((a_f, a_b), axis=2) - b = tf.concat((b_f, b_b), axis=2) - a = self.dropout(a) - b = self.dropout(b) - ## 3.2 使用 MaxPooling 和 AvgPooling 进行池化操作 - a_avg = tf.reduce_mean(a, axis=2) - b_avg = tf.reduce_mean(b, axis=2) - a_max = tf.reduce_max(a, axis=2) - b_max = tf.reduce_max(b, axis=2) - v = tf.concat((a_avg, a_max, b_avg, b_max), axis=1) - ... -``` - -### 2.5 Prediction - -- 目标:预测 -- 思路: - - s1:把 V 送入到全连接层,激活函数采用的是tanh; - - s2:将得到的结果送到softmax层。 - -- 代码 - -```s - def forward(self): - ... - # step 4 : 预测 - ## 4.1 拼接 一个 全连接层 - v = tf.layers.dense(v, self.config['hidden'], activation='tanh') - v = self.dropout(v) - logits = tf.layers.dense(v, self.config['class_size'], activation='tanh') - ## 4.2 拼接 一个 softmax 层 - self.prob = tf.nn.softmax(logits, name="logits") - self.prediction = tf.argmax(logits, axis=1, name="predictions") - self.train(logits) -``` - -### 2.6 模型训练 - -- 代码介绍: - -```s - def train(self, logits): - y = tf.one_hot(self.y, self.config['class_size']) - # 计算最后一层是softmax层的cross entropy, - # 把softmax计算与cross entropy计算放到一起了, - # 用一个函数来实现,用来提高程序的运行速度。 - loss = tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=logits) - self.loss = tf.reduce_mean(loss) - self.train_op = tf.train.AdamOptimizer(self.config['learning_rate']).minimize(self.loss) - correct_prediction = tf.equal(tf.cast(self.prediction, tf.int32), self.y) - self.acc = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) -``` - -- 损失函数介绍 - -```s - tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=pred, name=None) -``` - -函数功能:计算最后一层是softmax层的cross entropy,把softmax计算与cross entropy计算放到一起了,用一个函数来实现,用来提高程序的运行速度。 - -- 参数介绍 - - 参数name:该操作的name - - 参数labels:shape是[batch_size, num_classes],神经网络期望输出。 - - 参数logits:shape是[batch_size, num_classes] ,神经网络最后一层的输入。 - -## 参考 - -1. [文本匹配、文本相似度模型之ESIM](https://blog.csdn.net/u012526436/article/details/90380840) -2. [短文本匹配的利器-ESIM](https://zhuanlan.zhihu.com/p/47580077) \ No newline at end of file diff --git "a/NLPinterview/TextMatch/bert_similairity/img/QQ\346\210\252\345\233\27620201014080612.png" "b/NLPinterview/TextMatch/bert_similairity/img/QQ\346\210\252\345\233\27620201014080612.png" deleted file mode 100644 index 3dfff80..0000000 Binary files "a/NLPinterview/TextMatch/bert_similairity/img/QQ\346\210\252\345\233\27620201014080612.png" and /dev/null differ diff --git "a/NLPinterview/TextMatch/bert_similairity/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206165041.png" "b/NLPinterview/TextMatch/bert_similairity/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206165041.png" deleted file mode 100644 index 89fb398..0000000 Binary files "a/NLPinterview/TextMatch/bert_similairity/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206165041.png" and /dev/null differ diff --git a/NLPinterview/TextMatch/bert_similairity/readme.md b/NLPinterview/TextMatch/bert_similairity/readme.md deleted file mode 100644 index 7f85eeb..0000000 --- a/NLPinterview/TextMatch/bert_similairity/readme.md +++ /dev/null @@ -1,55 +0,0 @@ -# 【关于 语义相似度匹配任务中的 BERT】 那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人论文读书笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20210206165041.png) - -## 一、Sentence Pair Classification Task:使用 [CLS] - -![](img/QQ截图20201014080612.png) - -- 方法: - - 1. 将输入送入BERT前,在首部加入[CLS],在两个句子之间加入[SEP]作为分隔; - - 2. 取到BERT的输出(句子对的embedding),取[CLS]即可完成多分类任务/相似度计算任务; - - 3. 取到的[CLS]对应的embedding为 c; - - 3.1. 多分类任务,需进行:P = softmax(cW'); - - 3.2. 相似度计算,需进行:P = sigmoid(cW'); - - 4. 计算各自所需的loss; -- 解析:c 可一定程度表示整个句子的语义 -- 举例 - - 原文中有提到“ The final hidden state (i.e., output of Transformer) corresponding to this token is used as the aggregate sequence representation for classification tasks.”这句话中的“this token”就是CLS位。 - -## 二、cosine similairity - -- 方法: - - 1. 利用 bert 生成两个句子的句向量; - - 2. 在不finetune的情况下,计算 cosine similairty 绝对值; -- 问题:不合理的 -- 原因:bert pretrain计算的cosine similairty都是很大的; - - 如果直接以cosine similariy>0.5之类的阈值来判断相似不相似那肯定效果很差; - - 如果用做排序,也就是cosine(a,b)>cosine(a,c)->b相较于c和a更相似,是可以用的; -- 评价指标:auc,而不是accuracy; - -## 三、长短文本的区别 - -- 短文本(新闻标题)语义相似度任务:用先进的word embedding(英文fasttext/glove,中文tencent embedding)mean pooling后的效果就已经不错; -- 长文本(文章):用simhash这种纯词频统计的完全没语言模型的简单方法也可以; - -## 四、sentence/word embedding - -bert pretrain模型直接拿来用作 sentence embedding效果甚至不如word embedding,cls的emebdding效果最差(也就是pooled output)。把所有普通token embedding做pooling勉强能用(这个也是开源项目bert-as-service的默认做法),但也不会比word embedding更好。 - -## 五、siamese network 方式 - -- 思路:除了直接使用bert的句对匹配之外,还可以只用bert来对每个句子求embedding,再通过向Siamese Network这样的经典模式去求相似度; -- 用siamese的方式训练bert,上层通过cosine做判别,能够让bert学习到一种适用于cosine作为最终相似度判别的sentence embedding,效果优于word embedding,但因为缺少sentence pair之间的特征交互,比原始bert sentence pair fine tune还是要差些。 - -## 参考 - -1. [用BERT做语义相似度匹配任务:计算相似度的方式](https://www.cnblogs.com/shona/p/12021304.html) \ No newline at end of file diff --git a/NLPinterview/TextMatch/readme.md b/NLPinterview/TextMatch/readme.md deleted file mode 100644 index e69de29..0000000 diff --git a/NLPinterview/TextMining/readme.md b/NLPinterview/TextMining/readme.md deleted file mode 100644 index 98ec425..0000000 --- a/NLPinterview/TextMining/readme.md +++ /dev/null @@ -1,123 +0,0 @@ -# 【关于 数据挖掘】那些你不知道的事 - -## 摘要 - -- [【关于 数据挖掘】那些你不知道的事](#关于-数据挖掘那些你不知道的事) - - [摘要](#摘要) - - [一、什么是文本挖掘?](#一什么是文本挖掘) - - [二、文本挖掘的作用是什么?](#二文本挖掘的作用是什么) - - [三、文本预处理](#三文本预处理) - - [3.1 中文分词](#31-中文分词) - - [3.2 去停用词](#32-去停用词) - - [3.3 低频词和高频词处理](#33-低频词和高频词处理) - - [3.4 计算 N-gram 【这里采用 Bigrams】](#34-计算-n-gram-这里采用-bigrams) - - [四、文本挖掘](#四文本挖掘) - - [4.1 关键词提取](#41-关键词提取) - - [4.2 LDA 主题模型分析](#42-lda-主题模型分析) - - [4.3 情绪分析&LDA主题模型交叉分析](#43-情绪分析lda主题模型交叉分析) - - [4.4 ATM 模型](#44-atm-模型) - - [4.5 词向量训练及关联词分析](#45-词向量训练及关联词分析) - - [4.6 词聚类与词分类](#46-词聚类与词分类) - - [4.7 文本分类](#47-文本分类) - - [4.8 文本聚类](#48-文本聚类) - - [4.9 信息检索](#49-信息检索) - - [参考](#参考) - -## 一、什么是文本挖掘? - -文本挖掘指的是从文本数据中获取有价值的信息和知识,它是数据挖掘中的一种方法。文本挖掘中最重要最基本的应用是实现文本的分类和聚类,前者是有监督的挖掘算法,后者是无监督的挖掘算法。 - -## 二、文本挖掘的作用是什么? - -能够从文本数据中获取有价值的信息和知识 - -## 三、文本预处理 - -### 3.1 中文分词 - -使用jieba来对文本进行分词处理,它有3类分词模式,即全模式、精确模式、搜索引擎模式: - -- 精确模式:试图将句子**最精确地切开**,适合文本分析; -- 全模式:把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是**不能解决歧义**; -- 搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。 - -> 举例:定位理论认为营销的终极战场在于消费者心智
-> 【全模式】: 定位/理论/定位理论/认为/营销/的/终极/战场/终极战场/在/于/在于/消费者/心智/消费者心智
-> 【精确模式】: 定位理论/认为/营销/的/终极战场/在于/消费者心智
-> 【搜索引擎模式】:定位,理论,定位理论,认为,营销,的,终极,战场,终极战场,在于,消费者心智,消费者,心智
- -### 3.2 去停用词 - -对于 文本中 的 停用词需要做处理 - -- 标点符号:, 。! /、*+- -- 特殊符号:❤❥웃유♋☮✌☏☢☠✔☑♚▲♪等 -- 无意义的虚词:“the”、“a”、“an”、“that”、“你”、“我”、“他们”、“想要”、“打开”、“可以”等 - -### 3.3 低频词和高频词处理 - -- 动机:低频词和高频词对于 后续的文本分析 容易造成影响,比如对于后续的主题模型(LDA、ATM)时使用的,主要是为了排除对区隔主题意义不大的词汇,最终得到类似于停用词的效果。 - -### 3.4 计算 N-gram 【这里采用 Bigrams】 - -- 动机:针对 分词工具 分错 一些新词问题,比如基于词汇之间的共现关系—如果两个词经常一起毗邻出现,那么这两个词可以结合成一个新词,比如“数据”、“产品经理”经常一起出现在不同的段落里,那么,“数据_产品经理”则是二者合成出来的新词,只不过二者之间包含着下划线。 - -## 四、文本挖掘 - -### 4.1 关键词提取 - -- 动机:对于文档而言,可以抽取出提取某段文本的关键信息,即关键词来表示文档信息; -- 方法:TF-IDF(termfrequency–inverse document frequency) - -> 它用以评估一字/词对于一个文件集或一个语料库中的其中一份文件的重要程度,字/词的重要性会随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。 - -### 4.2 LDA 主题模型分析 - -- 动机:如果采用 关键词的分类较为粗糙,人为因素严重,达不到全面效果。 -- 方法:LDA 主题模型 -- 作用:抽取出语料中的潜在主题以及每个主题下对应的主题词 - -### 4.3 情绪分析&LDA主题模型交叉分析 - -- 动机:对于有些文本,我们需要找到其所表述的情感信息; -- 方法:使用基于深度学习的情绪语义分析模型(该模型有6类情绪,即喜悦、愤怒、悲伤、惊奇、恐惧和中性) - -### 4.4 ATM 模型 - -- 动机:想了解“文本中各个作家的写作主题,分析某些牛X作家喜欢写哪方面的文章(比如“行业洞察”、“爆品营销”、“新媒体运营”等),以及写作主题类似的作者有哪些; -- 方法:ATM模型(author-topic model)也是“概率主题模型”家族的一员,是LDA主题模型(Latent Dirichlet Allocation )的拓展,它能对某个语料库中作者的写作主题进行分析,找出某个作家的写作主题倾向,以及找到具有同样写作倾向的作家,它是一种新颖的主题探索方式。 - -### 4.5 词向量训练及关联词分析 - -- 动机:前面的方法无法学习到语义信息问题 -- 方法:word2vec -- 介绍:基于深度神经网络的词向量能从大量未标注的普通文本数据中无监督地学习出词向量,这些词向量包含了词汇与词汇之间的语义关系 -- 原理介绍:基于词嵌入的Word2vec是指把一个维数为所有词的数量的高维空间嵌入到一个维数低得多的连续向量空间中,每个单词或词组被映射为实数域上的向量。把每个单词变成一个向量,目的还是为了方便计算,比如“求单词A的同义词”,就可以通过“求与单词A在cos距离下最相似的向量”来做到。 - -### 4.6 词聚类与词分类 - -- 动机:需要对某类词 进行聚类; -- 方法:聚类分析 -- 思路:运用基于Word2Vec(词向量)的K-Means聚类,充分考虑了词汇之间的语义关系,将余弦夹角值较小的词汇聚集在一起,形成簇群。 - -### 4.7 文本分类 - -文本分类是一种典型的机器学习方法,一般分为训练和分类两个阶段。文本分类一般采用统计方法或机器学习来实现。 - -### 4.8 文本聚类 - -- 类型:无监督方法 -- 思路: - - 首先,文档聚类可以发现与某文档相似的一批文档,帮助知识工作者发现相关知识; - - 其次,文档聚类可以将一类文档聚类成若干个类,提供一种组织文档集合的方法; - - 再次,文档聚类还可以生成分类器以对文档进行分类。 - -### 4.9 信息检索 - -主要是利用计算机系统的快速计算能力,从海量文档中寻找用户需要的相关文档。 - - - -## 参考 - -1. [以虎嗅网4W+文章的文本挖掘为例,展现数据分析的一整套流程](http://www.woshipm.com/data-analysis/873430.html) \ No newline at end of file diff --git a/NLPinterview/TopicModel/readme.md b/NLPinterview/TopicModel/readme.md deleted file mode 100644 index cf36b87..0000000 --- a/NLPinterview/TopicModel/readme.md +++ /dev/null @@ -1,26 +0,0 @@ -# 【关于 主题模型】那些你不知道的事 - -- [【关于 主题模型】那些你不知道的事](#关于-主题模型那些你不知道的事) - - [一、 trick](#一-trick) - - -## 一、 trick - -1. 利用优质“少量”数据学习模型,缓解单机速度和内存问题,然后对剩余/新文档做推导(可数据并行)。比如用微博训练LDA时,先把长度短的微博过滤掉(有工作得出长度为7的短文本适合LDA进行学习),过滤相似微博(转发会造成很多近乎相同的微博)。当训练数据量大并且单机环境中可试一下GraphLab Create,该工具还支持采样比较快的alias LDA。如果不仅是为了学习当前语料中的主题分布,并且也用于预测新数据,则数据量越大越好。 -2. 去除一些TF/DF较低/高的词,较低的词在拟合的过程中会被平滑掉,较高的词没有区分力,标点,助词,语气词也可以去掉(中文常用词60万左右)。在中文中应考虑全角变半角,去乱码,繁转简,英文中考虑大小写转换。实际处理数据时会发现分词后不同词个数很容易达到百万级别,这里很多词是没有意义的,数字词,长度过长的词,乱码词。此外,分词过程中如果两个词在一起的频率比较高,那么分词结果会把两个词合并,那么合并与否对LDA的训练是否有影响呢?有的词应该合并,比如”北京 大学“,也有的词分开会好一些,比如”阶级 斗争“。 -3. 根据上下文合并短文本,比如合并用户所有的微博作为一个文档,合并相似的微博作为一个文档,把微博当做一个查询,利用伪反馈来补充微博内容(中文微博比twitter字数更多一些,长微博不用扩展已经可以正确分类,短微博本身可能就是歧义的,扩展效果也不一定好),把微博及其评论作为一个文档。在一定程度上可缓解短文本问题。 -4. Topic Model的训练是一个数据拟合过程,找出latent topic最大训练语料库的似然概率,当不同类的数据不平衡时,数量量少的主题可能会被数据量多的主题主导。LDA本来就倾向于拟合高频的topic。LDA很多奇怪的结果大多都是因为词的共现导致的。 -5. 训练过程中,迭代次数一般可设为1000 – 2000次,可根据时间要求,机器配置选择。迭代次数达到一定值后,会在最小值处来回跳转。LDA的运行时间和文档数,不同词个数,文档长度,topic个数有关。 -6. K的选择,对每个K跑一个LDA,肉眼观察每个topic的情况最靠谱。当训练数据量大时不可行。此时可以根据不同的topic的相似度来调整K。假设不同topic之间的相似性小为佳(Perplexity, GraphLab Create直接输出这个结果)。一个经验设置是K × 词典的大小 约等于 语料库中词的总数。 -7. 挖掘优质的词典很重要,一方面有助于分词,也有助于明确潜在的主题。 -8. 数据量大后,LDA和PLSA的效果差不多,但是PLSA更容易并行化。LDA和PLSA的最大区别在于LDA对于Doc的Topic分布加上了一层先验,Doc-topic分布是当作模型变量,而LDA则只有一个超参数,Doc-Topic分布则是隐藏变量。在预测的时候,plsa是求一个似然概率,lda则是有两项,先验乘以似然。 -9. LDA在文本领域中,把word抽象成topic。类似,LDA也可以用在其它任务中,我们在信用评估中,直接把每个用户当成一个文档,文档中的词是每个关注的人,得到的topic相当于是一个用户group,相当于对用户进行聚类。还有,把微博中的@/rt的人当作word。http://www.machinedlearnings.com/2011/03/lda-on-social-graph.html -10. 超参数\alpha \beta对训练的影响?\alpha越大,先验起的作用就越大,推导的topic分布就越倾向于在每个topic上的概率都差不多。\alpha的经验选择为50/k, 其中k是topic数目,beta一般为0.01 -11. the color of a word tend to be similar to other words in the same document. -12. the color of a word tend to be similar to its major color in the whole corpus. -13. 用大的数据集训练一个general的model,还是根据垂直领域训练一个specific的model呢?应该看是想得到一些小众的topic,还是比较热门的topic。 -14. 为什么LDA的最大似然难求?含有两个连续的隐藏变量,需要积分掉,对于一个word,需要考虑每个topic生成这个word的概率,因此也有个求和项。因为这个条件分布很难求,导致求解带隐变量优化问题的EM算法也不行,因此EM算法往往都是用一个近似分布来代替。Gibbs Sampling则是生成p(z|…)的几个样本来近似这个条件分布。经过多次迭代(一次迭代对于一篇文章中的一个词只采样一次),一开始随机产生的 topic-word 矩阵 和 doc-topic 会处于稳定,真实的分布。对于一个Doc,根据词之间的可交换性,取不同词对应的topic的过程也是独立的。 -15. 短文本可以尝试TwitterLDA(假设一个短文本只关于一个话题),https://github.com/smutahoang/ttm - - - diff --git a/NLPinterview/ner/ChineseNer/img/20200609080811.png b/NLPinterview/ner/ChineseNer/img/20200609080811.png deleted file mode 100644 index fb43fa4..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20200609080811.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/20200609081004.png b/NLPinterview/ner/ChineseNer/img/20200609081004.png deleted file mode 100644 index 74dbc1c..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20200609081004.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/20200609092456.png b/NLPinterview/ner/ChineseNer/img/20200609092456.png deleted file mode 100644 index ad4d7d0..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20200609092456.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/20200609092556.png b/NLPinterview/ner/ChineseNer/img/20200609092556.png deleted file mode 100644 index b51adba..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20200609092556.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/20200609123825.png b/NLPinterview/ner/ChineseNer/img/20200609123825.png deleted file mode 100644 index 0778024..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20200609123825.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/20210115164908.png b/NLPinterview/ner/ChineseNer/img/20210115164908.png deleted file mode 100644 index 34e22f0..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20210115164908.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/20210115165224.png b/NLPinterview/ner/ChineseNer/img/20210115165224.png deleted file mode 100644 index 49d441a..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20210115165224.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/20210115165357.png b/NLPinterview/ner/ChineseNer/img/20210115165357.png deleted file mode 100644 index 462f896..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20210115165357.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/20210115165446.png b/NLPinterview/ner/ChineseNer/img/20210115165446.png deleted file mode 100644 index 0ac7cb3..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/20210115165446.png and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/img/gs.png b/NLPinterview/ner/ChineseNer/img/gs.png deleted file mode 100644 index e249769..0000000 Binary files a/NLPinterview/ner/ChineseNer/img/gs.png and /dev/null differ diff --git "a/NLPinterview/ner/ChineseNer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206163209.png" "b/NLPinterview/ner/ChineseNer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206163209.png" deleted file mode 100644 index 513d285..0000000 Binary files "a/NLPinterview/ner/ChineseNer/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206163209.png" and /dev/null differ diff --git a/NLPinterview/ner/ChineseNer/readme.md b/NLPinterview/ner/ChineseNer/readme.md deleted file mode 100644 index b06ac6a..0000000 --- a/NLPinterview/ner/ChineseNer/readme.md +++ /dev/null @@ -1,199 +0,0 @@ -# 【关于 中文领域 NER】 那些的你不知道的事 - -> 作者:杨夕 -> -> 介绍:本项目是作者们根据个人面试和经验总结出的自然语言处理(NLP)面试准备的学习笔记与资料,该资料目前包含 自然语言处理各领域的 面试题积累。 -> -> NLP 百面百搭 地址:https://github.com/km1994/NLP-Interview-Notes -> -> **[手机版NLP百面百搭](https://mp.weixin.qq.com/s?__biz=MzAxMTU5Njg4NQ==&mid=100005719&idx=3&sn=5d8e62993e5ecd4582703684c0d12e44&chksm=1bbff26d2cc87b7bf2504a8a4cafc60919d722b6e9acbcee81a626924d80f53a49301df9bd97&scene=18#wechat_redirect)** -> -> 推荐系统 百面百搭 地址:https://github.com/km1994/RES-Interview-Notes -> -> **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** -> -> 搜索引擎 百面百搭 地址:https://github.com/km1994/search-engine-Interview-Notes 【编写ing】 -> -> NLP论文学习笔记:https://github.com/km1994/nlp_paper_study -> -> 推荐系统论文学习笔记:https://github.com/km1994/RS_paper_study -> -> GCN 论文学习笔记:https://github.com/km1994/GCN_study -> -> **推广搜 军火库**:https://github.com/km1994/recommendation_advertisement_search -> -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210206163209.png) - -## 一、动机篇 - -### 1.1 中文命名实体识别 与 英文命名实体识别的区别? - -和英文 NER 每个单词都使用空格分隔不同,中文 NER 是基于字的表示方法,所以一般会涉及到中文分词和中文NER技术,导致 中文 NER 技术容易受到中文分词的误差的影响。 - -那么常用的方法有哪些呢? - -- 词汇增强:在早期的中文NER技术中,基于字符的 NER 方法往往具有高于 基于词汇(分词后)的方法,为了提高 基于词汇方法的效果,一般会采取引入词汇信息(词汇增强)的方法; -- 词汇/实体类型信息增强:使用特殊标记来识别句子中单词的边界,修改后的句子将由BERT直接编码 - -## 二、词汇增强篇 - -### 2.1 什么是 词汇增强? - -- 词汇增强:引入词汇信息(词汇增强)来增强 模型 识别 句子中实体的方法 - -### 2.2 为什么说 「词汇增强」 方法对于中文 NER 任务有效呢? - -虽然**基于字符的NER系统通常好于基于词汇(经过分词)的方法**,但**基于字符的NER没有利用词汇信息**,而**词汇边界对于实体边界通常起着至关重要的作用**。 - -**如何在基于字符的NER系统中引入词汇信息**,是近年来NER的一个研究重点。本文将这种引入词汇的方法称之为「词汇增强」,以表达引入词汇信息可以增强NER性能。 - -从另一个角度看,**由于NER标注数据资源的稀缺,BERT等预训练语言模型在一些NER任务上表现不佳。特别是在一些中文NER任务上,词汇增强的方法会好于或逼近BERT的性能**。因此,关注「词汇增强」方法在中文NER任务很有必要。 - -### 2.3 词汇增强 方法有哪些? - -- Dynamic Architecture:设计一个动态框架,能够兼容词汇输入; -- Adaptive Embedding :基于词汇信息,构建自适应Embedding; - -### 2.4 Dynamic Architecture - -#### 2.4.1 什么是 Dynamic Architecture? - -Dynamic Architecture 就是 需要设计相应结构以融入词汇信息。 - -#### 2.4.2 常用方法有哪些? - -- Lattice LSTM -- ... -- FLAT - -#### 2.4.3 什么是 Lattice LSTM ,存在什么问题? - -1. 介绍 - - -Lattice LSTM 通过词汇信息(词典)匹配一个句子时,可以获得一个类似Lattice的结构。 - -![Lattice 方法](img/20200609080811.png) -> 融合了词汇信息到原生的LSTM - -Lattice是一个有向无环图,词汇的开始和结束字符决定了其位置。Lattice LSTM结构则融合了词汇信息到原生的LSTM中: - -![](img/20200609081004.png) -> Lattice LSTM 结构 - -如上图所示,Lattice LSTM引入了一个word cell结构,对于当前的字符,融合以该字符结束的所有word信息,如对于「桥」融合了「长江大桥」和「大桥」的信息。对于每一个字符,Lattice LSTM采取注意力机制去融合个数可变的word cell单元,其主要的数学形式化表达为: - -![](img/gs.png) - -2. 存在问题 - -Lattice LSTM 的提出,将词汇信息引入,有效提升了NER性能;但其也存在一些缺点: - -- 计算性能低下,不能batch并行化。究其原因主要是每个字符之间的增加word cell(看作节点)数目不一致; -- 信息损失: - - 1)每个字符只能获取以它为结尾的词汇信息,对于其之前的词汇信息也没有持续记忆。如对于「大」,并无法获得‘inside’的「长江大桥」信息。 - - 2)由于RNN特性,采取BiLSTM时其前向和后向的词汇信息不能共享。 -- 可迁移性差:只适配于LSTM,不具备向其他网络迁移的特性。 - - -#### 2.4.4 什么是 FLAT ,存在什么问题? - -1. 动机 - -- 动机一:Lattice-LSTM 和 LR-CNN 问题 - 1. 这些模型采取的RNN和CNN结构无法捕捉长距离依赖; - 2. 动态的Lattice结构也不能充分进行GPU并行; -- 动机二:CGN 和 LGN 问题 - 1. 采取的图网络虽然可以捕捉对于NER任务至关重要的顺序结构,但这两者之间的gap是不可忽略的; - 2. 这类图网络通常需要RNN作为底层编码器来捕捉顺序性,通常需要复杂的模型结构 - -2. 思路 - -- Transformer:采取全连接的自注意力机制可以很好捕捉长距离依赖,由于自注意力机制对位置是无偏的,因此Transformer引入位置向量来保持位置信息。 -- FLAT 亮点:对于每一个字符和词汇都构建两个head position encoding 和 tail position encoding。例如,字符[药]可以匹配词汇[人和药店]和[药店]。 - -![](img/20200609092456.png) - -因此,我们可以将Lattice结构展平,将其从一个有向无环图展平为一个平面的Flat-Lattice Transformer结构,由多个span构成:每个字符的head和tail是相同的,每个词汇的head和tail是skipped的。 - -![](img/20200609092556.png) - -### 2.5 Adaptive Embedding 范式 - -#### 2.5.1 什么是 Adaptive Embedding 范式? - -Adaptive Embedding 范式 就是 在embedding层对于词汇信息进行自适应,后面通常接入LSTM+CRF和其他通用网络,这种范式与模型无关,具备可迁移性。 - -#### 2.5.2 常用方法有哪些? - -- WC-LSTM -- Multi-digraph -- ... -- Simple-Lexicon - -#### 2.5.3 什么是 WC-LSTM ,存在什么问题? - -1. 动机 - -**Lattice LSTM中每个字符只能获取以它为结尾的词汇数量是动态的、不固定**的,这也是导致Lattice LSTM**不能batch并行化**的原因。 - -2. 思路 - -WC-LSTM为改进这一问题,采取** Words Encoding Strategy**,**将每个字符为结尾的词汇信息进行固定编码表示**,即每一个字符引入的词汇表征是静态的、固定的,如果没有对应的词汇则用代替,从而可以进行batch并行化。 - -这四种 encoding 策略分别为:最短词汇信息、最长词汇信息、average、self-attenion。以「average」为例:即将当前字符引入所有相关的词汇信息对应的词向量进行平均。 - -![](img/20200609123825.png) - -3. 存在问题 - -WC-LSTM仍然**存在信息损失问题**,无法获得‘inside’的词汇信息,不能充分利用词汇信息。虽然是Adaptive Embedding范式,但WC-LSTM仍然采取LSTM进行编码,建模能力有限、存在效率问题。 - -## 三、词汇/实体类型信息增强篇 - -### 3.1 什么是 词汇/实体类型信息增强? - -- 词汇/实体类型信息增强:使用特殊标记来识别句子中单词的边界,修改后的句子将由BERT直接编码 - -### 3.2 为什么说 「词汇/实体类型信息增强」 方法对于中文 NER 任务有效呢? - -词汇增强方法 在NER任务中的表现令人印象深刻,但最近已经证明,添加词汇信息可以显著提高下游性能。然而,**没有任何工作在不引入额外结构的情况下将单词信息纳入BERT**。 - -### 3.3 词汇/实体类型信息增强 方法有哪些? - -- LEX-BERT - -### 3.4 什么是 LEX-BERT ? - -1. LEX-BERT V1 - -- 方法:Lex BERT的第一个版本通过在单词的左右两侧插入特殊标记来识别句子中单词的 span。特殊标记不仅可以标记单词的起始位置和结束位置,还可以为句子提供实体类型信息 - -![](img/20210115164908.png) - -- 作用: - - 首先,如果我们的字典带有实体类型信息,我们可以通过标记将其插入到句子中。这里是医学相关动词的缩写,表示药物,表示检查索引,表示医学概念术语。 - - 其次,它们表示词汇集合中单词的开始或结束。这里开始标记的格式是[x],结束标记的格式是[/x],其中x可以是v、d、i等 - -2. LEX-BERT V2 - -- 方法:对于在句子中加宽的单词,我们没有在句子中单词的周围插入起始和结束标记,而是在句子的末尾附加一个标记[x]。请注意,我们将标记的位置嵌入与单词的起始标记绑定: - -![](img/20210115165224.png) - -修改了BERT的注意矩阵,如图2所示。句子中的文字标记只会互相注意,而不会注意标记。相反,markertoken可以处理输入序列中的所有标记。 - -![](img/20210115165357.png) - - -## 参考资料 - -1. [Lattice LSTM:Chinese NER Using Lattice LSTM(ACL2018)](https://arxiv.org/abs/1805.02023) -2. [FLAT: Chinese NER Using Flat-Lattice Transformer(ACL2020)](https://arxiv.org/pdf/2004.11795.pdf) -3. [WC-LSTM: An Encoding Strategy Based Word-Character LSTM for Chinese NER Lattice LSTM(NAACL2019)](https://pdfs.semanticscholar.org/43d7/4cd04fb22bbe61d650861766528e369e08cc.pdf%3F_ga%3D2.158312058.1142019791.1590478401-1756505226.1584453795) -4. [Multi-digraph: A Neural Multi-digraph Model for Chinese NER with Gazetteers(ACL2019)](https://www.aclweb.org/anthology/P19-1141.pdf) -5. [Simple-Lexicon:Simplify the Usage of Lexicon in Chinese NER(ACL2020)](https://arxiv.org/pdf/1908.05969.pdf) -6. [Lex-BERT: Enhancing BERT based NER with lexicons](https://arxiv.org/pdf/2101.00396) \ No newline at end of file diff --git a/NLPinterview/ner/DNN/img/DNN-CRF.png b/NLPinterview/ner/DNN/img/DNN-CRF.png deleted file mode 100644 index e64da8d..0000000 Binary files a/NLPinterview/ner/DNN/img/DNN-CRF.png and /dev/null differ diff --git a/NLPinterview/ner/DNN/img/crf.png b/NLPinterview/ner/DNN/img/crf.png deleted file mode 100644 index f27fa40..0000000 Binary files a/NLPinterview/ner/DNN/img/crf.png and /dev/null differ diff --git a/NLPinterview/ner/DNN/img/pointer.png b/NLPinterview/ner/DNN/img/pointer.png deleted file mode 100644 index f2fe1b1..0000000 Binary files a/NLPinterview/ner/DNN/img/pointer.png and /dev/null differ diff --git a/NLPinterview/ner/DNN/img/rnn.png b/NLPinterview/ner/DNN/img/rnn.png deleted file mode 100644 index aa153e3..0000000 Binary files a/NLPinterview/ner/DNN/img/rnn.png and /dev/null differ diff --git a/NLPinterview/ner/DNN/img/softmax.png b/NLPinterview/ner/DNN/img/softmax.png deleted file mode 100644 index eee4dda..0000000 Binary files a/NLPinterview/ner/DNN/img/softmax.png and /dev/null differ diff --git "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229225910.png" "b/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229225910.png" deleted file mode 100644 index 4273c3f..0000000 Binary files "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229225910.png" and /dev/null differ diff --git "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229231347.png" "b/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229231347.png" deleted file mode 100644 index ff82b26..0000000 Binary files "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229231347.png" and /dev/null differ diff --git "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229231740.png" "b/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229231740.png" deleted file mode 100644 index d15aa59..0000000 Binary files "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201229231740.png" and /dev/null differ diff --git "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210107224419.png" "b/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210107224419.png" deleted file mode 100644 index 9c7e845..0000000 Binary files "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210107224419.png" and /dev/null differ diff --git "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210107230805.png" "b/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210107230805.png" deleted file mode 100644 index da1189d..0000000 Binary files "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210107230805.png" and /dev/null differ diff --git "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200655.png" "b/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200655.png" deleted file mode 100644 index b8cbf5e..0000000 Binary files "a/NLPinterview/ner/DNN/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200655.png" and /dev/null differ diff --git a/NLPinterview/ner/DNN/readme.md b/NLPinterview/ner/DNN/readme.md deleted file mode 100644 index 187484a..0000000 --- a/NLPinterview/ner/DNN/readme.md +++ /dev/null @@ -1,197 +0,0 @@ -# 【关于 DNN-CRF】 那些你不知道的事 - -> 作者:杨夕 -> -> 介绍:本项目是作者们根据个人面试和经验总结出的自然语言处理(NLP)面试准备的学习笔记与资料,该资料目前包含 自然语言处理各领域的 面试题积累。 -> -> NLP 百面百搭 地址:https://github.com/km1994/NLP-Interview-Notes -> -> **[手机版NLP百面百搭](https://mp.weixin.qq.com/s?__biz=MzAxMTU5Njg4NQ==&mid=100005719&idx=3&sn=5d8e62993e5ecd4582703684c0d12e44&chksm=1bbff26d2cc87b7bf2504a8a4cafc60919d722b6e9acbcee81a626924d80f53a49301df9bd97&scene=18#wechat_redirect)** -> -> 推荐系统 百面百搭 地址:https://github.com/km1994/RES-Interview-Notes -> -> **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** -> -> 搜索引擎 百面百搭 地址:https://github.com/km1994/search-engine-Interview-Notes 【编写ing】 -> -> NLP论文学习笔记:https://github.com/km1994/nlp_paper_study -> -> 推荐系统论文学习笔记:https://github.com/km1994/RS_paper_study -> -> GCN 论文学习笔记:https://github.com/km1994/GCN_study -> -> **推广搜 军火库**:https://github.com/km1994/recommendation_advertisement_search -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210210200655.png) - -## 一、基本信息 - -### 1.1 命名实体识别 评价指标 是什么? - -- 命名实体识别 本质有两个任务组成: - - 边界检测 - - 类型识别 -- 精确匹配评估 - -![](img/微信截图_20210107224419.png) - - -> 注:其中 #TP 表示识别出的实体且是正确实体的数量, #FP 表示识别出的实体却是不存在实体的数量, #FN 表示是正确的实体却没被识别出的数量。当然,除此之外,像macro-f1、micro-f1也会用来作评估。 - -- 宽松匹配评估 - - 特点:降低了匹配正确的要求 - - 类别: - - 类别正确:一个实体被正确识别到类别,而边界与正确边界有重叠即可; - - 边界正确:一个实体被正确识别到边界,而不管类别是什么; - -## 二、传统的命名实体识别方法 - -### 2.1 基于规则的命名实体识别方法是什么? - -- 介绍:基于特定领域或者特定语法规则来设计规则,然后利用这些规则去抽取 句子中实体 -- 缺点:依赖专家知识 构建 规则 -- 特点:由于特定领域的规则和不完整的词典,这类系统往往具有较高的精度和较低的召回率,无法转移到其他领域 - -### 2.2 基于无监督学习的命名实体识别方法是什么? - -- 主要思想:词汇、词语模式以及在大语料上计算的统计特性可以用来推断命名实体的出现 - -### 2.3 基于特征的监督学习的命名实体识别方法是什么? - -- 介绍:NER被转化为一个多分类问题或者序列标注问题,通过精心设计的特征,在标注语料上进行训练,从而在未知文本上识别出类似的模式实体。 - -## 三、基于深度学习的命名实体识别方法 - -### 3.1 基于深度学习的命名实体识别方法 相比于 基于机器学习的命名实体识别方法的优点? - -1. 受益于深度学习的非线性转换,可以从数据中学到更复杂的特征; -2. 避免大量的人工特征的构建; -3. 可以设计为端到端的结构。 - -### 3.2 基于深度学习的命名实体识别方法 的 结构是怎么样? - -- 介绍:基于深度学习的命名实体识别方法 由 分布式输入层、文本编码器、解码层 组成; - -![](img/微信截图_20210107230805.png) - -### 3.3 分布式输入层 是什么,有哪些方法? - -- 介绍:将 句子 转化为 词粒度、字符粒度、混合的表示方法作为模型输入; -- 类别: - - 词粒度的表示:像word2vec、fasttext、glove或者SENNA等算法可以通过大规模的无监督语料学习词粒度的表示,作为NER模型的输入,在训练过程中既可以固定不变也可以微调。 - - 字符粒度的表示:除了仅考虑词向量作为输入之外,也融合了字符粒度的表示作为模型的输入。字符级别的表示,相对于词向量,能够提取出子词的特征,比如前缀后缀等,也能够缓解oov的问题。如下图所示,最常用的两种提取结构分别基于CNN与RNN模型。 - - 混合表示:除了词粒度和字符粒度的表示之外,还融合了一些额外信息,比如地点信息、词汇相似度、视觉信息等等。像FLAT、BERT、XLNET等模型也被本文划分为混合表示,因为输入的时候还包含有位置等信息。 - -### 3.4 文本编码器篇 - -#### 3.4.1 BiLSTM-CRF 篇 - -##### 3.4.1.1 什么是 BiLSTM-CRF? - -![](img/微信截图_20201229225910.png) - -- step 1:利用 字粒度表示层 将 句子中每个字 编码成一个字向量; -- step 2:然后利用 BiLSTM 编码层 对句子中每个字的字向量,以捕获 句子中每个字的信息; -- step 3:在 BiLSTM 后接一个 CRF 解码层,对 编码的向量进行解码,以解码出 句子最优的标注序列; - -##### 3.4.1.2 为什么要用 BiLSTM? - -由于 BiLSTM 能够捕获句子的长距离依赖信息。 - -#### 3.4.2 IDCNN-CRF 篇 - -##### 3.4.2.1 什么是 Dilated CNN? - -Dilated/Atrous Convolution(中文叫做空洞卷积或者膨胀卷积) 或者是 Convolution with holes 从字面上就很好理解,是在标准的 convolution map 里注入空洞,以此来增加 reception field。相比原来的正常convolution,dilated convolution 多了一个 hyper-parameter 称之为 dilation rate 指的是kernel的间隔数量(e.g. 正常的 convolution 是 dilatation rate 1)。 - -![](img/微信截图_20201229231347.png) - -##### 3.4.2.2 为什么会有 Dilated CNN? - -- CNN 特点:方便的获取局部特征,通过pad操作,可以让CNN的输出层与输入层具有相同的序列长度,从而可以使用CNN来进行序列相关的特征抽取; -- CNN 问题: - - 正常CNN 的 filler 作用于输入矩阵连续位置,利用 卷积 和 池化 整合多尺度的上下文信息,导致分辨率损失; - - pooling 会损失信息,降低精度,不加则导致感受野变小,学不到全局信息; - - 浅层的CNN只能获取局部特征,要获取全局特征或者更大的感受野,则需要比较深的CNN层,这会增加计算量也会提高过拟合的风险 - -##### 3.4.2.3 Dilated CNN 的优点? - -- 优点:利用空洞卷积能够使输入宽度随模型深度呈指数增长,达到在不影响每层网络的分辨率的情况下,降低参数数量。 -- 与传统CNN层相比,空洞卷积同样对序列上下文的滑动窗口进行操作; - -##### 3.4.2.4 IDCNN-CRF 介绍 - -- 动机:然后 Dilated CNN 相比于 CNN 能够捕获更多信息,但是扩张的窗口捕获的信息只能学习距离为d的其他信息。 -- 操作:通过堆叠不同扩张大小的空洞卷积层,有效扩展输入宽度的大小,使其在仅使用几个空洞卷积层的情况下,学习序列的整个长度信息。 - -![](img/微信截图_20201229231740.png) -> 注:利用四个结构相同的 Dilated CNN 拼接起来,每个 block 里面 dilated width 为 1,1,2 的三层 DCNN - -### 3.5 标签解码器篇 - -#### 3.5.1 标签解码器是什么? - -标签解码器是NER模型的最后一个阶段。它接受上下文相关的表示作为输入,并基于输入产生相关的序列标签。 - -#### 3.5.2 MLP+softmax层 介绍? - -- 介绍:使用多层感知器+Softmax层作为标签解码器层,则将序列标注任务转化为一个多分类问题。每个单词的标签都是根据上下文相关的表示独立预测的,而不考虑它的邻居标签结果。 - -![](img/softmax.png) - -#### 3.5.3 条件随机场CRF层 介绍? - -- 介绍:使一个以观测序列为全局条件的随机场。CRF已被广泛应用于基于特征的监督学习方法。许多基于深度学习的NER模型使用CRF层作为标签解码器,并取得了很好的精度。 - -![](img/crf.png) - -#### 3.5.4 循环神经网络RNN层 介绍? - -- 介绍:RNN解码是个贪婪的过程,先计算出第一个位置的标签,然后后面每一个位置的标签都是基于前面的状态计算出标签,在标签数量比较多的时候,可以比CRF更加快速。 - -![](img/rnn.png) - -#### 3.5.3 指针网路层 介绍? - -- 介绍:将序列标注问题转化为两个子问题:先分块再分类。指针网络会贪婪地从头开始找下一个块结束的位置(开始的位置很显然,第一个块的开始位置是起始点,后面的开始位置都是前面一块的结束位置的后继位置)如上图d所示,在起始块"<\s>"后一块的结束块位置是"Jordan",这样就得到块"Michael Jeffrey Jordan",然后将这个块进行分类确定类别,之后再继续找下一个块的结束位置,找到"was",这样就得到一个新的块"was",再将这个块进行分类,然后这样循环下去直到序列结束。指针网络主要就起到确定块起始位置的作用。 - -![](img/pointer.png) - - -## 四、对比 篇 - -### 4.1 CNN-CRF vs BiLSTM-CRF vs IDCNN-CRF? - -- CNN-CRF:对于序列标注来讲,普通CNN有一个不足,就是卷积之后,末层神经元可能只是得到了原始输入数据中一小块的信息。而对NER来讲,整个输入句子中每个字都有可能对当前位置的标注产生影响,即所谓的长距离依赖问题。为了覆盖到全部的输入信息就需要加入更多的卷积层,导致层数越来越深,参数越来越多。而为了防止过拟合又要加入更多的Dropout之类的正则化,带来更多的超参数,整个模型变得庞大且难以训练。 -- BiLSTM-CRF:因为CNN这样的劣势,对于大部分序列标注问题人们还是选择biLSTM之类的网络结构,尽可能利用网络的记忆力记住全句的信息来对当前字做标注。但这又带来另外一个问题,biLSTM本质是一个序列模型,在对GPU并行计算的利用上不如CNN那么强大。 -- IDCNN-CRF: - - 如何解决 CNN-CRF 问题:通过堆叠不同扩张大小的空洞卷积层,有效扩展输入宽度的大小,使其在仅使用几个空洞卷积层的情况下,学习序列的整个长度信息; - - 如何解决 BiLSTM-CRF 问题:因为 IDCNN 本身是一个 CNN ,所以可以像 CNN 一样进行并行化计算; - -### 4.2 为什么 DNN 后面要加 CRF? - -- DNN 做 序列标注 的 机制 - - 做法:NN 对每个 token 打标签的过程是独立进行的,不能直接利用上文已预测的标签(只能靠隐含状态传递上下文信息),进而导致预测出的标签序列可能无效 - - 存在问题: - - B、S、I、E 顺序错乱问题 -- CRF 做 序列标注 的 机制 - - 方法:CRF是全局范围内统计归一化的条件状态转移概率矩阵,再预测出一条指定的sample的每个token的label - - 介绍:因为CRF的特征函数的存在就是为了对given序列观察学习各种特征(n-gram,窗口),这些特征就是在限定窗口size下的各种词之间的关系。然后一般都会学到这样的一条规律(特征):B后面接E,不会出现B。这个限定特征会使得CRF的预测结果不出现上述例子的错误。 -- DNN-CRF - - 做法:把CRF接到LSTM后面,把LSTM在timestep上把每一个hiddenstate的tensor输入给CRF,进行句子级别的标签预测,使得标注过程中不再是对各个 token 单独分类 - -### 4.3 CRF in TensorFlow V.S. CRF in discrete toolkit? - -- CRF相关的工具包:采用上述理论提到的为特征打分的方式统计出来的。统计的特征分数作为每个token对应的tag的类别的分数,输入给CRF解码即可。 -- TensorFlow:LSTM每个节点的隐含表征vector:Hi的值作为CRF层对应的每个节点的统计分数,再计算每个序列(句子)的整体得分score,作为损失目标,最后inference阶段让viterbi对每个序列的transition matrix去解码,搜出一条最优路径。 -- 区别: - - 在LSTM+CRF中,CRF的特征分数直接来源于LSTM传上来的Hi的值;而在general CRF中,分数是统计来的。 - - 解释:所有导致有的同学认为LSTM+CRF中其实并没有实际意义的CRF。其实按刚才说的,Hi本身当做特征分数形成transition matrix再让viterbi进行路径搜索,这整个其实就是CRF的意义了。所以LSTM+CRF中的CRF没毛病。 - - -## 参考资料 - -1. [A Survey on Deep Learning for Named Entity Recognition](https://arxiv.org/pdf/1812.09449.pdf) -2. [NLP集大成之命名实体识别](https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=2247520685&idx=3&sn=aef975d579c190594a202abb8159513b&chksm=ebb7a979dcc0206f7b0aa745ddbae777fb84cd57481ed5697a12fccddca5be5d9f0010bc07ef&mpshare=1&scene=22&srcid=1231rtG7X3DlS9ZGf2XZJBSu&sharer_sharetime=1609377507173&sharer_shareid=da84f0d2d31380d783922b9e26cacfe2#rd) \ No newline at end of file diff --git a/NLPinterview/ner/NERtrick/NERtrick.md b/NLPinterview/ner/NERtrick/NERtrick.md deleted file mode 100644 index 7cd56fa..0000000 --- a/NLPinterview/ner/NERtrick/NERtrick.md +++ /dev/null @@ -1,253 +0,0 @@ -# 【关于 NER trick】 那些你不知道的事 - -> 作者:杨夕 -> -> 介绍:本项目是作者们根据个人面试和经验总结出的自然语言处理(NLP)面试准备的学习笔记与资料,该资料目前包含 自然语言处理各领域的 面试题积累。 -> -> NLP 百面百搭 地址:https://github.com/km1994/NLP-Interview-Notes -> -> **[手机版NLP百面百搭](https://mp.weixin.qq.com/s?__biz=MzAxMTU5Njg4NQ==&mid=100005719&idx=3&sn=5d8e62993e5ecd4582703684c0d12e44&chksm=1bbff26d2cc87b7bf2504a8a4cafc60919d722b6e9acbcee81a626924d80f53a49301df9bd97&scene=18#wechat_redirect)** -> -> 推荐系统 百面百搭 地址:https://github.com/km1994/RES-Interview-Notes -> -> **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** -> -> 搜索引擎 百面百搭 地址:https://github.com/km1994/search-engine-Interview-Notes 【编写ing】 -> -> NLP论文学习笔记:https://github.com/km1994/nlp_paper_study -> -> 推荐系统论文学习笔记:https://github.com/km1994/RS_paper_study -> -> GCN 论文学习笔记:https://github.com/km1994/GCN_study -> -> **推广搜 军火库**:https://github.com/km1994/recommendation_advertisement_search -> -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210224224353.png) - -## trick 1:领域词典匹配 - -- 场景:对于某些 常见短语,可以 采用 词典匹配 的方式。 -- 方法:构建一个 常见短语 的 词典,比如 药物、疾病等,然后采用 flashtext 进行 关键词匹配; -- 优点: - - 能够准确的挖掘出 常见短语; - - 效率更快 -- 缺点: - - 对于有些 嵌套实体,如果 长实体未包含在词典中,那么将匹配到 短实体; - - 词典收集工作量大 - -## trick 2:规则抽取 - -- 场景:对于一些 规定句式,可以 采用 规则匹配 的方式。 -- 方法:构建一些 规则模板库,比如 “ 去|到|抵达|经过 ”、“ 能够|可以 治疗 ” 等; -- 优点: - - 对于某些固定句式,这种方法匹配度高; - - 效率快; -- 缺点: - - 会出现干扰词,eg: “ 去|到|抵达|经过|访 ” 抽取 "特朗普和第一夫人访华" -> (特朗普和第一夫人,)、(华,); - - 需要手工制定规则; - -## trick 3:词向量选取:词向量 or 字向量? - -- 词向量 - - 方式:首先对句子进行分词,然后训练 所有词语 的 向量表示,最后利用 这些 词向量 训练模型; - - 优点: - - 能够 帮助 模型 学习 句子中 词汇关系; - - 缺点: - - OOV 问题; - - 维护成本高; - - 如果分词效果不好,那么词向量的质量 将受影响; -- 字向量 - - 方式:首先对句子按字切分,然后训练 所有字的 向量表示,最后利用 这些 字向量 训练模型; - - 优点: - - 解决了 词向量的 OOV 问题; - - 减少人工维护成本; - - 不用分词; - - 在训练数据质量较差的时候(比如口语化较多,错别字较多,简称缩写较多等),采用字向量的效果好于词向量; - - 缺点: - - 学不出 词语间 的 关系; - - 解决方法: - - 利用 具有 双向 的 特征提取器 能够 缓解 该功能,eg: bilstm、bert 等; - -## trick 4:特征提取器 如何选择? - -- 短句子: - - 模型:LSTM、BiLSTM、CNN、IDCNN - - 优点: - - 在句子较短的情况下, 模型能够 捕获 句子中词语间的依赖关系 -- 长句子: - - 模型:Bert - - 优点: - - 在句子较长的情况下, 由于 LSTM、BiLSTM、CNN、IDCNN 会出现 长距离依赖问题,所以性能下降; - - -## trick 5:专有名称 怎么 处理?【注:这一点来自于 [命名实体识别的几点心得](https://zhuanlan.zhihu.com/p/163607351) 】 - -- 场景:#1机组1A锅炉磨煤机故障,#2机组2C炉磨煤机故障。 实体是磨煤机。 -- 方法:在训练ner模型时,可以将一类专业名词改写成一个符号表示 -- 具体操作: - - #1机组、#2机组、#3机组...是一类机组名词,可用符号表示; - - 1A锅炉,1A炉,1B炉,1C锅炉...是一类锅炉专业名词,可用符号表示; -- 转化后: - - 磨煤机故障,标注:[OOBIIOO] - -## trick 6:标注数据 不足怎么处理?【这个问题可以说是现在很多小厂最头疼的问题】 - -- 问题介绍:随着模型的愈发精细复杂,需要训练的参数日益庞大,但其训练所需的人工标注数据却因为标注成本的问题难以得到相应地增长。 -- 方法一:远程监督标注数据 - - 思路:使用远程监督的方法来得到大量的远程监督标注数据 - - 问题:有限覆盖问题(Limited Coverage)。由于用于远程监督的知识库规模有限,大量的实体存在于文本中而未出现在知识库中,导致在远程监督时,将这些未出现在知识库中的实体标注为非实体,从而产生大量的假负例; -- 方法二:优化模型 - - 思路:限制参数量,从而使得模型能够在较小的标注数据集上也能够完成训练; -- 方法三:采用主动学习方法 - - 思路: - - step 1:先标注一小部分数据,利用这部分标注数据训练模型; - - step 2:利用模型去标注 未标记数据; - - step 3: 利用 查询函数 筛选 信息量最大的数据;(方法:信息熵计算不确定样本法、多模型投票选取争议性最高样本法); - - step 4:由人工进行标注,并加入到 标注数据中,回到 step 1,直到 样本足够大,或者 模型预测值 趋于平衡; - - 优点: - - 减少标注成本。由于 选取的数据 所包含的信息量较高,所以减少数据 标注成本(本人之前做过一个小实验,发现采用主动学习方法筛选出的总样本的30%左右,训练出的命名实体识别模型性能与全量训练效果相近); - - 数据质量高; - - 缺点: - - 如果 查询函数 选取 不对,可能吃力不讨好,也就是 选取的样本存在偏差,比如选到了 离群点。 -- 方法四:迁移学习 【这种方法也蛮常见,问题就是风险太高】 -- 方法五:预训练+自训练 【Self-training Improves Pre-training for Natural Language Understanding】 - - 背景知识: - - 方法: - - 预训练(Pre-training)从广义上来讲,是指先在较大规模的数据上对模型训练一波,然后再在具体的下游任务数据中微调。大多数情况下,预训练的含义都比较狭窄:在大规模无标注语料上,用自监督的方式训练模型。这里的自监督方法一般指的是语言模型; - - 自训练是说有一个Teacher模型Ft和一个Student模型Fs,首先在标注数据上训练Ft,然后用它对大规模无标注数据进行标注,把得到的结果当做伪标注数据去训练Fs。 - - 相同点:用到了大规模无标注的数据 - - 区别: - - 预训练始终对针对一个模型进行操作,而自训练却用到了两个模型; - - 预训练是直接从无标注数据中学习,而自训练是间接地从数据中学习; - - 思路: - 1. 将一个预训练模型(本文使用RoBERTa_Large)在标注数据上训练,作为教师模型Ft; - 2. 使用Ft从海量通用语料中提取相关领域的数据,一般是 抽取出 置信度较高的样本; - 3. 用Ft对提取的数据作标注; - 4. 用伪标注语料训练学生模型Fs。 -- 方法六:实体词典+BERT相结合 - - 利用实体词典+BERT相结合,进行半监督自训练**【注:参考 资料11】 ** - -## trick 7:嵌套命名实体识别怎么处理 【注:参考 资料3】 - -### 7.1 什么是实体嵌套? - -实体嵌套是指在一句文本中出现的实体,存在某个较短实体完全包含在另外一个较长实体内部的情况,如“南京市长”中地名“南京”就嵌套在职务名“南京市长”中。 - -### 7.2 与 传统命名实体识别任务的区别 -传统的命名实体识别任务关注的都是平坦实体(Flat entities),即文本中的实体之间不交叉、不嵌套。 -### 7.3 解决方法: -#### 7.3.1 方法一:序列标注 -- 多标签分类 - - 思路:命名实体识别本来属于基于字的多分类问题,嵌套实体需要将其转化为 多标签问题(即每个字有多种标签,如下图所示) - - 问题: - - 学习难度较大 - - 容易导致label之间依赖关系的缺失 - -![](img/20201208200430.png) - -- 合并标签层 - - 思路:采用CRF,但设置多个标签层,对于每一个token给出其所有的label,然后将所有标签层合并 - - 问题: - - 指数级增加了标签; - - 对于多层嵌套,稀疏问题较为棘手; - -![](img/20201208200631.png) - -#### 7.3.2 方法二:指针标注 -- 层叠式指针标注 - - 思路:设置 C 个指针网络 - -![](img/20201208200933.png) - -- MRC-QA+指针标注 - - 思路:构建query问题指代所要抽取的实体类型,同时也引入了先验语义知识,如下图(d)所示。在文献中就对不同实体类型构建query,并采取指针标注,此外也构建了 **1 矩阵来判断span是否构成一个实体mention。 - -![](img/20201208201135.png) - -#### 7.3.3 方法三:多头标注 - -- 构建 span 矩阵 - - 思路:构建一个 ** 的Span矩阵 - - 说明:如图,Span{呼}{枢}=1,代表「呼吸中枢」是一个部位实体;Span{呼}{累}=2,代表「呼吸中枢受累」是一个症状实体; - - 问题: - - 如何构造Span矩阵问题 - - 如何解决0-1标签稀疏问题 - -![](img/20201208202535.png) - -- 嵌套实体的2篇SOTA之作: - - ACL20的《Named Entity Recognition as Dependency Parsing》采取Biaffine机制构造Span矩阵 **【注:具体可以参考 资料12】**; - - EMNLP20的HIT **【注:具体可以参考 资料13】**则通过Biaffine机制专门捕获边界信息,并采取传统的序列标注任务强化嵌套结构的内部信息交互,同时采取focal loss来解决0-1标签不平衡问题。 - -#### 7.3.4 方法四:片段排列 - -十分直接,如下图(f)所示。对于含T个token的文本,理论上共有 = (+1)/2 种片段排列。如果文本过长,会产生大量的负样本,在实际中需要限制span长度并合理削减负样本。 - -![](img/20201208202913.png) - -## trick 8:为什么说 「词汇增强」 方法对于中文 NER 任务有效? - -- 动机:虽然**基于字符的NER系统通常好于基于词汇(经过分词)的方法**,但**基于字符的NER没有利用词汇信息**,而**词汇边界对于实体边界通常起着至关重要的作用**。 -- 目标:**如何在基于字符的NER系统中引入词汇信息** -- 思路: - - 方法一:设计一个动态框架,能够兼容词汇输入 **【注:具体可以参考 资料6-10】** - - 方法二:采用多种分词工具和多种句法短语⼯具进行融合来提取候选实体,并结合词典进行NER - -## trick 9:NER实体span过长怎么办? - -- 动机:如果NER任务中某一类实体span比较长(⽐如医疗NER中的⼿术名称是很长的),直接采取CRF解码可能会导致很多连续的实体span断裂; -- 解决方法: - - 加入规则进行修正 - - 引入指针网络+CRF构建多任务学习。指针网络会更容易捕捉较长的span,不过指针网络的收敛是较慢的,可以对CRF和指针网络设置不同学习率,或者设置不同的loss权重。 - -## trick 10: NER 标注数据噪声问题? - -- 动机:NER 标注数据存在噪声问题,导致模型训练效果差 -- 方法: - - 方法一:对训练集进行交叉验证,然后人工去清洗这些“脏数据” - - 方法二:将noisy label learning应用于NER任务,惩罚那些噪音大的样本loss权重 **【注:具体可以参考 资料12】** - -## trick 11: 给定两个命名实体识别任务,一个任务数据量足够,另外一个数据量很少,可以怎么做? - -- 动机:NER 标注数据 有些类别 标注数据量 较少; -- 方法: - - 重采样 - - loss惩罚 - - Dice loss - - 若 该类实体属于 长尾实体(填充率低),可以挖掘相关规则模板、构建词典库 - -## trick 12: NER 标注数据不均衡问题? - -- 迁移学习 - - 假设:数据量足够任务为 T1,数据量很少任务为 T2。 - - 思路 - - 首先在任务T1中训练模型,然后模型利用之前学习任务所得的知识,应用于任务T2。也就是说模型在任务T1学习知识(特征、权重),然后推广这一知识(特征、权重)至任务T2(明显数据更少)。 - -- 半监督策略,即引入虚拟对抗; - - 思路:随机生成一个扰动,然后进行导数,L2规范化等处理,生成当前所需要的扰动,将其加入到model原始input embedding,再次求损失;模型最终优化loss + loss(带扰动);使得模型鲁棒性更强,准确率更高 - -## 参考资料 - -1. [命名实体识别的几点心得](https://zhuanlan.zhihu.com/p/163607351) -2. [刷爆3路榜单,信息抽取冠军方案分享:嵌套NER+关系抽取+实体标准化](https://zhuanlan.zhihu.com/p/326302618) -3. [标注样本少怎么办?「文本增强+半监督学习」总结(从PseudoLabel到UDA/FixMatch)](https://zhuanlan.zhihu.com/p/146777068) -4. [如何解决NLP分类任务的11个关键问题:类别不平衡&低耗时计算&小样本&鲁棒性&测试检验&长文本分类](https://zhuanlan.zhihu.com/p/183852900) -5. [工业界如何解决NER问题?12个trick,与你分享~](https://zhuanlan.zhihu.com/p/152463745) -6. [Lattice LSTM:Chinese NER Using Lattice LSTM(ACL2018)](https://arxiv.org/abs/1805.02023) -7. [LR-CNN:CNN-Based Chinese NER with Lexicon Rethinking(IJCAI2019)](https://pdfs.semanticscholar.org/1698/d96c6fffee9ec969e07a58bab62cb4836614.pdf) -8. [CGN: Leverage Lexical Knowledge for Chinese Named Entity Recognition via Collaborative Graph Network( EMNLP2019)](https://www.aclweb.org/anthology/D19-1396.pdf) -9. [LGN: A Lexicon-Based Graph Neural Network for Chinese NER(EMNLP2019)](https://www.aclweb.org/anthology/D19-1096.pdf) -10. [FLAT: Chinese NER Using Flat-Lattice Transformer(ACL2020)](https://arxiv.org/pdf/2004.11795.pdf) -11. [Better Modeling of Incomplete Annotations for Named Entity Recognition](http://www.statnlp.org/research/ie/zhanming19naacl-ner.pdf) -12. [CrossWeigh: Training Named Entity Tagger from Imperfect Annotations](https://arxiv.org/pdf/1909.01441.pdf) -13. [HIT: Nested Named Entity Recognition via Head-Tail Pair and Token Interaction](https://www.aclweb.org/anthology/2020.emnlp-main.486.pdf) -14. [Named Entity Recognition as Dependency Parsing](https://www.aclweb.org/anthology/2020.acl-main.577/) - - - - - - diff --git a/NLPinterview/ner/NERtrick/img/20200609080328.png b/NLPinterview/ner/NERtrick/img/20200609080328.png deleted file mode 100644 index ad5bf78..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609080328.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609080811.png b/NLPinterview/ner/NERtrick/img/20200609080811.png deleted file mode 100644 index fb43fa4..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609080811.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609081004.png b/NLPinterview/ner/NERtrick/img/20200609081004.png deleted file mode 100644 index 74dbc1c..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609081004.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609081729.png b/NLPinterview/ner/NERtrick/img/20200609081729.png deleted file mode 100644 index 9a42269..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609081729.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609082337.png b/NLPinterview/ner/NERtrick/img/20200609082337.png deleted file mode 100644 index 3bb7394..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609082337.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609083307.png b/NLPinterview/ner/NERtrick/img/20200609083307.png deleted file mode 100644 index 55b00c3..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609083307.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609083617.png b/NLPinterview/ner/NERtrick/img/20200609083617.png deleted file mode 100644 index 8787add..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609083617.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609083653.png b/NLPinterview/ner/NERtrick/img/20200609083653.png deleted file mode 100644 index b5a7248..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609083653.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609085531.png b/NLPinterview/ner/NERtrick/img/20200609085531.png deleted file mode 100644 index 62b8f14..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609085531.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609091503.png b/NLPinterview/ner/NERtrick/img/20200609091503.png deleted file mode 100644 index 799c14b..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609091503.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609092456.png b/NLPinterview/ner/NERtrick/img/20200609092456.png deleted file mode 100644 index ad4d7d0..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609092456.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609092556.png b/NLPinterview/ner/NERtrick/img/20200609092556.png deleted file mode 100644 index b51adba..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609092556.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609092718.png b/NLPinterview/ner/NERtrick/img/20200609092718.png deleted file mode 100644 index 1406b33..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609092718.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609092832.png b/NLPinterview/ner/NERtrick/img/20200609092832.png deleted file mode 100644 index 007fd99..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609092832.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609093011.png b/NLPinterview/ner/NERtrick/img/20200609093011.png deleted file mode 100644 index 50dbe81..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609093011.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609123825.png b/NLPinterview/ner/NERtrick/img/20200609123825.png deleted file mode 100644 index 0778024..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609123825.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609124437.png b/NLPinterview/ner/NERtrick/img/20200609124437.png deleted file mode 100644 index 9acf228..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609124437.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609124525.png b/NLPinterview/ner/NERtrick/img/20200609124525.png deleted file mode 100644 index 4a6251f..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609124525.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609124647.png b/NLPinterview/ner/NERtrick/img/20200609124647.png deleted file mode 100644 index 9beb6d1..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609124647.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609124729.png b/NLPinterview/ner/NERtrick/img/20200609124729.png deleted file mode 100644 index 1865f1b..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609124729.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609125118.png b/NLPinterview/ner/NERtrick/img/20200609125118.png deleted file mode 100644 index 656c968..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609125118.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609125232.png b/NLPinterview/ner/NERtrick/img/20200609125232.png deleted file mode 100644 index e652114..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609125232.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609125343.png b/NLPinterview/ner/NERtrick/img/20200609125343.png deleted file mode 100644 index 705c0f6..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609125343.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609125430.png b/NLPinterview/ner/NERtrick/img/20200609125430.png deleted file mode 100644 index 195e857..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609125430.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609125552.png b/NLPinterview/ner/NERtrick/img/20200609125552.png deleted file mode 100644 index a2f6606..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609125552.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609125636.png b/NLPinterview/ner/NERtrick/img/20200609125636.png deleted file mode 100644 index 6ce3902..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609125636.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609125824.png b/NLPinterview/ner/NERtrick/img/20200609125824.png deleted file mode 100644 index 6f6133d..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609125824.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609130051.png b/NLPinterview/ner/NERtrick/img/20200609130051.png deleted file mode 100644 index 2fed941..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609130051.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609130230.png b/NLPinterview/ner/NERtrick/img/20200609130230.png deleted file mode 100644 index f73dcd4..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609130230.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609130350.png b/NLPinterview/ner/NERtrick/img/20200609130350.png deleted file mode 100644 index 89369e8..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609130350.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20200609130428.png b/NLPinterview/ner/NERtrick/img/20200609130428.png deleted file mode 100644 index 5ca39e0..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20200609130428.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20201208200430.png b/NLPinterview/ner/NERtrick/img/20201208200430.png deleted file mode 100644 index 6b03222..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20201208200430.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20201208200631.png b/NLPinterview/ner/NERtrick/img/20201208200631.png deleted file mode 100644 index 3b1cbac..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20201208200631.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20201208200933.png b/NLPinterview/ner/NERtrick/img/20201208200933.png deleted file mode 100644 index a9bff7f..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20201208200933.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20201208201135.png b/NLPinterview/ner/NERtrick/img/20201208201135.png deleted file mode 100644 index af58c64..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20201208201135.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20201208202535.png b/NLPinterview/ner/NERtrick/img/20201208202535.png deleted file mode 100644 index c56e04d..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20201208202535.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/20201208202913.png b/NLPinterview/ner/NERtrick/img/20201208202913.png deleted file mode 100644 index 63d4bc5..0000000 Binary files a/NLPinterview/ner/NERtrick/img/20201208202913.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph1.png b/NLPinterview/ner/NERtrick/img/graph1.png deleted file mode 100644 index 1f71d7f..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph1.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph2.png b/NLPinterview/ner/NERtrick/img/graph2.png deleted file mode 100644 index 69a9e66..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph2.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph3.png b/NLPinterview/ner/NERtrick/img/graph3.png deleted file mode 100644 index d9f77f2..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph3.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph4.png b/NLPinterview/ner/NERtrick/img/graph4.png deleted file mode 100644 index f774120..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph4.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph5.png b/NLPinterview/ner/NERtrick/img/graph5.png deleted file mode 100644 index 72c16b4..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph5.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph6.png b/NLPinterview/ner/NERtrick/img/graph6.png deleted file mode 100644 index dca6654..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph6.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph7.png b/NLPinterview/ner/NERtrick/img/graph7.png deleted file mode 100644 index b73e8ee..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph7.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph8.png b/NLPinterview/ner/NERtrick/img/graph8.png deleted file mode 100644 index 26126be..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph8.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/graph9.png b/NLPinterview/ner/NERtrick/img/graph9.png deleted file mode 100644 index 102bd56..0000000 Binary files a/NLPinterview/ner/NERtrick/img/graph9.png and /dev/null differ diff --git a/NLPinterview/ner/NERtrick/img/gs.png b/NLPinterview/ner/NERtrick/img/gs.png deleted file mode 100644 index e249769..0000000 Binary files a/NLPinterview/ner/NERtrick/img/gs.png and /dev/null differ diff --git "a/NLPinterview/ner/NERtrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210224224353.png" "b/NLPinterview/ner/NERtrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210224224353.png" deleted file mode 100644 index 8820261..0000000 Binary files "a/NLPinterview/ner/NERtrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210224224353.png" and /dev/null differ diff --git a/NLPinterview/ner/crf/img/HMM1.png b/NLPinterview/ner/crf/img/HMM1.png deleted file mode 100644 index 91156a0..0000000 Binary files a/NLPinterview/ner/crf/img/HMM1.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/HMM2.png b/NLPinterview/ner/crf/img/HMM2.png deleted file mode 100644 index 286b9a7..0000000 Binary files a/NLPinterview/ner/crf/img/HMM2.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/MEMM1.png b/NLPinterview/ner/crf/img/MEMM1.png deleted file mode 100644 index 64e4bd4..0000000 Binary files a/NLPinterview/ner/crf/img/MEMM1.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/MEMM2.png b/NLPinterview/ner/crf/img/MEMM2.png deleted file mode 100644 index 2148553..0000000 Binary files a/NLPinterview/ner/crf/img/MEMM2.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/MEMM3.png b/NLPinterview/ner/crf/img/MEMM3.png deleted file mode 100644 index d3bf0b9..0000000 Binary files a/NLPinterview/ner/crf/img/MEMM3.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/MEMM4.png b/NLPinterview/ner/crf/img/MEMM4.png deleted file mode 100644 index be578ce..0000000 Binary files a/NLPinterview/ner/crf/img/MEMM4.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/MEMM5.png b/NLPinterview/ner/crf/img/MEMM5.png deleted file mode 100644 index e4bfefd..0000000 Binary files a/NLPinterview/ner/crf/img/MEMM5.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/labeledBais.png b/NLPinterview/ner/crf/img/labeledBais.png deleted file mode 100644 index d0e7e8b..0000000 Binary files a/NLPinterview/ner/crf/img/labeledBais.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/labeledBais1.png b/NLPinterview/ner/crf/img/labeledBais1.png deleted file mode 100644 index ab078b9..0000000 Binary files a/NLPinterview/ner/crf/img/labeledBais1.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/labeledBais3.png b/NLPinterview/ner/crf/img/labeledBais3.png deleted file mode 100644 index 8594863..0000000 Binary files a/NLPinterview/ner/crf/img/labeledBais3.png and /dev/null differ diff --git a/NLPinterview/ner/crf/img/viterbi.png b/NLPinterview/ner/crf/img/viterbi.png deleted file mode 100644 index d36eb3d..0000000 Binary files a/NLPinterview/ner/crf/img/viterbi.png and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2211.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2211.png" deleted file mode 100644 index 33b8554..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2211.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\22110.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\22110.png" deleted file mode 100644 index 3eaadf1..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\22110.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2212.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2212.png" deleted file mode 100644 index dc368c7..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2212.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2213.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2213.png" deleted file mode 100644 index 5b24f50..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2213.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2214.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2214.png" deleted file mode 100644 index 5307817..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2214.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2215.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2215.png" deleted file mode 100644 index d674bc2..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2215.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2216.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2216.png" deleted file mode 100644 index cbc2bcc..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2216.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2217.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2217.png" deleted file mode 100644 index f6a1c43..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2217.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2218.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2218.png" deleted file mode 100644 index 5b9fb73..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2218.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2219.png" "b/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2219.png" deleted file mode 100644 index 6a34f34..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\211\215\345\220\221\345\220\216\345\220\2219.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\255\246\344\271\240\351\227\256\351\242\2301.png" "b/NLPinterview/ner/crf/img/\345\255\246\344\271\240\351\227\256\351\242\2301.png" deleted file mode 100644 index 6ca336f..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\255\246\344\271\240\351\227\256\351\242\2301.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\255\246\344\271\240\351\227\256\351\242\2302.png" "b/NLPinterview/ner/crf/img/\345\255\246\344\271\240\351\227\256\351\242\2302.png" deleted file mode 100644 index 2ccafff..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\255\246\344\271\240\351\227\256\351\242\2302.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210901095003.png" "b/NLPinterview/ner/crf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210901095003.png" deleted file mode 100644 index 1e35050..0000000 Binary files "a/NLPinterview/ner/crf/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210901095003.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\346\235\241\344\273\266\351\232\217\346\234\272\345\234\272.png" "b/NLPinterview/ner/crf/img/\346\235\241\344\273\266\351\232\217\346\234\272\345\234\272.png" deleted file mode 100644 index 01cc7b4..0000000 Binary files "a/NLPinterview/ner/crf/img/\346\235\241\344\273\266\351\232\217\346\234\272\345\234\272.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\346\246\202\347\216\207\345\233\276\346\250\241\345\236\213.png" "b/NLPinterview/ner/crf/img/\346\246\202\347\216\207\345\233\276\346\250\241\345\236\213.png" deleted file mode 100644 index a5644ca..0000000 Binary files "a/NLPinterview/ner/crf/img/\346\246\202\347\216\207\345\233\276\346\250\241\345\236\213.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2171.png" "b/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2171.png" deleted file mode 100644 index d842c23..0000000 Binary files "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2171.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2172.png" "b/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2172.png" deleted file mode 100644 index fc55786..0000000 Binary files "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2172.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2173.png" "b/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2173.png" deleted file mode 100644 index 39908e4..0000000 Binary files "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2173.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2174.png" "b/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2174.png" deleted file mode 100644 index 2f4c1e8..0000000 Binary files "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2174.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2175.png" "b/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2175.png" deleted file mode 100644 index 02bbb95..0000000 Binary files "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2175.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2176.png" "b/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2176.png" deleted file mode 100644 index 0fa3a47..0000000 Binary files "a/NLPinterview/ner/crf/img/\347\256\200\345\214\226\345\275\242\345\274\2176.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\232\220\351\251\254\345\260\224\347\247\221\345\244\253\347\256\227\346\263\225.png" "b/NLPinterview/ner/crf/img/\351\232\220\351\251\254\345\260\224\347\247\221\345\244\253\347\256\227\346\263\225.png" deleted file mode 100644 index 47a7da4..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\232\220\351\251\254\345\260\224\347\247\221\345\244\253\347\256\227\346\263\225.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2131.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\2131.png" deleted file mode 100644 index 1e3408e..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2131.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\21310.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\21310.png" deleted file mode 100644 index ad5a971..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\21310.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\21311.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\21311.png" deleted file mode 100644 index 6a7864c..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\21311.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2132.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\2132.png" deleted file mode 100644 index 43874f7..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2132.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2133.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\2133.png" deleted file mode 100644 index dba5b46..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2133.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2134.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\2134.png" deleted file mode 100644 index 9d8ba29..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2134.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2135.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\2135.png" deleted file mode 100644 index e14efae..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2135.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2136.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\2136.png" deleted file mode 100644 index 8126a59..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2136.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2138.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\2138.png" deleted file mode 100644 index 145a5e3..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2138.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2139.png" "b/NLPinterview/ner/crf/img/\351\242\204\346\265\2139.png" deleted file mode 100644 index 7ea9ff1..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\242\204\346\265\2139.png" and /dev/null differ diff --git "a/NLPinterview/ner/crf/img/\351\251\254\345\260\224\345\217\257\345\244\253\350\277\207\347\250\213.png" "b/NLPinterview/ner/crf/img/\351\251\254\345\260\224\345\217\257\345\244\253\350\277\207\347\250\213.png" deleted file mode 100644 index b3682b9..0000000 Binary files "a/NLPinterview/ner/crf/img/\351\251\254\345\260\224\345\217\257\345\244\253\350\277\207\347\250\213.png" and /dev/null differ diff --git a/NLPinterview/ner/crf/readme.md b/NLPinterview/ner/crf/readme.md deleted file mode 100644 index 9d84a57..0000000 --- a/NLPinterview/ner/crf/readme.md +++ /dev/null @@ -1,461 +0,0 @@ -# 【关于 概率图模型】 那些你不知道的事 - -> 作者:杨夕 -> -> 介绍:本项目是作者们根据个人面试和经验总结出的自然语言处理(NLP)面试准备的学习笔记与资料,该资料目前包含 自然语言处理各领域的 面试题积累。 -> -> NLP 百面百搭 地址:https://github.com/km1994/NLP-Interview-Notes -> -> **[手机版NLP百面百搭](https://mp.weixin.qq.com/s?__biz=MzAxMTU5Njg4NQ==&mid=100005719&idx=3&sn=5d8e62993e5ecd4582703684c0d12e44&chksm=1bbff26d2cc87b7bf2504a8a4cafc60919d722b6e9acbcee81a626924d80f53a49301df9bd97&scene=18#wechat_redirect)** -> -> 推荐系统 百面百搭 地址:https://github.com/km1994/RES-Interview-Notes -> -> **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** -> -> 搜索引擎 百面百搭 地址:https://github.com/km1994/search-engine-Interview-Notes 【编写ing】 -> -> NLP论文学习笔记:https://github.com/km1994/nlp_paper_study -> -> 推荐系统论文学习笔记:https://github.com/km1994/RS_paper_study -> -> GCN 论文学习笔记:https://github.com/km1994/GCN_study -> -> **推广搜 军火库**:https://github.com/km1994/recommendation_advertisement_search -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/概率图模型.png) - -## 一、基础信息 介绍篇 - -### 1.1 什么是概率图模型? - -概率图模型(Probabilistic Graphical Model, PGM),简称图模型(Graphical Model,GM),是指一种用图结构来描述**多元随机变量之间条件独立性的概率模型(注意条件独立性)**,从而给研究高维空间的概率模型带来了很大的便捷性。 - -### 1.2 什么是 随机场? - -每个位置按照某种分布随机赋予一个值 所构成 的 整体。 - -## 二、马尔可夫过程 介绍篇 - -### 2.1 什么是 马尔可夫过程? - -假设一个随机过程中,$t_n$ 时刻的状态$x_n$的条件发布,只与其前一状态$x_{n-1}$ 相关,即: - -$$ - P(x_n|x_1,x_2,...,x_{n-1}) = P(x_n|x_{n-1}) -$$ - -则将其称为 马尔可夫过程。 - -![](img/马尔可夫过程.png) - -### 2.2 马尔可夫过程 的核心思想 是什么? - -对于 马尔可夫过程 的 思想,用一句话去概括:**当前时刻状态 仅与上一时刻状态相关,与其他时刻不相关。** - -可以从 马尔可夫过程 图 去理解,由于 每个状态间 是以 有向直线连接,也就是 当前时刻状态 仅与上一时刻状态相关。 - -## 三、隐马尔科夫算法 篇 - -### 3.1 隐马尔科夫算法 介绍篇 - -#### 3.1.1 隐马尔科夫算法 是什么? - -隐马尔科夫算法是对含有未知参数(隐状态)的马尔可夫链进行建模的**生成模型**,如下图所示: - -![](img/隐马尔科夫算法.png) - -在隐马尔科夫模型中,包含隐状态 和 观察状态,隐状态 $i_i$ 对于观察者而言是不可见的,而观察状态 $o_i$ 对于观察者而言是可见的。隐状态间存在转移概率,隐状态 $i_i$到对应的观察状态 $o_i$ 间存在输出概率。 - -#### 3.1.2 隐马尔科夫算法 中 两个序列 是什么? - -![](img/HMM2.png) - -- 两序列 - - 隐藏序列:隐状态 $i_i$ 对于观察者而言是不可见的 - - 观测序列:$o_i$ 对于观察者而言是可见的 - -#### 3.1.3 隐马尔科夫算法 中 三个矩阵 是什么? - -- 初始状态矩阵:每个标签的概率矩阵 -- 发射状态矩阵:一个字变成每个标签的概率 $B=\left[b_{i j}\right]_{N \times M}$($N$为隐藏状态集元素个数,M为观测集元素个数),其中$b_{i j}=P\left(o_{t} | i_{t}\right)$,$(o_{t}$为第i个观测节点 ,$i_t$ 为第i个隐状态节点,即所谓的观测概率(发射概率); -- 状态转移级证:标签到每个标签的概率 $A=\left[a_{i j}\right]_{N \times N}$ (N 表示隐藏状态集元素的个数),其中 $a_{i j}=P\left(i_{t+1} | i_{t}\right)$,$i_t$ 即第i个隐状态节点,即所谓的状态转移; - -#### 3.1.4 隐马尔科夫算法 中 两个假设 是什么? - -- 齐次马尔可夫性假设:即假设隐藏的马尔科夫链在任意时刻 t 的状态只依赖于其前一时刻的状态,与其他时刻的状态及观测无关,也与时刻 t 无关; - -$$ - P(x_i|x_1,x_2,...,x_{i-1}) = P(x_i|x_{i-1}) -$$ - -- 观测独立性假设:即假设任意时刻的观测只依赖于该时刻的马尔科夫链的状态,与其他观测及状态无关。 - -$$ - P(y_i|x_1,x_2,...,x_{i-1},y_1,y_2,...,y_{i-1},y_{i+1},...) = P(y_i|x_{i}) -$$ - -#### 3.1.5 隐马尔科夫算法 中 工作流程 是什么? - -1. 隐状态节点 $i_t$ 是不能直接观测到的数据节点, $o_t$ 才是能观测到的节点,并且注意箭头的指向表示了依赖生成条件关系; -2. $i_t$在$A$的指导下生成下一个隐状态节点$i_{t+1}$; -3. $i_t$在$B$的指导下生成依赖于该$i_t$的观测节点$o_{t}$; - -- 深层次理解:由于 为有向图,而且属于生成式模型,直接对联合概率分布建模 - -$$ - P(O, I)=\sum_{t=1}^{T} P\left(O_{t} | O_{t-1}\right) P\left(I_{t} | O_{t}\right) -$$ - -### 3.2 隐马尔科夫算法 模型计算过程篇 - -#### 3.2.1 隐马尔科夫算法 序列概率计算过程 是什么样的? - -1. 思想 - -如何对一条序列计算其整体的概率。即目标是计算出 $P(O | \lambda)$ ; - -给定模型 $\lambda=(A,B,π)$ 和观测序列 O=(o1,o2,...,oT) ,计算在模型 $\lambda$ 下观测序列 $O$ 出现的概率 $P(O|\lambda)$ - -1. 常用方法 - -- 直接计算法(穷举搜索) - -由于有隐藏的状态序列 I 的存在,我们是无法计算 $P(O|\lambda)$ 的。一种常见的做法是把 I 边缘掉,即 $P(O|\lambda)=\sum(P(O,I|\lambda))$ ,当然,这种计算复杂度非常高,为 $O(TN^2)$ - -- 前向算法 - -减少计算量的原因在于每一次计算直接引用前一个时刻的计算结果,避免重复计算,计算复杂度将为$O(T^2 * N)$ - -- 后向算法 - -#### 3.2.2 隐马尔科夫算法 学习训练过程 是什么样的? - -1. 思想 - - - 找出数据的分布情况,也就是模型参数的确定; - - 已知观测序列 O=(o1,o2,...,oT) ,估计模型 $\lambda=(A,B,π)$ 参数,使得在该模型下观测序列概率 $P(O|\lambda)$ 最大,即用极大似然估计的方法估计参数 - -2. 常用方法 - -- 极大似然估计:该算法在训练数据是**会 将 观测状态序列 $O$ 和 隐状态序列 $I$**; -- Baum-Welch(前向后向):该算法在训练数据是**只会 将 观测状态序列 $O$**; - -#### 3.2.3 隐马尔科夫算法 序列标注(解码)过程 是什么样的? - -1. 思想 - -也就是“预测过程”,通常称为解码过程。在给定的观测序列下找出一条隐状态序列,条件是这个隐状态序列的概率是最大的那个 - -$$Q_{\max }=\operatorname{argmax}_{\text {allQ}} \frac{P(Q, O)}{P(O)}$$ - -2. 常用方法:Viterbi算法 - -Viterbi计算有向无环图的一条最大路径: - -![](img/viterbi.png) - -### 3.3 HMM模型三个基本问题的联系? - -三个基本问题 存在 渐进关系。首先,要学会用前向算法和后向算法算观测序列出现的概率,然后用Baum-Welch算法求参数的时候,某些步骤是需要用到前向算法和后向算法的,计算得到参数后,我们就可以用来做预测了。因此可以看到,三个基本问题,它们是渐进的,对于做NLP的同学来说,应用HMM模型做解码任务应该是最终的目的。 - -### 3.4 隐马尔科夫算法 问题篇 - -因为HMM模型其实它简化了很多问题,做了某些很强的假设,如**齐次马尔可夫性假设**和**观测独立性假设**,做了假设的好处是,**简化求解的难度**,坏处是**对真实情况的建模能力变弱**了。 - -在序列标注问题中,隐状态(标注)不仅和单个观测状态相关,还和观察序列的长度、上下文等信息相关。例如词性标注问题中,一个词被标注为动词还是名词,不仅与它本身以及它前一个词的标注有关,还依赖于上下文中的其他词。 - -## 四、最大熵马尔科夫模型(MEMM)篇 - -### 4.1 最大熵马尔科夫模型(MEMM)动机篇 - -#### 4.1.1 HMM 存在 什么问题? - -HMM中,观测节点 $o_i$ 依赖隐藏状态节点 $i_i$ ,也就意味着我的观测节点只依赖当前时刻的隐藏状态。但在更多的实际场景下,**观测序列是需要很多的特征来刻画的**,比如说,我在做NER时,我的标注 $i_i$ 不仅跟当前状态 $o_i$ 相关,而且还跟前后标注 $o_{j}(j \neq i)$ 相关,比如字母大小写、词性等等。 - -### 4.2 最大熵马尔科夫模型(MEMM)介绍篇 - -#### 4.2.1 最大熵马尔科夫模型(MEMM) 是什么样? - -![](img/MEMM4.png) - -通过 “定义特征” 的方式,学习条件概率: - -$$P(I | O)=\prod_{t=1}^{n} P\left(i_{i} | i_{i-1}, o_{i}\right), i=1, \cdots, n$$ - -并且, $P(i|i',o)$ 这个概率通过最大熵分类器建模(取名MEMM的原因): - -![](img/MEMM1.png) - -重点来了,这是ME的内容,也是理解MEMM的关键: $Z(o,i')$ 这部分是归一化; $f_{a}(o, i)$ 是特征函数,具体点,这个函数是需要去定义的; $\lambda$ 是特征函数的权重,这是个未知参数,需要从训练阶段学习而得。 - -定义特征函数: - -![](img/MEMM2.png) - -其中,特征函数 $f_{a}(o, i)$ 的 个数 可以任意制定,(a=1,...,n) - -所以总体上,MEMM的建模公式这样: - -![](img/MEMM3.png) - -请务必注意,理解判别模型和定义特征两部分含义,这已经涉及到CRF的雏形了。 - -#### 4.2.2 最大熵马尔科夫模型(MEMM) 如何解决 HMM 问题? - -在前面介绍 HMM 时,HMM 提出了 **观测节点 $o_i$ 依赖隐藏状态节点 $i_i$** 假设,该假设不合理的,针对该问题, MEMM 提出 **观测节点 $i_i$ 依赖隐藏状态节点 $o_i$ 以及上一时刻的隐藏节点$i_{i-1}$** 假设。(HMM 和 MEMM 箭头); - -### 4.3 最大熵马尔科夫模型(MEMM)问题篇 - -1. 问题简述 - - -MEMM 容易出现标注偏置问题,MEMM倾向于选择拥有更少转移的状态。 - -2. 问题介绍 - - -![](img/labeledBais.png) - -用Viterbi算法解码MEMM,状态1倾向于转换到状态2,同时状态2倾向于保留在状态2。 解码过程细节(需要会viterbi算法这个前提): - -![](img/labeledBais1.png) - -但是得到的最优的状态转换路径是1->1->1->1,为什么呢?因为状态2可以转换的状态比状态1要多,从而使转移概率降低,即MEMM倾向于选择拥有更少转移的状态。 - -3. 问题原因分析 - -对于MEMM公式: - -![](img/labeledBais1.png) - -求和的作用在概率中是归一化,但是这里归一化放在了指数内部,管这叫local归一化。 来了,viterbi求解过程,是用dp的状态转移公式(MEMM的没展开,请参考CRF下面的公式),因为是局部归一化,所以MEMM的viterbi的转移公式的第二部分出现了问题,导致dp无法正确的递归到全局的最优。 - -![](img/MEMM5.png) - -## 五、条件随机场(CRF)篇 - -### 5.1 CRF 动机篇 - -#### 5.1.1 HMM 和 MEMM 存在什么问题? - -- HMM :状态的转移过程中当前状态只与前一状态相关问题 -- MEMM :标注偏置 问题 - - 解决方法:统计全局概率,在做归一化时考虑数据在全局的分布 - -### 5.2 CRF 介绍篇 - -#### 5.2.1 什么是 CRF? - -设 X 与 Y 是随机变量,**P(Y|X) 是给定条件 X 的条件下 Y 的条件概率分布**,若**随机变量 Y 构成一个由无向图G=(V,E)表示的马尔科夫随机场**。则称 **条件概率分布P(X|Y)为条件随机场**。 - -![条件随机场图片](img/条件随机场.png) - -#### 5.2.2 CRF 的 主要思想是什么? - -统计全局概率,在做归一化时,考虑了数据在全局的分布。 - -#### 5.2.3 CRF 的定义是什么? - -给定 $X=(x_1,x_2,...,x_n)$ ,$Y=(y_1,y_2,...,y_n)$ 均为线性链表示的随机变量序列,若在给随机变量序列 X 的条件下,随机变量序列 Y 的条件概率分布 $P(Y|X)$ 构成条件随机场,即满足马尔可夫性: - -$$ - P(y_i|x_1,x_2,...,x_{i-1},y_1,y_2,...,y_{i-1},y_{i+1}) - = P(y_i|x,y_{i-1},y_{i+1}) -$$ - -则称为 P(Y|X) 为线性链条件随机场。 - -通过去除了隐马尔科夫算法中的观测状态相互独立假设,使算法在计算当前隐状态$x_i$时,会考虑整个观测序列,从而获得更高的表达能力,并进行全局归一化解决标注偏置问题。 - -![条件随机场图片](img/条件随机场.png) - -#### 5.2.4 CRF 的 三个基本问题 是什么? - -##### 5.2.4.1 概率计算问题 - -- 定义:给定 观测序列 x 和 状态序列 y, 计算概率 P(y|x) -- 公式定义: - -$$ -p\left(y | x\right)=\frac{1}{Z\left(x\right)} \prod_{i=1}^{n} \exp \left(\sum_{i, k} \lambda_{k} t_{k}\left(y_{i-1}, y_{i}, x, i\right)+\sum_{i, l} \mu_{l} s_{l}\left(y_{i}, x, i\right)\right) -$$ - -其中: - -> $Z(x)$ 为归一化因子,是在全局范围进行归一化,枚举了整个隐状态序列$x_{1…n}$的全部可能,从而解决了局部归一化带来的标注偏置问题。 - -$$ -Z(x)=\sum_{y} \exp \left(\sum_{i, k} \lambda_{x} t_{k}\left(y_{i-1}, y_{i}, x, i\right)+\sum_{i, l} \mu_{l} s_{l}\left(y_{i}, x, i\right)\right) -$$ - -> $t_k$ 为定义在边上的特征函数,转移特征,依赖于前一个和当前位置 - -> $s_1$ 为定义在节点上的特征函数,状态特征,依赖于当前位置。 - -- 解决方法:前向计算、后向计算 - -##### 5.2.4.2 学习计算问题 - -- 定义:给定训练数据集估计条件随机场模型参数的问题,即条件随机场的学习问题。 -- 公式定义:利用极大似然的方法来定义我们的目标函数 - -![](IMG/微信截图_20210901095003.png) - -- 解决方法:随机梯度法、牛顿法、拟牛顿法、迭代尺度法这些优化方法来求解得到参数 -- 目标:解耦 模型定义,目标函数,优化方法 - -##### 5.2.4.3 预测问题 - -- 定义:给定条件随机场 P(Y|X) 和输入序列(观测序列) x ,求条件概率最大的输出序列(标记序列) y* ,即对观测序列进行标注。 -- 方法:维特比算法 - -#### 5.2.5 CRF 的 流程是什么? - -1. 选择特征模板:抽取文本中的字符组合 or 具有其他特殊意义的标记组成特征,作为当前 token 在模板中的表示; -2. 构建特征函数:通过一组函数来完成由特征向数值转换的过程,使特征与权重对应; -3. 进行前向计算:每个状态特征函数(0-1二值特征函数)对应 L 维向量,最终状态特征函数权值的和即为该位置上激活了的状态特征函数对应的 L 维向量之和; -4. 解码:利用 维特比算法 解码 出 最优标注序列 - -### 5.3 CRF 优缺点篇 - -#### 5.3.1 CRF 的 优点在哪里? - -- 为每个位置进行标注过程中可利用丰富的内部及上下文特征信息; -- CRF模型在结合多种特征方面的存在优势; -- 避免了标记偏置问题; -- CRF的性能更好,对特征的融合能力更强; - -#### 5.3.2 CRF 的 缺点在哪里? - -- 训练模型的时间比ME更长,且获得的模型非常大。在一般的PC机上可能无法执行; -- 特征的选择和优化是影响结果的关键因素。特征选择问题的好与坏,直接决定了系统性能的高低 - -### 5.4 CRF 复现? - -```python - import numpy as np - class CRF(object): - '''实现条件随机场预测问题的维特比算法 - ''' - def __init__(self, V, VW, E, EW): - ''' - :param V:是定义在节点上的特征函数,称为状态特征 - :param VW:是V对应的权值 - :param E:是定义在边上的特征函数,称为转移特征 - :param EW:是E对应的权值 - ''' - self.V = V #点分布表 - self.VW = VW #点权值表 - self.E = E #边分布表 - self.EW = EW #边权值表 - self.D = [] #Delta表,最大非规范化概率的局部状态路径概率 - self.P = [] #Psi表,当前状态和最优前导状态的索引表s - self.BP = [] #BestPath,最优路径 - return - - def Viterbi(self): - ''' - 条件随机场预测问题的维特比算法,此算法一定要结合CRF参数化形式对应的状态路径图来理解,更容易理解. - ''' - self.D = np.full(shape=(np.shape(self.V)), fill_value=.0) - self.P = np.full(shape=(np.shape(self.V)), fill_value=.0) - for i in range(np.shape(self.V)[0]): - #初始化 - if 0 == i: - self.D[i] = np.multiply(self.V[i], self.VW[i]) - self.P[i] = np.array([0, 0]) - print('self.V[%d]='%i, self.V[i], 'self.VW[%d]='%i, self.VW[i], 'self.D[%d]='%i, self.D[i]) - print('self.P:', self.P) - pass - #递推求解布局最优状态路径 - else: - for y in range(np.shape(self.V)[1]): #delta[i][y=1,2...] - for l in range(np.shape(self.V)[1]): #V[i-1][l=1,2...] - delta = 0.0 - delta += self.D[i-1, l] #前导状态的最优状态路径的概率 - delta += self.E[i-1][l,y]*self.EW[i-1][l,y] #前导状态到当前状体的转移概率 - delta += self.V[i,y]*self.VW[i,y] #当前状态的概率 - print('(x%d,y=%d)-->(x%d,y=%d):%.2f + %.2f + %.2f='%(i-1, l, i, y, \ - self.D[i-1, l], \ - self.E[i-1][l,y]*self.EW[i-1][l,y], \ - self.V[i,y]*self.VW[i,y]), delta) - if 0 == l or delta > self.D[i, y]: - self.D[i, y] = delta - self.P[i, y] = l - print('self.D[x%d,y=%d]=%.2f\n'%(i, y, self.D[i,y])) - print('self.Delta:\n', self.D) - print('self.Psi:\n', self.P) - - #返回,得到所有的最优前导状态 - N = np.shape(self.V)[0] - self.BP = np.full(shape=(N,), fill_value=0.0) - t_range = -1 * np.array(sorted(-1*np.arange(N))) - for t in t_range: - if N-1 == t:#得到最优状态 - self.BP[t] = np.argmax(self.D[-1]) - else: #得到最优前导状态 - self.BP[t] = self.P[t+1, int(self.BP[t+1])] - - #最优状态路径表现在存储的是状态的下标,我们执行存储值+1转换成示例中的状态值 - #也可以不用转换,只要你能理解,self.BP中存储的0是状态1就可以~~~~ - self.BP += 1 - - print('最优状态路径为:', self.BP) - return self.BP - - def CRF_manual(): - S = np.array([[1,1], #X1:S(Y1=1), S(Y1=2) - [1,1], #X2:S(Y2=1), S(Y2=2) - [1,1]]) #X3:S(Y3=1), S(Y3=1) - SW = np.array([[1.0, 0.5], #X1:SW(Y1=1), SW(Y1=2) - [0.8, 0.5], #X2:SW(Y2=1), SW(Y2=2) - [0.8, 0.5]])#X3:SW(Y3=1), SW(Y3=1) - E = np.array([[[1, 1], #Edge:Y1=1--->(Y2=1, Y2=2) - [1, 0]], #Edge:Y1=2--->(Y2=1, Y2=2) - [[0, 1], #Edge:Y2=1--->(Y3=1, Y3=2) - [1, 1]]])#Edge:Y2=2--->(Y3=1, Y3=2) - EW= np.array([[[0.6, 1], #EdgeW:Y1=1--->(Y2=1, Y2=2) - [1, 0.0]], #EdgeW:Y1=2--->(Y2=1, Y2=2) - [[0.0, 1], #EdgeW:Y2=1--->(Y3=1, Y3=2) - [1, 0.2]]])#EdgeW:Y2=2--->(Y3=1, Y3=2) - - crf = CRF(S, SW, E, EW) - ret = crf.Viterbi() - print('最优状态路径为:', ret) - return - - if __name__=='__main__': - CRF_manual() -``` - -## 六、对比篇 - -### 6.1 CRF模型 和 HMM 和 MEMM 模型 区别? - -- 相同点:MEMM、HMM、CRF 都常用于 序列标注任务; -- 不同点: - - 与 HMM 的区别:CRF 能够解决 HMMM 因其输出独立性假设,导致其不能考虑上下文的特征,限制了特征的选择的问题; - - 与 MEMM 的区别:MEMM 虽然能够解决 HMM 的问题,但是 MEMM 由于在每一节点都要进行归一化,所以只能找到局部的最优值,同时也带来了标记偏见的问题,即凡是训练语料中未出现的情况全都忽略掉。 - - CRF :很好的解决了这一问题,他并不在每一个节点进行归一化,而是所有特征进行全局归一化,因此可以求得全局的最优值。 - -### 6.2 为什么 CRF模型 会比 HMM 被普遍使用? - -- 原因 1:CRF模型 属于 判别式模型,在 序列标注 任务上,效果优于 生成式模型; -- 原因 2:HMM 提出 齐次马尔可夫性假设 和 观测独立性假设,这两个假设过强,而 CRF 只需要满足 局部马尔可夫性就好,通过降低假设的方式,提升模型效果; - - -## 参考资料 - -1. [条件随机场CRF](https://zhuanlan.zhihu.com/p/29989121) -2. [朴素贝叶斯(NB)、逻辑回归(LR)、隐马尔科夫模型(HMM)、条件随机场(CRF)](https://blog.csdn.net/u013010889/article/details/81148809) -3. [学习笔记:条件随机场(CRF)](https://hit-computer.github.io/2017/06/10/CRF/) -4. [如何轻松愉快地理解条件随机场(CRF)?](https://www.jianshu.com/p/55755fc649b1) -5. [概率图模型体系:HMM、MEMM、CRF](https://zhuanlan.zhihu.com/p/33397147) -6. [CRF 视频介绍](https://b23.tv/BV19t411R7QU/p1) -7. [概率图模型(二):捋一捋HMM模型](https://zhuanlan.zhihu.com/p/398880896) -8. [概率图模型(三):理一理CRF模型](https://zhuanlan.zhihu.com/p/402132237) - diff --git a/NLPinterview/ner/readme.md b/NLPinterview/ner/readme.md deleted file mode 100644 index f01fe86..0000000 --- a/NLPinterview/ner/readme.md +++ /dev/null @@ -1,21 +0,0 @@ -# 【关于 NER】 那些你不知道的事 - -> 作者:杨夕 -> -> 论文链接:https://arxiv.org/pdf/1810.04805.pdf -> -> 本文链接:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - - - - - - -## 参考资料 - -1. [A Survey on Deep Learning for Named Entity Recognition](https://arxiv.org/pdf/1812.09449.pdf) -2. [NLP集大成之命名实体识别](https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=2247520685&idx=3&sn=aef975d579c190594a202abb8159513b&chksm=ebb7a979dcc0206f7b0aa745ddbae777fb84cd57481ed5697a12fccddca5be5d9f0010bc07ef&mpshare=1&scene=22&srcid=1231rtG7X3DlS9ZGf2XZJBSu&sharer_sharetime=1609377507173&sharer_shareid=da84f0d2d31380d783922b9e26cacfe2#rd) \ No newline at end of file diff --git a/NLPinterview/readme.md b/NLPinterview/readme.md deleted file mode 100644 index e69de29..0000000 diff --git a/NLPinterview/summary/img/0r2697858p414n3p86686ps76r003n60.jpg b/NLPinterview/summary/img/0r2697858p414n3p86686ps76r003n60.jpg deleted file mode 100644 index 52bcf9e..0000000 Binary files a/NLPinterview/summary/img/0r2697858p414n3p86686ps76r003n60.jpg and /dev/null differ diff --git a/NLPinterview/summary/img/20171202135226461.png b/NLPinterview/summary/img/20171202135226461.png deleted file mode 100644 index 376064b..0000000 Binary files a/NLPinterview/summary/img/20171202135226461.png and /dev/null differ diff --git a/NLPinterview/summary/img/20171202143111808.png b/NLPinterview/summary/img/20171202143111808.png deleted file mode 100644 index 7a8a2f5..0000000 Binary files a/NLPinterview/summary/img/20171202143111808.png and /dev/null differ diff --git a/NLPinterview/summary/img/F.png b/NLPinterview/summary/img/F.png deleted file mode 100644 index b80e83b..0000000 Binary files a/NLPinterview/summary/img/F.png and /dev/null differ diff --git a/NLPinterview/summary/img/P.png b/NLPinterview/summary/img/P.png deleted file mode 100644 index b991b27..0000000 Binary files a/NLPinterview/summary/img/P.png and /dev/null differ diff --git a/NLPinterview/summary/img/R.png b/NLPinterview/summary/img/R.png deleted file mode 100644 index 5cde2fe..0000000 Binary files a/NLPinterview/summary/img/R.png and /dev/null differ diff --git a/NLPinterview/summary/img/qs2oo7qqrp8s4o368q2o65o221690qr7.jpg b/NLPinterview/summary/img/qs2oo7qqrp8s4o368q2o65o221690qr7.jpg deleted file mode 100644 index 62b0008..0000000 Binary files a/NLPinterview/summary/img/qs2oo7qqrp8s4o368q2o65o221690qr7.jpg and /dev/null differ diff --git "a/NLPinterview/summary/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\346\221\230\350\246\201\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" "b/NLPinterview/summary/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\346\221\230\350\246\201\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" deleted file mode 100644 index 7f1da85..0000000 Binary files "a/NLPinterview/summary/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\346\221\230\350\246\201\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" and /dev/null differ diff --git "a/NLPinterview/summary/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\346\221\230\350\246\201\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" "b/NLPinterview/summary/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\346\221\230\350\246\201\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" deleted file mode 100644 index ec28c61..0000000 Binary files "a/NLPinterview/summary/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\346\221\230\350\246\201\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.xmind" and /dev/null differ diff --git a/NLPinterview/summary/readme.md b/NLPinterview/summary/readme.md deleted file mode 100644 index ec3a3c7..0000000 --- a/NLPinterview/summary/readme.md +++ /dev/null @@ -1,281 +0,0 @@ -# 【关于 文本摘要】 那些你不知道的事 - -> 作者:李玲 - -![](img/【关于文本摘要】那些你不知道的事.png) - -## 一、动机篇 - -### 1.1 什么是文本摘要? - -文本(自动)摘要是利用计算机自动地将文本(或文档集合)转换成简短摘要的一种信息压缩技术。 - -一般而言,生成的简短摘要必须满足信息量充分、能够覆盖原文的主要内容、冗余度低和可读性高等要求。 - -### 1.2 文本摘要技术有哪些类型? - -从不同的角度文本自动摘要技术可以被划分为不同的类型。 - -按照摘要的功能划分: - -- 指示型摘要(indicative)——仅提供输入文档(或文档集)的关键主题,旨在帮助用户决定是否需要阅读原文,如标题生成。 -- 报道型摘要(informative)——提供输入文档(或文档集)的主要信息,使用户无需阅读原文。 -- 评论型摘要(critical)——不仅提供输入文档(或文档集)的主要信息,而且需要给出关于原文的关键评论。 - -根据输入文本的数量划分: - -- 单文档摘要(single-document summarization) -- 多文档摘要(multi-document summarization) - -根据输入和输出语言的不同划分: - -- 单语言摘要(monolingual summarization)——输入和输出都是同一种语言 -- 跨语言摘要(cross-lingual summarization)——输入和输出是不同的语言 -- 多语言摘要(multi-lingual summarization)——输入是多种语言,输出是其中的某一种语言 - -根据应用形式的划分: - -- 通用型摘要(generic summarization)——总结原文作者的主要观点 -- 面向用户查询的摘要(query-based summarization)——提供与用户兴趣密切相关的内容 - -根据文摘与原文的关系(即文摘获取方法)划分: - -- 抽取式摘要(extraction-based summarization)——摘录原文的重要句子形成摘要 -- 压缩式摘要(compression-based summarization)——抽取并简化原文的重要句子形成摘要 -- 理解式摘要(abstraction-based summarization)——改写或重新组织原文内容形成摘要 - -按照输出文摘的长度划分: - -- 标题式摘要 -- 短摘要 -- 长摘要 - -其中抽取式、压缩式、理解式(或称生成式)是常用的分类方法。 - -## 二、抽取式摘要篇 - -### 2.1 抽取式摘要是怎么做的? - -抽取式摘要,即直接从原文中抽取一些句子组成摘要。抽取式的方法基于一个假设,一篇文档的核心思想可以用文档中的某一句或几句话来概括。那么摘要的任务就变成了找到文档中最重要的几句话。 - -这种摘要方式本质上是个排序问题,给每个句子打分排序,再考虑冗余性、新颖性、多样性等做一些后处理(比如MMR),抽取高分的句子作为摘要。这个过程涉及到句子重要性评估算法和基于约束的摘要生成算法。 - -#### 2.1.1 句子重要性评估算法有哪些? - -常见的句子重要性评估算法有: - -- 基于统计:统计词频、位置、长度、是否包含标题词等信息,计算句子的得分,再选出得分高的句子作为摘要。例如Lead3、TextTeaser等。特点:简单易用,但对词句的使用大多仅停留在表面信息。 -- 基于图模型:将句子看作结点,句子之间的相似度看作边,构建图,然后用PageRank算法迭代得到每个句子的得分。例如TextRank, LexRank等 -- 基于潜在语义:使用主题模型,挖掘语句的隐藏信息。例如LDA,HMM等 -- 基于线路规划:将摘要问题转为线路规划,求全局最优解。 -- 基于机器学习:句子分类(摘要句、非摘要句,可视为序列标注问题)、聚类(每个类选择一个距离质心最近的句子)等 - -#### 2.1.2 基于约束的摘要生成方法有哪些? - -排序之后的结果只考虑了相关性并没有考虑新颖性,非常有可能出现排名靠前的几句话表达的都是相似的意思。所以需要引入一个惩罚因子,将新颖性考虑进去。对所有的句子重新打分,如下公式: - -$a * score(i) + (1-a) * similarity(i, i-1), i = 2,3,….N$ - - -序号i表示排序后的顺序,从第二句开始,排第一的句子不需要重新计算,后面的句子必须被和前一句的相似度进行惩罚。 - -这个算法就是MMR(Maximum Margin Relevance,最大边缘相关)(注意:这里的公式不是原始的MMR公式,而是针对文本摘要任务做了修改) 。它是常见的最小化冗余度算法,主要是面向查询相关的文档自动摘要任务提出。基本思想是在未选句子集合中选择一个与输入查询最相关并且与已选句子最不相似的句子,迭代该过程,直至句子数目或单词数目达到上限。 - -#### 2.1.3 TextTeaser算法是怎么抽取摘要的? - -简单来说,根据词频、位置、长度、是否包含标题词等统计指标,计算句子的得分,再选出得分高的句子作为摘要。 - -具体来说,TextTeaser的统计指标有: - -1)句子长度,长度为某个长度(比如20)的句子为最理想的长度,依照距离这个长度的远近来打分。 - -2)句子位置,根据句子在全文中的位置,给出分数。(比如每段的第一句是核心句的比例大概是70%)。也可以考虑用句子在段落中的位置来评估。 - -3)文章标题与文章内容的关系,句子是否包含标题词,根据句子中包含标题词的多少来打分。 - -4)句子关键词打分,文本进行预处理之后,按照词频统计出排名前10的关键词,通过比较句子中包含关键词的情况,以及关键词分布的情况来打分。 - - 综合上述步骤的打分做累加,然后倒排得到每个句子的重要性得分,此时要考虑到摘要的可读性,通俗的做法是按照句子在文章中出现的顺序输出得分最高的n句话作为摘要。 - -Python代码开源版本:https://github.com/DataTeaser/textteaser - -#### 2.1.4 TextRank算法是怎么抽取摘要的? - -简单来说,将句子看作结点,句子之间的相似度看作边,构建图,然后用类似PageRank的算法迭代得到每个句子的得分,最终将得分高的句子输出得到摘要。 - -详细的步骤如下 - -1. 预处理:将输入的文本或文本集的内容分割成句子得$T=[S_{1},S_{2},…..,S_{m}]$, 构建图$G=(V,E)$, 其中V为句子集,对句子进行分词、去除停止词,得$S_{i}=[t_{i,1},t_{i,2},…….,t_{i,n}]$,其中$t_{i,j} \in S_{j}$是保留后的候选关键词。 - -2. 句子相似度计算:构建图G中的边集E,基于句子间的内容覆盖率,给定两个句子$S_{i},S_{j}$,采用如下公式进行计算: - $$ - Similarity(S_{i},S_{j})=\frac{|{w_{k}|w_{k}\in S_{i} \cap w_{k}\in S_{j}}|}{log(|S_{i}|)+log(|S_{j}|)} - $$ - - > $S_i$:第i个句子。$w_k$:第k个单词。$|S_i|$:句子i中单词数。 - > 简单来说就是,两个句子单词的交集除以两个句子的长度。也可以用其他计算相似度的方法。 - - 若两个句子之间的相似度大于给定的阈值,就认为这两个句子语义相关并将它们连接起来,即边的权值$w_{i,j}=Similarity(S_{i},S_{j})$ - -3. 句子权重计算:迭代传播权重计算各句子的得分,计算公式如下: - $$ - WS(V_{i})=(1-d)+d* \sum_{V_{j} \in In(V_{i})}\frac{w_{ji}}{\sum_{V_{k} \in Out(V_{j})}w_{jk}}WS(V_{j}) - $$ - - > $V_i$为结点。 - > - > d为阻尼系数,表示从图中某一结点指向其他任意结点的概率。介于0-1之间,通常设为0.85。 - > - > $w_{ji}$为$V_i$到$V_j$的边的权重。 - > - > $In(V_i)$为指向$V_i$的点的集合,$Out(V_j)$为$V_j$指出的点的集合。 - > - > 上面公式与PageRank中的公式相比而言,PageRank中的出度权重每条边的权重都是相等的,在上述公式中使用相似度来进行加权赋值,这样每条出度的边的权重就不一定一样了,而在PageRanK中是等权的。 - -4. 抽取文摘句:将上述得到的句子得分进行倒序排序,抽取重要度最高的T个句子作为候选文摘句。 - -5. 形成文摘:根据字数或句子数要求,从候选文摘句中抽取句子组成文摘 - - -### 2.2 抽取式摘要的可读性问题是什么? - -自动文摘质量一直被诟病的问题就是可读性。因为各个句子都是从不同的段落中选择出来的,如果只是生硬地连起来生成摘要的话,很难保证句子之间的衔接和连贯。保证可读性是一件很难的事情。 - -有一个取巧的方法,就是将排序之后的句子按照原文中的顺序输出,可以在一定程度下保证一点点连贯性。 - -## 三、压缩式摘要篇 - -### 3.1 压缩式摘要是怎么做的? - -压缩式自动摘要对句子进行压缩,保留重要的句子成分,删除无关紧要的成分,使得最终的摘要在固定长度的范围内包含更多的句子,以提升摘要的覆盖度。 - -核心模块:**句子压缩** - -- 可视为树的精简问题。 -- 可视为01序列标注问题。 - -句子压缩任务可以被定义为一个删词问题:删除句子中不重要的词,形成该句子的一个压缩式表达。常见的方法: - -- 基于句法分析树(无监督):先得到句子对应的短语结构树,再根据规则删除不重要的子树(比如删除介词短语子树、时间短语子树等) -- 基于噪声信道模型(有监督):给定原始长句子s,寻找最佳压缩句子t,使得后验概率P(t|s)最大(利用贝叶斯准则得到后验概率)。 -- 基于决策(有监督):从结构树改写的角度对句子进行处理,通过一系列“移进-规约-删除”动作实现 - -压缩式自动摘要方法结合了句子选择和句子压缩两个算法过程,结合方法可以是:(1)先选择后压缩;(2)先压缩后选择;(3)两个过程同时进行。 - -例如整数线性规划ILP,句子中的每个词都对应一个二值变量表示该词是否保留,每个词都有一个打分(比如tf-idf),目标函数就是最大化句子中的词的打分。最简单的限制比如说至少保留一个词,再比如说当形容词被保留时其修饰的词也要保留(根据parse tree)。 - -## 四、生成式摘要篇 - -### 4.1 生成式摘要是怎么做的? - -生成式摘要,它试图通过理解原文的意思来生成摘要,其实就是模仿人类写摘要的方式。 - -生成式摘要常见的方法有 - -- 基于信息融合的生成式摘要:例如基于句法分析树的信息融合技术,利用句法结构树定义概念和事实,计算概念和事实的重要性,度量概念和事实的兼容性,最终组合概念和事实形成摘要句子。 -- 基于编码-解码的生成式摘要:在语义向量空间内对文本进行编码,然后通过解码网络逐词生成摘要。 - -由于深度学习的发展,基于编码-解码的生成式摘要更常见。 - -### 4.2 生成式摘要存在哪些问题? - -使用seq2seq框架做摘要通常会遇到以下几个问题: - -1. OOV问题。源文档语料中的词的数量级通常会很大,但是经常使用的词数量则相对比较固定。因此通常会根据词的频率过滤掉一些词做成词表。这样的做法会导致生成摘要时会遇到UNK的词。 -2. 摘要的可读性。通常使用贪心算法或者beamsearch方法来做decoding。这些方法生成的句子有时候会存在不通顺的问题。 -3. 摘要的重复性。这个问题出现的频次很高。与2的原因类似,由于一些decoding的方法的自身缺陷,导致模型会在某一段连续timesteps生成重复的词。 -4. 长文本摘要生成难度大。对于机器翻译来说,NLG的输入和输出的语素长度大致都在一个量级上,因此NLG在其之上的效果较好。但是对摘要来说,源文本的长度与目标文本的长度通常相差很大,此时就需要encoder很好的将文档的信息总结归纳并传递给decoder,decoder需要完全理解并生成句子。可想而知,这是一个很难的事情。 -5. 模型的训练目标与最终的评测指标不太一致。这里牵扯到两个问题,一个是seq2seq的训练模式中,通常会使用teacher-forcing的方式,即在decoder上,将真实target的输入和模型在前一时刻生成的词一起送到下一个时刻的神经元中计算。但是在inference时,是不会有真实target的,因此存在一个gap;另一个问题就是通常模型训练的目标函数都是交叉熵损失函数。但是摘要的评测却不是以交叉熵来判断的,目前一些榜单通常以ROUGE、BLEU等方式评测,虽然这些评测也不是很完美,但是与交叉熵的评测角度均在较大差异。 - -### 4.3 Pointer-generator network解决了什么问题? - -指针生成网络从两方面针对seq-to-seq模型在生成式文本摘要中的应用做了改进。 - -第一,使用指针生成器网络可以通过指向从源文本中复制单词(解决OOV的问题),这有助于准确复制信息,同时保留generater的生成能力。PGN可以看作是抽取式和生成式摘要之间的平衡。 - -通过一个门来选择产生的单词是来自于词汇表,还是来自输入序列复制。 - -第二,使用coverage跟踪摘要的内容,不断更新注意力,从而阻止文本不断重复(解决重复性问题)。利用注意力分布区追踪目前应该被覆盖的单词,当网络再次注意同一部分的时候予以惩罚。 - -## 五、摘要质量评估方法 - -### 5.1 摘要质量的评估方法有哪些类型? - -1.人工评价方法 - -请专家对系统的自动摘要结果打分,但是专家之间差异性较大。解决方法之一是金字塔方法(pyramid method)。m位专家撰写参考摘要,然后人工分析每个参考摘要,提取摘要内容单元(summary content unit, SCU)(表示摘要中子句级的重要语义单元)的集合,并为参考摘要中每个SCU赋值,被w个参考摘要提及则赋值为w。然后计算所有SCU在系统摘要中的得分之和,系统摘要得分与理想摘要得分的比值作为质量评价得分。 - -2.自动评价方法 - -(1)内部(intrinsic)评价:分析摘要的质量评价 -- 形式度量(form metrics):侧重于语法、摘要的连贯性和组织结构 -- 内容度量(content metrics):侧重内容和信息,比如ROUGE(Recall-Oriented Understudy for Gisting Evaluation)。 - -(2)外部(extrinsic)评价:依据摘要结果对其他应用任务的效果评价 - -### 5.2 什么是ROUGE? - -ROUGE(Recall-Oriented Understudy for Gisting Evaluation)是评估自动文本摘要和机器翻译的一组指标。它通过将待审摘要或翻译与一组参考摘要或翻译进行比较计算,得出相应的分数,以衡量自动生成的摘要或翻译与参考摘要之间的相似度。 - -它的基本思想是将待审摘要和参考摘要的n元组共现统计量作为评价依据。然后通过一系列标准进行打分。 - -ROUGE包括:ROUGH-N、ROUGH-L、ROUGH-W、ROUGH-S和ROUGH-SU几个类型。通俗地讲就是通过一些定量化的指标来描述待审摘要和参考文摘之间的相似性,维度考虑比较多,在一定程度上可以很好地评价产生的摘要。 - -### 5.3 几种ROUGE指标之间的区别是什么? - -ROUGE是将待审摘要和参考摘要的n元组共现统计量作为评价依据。 - -ROUGE-N = 每个n-gram在参考摘要和系统摘要中同现的最大次数之和 / 参考摘要中每个n-gram出现的次数之和 - -分母也可以是待审摘要中每个n-gram出现的次数之和,不过用参考摘要的话更看重召回,用待审摘要则更看重精确率。 - -![Rouge-N](img/20171202135226461.png) - -ROUGE-L计算最长公共子序列的匹配率,L是LCS(longest common subsequence)的首字母。如果两个句子包含的最长公共子序列越长,说明两个句子越相似。 - -![](img/P.png) - -![](img/R.png) - -![](img/F.png) - -其中LCS(X,Y)是X和Y的最长公共子序列的长度,m,n分别表示参考摘要和待审摘要的长度(一般就是所含词的个数)。R和P分别表示召回率和精确率,F即是Rouge-L。一般只考虑召回率,所以参数$\beta$会被设置为一个很大的数。 - -Rouge-W是Rouge-L的改进版,使用了加权最长公共子序列(Weighted Longest Common Subsequence),连续最长公共子序列会拥有更大的权重。 - -ROUGE-S使用了skip-grams。在参考摘要和待审摘要进行匹配时,不要求gram之间必须是连续的,可以跳过几个单词。比如skip-bigram,在产生grams时,允许最多跳过两个词。比如“cat in the hat”的 skip-bigrams 就是 “cat in, cat the, cat hat, in the, in hat, the hat”. - -### 5.4 BLEU和ROUGE有什么不同? - -BLEU 是 2002 年提出的,而 ROUGE 是 2003 年提出的。 - -**BLEU的计算主要基于精确率,ROUGE的计算主要基于召回率。** - -ROUGE 用作机器翻译评价指标的初衷是这样的:在 SMT(统计机器翻译)时代,机器翻译效果稀烂,需要同时评价翻译的准确度和流畅度;等到 NMT (神经网络机器翻译)出来以后,神经网络脑补能力极强,翻译出的结果都是通顺的,但是有时候容易瞎翻译。 - -ROUGE的出现很大程度上是为了解决NMT的漏翻问题(低召回率)。所以 ROUGE 只适合评价 NMT,而不适用于 SMT,因为它不管候选译文流不流畅。 - -BLEU的计算公式: - -![img](img/0r2697858p414n3p86686ps76r003n60.jpg) - -- BLEU 需要计算译文 1-gram,2-gram,...,N-gram 的精确率,一般 N 设置为 4 即可,公式中的 $P_n$指 n-gram 的精确率。 -- $W_n$ 指 n-gram 的权重,一般设为均匀权重,即对于任意 n 都有 $W_n = 1/N$。 -- BP 是惩罚因子,如果译文的长度小于最短的参考译文,则 BP 小于 1。 -- BLEU 的 1-gram 精确率表示译文忠于原文的程度,而其他 n-gram 表示翻译的流畅程度。 - -BLEU一般使用改进的方法计算精确率。给定参考译文S1, S2, ..., Sm,待审译文C,可以计算C里面n元组的Precision: - -![img](img/qs2oo7qqrp8s4o368q2o65o221690qr7.jpg) - - - -## 参考资料 - -1. 《文本数据挖掘》宗成庆等人著 -2. [textteaser算法学习](https://blog.csdn.net/Silience_Probe/article/details/80700018) -3. [TextRank算法](https://www.dazhuanlan.com/2019/12/25/5e02ae0a227c3/) -4. [自动文摘评测方法:Rouge-1、Rouge-2、Rouge-L、Rouge-S](https://blog.csdn.net/qq_25222361/article/details/78694617) -5. [文本生成13:万字长文梳理文本生成评价指标](https://zhuanlan.zhihu.com/p/144182853) -6. [文本自动摘要任务的“不完全”心得总结](https://zhuanlan.zhihu.com/p/83596443 ) -7. [真正理解指针生成网络 Pointer-Generator Networks](https://zhuanlan.zhihu.com/p/106171651) diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815181809.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815181809.png deleted file mode 100644 index aba85cb..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815181809.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815201034.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815201034.png deleted file mode 100644 index 88ddf61..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815201034.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815201234.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815201234.png deleted file mode 100644 index f1d2bc4..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815201234.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202133.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202133.png deleted file mode 100644 index 7ac2118..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202133.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202203.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202203.png deleted file mode 100644 index efd7f1e..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202203.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202329.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202329.png deleted file mode 100644 index f1532f7..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202329.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202419.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202419.png deleted file mode 100644 index fbb2ed1..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202419.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202453.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202453.png deleted file mode 100644 index 7bb77c4..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202453.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202530.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202530.png deleted file mode 100644 index a11bf65..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202530.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202636.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202636.png deleted file mode 100644 index 49f0755..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202636.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202714.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202714.png deleted file mode 100644 index 56df67c..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202714.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202733.png b/NLPinterview/textclassifier/ClassifierTrick/img/20200815202733.png deleted file mode 100644 index 5395327..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/20200815202733.png and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/courgette.log b/NLPinterview/textclassifier/ClassifierTrick/img/courgette.log deleted file mode 100644 index e69de29..0000000 diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/v2-2d117c09ea324562fafb147be76a2c08_720w.jpg b/NLPinterview/textclassifier/ClassifierTrick/img/v2-2d117c09ea324562fafb147be76a2c08_720w.jpg deleted file mode 100644 index 46803ad..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/v2-2d117c09ea324562fafb147be76a2c08_720w.jpg and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/v2-a45895308759b24db4937d83729ec883_720w.jpg b/NLPinterview/textclassifier/ClassifierTrick/img/v2-a45895308759b24db4937d83729ec883_720w.jpg deleted file mode 100644 index 3b6ebd9..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/v2-a45895308759b24db4937d83729ec883_720w.jpg and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/img/v2-d439cd6d2c188ef17bd0b3c437c7849b_720w.jpg b/NLPinterview/textclassifier/ClassifierTrick/img/v2-d439cd6d2c188ef17bd0b3c437c7849b_720w.jpg deleted file mode 100644 index f80f67e..0000000 Binary files a/NLPinterview/textclassifier/ClassifierTrick/img/v2-d439cd6d2c188ef17bd0b3c437c7849b_720w.jpg and /dev/null differ diff --git "a/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206154622.png" "b/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206154622.png" deleted file mode 100644 index 8ed106c..0000000 Binary files "a/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206154622.png" and /dev/null differ diff --git "a/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210193835.png" "b/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210193835.png" deleted file mode 100644 index 6695ed0..0000000 Binary files "a/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210193835.png" and /dev/null differ diff --git "a/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220126084917.png" "b/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220126084917.png" deleted file mode 100644 index 3cee589..0000000 Binary files "a/NLPinterview/textclassifier/ClassifierTrick/img/\345\276\256\344\277\241\346\210\252\345\233\276_20220126084917.png" and /dev/null differ diff --git a/NLPinterview/textclassifier/ClassifierTrick/readme.md b/NLPinterview/textclassifier/ClassifierTrick/readme.md deleted file mode 100644 index 43625d2..0000000 --- a/NLPinterview/textclassifier/ClassifierTrick/readme.md +++ /dev/null @@ -1,521 +0,0 @@ -# 【关于 文本分类 trick】那些你不知道的事 - -> 作者:杨夕 -> -> 项目地址:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 - -![](img/微信截图_20220126084917.png) - -## 一、数据预处理问题 - -### 1.1 vocab 构建问题 - -- 数据预处理时vocab的选取(前N个高频词或者过滤掉出现次数小于3的词等等); - -### 1.2 模型输入问题 - -1. 结合要使用的模型,这里可以把数据处理成char、word或者都用等; -2. 词的词性特征、词的情感特征 加入训练数据会收到比较好的效果; -3. 至于PAD的话,取均值或者一个稍微比较大的数【75%位数】,但是别取最大值那种应该都还好; -4. 可以只保留某几个词性的词语,比如只要形容词和名词 -5. 词干化 加入训练数据会收到比较好的效果; -6. 主题向量 加入训练数据会收到比较好的效果; -7. 位置向量 加入训练数据会收到比较好的效果;【位置向量则是将当前词汇的位置进行embedding,然后和词向量进行拼接】 - -### 1.3 噪声数据处理问题 - -- 噪声类型:【数据集D(X, Y)】 - - 噪声类型一:X内部噪声很大(比如文本为口语化表述或由广大互联网用户生成); - - 噪声类型二:Y的噪声很大(一些样本被明显的错误标注,一些样本人也很难定义是属于哪一类,甚至具备类别二义性) - - 噪声类型三:固定规则数据(eg:XX报告、XX编辑等高频字段;明显影响模型判断的词语【标点符号影响】)。 -- 噪声类型一的解决方法: - - 方法一:字向量 and 词向量 角度: - - s1:使用 char-level(中文中就是字的粒度) 作为模型输入; - - s2:将 train from scratch(不使用预训练词向量)去跟word-level的对比一下; - - s3:择优使用; - - 方法二:使用特殊超参的fasttext去训练一份词向量: - - 介绍:一般来说fasttext在英文中的char ngram的窗口大小一般取值3~6,但是在处理中文时,如果我们的目的是为了去除输入中的噪声,那么我们可以把这个窗口限制为1~2,这种小窗口有利于模型去捕获错别字(想象一下,我们打一个错误词的时候,一般都是将其中的一个字达成同音异形的另一个字),比如word2vec学出来的“似乎”的最近词可能是“好像”,然而小ngram窗口fasttext学出来的“似乎”最近词则很有可能是“是乎”等内部包含错别字的词,这样就一下子让不太过分的错别字构成的词们又重新回到了一起,甚至可以一定程度上对抗分词器产生的噪声(把一个词切分成多个字)。 - - 方法三:文本更正: - - 中文如果是正常的文本多数都不涉及,但是很多恶意的文本,里面会有大量非法字符,比如在正常的词语中间插入特殊符号,倒序,全半角等。还有一些奇怪的字符,就可能需要你自己维护一个转换表了; - - 如果是英文的,就涉及拼写检查,可以用python包pyenchant实现,比如 mothjer -> mother。 - - 方法四:文本泛化: - - 表情符号、数字、人名、地址、网址、命名实体等,用关键字替代就行。这个视具体的任务,可能还得往下细化。比如数字也分很多种,普通数字,手机号码,座机号码,热线号码、银行卡号,QQ号,微信号,金钱,距离等等,并且很多任务中,这些还可以单独作为一维特征。还得考虑中文数字阿拉伯数字等。 - - 中文将字转换成拼音,许多恶意文本中会用同音字替代。 - - 如果是英文的,那可能还得做词干提取、形态还原等,比如fucking,fucked -> fuck - -- 噪声类型二的解决方法: - - 方法一:交叉验证 - - s1:训练模型; - - s2:让模型去 筛选出 训练集和验证集 中 标签不一致的样本; - - s3:bad case 分析; - - 错误来源: - - 存在规律性:编写规则过滤; - - 无规律,但是存在标注错误的可能:删除; - - 其他,... - -- 噪声类型三的解决方法: - - 方法一:对语料的片段或词进行统计,把很高频的无用元素去掉; - - -### 1.4 中文任务分词问题 - -- 可以只保留长度大于1的词 - - 结果:对结果精度没什么影响,但是可以有效降低特征维度。 -- 确保分词器与词向量表中的token粒度match - - 原因:如果 分词分对了,但是词找 词向量中找不到,也就是变成 OOV,那么分词性能再好也没用 - - 策略: - - 使用 word2vec、glove、fasttext 对应的分词器; - - 将 词典 作为 结巴分词器词典 加入 结巴分词中; - - 大小写问题:建议将 大小写 全部转化为 大写或小写,防止由于大小写问题造成的 OOV; - -### 1.5 停用词处理问题 - -1. 采用常用词 - 1. 来源:网上 - 2. 调整:需要根据 具体任务 增加或删除 一些停用词 -2. 词筛选。出现次数太多和太少的都可以考虑去掉 - 1. 太多的一般是这类文本的常用词; - 2. 太少的往往是拼写错误、命名实体、特殊词组等 -3. 根据tfidf来筛选 - -### 1.6 初期标注数据不足问题? - -作为算法工程师,在项目初期,标注数据不足问题,永远是一个老大难问题,那么如何解决该问题呢? - -- **Fewshot Learning** 把分类问题转化为匹配或者相似度学习的问题,减小分类空间学习的难度; -- **迁移学习** 由于 Bert 模型在小数据集上效果相对于 其他 深度学习模型出色,除了慢一点,似乎没有其他毛病了。上两个阶段大概只需要几千条数据就可以跑起来了。 - -## 二、模型篇 - -### 2.1 模型选择 - -1. 神经网络结构的话,可以多试几种比如fastText、TextCNN、RCNN、char-CNN/RNN、HAN等。 - 1. fasttext:显然问题; - 2. TextCNN:简单问题(eg:存在 ngram 可帮助模型正确决策);【句子太长,可以考虑空洞卷积,扩大感受野】 - 1. Filter尺寸:这个参数决定了抽取n-gram特征的长度,这个参数主要跟数据有关,平均长度在50以内的话用10以下就可以了,否则可以长一些。在调参时可以先用一个尺寸grid search,找到一个最优尺寸,然后尝试最优尺寸和附近尺寸的组合; - 2. Filter个数:这个参数会影响最终特征的维度,维度太大的话训练速度就会变慢。这里在100-600之间调参即可; - 3. CNN的激活函数:可以尝试Identity、ReLU、Tanh - 4. 正则化:指对CNN参数的正则化,可以使用dropout或L2,但能起的作用很小,可以试下小的dropout率(<0.5),L2限制大一点 - 5. Pooling方法:根据情况选择mean、max、k-max pooling,大部分时候max表现就很好,因为分类任务对细粒度语义的要求不高,只抓住最大特征就好了 - 6. Embedding表:中文可以选择char或word级别的输入,也可以两种都用,会提升些效果。如果训练数据充足(10w+),也可以从头训练 - 7. 蒸馏BERT的logits,利用领域内无监督数据 - 8. 加深全连接:原论文只使用了一层全连接,而加到3、4层左右效果 - 3. TextRNN:复杂问题(eg:人工检查,无法找到规律); - 4. Transformer:数据量大,显存资源足够; - 5. Bert:超复杂问题; - 1. 多试试不同的预训练模型,比如RoBERT、WWM、ALBERT - 2. 除了 [CLS] 外还可以用 avg、max 池化做句表示,甚至可以把不同层组合起来 - 3. 在领域数据上增量预训练 - 4. 集成蒸馏,训多个大模型集成起来后蒸馏到一个上 - 5. 先用多任务训,再迁移到自己的任务 - -### 2.2 词向量选择 - -- 词袋模型:适用于传统的机器学习分类算法; -- 词向量:对于 传统的机器学习分类算法和深度学习方法均适用 - - 传统的机器学习分类算法: - - 问题:如何将词向量转句向量; - - 策略:平均、加权平均【tfidf作为权重】 - - 深度学习方法: - - 问题:如何确定 取 多少个词问题 - - 策略:对正负样本分别统计,综合考虑长度与样本覆盖,用 均值 + n*方差的方式确定,尽量能完全覆盖80%以上的负样本,剩下的再截断,长度对rnn一类的算法性能影响比较大,对cnn类要好很多,所以,cnn类的可以稍微长点关系也不大 - -### 2.3 Word Embedding 处理未登录词问题 - -这里借用了 [包包大人的回答](https://www.zhihu.com/question/308543084/answer/604729983) - -基本思路就是尽可能找还原语义的pre-trained embedding。 - -步骤是: - -1. 原始词有没有 -2. 全小写有没有 -3. 全大写有没有 -4. 首字母大写有没有 -5. 三种次干化有没有 -6. 长得最像的几种编辑方法有没有依次瀑布式查找。 - -当然,最好的方式,是使用subword level的pre-trained language model,生成此OOV的contextual的特征。 - -```python -from nltk.stem import PorterStemmer -ps = PorterStemmer() -from nltk.stem.lancaster import LancasterStemmer -lc = LancasterStemmer() -from nltk.stem import SnowballStemmer -sb = SnowballStemmer("english")3 -spell_model = gensim.models.KeyedVectors.load_word2vec_format('../input/embeddings/wiki-news-300d-1M/wiki-news-300d-1M.vec') -words = spell_model.index2word -w_rank = {} -for i,word in enumerate(words): - w_rank[word] = i -WORDS = w_rank -# Use fast text as vocabulary -def words(text): return re.findall(r'\w+', text.lower()) -def P(word): - "Probability of `word`." - # use inverse of rank as proxy - # returns 0 if the word isn't in the dictionary - return - WORDS.get(word, 0) -def correction(word): - "Most probable spelling correction for word." - return max(candidates(word), key=P) -def candidates(word): - "Generate possible spelling corrections for word." - return (known([word]) or known(edits1(word)) or [word]) -def known(words): - "The subset of `words` that appear in the dictionary of WORDS." - return set(w for w in words if w in WORDS) -def edits1(word): - "All edits that are one edit away from `word`." - letters = 'abcdefghijklmnopqrstuvwxyz' - splits = [(word[:i], word[i:]) for i in range(len(word) + 1)] - deletes = [L + R[1:] for L, R in splits if R] - transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R)>1] - replaces = [L + c + R[1:] for L, R in splits if R for c in letters] - inserts = [L + c + R for L, R in splits for c in letters] - return set(deletes + transposes + replaces + inserts) -def edits2(word): - "All edits that are two edits away from `word`." - return (e2 for e1 in edits1(word) for e2 in edits1(e1)) -def singlify(word): - return "".join([letter for i,letter in enumerate(word) if i == 0 or letter != word[i-1]]) - -def load_glove(word_dict, lemma_dict): - EMBEDDING_FILE = '../input/embeddings/glove.840B.300d/glove.840B.300d.txt' - def get_coefs(word,*arr): return word, np.asarray(arr, dtype='float32') - embeddings_index = dict(get_coefs(*o.split(" ")) for o in open(EMBEDDING_FILE)) - embed_size = 300 - nb_words = len(word_dict)+1 - embedding_matrix = np.zeros((nb_words, embed_size), dtype=np.float32) - unknown_vector = np.zeros((embed_size,), dtype=np.float32) - 1. - print(unknown_vector[:5]) - for key in tqdm(word_dict): - word = key - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - word = key.lower() - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - word = key.upper() - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - word = key.capitalize() - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - word = ps.stem(key) - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - word = lc.stem(key) - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - word = sb.stem(key) - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - word = lemma_dict[key] - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - if len(key) > 1: - word = correction(key) - embedding_vector = embeddings_index.get(word) - if embedding_vector is not None: - embedding_matrix[word_dict[key]] = embedding_vector - continue - embedding_matrix[word_dict[key]] = unknown_vector - return embedding_matrix, nb_words -``` - -### 2.3 字 or 词向量 预训练 - -- 字向量:预训练时扩展窗口 -- 词向量的选择,可以使用预训练好的词向量如谷歌、facebook开源出来的,当训练集比较大的时候也可以进行微调或者随机初始化与训练同时进行。训练集较小时就别微调了 - -## 三、参数篇 - -### 3.1 正则化 - -- BN 和 dropout(<0.5),以及他们的相对位置和顺序:存在一定收益,需要结合语料分析 -- dropout 添加位置:word embed 层后、pooling 后、FC层后 - -### 3.2 学习率 - -- 学习率设置:默认学习率 (通常 1e-3) ; -- 衰减:在多轮 epoch 之后将 lr * 0.1; -- 其他策略: - - 以默认学习率 (通常 1e-3) 训练模型,得到一个在验证集上表现最好的模型。 - - 加载上一步最优模型,学习率降到 1e-4,继续训练模型,保留在验证集上表现最好的模型; - - 加载上一步最优模型,去掉正则化策略(dropout 等),学习率调为 1e-5,然后训练得到最终的最优模型。 - -## 四、任务篇 - -### 4.1 二分类问题 - -- 输出层的选择:sigmoid or softmax - - softmax:有时可能有一定的提升 - -### 4.2 多标签分类 - -- 问题:如果一个样本同时拥有多个标签,甚至标签同时还构成了DAG(有向无环图) -- 方法:用binary-cross-entropy训出个baseline来(即把每个类别变成一个二分类问题,这样N个类别的多标签分类问题就变成了N个二分类问题) -- 工具:tf.nn.sigmoid_cross_entropy_with_logits - -### 4.3 长文本问题 - -- 方法一:粗暴截断: - - 只取句首+句尾:截取信息量比较大的头部和尾部,然后进行拼接; - - 随机截取:如果固定截断信息损失较大,可以在DataLoader中每次以不同的随机概率进行截断,这种截断可以让模型看到更多形态的case; - - 句首+tfidf筛几个词出来:截取句首,对于句中和句尾,通过关键字提前方法提取关键词,拼接到句子后面; - - 截断&滑窗+预测平均:通过随机截断或者固定滑窗将一个样本切割成多个样本,在预测时对多个样本的结果进行平均; -- 方法二:模型角度,常用一些模型优化,eg:XLNet、Reformer、Longformer - -### 4.4 鲁棒性问题 - -- 粗暴的数据增强,加停用词加标点、删词、同义词替换等,如果效果下降就把增强后的训练数据洗一下。 -- 对抗学习、对比学习这样的高阶技巧来提升; - -## 五、标签体系构建 - -### 5.1 标签体系构建 - -1. **长尾标签**:某些分类标签下的样本天然就很少,可以把这一类标签设置「其他」,然后在下一层级单独对这些长尾标签进一步处理。 -2. **易混淆标签**:一些标签下的样本表现形式不易区分,首先需要思考这类标签是否可以直接合并;如果不可以,可以先将这类标签进行统一,然后在下一层级进行规则处理。 -3. **多标签**:一些场景下的标签设置可能达到几百个,可以设置多层级的标签体系进行处理。例如,**先构建标签大类、再构建标签小类**;也可以**设置多个二分类,适用于标签分类相对独立,并且经常需要新增修改的场景,能做到相互独立、便于维护**。 -4. **未知标签**:业务冷启动时,如果尚不清楚设置哪些标签合适,可以尝试通过文本聚类方式初步划分标签,再辅以专家介入共同设定,这也是一个循环迭代的过程。 - -### 5.2 标签体系合理性评估 - -1. 标签体系合理性评估: - 1. 采样一部分数据标注,分析标签体系是否合理 -2. 训练集构建: - 1. 初始训练集构建: - 1. 观察 每个标签下数据特点,常用词典+规则进行预标准,并结合人工 check; - 2. 结合【主动学习+迁移学习+自训练+数据增强】减低标注成本: - 1. **主动学习旨在挖掘高价值样本**:即通过构建较少的样本就可以满足指标要求。根据初始构建的数据集,可以train一个base model,然后挑选一些 **不确定性程度高(熵最大)+代表性高(非离群点)的样本进行人工标注**; - 2. **迁移学习降低对数据的依赖**:迁移学习中预训练语言模型的成功,可以使其在较少的标注样本上finetune就可达到目标指标; - 3. **扩充标注规模,数据增强最为关键**:在标注规模较小的少样本场景下,可以通过文本增强方式扩充数据集,撬动数据杠杆; - 4. **自训练**: - 1. 利用 初始标注集微调预训练模型 Bert; - 2. 然后利用微调后的Bert模型去回标 未标注数据集; - 3. 选取 置信度高 的 样本 作为训练集; -3. 评测集构建: - 1. 贴合真实数据分布的线上评估集,反映线上效果; - 2. 用规则去重后均匀采样的随机评估集,反映模型的真实能力; - -## 六、策略构建 - -### 6.1 算法策略构建 - -1. 规则挖掘【规则兜底】:对于一些 高频case 和 hard case 优先考虑规则或词典解决,避免由于模型的更新迭代,而导致模型对于 这些 case 处理不够健壮; - 1. 常用的规则方法:重要case缓存、模式挖掘、关键词+规则设置等 -2. 模型泛化:模型化方法适合处理无法命中规则的case,具备泛化性。还有另一种处理逻辑是:如果case命中了规则,但模型对于规则预测的结果给出了很低的置信度(也就是模型认为另一种类别的置信度更高),这时我们可以选择相信模型,以模型输出为准。 - -### 6.2 特征挖掘策略 - -1. **离散数据挖掘** - 1. **构建关键词的高维稀疏特征**:类似结构化数据挖掘(如CTR中的wide&deep),比如根据关键词列表对文本内容进行挖掘,构建高维稀疏特征并喂入xDeepFM [3] 中进行处理,最后与文本向量一同拼接。 - 2. **其他业务特征**:如疾病大类划分、就诊科室等业务特征。 -2. **文本特征挖掘** - 1. **关键词&实体词与文本拼接**:将从文本序列提取的关键词或实体词拼接在文本序列后,再进行分类。如在BERT中:[CLS][原始文本][SEP][关键词1][SEP][实体词1]... - 2. **关键词embedding化**:将关键词划分为不同的类别属性,进行embedding化,不同于离散数据挖掘,这里的embedding不应稀疏。 - 3. **领域化向量挖掘**:除了在领域语料上继续预训练词向量外,还可以有监督地构建词向量:例如对于21分类问题,先根据弱监督方法训练21个基于SVM的二分类器,然后提取每个词汇在21个SVM中的权重,即可为每个词汇可以构建21维的词向量。 -3. **标签特征融入** - 1. **标签embedding 化**:设置label embedding,然后通过注意力机制与词向量进行交互,提取全局向量分类。 - 2. **标签信息补充**:可以将类别标签与原始文本一同拼接,然后进行2分类,如在BERT中:[CLS][原始文本][SEP][类别标签]。此外,也可以通过强化学习动态地补充标签信息,具体可参考文献 [4] 。 - -### 6.3 数据不均衡问题 - -- 不均衡问题类别: - - 数据量不均衡; - - 数据多样性不均衡; -- 解决不平衡问题的通常思路: - - **重采样(re-sampling)**; - - **重加权(re-weighting)**; - - **数据增强**; - - 梯度放缩; - - 伪标签; - -#### 6.3.1 重采样(re-sampling) - -- 目标:使所有标签对应的样本数量均衡 -- 公式介绍: - -![](img/20200815201034.png) -> C 为数据集的类别数量,$n_i$为类别 i 的样本总数, $p_j$ 为从 j 类别中采样一个样本的概率 - -![](img/20200815201234.png) -> 表示所有类别都采样相同数量的样本。 - -- 方法: - - 欠采样&过采样&SMOTE - - 欠采样:抛弃大量case,可能导致偏差加大; - - 过采样:可能会导致过拟合; - - SMOTE:一种近邻插值,降低过拟合风险,但不能直接应用于NLP任务的离散空间插值。 - - 数据增强:文本增强技术更适合于替代上述过采样和SMOTE。 - -#### 6.3.2 重加权(re-weighting) - -重加权就是改变分类loss。相较于重采样,重加权loss更加灵活和方便。其常用方法有: - -- loss类别加权:通常根据类别数量进行加权,加权系数与类别数量成反比。 - -![](img/20200815202133.png) - -- Focal Loss:上述loss类别加权主要关注正负样本数量的不平衡,并没有关注难易不平衡。Focal Loss主要关注难易样本的不平衡问题,可根据对高置信度(p)样本进行降权: - -![](img/20200815202203.png) - -- GHM Loss:GHM(gradient harmonizing mechanism) 是一种梯度调和机制。Focal Loss虽然强调对hard example的学习,但不是所有的hard example都值得关注,有的hard example很可能是离群点,过分关注不是错上加错了吗?GHM定义了梯度模长g: - -![](img/20200815202329.png) - -如下图所示(图片来自知乎[5]),梯度模长g接近于0的样本数量最多,随着梯度模长的增长,样本数量迅速减少,但是在梯度模长接近于1时,样本数量也挺多。 - -![](img/20200815202419.png) - -因此,GHM的出发点是:既不要关注那些容易学的样本,也不要关注那些离群点特别难分的样本。为此,作者定义了梯度密度 - -![](img/20200815202453.png) - -其物理含义是:单位梯度模长g部分的样本个数。最终GHM Loss为: - -![](img/20200815202530.png) - -- Dice Loss: - - 主要为了解决训练和测试时F1指标不一致的问题,提出一个基于Dice Loss的自适应损失——DSC,对F1指标更加健壮: - -![](img/20200815202636.png) - - - 与Focal Loss类似,训练时推动模型更加关注困难的样本,使用作为 (1-p) 每个样本的权重。改进之后的DSC为: - -![](img/20200815202714.png) - -- 对logit调整权重:实际上是将类别概率 p(y) 引入loss中,并对logit调整权重,本质上是一种通过[互信息思想来缓解类别不平衡问题](https://link.zhihu.com/?target=https%3A//kexue.fm/archives/7615): - -![](img/20200815202733.png) - -#### 6.3.3 数据增强 - -- 数据增强: - - “增删改”:句子中“增删改”一些词; - - 回译:将文本翻译成其他语言再翻译回来; - - 近义词:用 近义词 替换 部分词 - - 扩充 - - 截取 - -### 6.4 预训练模型融合角度 - -- 一般不需要直接进行finetune。当然也可先单独对BERT、XLNET、ALBERT进行finetune,然后再一起进行特征集成。 -- 分词器可以采取最佳预训练模型的tokenizer,也可同时使用不同预训练模型的tokenizer。 -- 不要忽视简单词向量的作用。类似字词向量、bi-gram向量的补充对于底层模型的丰富性很关键。 -- 配置上层模型时,应注意学习率的调整。将集成的底层特征喂入biLSTM或CNN中,也可以拼接biLSTM和CNN共同作为上层模型。训练时,可以先将底层预训练模型freeze,只调整上层模型的学习率(较大),最后再全局调整学习率(较小)。 -- CLS最后一定还要再用一次。无论上层模型怎样。CLS特征要再最后直接进入全连接层。 - -### 6.5 灾难性遗忘问题 - -- 动机:学习了新的知识之后,几乎彻底遗忘掉之前习得的内容; -- 具体描述:我们搭建了一个深度神经网络来学习识别各种动物。假定我们遇到了一个非常吝啬的数据提供者,每次只提供一种动物的数据,并在学习完成识别该动物后,将数据收缴上去;然后才给下一个动物的训练数据。有意思的现象出来了,这个神经网络在学习识别小狗后,让它识别之前学习过的小猫,它竟然识别不出来。这就是灾难性遗忘,它一直是深度学习领域一个比较严重的问题。 -- 为什么会出现该问题: - - 深度学习的结构一旦确定,在训练过程中很难调整。神经网络的结构直接决定学习模型的容量。固定结构的神经网络意味着模型的容量也是有限的,在容量有限的情况下,神经网络为了学习一个新的任务,就必须擦除旧有的知识。 - - 深度学习的隐含层的神经元是全局的,单个神经元的细小变化能够同时影响整个网络的输出结果。另外,所有前馈网络的参数与输入的每个维度都相连,新数据很大可能改变网络中所有的参数。我们知道,对于本身结构就已经固定的神经网络,参数是关于知识的唯一变化量。如果变化的参数中包含与历史知识相关性很大的参数,那么最终的效果就是,新知识覆盖了旧的知识。 -- 解决方案: - -1. 直接现有数据与原有数据混合训练; -2. 将特征抽取层freeze,对新类别只更新softMax全连接层; -3. 采取知识蒸馏方式。在现有数据与原有数据混合一起训练时,对原有类别进行蒸馏,指导新模型学习。 -4. 将分类标签统一进行label embedding,新增类别单独构建的label embedding不影响原有类别。从而将分类转为一个match和rank问题。 - -### 6.6 小模型大智慧 - -- 动机:BERT虽然强大,但在低耗时场景、少机器场景下,直接拿BERT部署分类模型通常行不通。我们是否可以采取一个轻量级的模型,比如TextCNN,去逼近BERT的效果呢? -- 思路:采用知识蒸馏技术。蒸馏的本质是函数逼近,但如果直接将BERT(Teacher模型)蒸馏到一个十分轻量的TextCNN(Student模型),指标一般会下降。 -- 方法: - - **模型蒸馏** - - **数据蒸馏** - -#### 6.6.1 模型蒸馏 - -如果业务中的无标注数据较少,我们通常采取logits近似(值近似)让TextCNN进行学习,这种方式可称之为模型蒸馏。这是一种离线蒸馏方式:即先对Teacher模型finetune,然后freeze,再让Student模型学习。为避免蒸馏后指标下降明显,我们可以采取以下方式改进: - -- 数据增强:在蒸馏的同时引入文本增强技术,具体的增强技术可参考[《NLP中的少样本困境问题探究》](https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzIwNzc2NTk0NQ%3D%3D%26mid%3D2247490516%26idx%3D1%26sn%3D16b1c520f312400ffcad5573d4330e08%26scene%3D21%23wechat_redirect)。TinyBERT就采取了增强技术,以辅助蒸馏。 -- 集成蒸馏:对不同Teacher模型(如不同的预训练模型)的logits集成,让TextCNN学习。**「集成蒸馏+数据增强」**可以有效避免指标明显下降。 -- 联合蒸馏:不同于离线蒸馏,这是一种联合训练方式。Teacher模型训练的同时,就将logits传给Student模型学习。联合蒸馏可以减轻异构化严重的Teacher和Student模型间的gap,Student模型可以慢慢从中间状态进行学习,更好地模仿Teacher行为。 - -#### 6.6.2 数据蒸馏 - -如果业务中的无标注数据规模较大,我们可以采取标签近似让TextCNN进行学习。这种方式称为数据蒸馏。其本质与伪标方法类似:让Teacher模型对无标注数据进行伪标,再让Student模型进行学习。其具体步骤为: - -1. 训练1:BERT在标注数据集A上finetune,训练一个bert_model; -2. 伪标:bert_model对大量无标注数据U进行预测(伪标),然后根据置信度打分,选择高置信度的数据B填充到标注数据A,这时候标注数据变为(A+B); -3. 训练2:基于标注数据A+B训练TextCNN,得到textcnn_model_1; -4. 训练3(optional):让第3步训练好的textcnn_model_1基于标注数据A再训练一次,形成最终模型textcnn_model_2; - -对上述两种蒸馏方式,笔者对业务中的一个21个分类任务(每类100条样本)进行了实验,相关结果如下: - -![](img/v2-d439cd6d2c188ef17bd0b3c437c7849b_720w.jpg) - -从上图可以看出,如果我们能够获取更多的无标注数据,采取数据蒸馏的方式则更为有效,可以让一个轻量级的TextCNN最大程度逼近BERT。 - -不过也许有的读者会问,为什么不直接蒸馏为一个浅层BERT呢?这当然可以,不过笔者这里推荐TextCNN的原因是:它实在太轻了,而且会更加方便引入一些业务相关的特征。 - -如果仍然想蒸馏为一个浅层BERT,我们需要首先思考自己所在的领域是否与BERT原始预训练领域的gap是否较大?如果gap较大,我们不要停止预训练,继续进行领域预训练、然后再蒸馏;或者重新预训练一个浅层BERT。此外,采取BERT上线时,也可以进行算子融合(Faster Transformer)或者混合精度等方式。 - -## 七、竞赛 trick - -### 7.1 刷分的奇技淫巧? - -一、稳定有收益的,祖传老方子(简直太少了) - -1. RNN based model 包括lstm gru等,使用双向结构 -2. embedding 后使用dropout -3. 显然问题fasttext,简单问题CNN,复杂问题RNN,终极问题bert -4. ensemble -5. 尽可能找到还原语义的pretrained embedding,实际情况是oov千奇百怪,拼写检查,基本上是100倍的努力,一点点收益,或者拆词,拆字能一定程度上缓解 - -二、有可能有负作用,跟具体的配方有关,考验炼丹水平,看运气 - -1. embedding 是否参与训练(Yoon Kim论文的结论是训练好,然而实际中基本对半)BN和dropout,以及他们的相对位置和顺序(有收益的对半分) -2. meta-feature的使用,比如词性,情感,还有各种语言学特征和元信息等等(有收益的比较少) -3. 要用CNN的话,用空洞版本,窗口搞大,基本稳定超过3.4.5的conv1D数据增强,drop,shuffle,replace,近义词,扩充,截取(CCF 360人机大战,kaggle Quora) -4. 循环学习率(这个base max step 调的好,能巨大加速收敛速度)(kaggle QIQC)char/subword level的使用(kaggle toxic)词元化,词干化(有收益的比较少) -5. 怼好分词(蚂蚁金服) -6. 不均衡下的采样,梯度放缩,focal loss(kaggle QIQC) -7. 伪标签,半监督(kaggle toxic) -8. 去停用词(基本都是负作用),标点保留还是去掉(kaggle QIQC) -9. 过拟合后冻层finetune(魔镜杯,CCF360) -10. 长短文本各适合什么模型呢,仅在一个数据集上发现,ngram+svm可以吊打深度模型,文本挺长的,结论应该不可以泛化(达观杯) -11. 多embedding concat,mean,收益不稳定,有时候能发现加速收敛(kaggle QIQC)加宽加深(知乎看山杯)boosting(知乎看山杯) -12. vocab的数量,是否统一替换或者过滤低频词(kaggle avito) -13. 网络增加冗余的激活然后concat(kaggle mecri) -14. Maxlen覆盖百分之99就可以了,不需要最大 -15. 还有一招,换种子 - -总结一下,数据量足够的情况下,强行破坏分布的行为,都有可能是无用功,比如清洗。但是小数据,或者分布有偏,就考验你能不能往正确的方向上改了。文本分类的论文,除了textCNN,fasttext,bert(顺路碾压下)。恕我直言,其他的哈哈哈哈,故事讲的一个比一个好看。就普适性(10个以上数据集的表现)来看,几乎所有的吊炸天structure可以被精调的两层lstm干掉。 - -- 参考:[在文本分类任务中,有哪些论文中很少提及却对性能有重要影响的tricks? 包包大人回答](https://www.zhihu.com/question/265357659/answer/582711744) - -## 参考资料 - -1. [【小夕精选】如何优雅而时髦的解决不均衡分类问题](https://mp.weixin.qq.com/s?__biz=MzIwNzc2NTk0NQ==&mid=2247484993&idx=1&sn=0bd32089a638e5a1b48239656febb6e0&chksm=970c2e97a07ba7818d63dddbb469486dccb369ecc11f38ffdea596452b9e5bf65772820a8ac9&token=407616831&lang=zh_CN#rd) -2. [在文本分类任务中,有哪些论文中很少提及却对性能有重要影响的trick](https://www.zhihu.com/question/265357659) -3. [xDeepFM: Combining Explicit and Implicit Feature Interactions for Recommender Systems](https://arxiv.org/pdf/1803.05170.pdf) -4. [Description Based Text Classification with Reinforcement Learning](https://arxiv.org/pdf/2002.03067.pdf) -5. [如何解决NLP分类任务的11个关键问题:类别不平衡&低耗时计算&小样本&鲁棒性&测试检验&长文本分类](https://zhuanlan.zhihu.com/p/183852900) -6. [工业界文本分类避坑指南](https://mp.weixin.qq.com/s?__biz=MzIwNDY1NTU5Mg==&mid=2247483929&idx=1&sn=fc0f49f1a2de9a9000b4a91dd2434564&chksm=973d9c9ea04a158895bf84a265795a40631c9fc42afbbeb38cbd58a06b7e4a556210a059222b&mpshare=1&scene=22&srcid=0110MkpTrylqwuaXjk4Wsgtw&sharer_sharetime=1641823257142&sharer_shareid=da84f0d2d31380d783922b9e26cacfe2#rd) \ No newline at end of file diff --git a/NLPinterview/textclassifier/TextClassification/README.md b/NLPinterview/textclassifier/TextClassification/README.md deleted file mode 100644 index f9b8ea4..0000000 --- a/NLPinterview/textclassifier/TextClassification/README.md +++ /dev/null @@ -1,600 +0,0 @@ -# 【关于 文本分类】那些你不知道的事 - -> 作者:小猪呼噜 - -![](img/【关于文本分类】那些你不知道的事.png) - -## 一、 抽象命题 - -### 1.1 分类任务有哪些类别?它们都有什么特征? - -分类任务是机器学习中最常见的监督学习任务之一。以文本分类为例,情感分类,新闻分类,主题分类、问答匹配、意图识别、推断等等领域都使用到了文本分类的相关知识或技术。 - -分类任务按照数据集的不同,可以分为二分类、多分类、多标签分类;按照数据的不平衡程度,还可以分为普通的分类问题和不平衡数据的分类问题(异常检测)等。 - -分类任务是监督学习任务,因此数据集是带标签的,而且是离散的标签。许多回归任务通过标签离散化也可以使用分类任务解决。 - -### 1.2 文本分类任务相较于其他领域的分类任务有何不同之处? - -同样是分类任务,文本分类和图像分类、语音信号分类不同点在于处理的数据不同。图像、语音信号等数据是连续的,而文本数据是离散的。 - -### 1.3 文本分类任务和文本领域的其他任务相比有何不同之处? - -可以从分类任务和回归任务的区别、分类任务和聚类任务的区别来回答。 - -### 1.4 文本分类的过程? - -![](img/2021-01-26-14-40-01.png) - -## 二、数据预处理 - -### 2.1 文本分类任务的数据预处理方法有哪些? - -分词:将句子分割成独立的语义单元组成的序列的过程 - -去停用词:识别并删除那些对分类意义不大的出现频率却很高的单词 - -词性标注:在分词后判断词性(动词、名词、形容词、副词…)来添加特征 - -### 2.2 你使用过哪些分词方法和工具? - -hanlp、jieba、哈工大LTP、清华THULAC、北大pkuseg、斯坦福分词器、KCWS分词器、NLTK分词器、snowNLP等。 - -> 关于分词工具的详细介绍,可以看【参考资料1】 - -### 2.3 中文文本分词的方法? - -基于字符串匹配的分词方法 - -基于统计语言模型的分词方法: - -基于统计机器学习的分词方法:中文分词可以建模成一个“序列标注”问题,即一个考虑上下文的字分类问题。因此可以先通过带标签的分词语料来训练一个序列标注模型,再用这个模型对无标签的语料进行分词。 - -统计序列标注模型的代表就是生成式模型的代表——隐马尔可夫模型(HMM),和判别式模型的代表——(线性链)条件随机场(CRF)。 - -### 2.4 基于字符串匹配的分词方法的原理 是什么? - -基于词典直接进行贪心匹配。直接从句子开头的第一个字开始查字典,找出字典中以该字开头的最长的单词。 - -举个例子,比如这句“小猪呼噜整天除了吃就是睡”,查字典发现“小猪呼噜”是最长的词了,于是得到 - -```text - 小猪呼噜 / 整天除了吃就是睡 -``` - -然后从下一个词的开头开始继续匹配字典,发现“整天”就是最长的词了,于是 - -``` - 小猪呼噜 / 整天 / 除了吃就是睡 -``` - -依此类推,最终得到 - -``` - 小猪呼噜 / 整天 / 除了 / 吃 / 就是 / 睡 -``` - -这种简单的算法即为前向最大匹配法(FMM) - -由于中文句子本身具有重要信息后置的特点,从后往前匹配的分词正确率往往要高于从前往后,于是就有了反向进行的“后向最大匹配法(BMM)”。当然了,无论是FMM还是BMM,都一定存在不少切分错误,因此一种考虑更周到的方法是“双向最大匹配”。 - -双向最大匹配算法是指对待切分句子分别使用FMM和RMM进行分词,然后对切分结果不重合的歧义句进行进一步的处理。通常可对两种方法得到的词汇数目进行比较,根据数目的相同与否采取相应的措施,以此来降低歧义句的分词错误率。 - -基于字符串匹配的分词算法的不足在于其无法应对歧义与单词表外的单词。 - -> 这一部分内容参考:【参考资料2】 - -### 2.5 统计语言模型如何应用于分词?N-gram最大概率分词? - -假定一个句子S可能有很多种分词方法,那么最好的一种分词方法应该保证分完词后这个句子出现的概率最大。因此,只需利用统计语言模型计算出每种分词后句子出现的概率,并找出其中概率最大的,就能找到最好的分词方法。 - -如果一个句子可以分成以下词序列: - -$$<\omega_1,\omega_2,\dots,\omega_m>$$ - -则语言模型可以计算出这个词序列存在的可能性: - -$$P(<\omega_1,\omega_2,\dots,\omega_m>)=P(\omega_1)\times P(\omega_2|\omega_2)\times \cdots \times P(\omega_m|\omega_1,\omega_2,\dots,\omega_{m-1})$$ - -从计算上来说,m一旦变大,也就是句子一旦变长,乘法后面的几项将会难以计算。因此我们使用**马尔可夫假设**:任意词$\omega_i$的出现概率只与它前面的词$\omega_{i-1}$有关。 - -![](img/2021-01-25-16-04-31.png) - -采用马尔可夫假设的语言模型为二元模型(bigram language model)。当然你也可以假设一个词出现的概率由前面N-1个词决定,对应的模型为N元模型(n-gram language model)。 - -![](img/2021-01-25-16-06-47.png) - -这里面还有一个实现上的技巧,即如果穷举所有可能的分词方法,并计算出每种可能性下句子的概率,那么计算量是相当大的。因此可以把该问题看作一个动态规划问题,并利用维特比(Viterbi)算法快速找到最佳分词。 - -需要指出的是任何方法都有它的局限性,虽然利用统计语言模型进行分词可以取得比人工更好的结果,但是也不能做到百分之百准确。因为统计语言模型受限于训练它的语料,因此得到的结果很大程度上是依照“大众的想法”,或者“多数句子的用法”,而在特定情况下可能是错的。 - -> 这一部分内容参考:【参考资料3】 - -### 2.6 基于序列标注的分词方法 是什么? - -将分词问题转换为给每个位置的字进行分类的问题,即序列标注问题。其中,类别有4个,一般用{B:begin, M:middle, E:end, S:single}这4个类别来描述一个分词样本中每个字所属的类别。它们代表的是该字在词语中的位置。其中,B代表该字是词语中的起始字,M代表是词语中的中间字,E代表是词语中的结束字,S则代表是单字成词。 - -```text - 人/b 们/e 常/s 说/s 生/b 活/e 是/s 一/s 部/s 教/b 科/m 书/e -``` - -根据序列标注结果,得到的分词序列为: - -```text - 人们 / 常 / 说 / 生活 / 是 / 一 / 部 / 教科书 -``` - -因此只需要使用数据集训练合适的机器学习模型来完成序列标注任务即可完成分词任务。 - -### 2.7 基于(Bi-)LSTM的词性标注 是什么? - -字的上下文信息对于排解切分歧义来说非常重要,能考虑的上下文越长,自然排解歧义的能力就越强。而前面的n-gram语言模型也只能做到考虑一定距离的上下文,那么有没有在理论上能考虑无限长上下文距离的分词模型呢?答案就是基于LSTM来做。当然啦,LSTM是有方向的,为了让每个位置的字分类时既能考虑全部历史信息(左边的所有的字),又能考虑全部未来信息(右边所有的字),我们可以使用双向LSTM(Bi-LSTM)来充当序列标注的骨架模型 - -LSTM完成对每个位置的上下文信息的编码后,最终通过softmax分类层完成对每个位置的分类,从而跟HMM和CRF一样完成了基于序列标注的中文分词。 - -### 2.8 词干提取和词形还原有什么区别? - -词形还原(Lemmatization),是把一个任何形式的语言词汇还原为一般形式(能表达完整语义),而词干提取(Stemming)是抽取词的词干或词根形式(不一定能够表达完整语义)。词形还原和词干提取是词形规范化的两类重要方式,都能够达到有效归并词形的目的,二者既有联系也有区别。 - -首先让我们看一下联系: - -1、目标一致。词干提取和词形还原的目标均为将词的屈折形态或派生形态简化或归并为词干(stem)或原形的基础形式,都是一种对词的不同形态的统一归并的过程。 - -2、结果部分交叉。词干提取和词形还原不是互斥关系,其结果是有部分交叉的。一部分词利用这两类方法都能达到相同的词形转换效果。如“dogs”的词干为“dog”,其原形也为“dog”。 - -3、主流实现方法类似。目前实现词干提取和词形还原的主流实现方法均是利用语言中存在的规则或利用词典映射提取词干或获得词的原形。 - -4、应用领域相似。主要应用于信息检索和文本、自然语言处理等方面,二者均是这些应用的基本步骤。 - -接下来我们看看区别: - -a、在原理上,词干提取主要是采用“缩减”的方法,将词转换为词干,如将“cats”处理为“cat”,将“effective”处理为“effect”。而词形还原主要采用“转变”的方法,将词转变为其原形,如将“drove”处理为“drive”,将“driving”处理为“drive”。 - -b、在复杂性上,词干提取方法相对简单,词形还原则需要返回词的原形,需要对词形进行分析,不仅要进行词缀的转化,还要进行词性识别,区分相同词形但原形不同的词的差别。词性标注的准确率也直接影响词形还原的准确率,因此,词形还原更为复杂。 - -c、在实现方法上,虽然词干提取和词形还原实现的主流方法类似,但二者在具体实现上各有侧重。词干提取的实现方法主要利用规则变化进行词缀的去除和缩减,从而达到词的简化效果。词形还原则相对较复杂,有复杂的形态变化,单纯依据规则无法很好地完成。其更依赖于词典,进行词形变化和原形的映射,生成词典中的有效词。 - -d、在结果上,词干提取和词形还原也有部分区别。词干提取的结果可能并不是完整的、具有意义的词,而只是词的一部分,如“revival”词干提取的结果为“reviv”,“ailiner”词干提取的结果为“airlin”。而经词形还原处理后获得的结果是具有一定意义的、完整的词,一般为词典中的有效词。 - -e、在应用领域上,同样各有侧重。虽然二者均被应用于信息检索和文本处理中,但侧重不同。词干提取更多被应用于信息检索领域,如Solr、Lucene等,用于扩展检索,粒度较粗。词形还原更主要被应用于文本挖掘、自然语言处理,用于更细粒度、更为准确的文本分析和表达。 - -> 这一部分内容参考:【参考资料4】 - -## 三、特征提取 - -### 3.1 (一个具体的)文本分类任务可以使用哪些特征? - -考察面试者特征工程的能力。自然语言处理领域可以使用的特征有字母、单词和单词的组合,甚至可能是字母出现的频率、二元字母出现的频率等等。 - -### 3.2 (对于西文文本)使用单词和使用字母作为特征相比,差异如何? - -使用字母会让模型更稳定,但这样要处理的文本也就更长,同时模型更难从文本中学习到有效的信息。 - -### 3.3 能不能简单介绍下词袋模型? - -用于机器学习的文本表示有一种最简单的方法,也是最常用的方法,就是使用词袋(bag-of-words)表示。使用这种表示方式时,我们舍弃了输入文本中的大部分结构,如章节、段落、句子和格式,**只计算语料库中每个单词在每个文本中的出现频次**。舍弃结构并仅计算单词出现次数,这会让脑海中出现将文本表示为“袋”的画面。 - -### 3.4 n-gram 篇 - -#### 3.4.1 什么是n元语法?为什么要用n-gram? - -使用词袋表示的主要缺点之一是完全舍弃了单词顺序。因此,“it’s bad, not good at all”(电影很差,一点也不好)和“it’s good, not bad at all”(电影很好,还不错)这两个字符串的词袋表示完全相同,尽管它们的含义相反。将“not”(不)放在单词前面,这只是上下文很重要的一个例子(可能是一个极端的例子)。幸运的是,使用词袋表示时有一种获取上下文的方法,就是不仅考虑单一词例的计数,而且还考虑相邻的两个或三个词例的计数。两个词例被称为二元分词(bigram),三个词例被称为三元分词(trigram),更一般的词例序列被称为 n 元分词(n-gram)。我们可以通过改变 CountVectorizer 或 TfidfVectorizer 的 ngram_range 参数来改变作为特征的词例范围。ngram_range 参数是一个元组,包含要考虑的词例序列的最小长度和最大长度。 - -#### 3.4.2 n-gram算法的局限性是什么? - -在大多数情况下,添加二元分词会有所帮助。添加更长的序列(一直到五元分词)也可能有所帮助,但这会导致特征数量的大大增加,也可能会导致过拟合,因为其中包含许多非常具体的特征。 - -原则上来说,二元分词的数量是一元分词数量的平方,三元分词的数量是一元分词数量的三次方,从而导致非常大的特征空间。 - -在实践中,更高的 n 元分词在数据中的出现次数实际上更少,原因在于(英语)语言的结构,不过这个数字仍然很大。 - -### 3.5 主题建模篇 - -#### 3.5.1 介绍一下主题建模任务? - -常用于文本数据的一种特殊技术是主题建模(topic modeling),这是描述将每个文档分配给一个或多个主题的任务(通常是无监督的)的概括性术语。 - -直观来讲,如果一篇文章有一个中心思想,那么一些特定词语会更频繁的出现。比方说,如果一篇文章是在讲狗的,那“狗”和“骨头”等词出现的频率会高些。一个主题模型试图用数学框架来体现文档的这种特点。 - -#### 3.5.2 主题建模的常用方法 - -凡是能筛选一部分词语来代表一篇文档的方法,都可以将其归类为主题建模方法。 - -主题建模方法包括tf-idf、LDA等 - -#### 3.5.3 TF-IDF算法是做什么的?简单介绍下TF-IDF算法 - -TF-IDF(Term Frequency-inverse Document Frequency)是一种针对关键词的统计分析方法,用于评估一个词对一个文件集或者一个语料库的重要程度。基本思想是如果某个字词在一篇文档中出现的频率较高,而在其他文档中出现频率较低,则认为这个字词更能够代表这篇文档。 - -在一份给定的文件里,词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率。对于在某一特定文件里的词语 $t_{i}$ 来说,它的重要性可表示为: - -![](img/tf.png) - -其中以上式子中 $n_{i,j}$ 是该词在文件 $d_{j}$ 中的出现次数,而分母则是在文件 $d_{{j}}$ 中所有字词的出现次数之和。 - -逆向文件频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到: - -![](img/idf.png) - -其中 $|D|$ 代表语料库中的文件总数; - -$|\{j:t_{{i}}\in d_{{j}}\}|$ :包含词语 $t_{{i}}$ 的文件数目(即 $n_{{i,j}}\neq 0$ 的文件数目)如果词语不在资料中,就导致分母为零,因此一般情况下使用 $1+|\{j:t_{{i}}\in d_{{j}}\}|$ - -综合词频该词的词频tf与逆文档频率idf,则: - -![](img/2021-02-10-02-39-21.png) - -#### 3.5.4 tf-idf高意味着什么? - -高权重的tf-idf意味着该词语在某一特定类别(文件)中出现频率高,且在整个类别的语料中出现频率相对较低。因此,tf-idf倾向于过滤掉常见的词语,保留重要的词语。 - -#### 3.5.5 tf-idf的不足之处 - -tf-idf算法是创建在这样一个假设之上的:对区别文档最有意义的词语应该是那些在文档中出现频率高,而在整个文档集合的其他文档中出现频率少的词语,所以如果特征空间坐标系取tf词频作为测度,就可以体现同类文本的特点。 - -另外考虑到单词区别不同类别的能力,tf-idf法认为一个单词出现的文本频数越小,它区别不同类别文本的能力就越大。因此引入了逆文本频度idf的概念,以tf和idf的乘积作为特征空间坐标系的取值测度,并用它完成对权值tf的调整,调整权值的目的在于突出重要单词,抑制次要单词。 - -但是在本质上idf是一种试图抑制噪声的加权,并且单纯地认为文本频率小的单词就越重要,文本频率大的单词就越无用,显然这并不是完全正确的。 - -idf的简单结构并不能有效地反映单词的重要程度和特征词的分布情况,使其无法很好地完成对权值调整的功能,所以tf-idf法的精度并不是很高。 - -此外,在tf-idf算法中并没有体现出单词的位置信息,对于Web文档而言,权重的计算方法应该体现出HTML的结构特征。 - -特征词在不同的标记符中对文章内容的反映程度不同,其权重的计算方法也应不同。因此应该对于处于网页不同位置的特征词分别赋予不同的系数,然后乘以特征词的词频,以提高文本表示的效果。 - -> 这一部分内容参考:【参考资料5】 - -### 3.6 文本相似度篇 - -#### 3.6.1 如何计算两段文本之间的距离? - -衡量文本之间的距离,与相似性计算是同一回事的两个方面,距离可以理解成“不相似性”。 - -如果我们比较相似度的计算对象是分词后的词汇序列、词性序列、命名实体序列等,那么常用的计算距离的方法有:Jaccard距离、Dice系数、汉明距离、编辑距离等等。 - -如果我们使用词嵌入向量作为相似度的比较对象,那么文本距离问题就简化成向量相似度计算方法了。常用的向量距离计算方法有余弦距离等。 - -#### 3.6.2 什么是jaccard距离? - -Jaccard指数又称为雅卡尔指数,是用来衡量两个有限集合之间的不相似度的度量指标。定义为两个集合交集大小与并集大小之间的比例: - -$${\displaystyle J(A,B)={{|A\cap B|} \over {|A\cup B|}}={{|A\cap B|} \over {|A|+|B|-|A\cap B|}}.}$$ - -如果A与B完全重合,则定义J(A,B) = 1。完全没有交集则J(A,B) = 0。 - -$${\displaystyle 0\leq J(A,B)\leq 1.}$$ - -雅卡尔距离(Jaccard distance)则用于量度样本集之间的不相似度,其定义为1减去雅卡尔系数,即 - -$${\displaystyle d_{J}(A,B)=1-J(A,B)={{|A\cup B|-|A\cap B|} \over |A\cup B|}.}$$ - -#### 3.6.3 Dice系数和Jaccard系数的区别? - -是一种集合相似度度量函数,通常用于计算两个样本的相似度: - -$${\displaystyle s={\frac {2|X\cap Y|}{|X|+|Y|}}}$$ - -计算方法为集合交集的 2 倍除以两个集合相加。注意与Jaccard不一样,Dice系数的分母并不是并集。 - -#### 3.6.4 同样是编辑距离,莱文斯坦距离和汉明距离的区别在哪里? - -汉明距离是编辑距离中的一个特殊情况,仅用来计算两个**等长**字符串中不一致的字符个数。 - -因此汉明距离不用考虑添加及删除,只需要对比不同即可,所以实现比较简单。莱文斯坦距离需要考虑插入和删除字符。 - -#### 3.6.5 写一下计算编辑距离(莱温斯坦距离)的编程题吧? - -编辑距离指两个字串之间,由一个转成另一个所需的最少编辑操作次数。,把这个次数叫做距离。这道题是[leetcode 72题](https://leetcode-cn.com/problems/edit-distance/),用到了动态规划。 - -下面给出我的实现: - -```python -class Solution: - def minDistance(self, word1: str, word2: str) -> int: - dp = [[0 for _ in range(len(word2)+1)] for _ in range(len(word1)+1)] - for i in range(len(word1)+1): - dp[i][0] = i - for i in range(len(word2)+1): - dp[0][i] = i - for i in range(1, len(word1)+1): - for j in range(1, len(word2)+1): - if word1[i-1] == word2[j-1]: - dp[i][j] = min(dp[i-1][j-1], 1+dp[i][j-1], 1+dp[i-1][j]) - else: - dp[i][j] = 1 + min(dp[i-1][j-1], dp[i][j-1], dp[i-1][j]) - return dp[-1][-1] -``` - -## 四、模型篇 - -### 4.1 fastText 篇 - -#### 4.1.1 fastText的分类过程? - -fastText首先把输入转化为词向量,取平均,再经过**线性分类器**得到类别。输入的词向量可以是预先训练好的,也可以随机初始化,跟着分类任务一起训练。 - -#### 4.1.2 fastText的优点? - -fastText是一个快速文本分类算法,与基于神经网络的分类算法相比有两大优点: -1、fastText在保持高精度的情况下加快了训练速度和测试速度 -2、fastText不需要预训练好的词向量,fastText会自己训练词向量 -3、fastText两个重要的优化:使用层级 Softmax提升效率、采用了char-level的n-gram作为附加特征。 - -### 4.2 TextCNN 篇 - -#### 4.2.1 TextCNN进行文本分类的过程? - -卷积神经网络的核心思想是捕捉局部特征,对于文本来说,局部特征就是由若干单词组成的滑动窗口,类似于N-gram。卷积神经网络的优势在于能够自动地对N-gram特征进行组合和筛选,获得不同抽象层次的语义信息。因此文本分类任务中可以利用CNN来提取句子中类似 n-gram 的关键信息。 - -![](img/textcnn_model.png) - -下面是详细信息 - -![](img/textcnn_model_details.png) - -第一层为输入层。将最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比为图像中的原始像素点了。 - -图中的输入层实际采用了双通道的形式,即有两个 $n\times k$ 的输入矩阵,其中一个用预训练好的词嵌入表达,并且在训练过程中不再发生变化;另外一个也由同样的方式初始化,但是会作为参数,随着网络的训练过程发生改变。 - -第二层为卷积层。然后经过有 filter_size=(2,3,4) 的一维卷积层,每个filter_size 有两个输出 channel。第三层是一个1-max pooling层,这样不同长度句子经过pooling层之后都能变成定长的表示了。 - -最后接一层全连接的 softmax 层,输出每个类别的概率。 - -每个词向量可以是预先在其他语料库中训练好的,也可以作为未知的参数由网络训练得到。 - -> 这一部分内容参考:【参考资料6】 - -#### 4.2.2 TextCNN可以调整哪些参数? - -1. 输入词向量表征:词向量表征的选取(如选word2vec还是GloVe) - -2. 卷积核大小:一个合理的值范围在1~10。若语料中的句子较长,可以考虑使用更大的卷积核。另外,可以在寻找到了最佳的单个filter的大小后,尝试在该filter的尺寸值附近寻找其他合适值来进行组合。实践证明这样的组合效果往往比单个最佳filter表现更出色 - -3. feature map 特征图个数:主要考虑的是当增加特征图个数时,训练时间也会加长,因此需要权衡好。这个参数会影响最终特征的维度,维度太大的话训练速度就会变慢。这里在100-600之间调参即可。 - -当特征图数量增加到将性能降低时,可以加强正则化效果,如将dropout率提高过0.5 - -4. 激活函数:ReLU和tanh - -5. 池化策略:1-max pooling表现最佳,复杂任务选择k-max - -6. 正则化项(dropout/L2):指对CNN参数的正则化,可以使用dropout或L2,但能起的作用很小,可以试下小的dropout率(<0.5),L2限制大一点 - -> 这一部分内容参考:【参考资料7】 - -#### 4.2.3 使用CNN作为文本分类器时,不同通道channels对应着文本的什么信息? - -图像中可以利用 (R, G, B) 作为不同channel,而文本的输入的channel通常是不同方式的embedding方式(比如 word2vec或Glove),实践中也有利用静态词向量和fine-tunning词向量作为不同channel的做法。 - -#### 4.2.4 TextCNN中卷积核的长与宽代表了什么? - -在TextCNN中,卷积核不是一个正方形,是一个宽和word embedding相同、长表示n-gram的窗口。一个卷积层会使用多个不同大小的卷积核,往往是(3, 4, 5)这种类型。每一种大小的卷积核也会使用很多个。 - -#### 4.2.5 在TextCNN中的pooling操作与一般CNN的pooling操作有何不同? - -TextCNN中用的是最大池化(1-Max pooling),但是可以多保留k个最大信息。pooling阶段保留 k 个最大的信息,保留了全局的序列信息。 - -举个例子: - -```text - “我觉得这个地方景色还不错,但是人也实在太多了 ” -``` - -虽然前半部分体现情感是正向的,全局文本表达的是偏负面的情感,利用 k-max pooling能够很好捕捉这类信息。 - -#### 4.2.6 TextCNN的局限性? - -TextCNN是很适合中短文本场景的强baseline,但不太适合长文本,因为卷积核尺寸通常不会设很大,无法捕获长距离特征。同时max-pooling也存在局限,会丢掉一些有用特征。TextCNN和传统的n-gram词袋模型本质是一样的,它的好效果很大部分来自于词向量的引入。 - -### 4.3 DPCNN 篇 - -#### 4.3.1 如何解决长文本分类任务? - -可以使用改进的CNN,如DPCNN - -可以使用RNN结构的分类器,也可以使用基于Attention机制的分类器 - -#### 4.3.2 简单介绍DPCNN模型相较于TextCNN的改进? - -TextCNN不太适合长文本分类任务,DPCNN通过叠加CNN来实现了这一点。 - -![](img/dpcnn.png) - -DPCNN的核心改进如下: - -1. 区域嵌入 -这里是将TextCNN的包含多尺寸卷积滤波器的卷积层的卷积结果称之为区域嵌入,即对一个文本区域/文本片段(比如3-gram)进行一组卷积操作后生成的embedding。 - -不同于TextCNN的二维卷积,DPCNN采用的是一维卷积。以3-gram为例,DPCNN,采用一种不保留词序的做法,即首先对3-gram中的3个词的词向量取均值得到一个大小为 $1 ∗ D$ 的向量,然后设置一组大小为 $1 ∗ D$ 的一维卷积核对该3-gram进行卷积操作。 - -2. 等长卷积 - -经过区域嵌入后,是两层卷积层,这里采用的是等长卷积,以此来提高词位embedding的表示的丰富性。 - -首先先介绍一下三种卷积的概念: - -假设输入的序列长度为 $n$,卷积核大小为 $$m,步长(stride)为 $s$,输入序列两端各填补 $p$ 个零(zero padding),那么该卷积层的输出序列为 $(n-m+2p)/s+1$。 - -1) 窄卷积:步长 $s=1$,两端不补零,即 $p=0$,卷积后输出长度为 $n-m+1$。 -2) 宽卷积:步长 $s=1$,两端补零 $p=m-1$,卷积后输出长度 $n+m-1$。 -3) 等长卷积:步长 $s=1$,两端补零 $p=(m-1)/2$,卷积后输出长度为 $n$。 - -输入输出序列的位置数一样多,即为等长卷积,该卷积的意义是:输出的词是由该位置输入的词以及其左右词的上下文信息提取得到的,也就是说,这个词包含被上下文信息修饰过的更高级别的语义。 - -3. 下采样(1/2池化) - -本文使用一个 size=3,stride=2(大小为3,步长为2)的池化层进行最大池化,在此称为1/2池化层。每经过一个1/2池化层,序列的长度就被压缩成了原来的一半。因此,经过1/2池化后,同样一个size为3的卷积核,其能够感知到的文本片段就比之前长了一倍。 - -在堆叠多层卷积池化层之后,就得到了加深的可以抽取长距离的文本依赖关系的网络。最后的池化层把每段文本聚合为一个向量。 - -4. 残差链接,参考ResNet,减缓梯度弥散问题 - -> 这一部分内容参考:【参考资料8】 - -### 4.4 TextRCNN 篇 - -#### 4.4.1 简要介绍TextRCNN相较于TextCNN的改进? - -TextRCNN实际是将RNN和CNN进行结合,先使用双向RNN获取输入文本的上语义和语法信息,接着使用最大池化自动地筛选出最重要的特征。然后接一个全连接层用于分类。 - -使用RNN处理输入序列时,是对输入序列的词按照次序进行处理,它通过隐藏层储存了之前的序列信息,能更好地获取上下文信息。然而RNN是有偏模型,后面输入的词的重要性要高于之前的词,而实际上一个文本中后面的词并不一定是最重要的词,最重要的词可能出现在文本的任何地方。而CNN则是无偏模型,通过最大池化来自动地筛选文本中重要的词,能够解决RNN有偏的问题。然而CNN是通过使用一定尺寸的窗口来提取特征(卷积操作),窗口的尺寸实际很难确定,尺寸太小则会丢失重要的信息,尺寸过大导致参数过多且难以训练。 - -![](img/textrcnn.png) - -利用前向和后向RNN得到每个词的前向和后向上下文的表示: - -![](img/textrcnn_f1.png) - -这样词的表示就变成词向量和前向后向上下文向量concat起来的形式了,即: - -![](img/textrcnn_f2.png) - -最后再接跟TextCNN相同卷积层,pooling层即可,唯一不同的是卷积层 filter_size = 1就可以了,不再需要更大 filter_size 获得更大视野,这里词的表示也可以只用双向RNN输出。 - -### 4.5 RNN+Attention 篇 - -#### 4.5.1 RNN+Attention进行文本分类任务的思路,以及为什么要加Attention / 注意力机制如何应用于文本分类领域? - -CNN和RNN用在文本分类任务中尽管效果显著,但都有一个不足的地方就是不够直观,可解释性不好,特别是在分析badcase时候感受尤其深刻。而注意力(Attention)机制是自然语言处理领域一个常用的建模长时间记忆机制,能够很直观的给出每个词对结果的贡献。 - -加入Attention之后最大的好处自然是能够直观的解释各个句子和词对分类类别的重要性。 - -![](img/attention.png) - -上图所示只是一个示例,attention层做最后的特征融合。这个加attention的套路用到CNN编码器之后代替pooling也是可以的。 - -也有学者先对每个句子用 BiGRU+Att 编码得到句向量,再对句向量用 BiGRU+Att 得到doc级别的表示进行分类。具体模型示意图如下: - -![](img/attention2.png) - -该模型就是HAN的示意图。HAN是attention机制用于文本分类的典型工作,通过将(1)文本组织成层次结构(词,句子),(2)并分别在词级别和句子级别使用注意力机制,保证最终文本表示由不同层次上重要的信息构成,在多个数据集上都取得较好效果。 - -### 4.6 GNN 图神经网络篇 - -#### 4.6.1 GNN 图神经网络如何应用于文本分类领域? - -自然语言可以当作树结构和图结构来解析,文本中同时包含图结构,如句法分析和语法树往往以树形结构表示。 - -TextRank将图神经网络应用到处理这些图数据上。用来处理这种拓扑结构信息的模型,除了Tree-LSTM之外,就是GNN了。Graph-CNN首先将文本转换为由词构成的图,并使用图卷积来获取文本语义信息 - -### 4.7 Transformer 篇 - -#### 4.7.1 基于Transformer的预训练模型如何应用于文本分类领域? - -预训练模型的提出,极大的促进了NLP的发展,也是未来NLP应用和演化的重要方向之一。比如BERT等。这几乎是NLP领域面试必定会被问到的问题。但是BERT的使用范围不局限于文本分类,几乎所有的NLP领域的应用BERT都能做,因此适合单独开一章来讲。 - -当用于分类任务时,这些预训练模型都可以后接一个线性分类层来微调模型参数。 - -### 4.8 预训练模型 篇 - -#### 4.8.1 你了解哪些预训练模型?它们的特点是什么? - -自回归训练的模型:ELMo、OpenGPT、XLNet等 - -自编码的训练方法:BERT、RoBERTa等 - -OpenGPT是最早的自回归模型,它由12层Transformer组成,每个Transformer块都包含着(一个masked多头注意力模块+Layer Norm+全连接网络)。OpenGPT原来是做序列生成的,从左到右生成逐个单词,下个单词的生成的概率依赖于之前的生成结果。但是OpenGPT也可以用于文本分类任务中。 - -![](img/opengpt.png) - -自编码模型中最著名的是BERT。不像OpenGPT在预测单词时依赖于前一个单词,BERT通过双向Transformer利用了整个序列的全部信息。BERT是通过随机mask掉序列中的单词后,令模型预测mask来训练的。这种思路正是降噪自编码器的思路。 - -RoBERTa是更加鲁棒的BERT,使用了更多的数据。ALBERT则减少了内存消耗和增加了训练速度。DistillBERT则通过知识蒸馏技术,在保证原有BERT的99%能力下,缩小了40%规模(猜想是参数量),推理速度提升60%。SpanBERT提升了BERT对文本span的表示能力和预测能力。 - -也有研究试图合并自回归和自编码模型。XLNet没有在pretraining阶段使用随机加mask的自编码模式,而是在pretraining阶段和fine-tune阶段采用了permutation operation。具体地说,XLNet依然是使用自回归器的训练模式,依赖context_before来预测当前的单词,只不过会对输入序列进行随机重排,这样context_after也有机会排到context_before去了。这个重新排序的操作是通过Attention Mask的方式实现的,它不会真正mask掉某个单词,只是通过Query向量,把那个单词的attention降到最低,这样模型就看不到它了。 - -XLNet的改进有三点,第一是吸收了BERT等自编码模型的经验,在自回归模型的训练和预测过程中引入了下文信息;第二是像GPT-2一样使用了 高质量的训练数据;第三是借鉴了Transformer XL中的技术(相对位置编码和分段RNN),能够应用于长文档的NLP场景。此外,由于XLNet是自回归模型,能够更好地融入文本生成类任务。 - -## 五、损失函数 - -### 5.1 激活函数sigmoid篇 - -#### 5.1.1 二分类问题使用的激活函数sigmoid简介? - -二分类问题中,我们可以使用sigmoid函数将输入Wx+b映射到(0,1)区间中,从而得到属于某个类别的概率。 - -Sigmod激活函数和导函数分别为 - -![](img/sigmoid.png) - -对应的图像分别为: - -![](img/sigmoid_graph2.png) - -#### 5.1.2 Sigmod的缺点是什么? - -1) 输出范围在0~1之间,均值为0.5,不是关于原点对称。需要做数据偏移,不方便下一层的学习。 - -2) 当x很小或很大时,存在导数很小的情况。神经网络主要的训练方法是BP算法,BP算法的基础是导数的链式法则,也就是多个导数的乘积。而sigmoid的导数最大为0.25,多个小于等于0.25的数值相乘,其运算结果很小。随着神经网络层数的加深,梯度后向传播到浅层网络时,基本无法引起参数的扰动,也就是没有将loss的信息传递到浅层网络,这样网络就无法训练学习了。这就是所谓的梯度消失。 - -3) 计算exp比较耗时。 - -### 5.2 激活函数softmax篇 - -#### 5.2.1 softmax函数是什么? - -![](img/softmax.png) - -二分类问题中,我们可以使用sigmoid函数将输入Wx+b映射到(0,1)区间中,从而得到属于某个类别的概率。将这个问题进行泛化,推广到多分类问题中,我们可以使用softmax函数,对输出的值归一化为概率值 - -> 这一部分内容参考:【参考资料9】 - -#### 5.2.2 softmax函数怎么求导? - -softmax函数如下: - -![](img/softmax2.png) - -当 $j≠i$ 时,我们只用对分母求偏导就好 - -![](img/softmax_diff1.png) - -当 $j=i$ 时: - -![](img/softmax_diff2.png) - -### 5.3 分类问题使用的损失函数还有有哪些? - -- 负对数似然损失(neg log-likelihood loss) -- 交叉熵损失(cross entropy loss) -- 指数损失(exponential loss) -- 平方损失 - -> 这一部分内容参考:【参考资料10、11、12】 - -## 六、模型评估和算法比较 - -### 6.1 文本分类任务使用的评估算法和指标有哪些? - -准确率、召回率、ROC,AUC,F1、混淆矩阵,kappa - -![](img/metric1.png) - -### 6.2 简单介绍混淆矩阵和kappa? - -混淆表(有时也称为混淆矩阵)是具有两行两列的表,该表报告假阳性,假阴性,真阳性和真阴性的数量。 所有正确的预测都位于表格的对角线上(以粗体突出显示),因此很容易从视觉上检查表格中的预测错误,因为它们将由对角线之外的值表示。 - -Kappa系数用于一致性检验,也可以用于衡量分类精度,但kappa系数的计算是基于混淆矩阵的。 - -![](img/kappa.png) - -其中,$p_o$ 是每一类正确分类的样本数量之和除以总样本数,也就是总体分类精度 。 - -假设每一类的真实样本个数分别为a1,a2,...,aC,而预测出来的每一类的样本个数分别为b1,b2,...,bC,总样本个数为n,则有: - -![](img/kappa2.png) - -## 参考资料 - -1. [中文分词方法和软件工具汇总笔记](https://zhuanlan.zhihu.com/p/86322679) -2. [史上最全的分词算法与工具介绍](https://blog.csdn.net/xixiaoyaoww/article/details/104589402) -3. [《数学之美》第二版]() -4. [第6天:文本处理流程——停用词的过滤、正则化操作](https://zhuanlan.zhihu.com/p/143099147) -5. [tf-idf 介绍](https://zh.wikipedia.org/wiki/Tf-idf) -6. [BAT面试题42:深度学习解决大规模文本分类问题](https://cloud.tencent.com/developer/article/1399904) -7. [深入TextCNN(一)详述CNN及TextCNN原理](https://zhuanlan.zhihu.com/p/77634533) -8. [文本分类——DPCNN模型](https://blog.csdn.net/qq_38293297/article/details/107307768) -9. [【机器学习】softmax函数总结](https://blog.csdn.net/haolexiao/article/details/72757796) -10. [分类问题中的损失函数](https://zhuanlan.zhihu.com/p/74073096) -11. [常见的损失函数(loss function)总结](https://zhuanlan.zhihu.com/p/58883095) -12. [常用的分类问题中的损失函数](https://blog.csdn.net/weixin_41065383/article/details/89413819) \ No newline at end of file diff --git a/NLPinterview/textclassifier/TextClassification/img/2021-01-25-16-04-31.png b/NLPinterview/textclassifier/TextClassification/img/2021-01-25-16-04-31.png deleted file mode 100644 index fc7724c..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/2021-01-25-16-04-31.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/2021-01-25-16-06-47.png b/NLPinterview/textclassifier/TextClassification/img/2021-01-25-16-06-47.png deleted file mode 100644 index 6faa68f..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/2021-01-25-16-06-47.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/2021-01-26-14-40-01.png b/NLPinterview/textclassifier/TextClassification/img/2021-01-26-14-40-01.png deleted file mode 100644 index 570963c..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/2021-01-26-14-40-01.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/2021-02-10-02-39-21.png b/NLPinterview/textclassifier/TextClassification/img/2021-02-10-02-39-21.png deleted file mode 100644 index f4a2346..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/2021-02-10-02-39-21.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/attention.png b/NLPinterview/textclassifier/TextClassification/img/attention.png deleted file mode 100644 index df616ff..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/attention.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/attention2.png b/NLPinterview/textclassifier/TextClassification/img/attention2.png deleted file mode 100644 index 20a2b39..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/attention2.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/dpcnn.png b/NLPinterview/textclassifier/TextClassification/img/dpcnn.png deleted file mode 100644 index a07dead..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/dpcnn.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/idf.png b/NLPinterview/textclassifier/TextClassification/img/idf.png deleted file mode 100644 index 61bd270..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/idf.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/kappa.png b/NLPinterview/textclassifier/TextClassification/img/kappa.png deleted file mode 100644 index f1eef16..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/kappa.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/kappa2.png b/NLPinterview/textclassifier/TextClassification/img/kappa2.png deleted file mode 100644 index 1db4f24..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/kappa2.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/metric1.png b/NLPinterview/textclassifier/TextClassification/img/metric1.png deleted file mode 100644 index 55375b7..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/metric1.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/opengpt.png b/NLPinterview/textclassifier/TextClassification/img/opengpt.png deleted file mode 100644 index 6178f4c..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/opengpt.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/sigmoid.png b/NLPinterview/textclassifier/TextClassification/img/sigmoid.png deleted file mode 100644 index 9c58ec9..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/sigmoid.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/sigmoid_graph2.png b/NLPinterview/textclassifier/TextClassification/img/sigmoid_graph2.png deleted file mode 100644 index e513a16..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/sigmoid_graph2.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/softmax.png b/NLPinterview/textclassifier/TextClassification/img/softmax.png deleted file mode 100644 index 8fa8847..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/softmax.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/softmax2.png b/NLPinterview/textclassifier/TextClassification/img/softmax2.png deleted file mode 100644 index acacd8e..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/softmax2.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/softmax_diff1.png b/NLPinterview/textclassifier/TextClassification/img/softmax_diff1.png deleted file mode 100644 index 811498d..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/softmax_diff1.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/softmax_diff2.png b/NLPinterview/textclassifier/TextClassification/img/softmax_diff2.png deleted file mode 100644 index 0d50f24..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/softmax_diff2.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/textcnn_model.png b/NLPinterview/textclassifier/TextClassification/img/textcnn_model.png deleted file mode 100644 index fde590c..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/textcnn_model.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/textcnn_model_details.png b/NLPinterview/textclassifier/TextClassification/img/textcnn_model_details.png deleted file mode 100644 index 5de7381..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/textcnn_model_details.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/textrcnn.png b/NLPinterview/textclassifier/TextClassification/img/textrcnn.png deleted file mode 100644 index 7def59c..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/textrcnn.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/textrcnn_f1.png b/NLPinterview/textclassifier/TextClassification/img/textrcnn_f1.png deleted file mode 100644 index de02711..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/textrcnn_f1.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/textrcnn_f2.png b/NLPinterview/textclassifier/TextClassification/img/textrcnn_f2.png deleted file mode 100644 index 3b3a35b..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/textrcnn_f2.png and /dev/null differ diff --git a/NLPinterview/textclassifier/TextClassification/img/tf.png b/NLPinterview/textclassifier/TextClassification/img/tf.png deleted file mode 100644 index b0293eb..0000000 Binary files a/NLPinterview/textclassifier/TextClassification/img/tf.png and /dev/null differ diff --git "a/NLPinterview/textclassifier/TextClassification/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\345\210\206\347\261\273\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" "b/NLPinterview/textclassifier/TextClassification/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\345\210\206\347\261\273\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" deleted file mode 100644 index 1ce1f1b..0000000 Binary files "a/NLPinterview/textclassifier/TextClassification/img/\343\200\220\345\205\263\344\272\216\346\226\207\346\234\254\345\210\206\347\261\273\343\200\221\351\202\243\344\272\233\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\344\272\213.png" and /dev/null differ diff --git a/README.md b/README.md index 23b620e..807f616 100644 --- a/README.md +++ b/README.md @@ -1,419 +1,19 @@ -# 【关于 NLP】百问百答 +# NLP 面无不过 -> 作者:杨夕、芙蕖、李玲、陈海顺、twilight、LeoLRH、JimmyDU、张永泰 -> > 介绍:本项目是作者们根据个人面试和经验总结出的自然语言处理(NLP)面试准备的学习笔记与资料,该资料目前包含 自然语言处理各领域的 面试题积累。 > -> NLP 百面百搭 地址:https://github.com/km1994/NLP-Interview-Notes -> -> **[手机版NLP百面百搭](https://mp.weixin.qq.com/s?__biz=MzAxMTU5Njg4NQ==&mid=100005719&idx=3&sn=5d8e62993e5ecd4582703684c0d12e44&chksm=1bbff26d2cc87b7bf2504a8a4cafc60919d722b6e9acbcee81a626924d80f53a49301df9bd97&scene=18#wechat_redirect)** -> -> 推荐系统 百面百搭 地址:https://github.com/km1994/RES-Interview-Notes -> -> **[手机版推荐系统百面百搭](https://mp.weixin.qq.com/s/b_KBT6rUw09cLGRHV_EUtw)** -> -> 搜索引擎 百面百搭 地址:https://github.com/km1994/search-engine-Interview-Notes 【编写ing】 -> -> NLP论文学习笔记:https://github.com/km1994/nlp_paper_study -> -> 推荐系统论文学习笔记:https://github.com/km1994/RS_paper_study -> -> GCN 论文学习笔记:https://github.com/km1994/GCN_study -> -> **推广搜 军火库**:https://github.com/km1994/recommendation_advertisement_search - -![](img/微信截图_20210301212242.png) -> **关注公众号 【关于NLP那些你不知道的事】 加入 【NLP && 推荐学习群】一起学习!!!** - -![](img/微信截图_20210212153059.png) - - -## 介绍 - -本项目是作者们根据个人面试和经验总结出的自然语言处理(NLP)面试准备的学习笔记与资料,该资料目前包含 自然语言处理各领域的 面试题积累。 - -> 注:github 网页版 看起来不舒服,可以看 **[手机版NLP百面百搭](https://mp.weixin.qq.com/s?__biz=MzAxMTU5Njg4NQ==&mid=100005719&idx=3&sn=5d8e62993e5ecd4582703684c0d12e44&chksm=1bbff26d2cc87b7bf2504a8a4cafc60919d722b6e9acbcee81a626924d80f53a49301df9bd97&scene=18#wechat_redirect)** - - -## 目录架构 - -- [【关于 NLP】百问百答](#关于-nlp百问百答) - - [介绍](#介绍) - - [目录架构](#目录架构) - - [手机版 NLP 百面百搭](#手机版-nlp-百面百搭) - - [内容框架](#内容框架) - - [一、【关于 基础算法篇】那些你不知道的事](#一关于-基础算法篇那些你不知道的事) - - [二、【关于 机器学习算法篇】那些你不知道的事](#二关于-机器学习算法篇那些你不知道的事) - - [三、【关于 深度学习算法篇】那些你不知道的事](#三关于-深度学习算法篇那些你不知道的事) - - [四、【关于 NLP 学习算法】那些你不知道的事](#四关于-nlp-学习算法那些你不知道的事) - - [4.1 【关于 信息抽取】那些你不知道的事](#41-关于-信息抽取那些你不知道的事) - - [4.1.1 【关于 命名实体识别】那些你不知道的事](#411-关于-命名实体识别那些你不知道的事) - - [4.1.2 【关于 关系抽取】那些你不知道的事](#412-关于-关系抽取那些你不知道的事) - - [4.1.3 【关于 事件抽取】那些你不知道的事](#413-关于-事件抽取那些你不知道的事) - - [4.2 【关于 NLP 预训练算法】那些你不知道的事](#42-关于-nlp-预训练算法那些你不知道的事) - - [4.3 【关于 文本分类】那些你不知道的事](#43-关于-文本分类那些你不知道的事) - - [4.4 【关于 文本匹配】那些你不知道的事](#44-关于-文本匹配那些你不知道的事) - - [4.5 【关于 问答系统】那些你不知道的事](#45-关于-问答系统那些你不知道的事) - - [4.5.1 【关于 FAQ 检索式问答系统】 那些你不知道的事](#451-关于-faq-检索式问答系统-那些你不知道的事) - - [4.5.2 【关于 问答系统工具篇】 那些你不知道的事](#452-关于-问答系统工具篇-那些你不知道的事) - - [4.6 【关于 对话系统】那些你不知道的事](#46-关于-对话系统那些你不知道的事) - - [4.7 【关于 知识图谱】那些你不知道的事](#47-关于-知识图谱那些你不知道的事) - - [4.7.1 【关于 知识图谱】 那些你不知道的事](#471-关于-知识图谱-那些你不知道的事) - - [4.7.2 【关于 KBQA】那些你不知道的事](#472-关于-kbqa那些你不知道的事) - - [4.7.3 【关于 Neo4j】那些你不知道的事](#473-关于-neo4j那些你不知道的事) - - [4.8 【关于 文本摘要】 那些你不知道的事](#48-关于-文本摘要-那些你不知道的事) - - [4.9 【关于 知识表示学习】那些你不知道的事](#49-关于-知识表示学习那些你不知道的事) - - [4.10 【关于 数据挖掘】那些你不知道的事](#410--关于-数据挖掘那些你不知道的事) - - [五、【关于 NLP 技巧】那些你不知道的事](#五关于-nlp-技巧那些你不知道的事) - - [5.1 【关于 少样本问题】那些你不知道的事](#51-关于-少样本问题那些你不知道的事) - - [5.2 【关于 脏数据】那些你不知道的事](#52-关于-脏数据那些你不知道的事) - - [5.3 【关于 炼丹炉】那些你不知道的事](#53-关于-炼丹炉那些你不知道的事) - - [5.4 【关于 早停法 EarlyStopping 】那些你不知道的事](#54-关于-早停法-earlystopping-那些你不知道的事) - - [5.5 【关于 标签平滑法 LabelSmoothing 】那些你不知道的事](#55-关于-标签平滑法-labelsmoothing-那些你不知道的事) - - [六、【关于 Python 】那些你不知道的事](#六关于-python-那些你不知道的事) - - [七、【关于 Tensorflow 】那些你不知道的事](#七关于-tensorflow-那些你不知道的事) - -## 手机版 NLP 百面百搭 - -- **[手机版NLP百面百搭](https://mp.weixin.qq.com/s?__biz=MzAxMTU5Njg4NQ==&mid=100005719&idx=3&sn=5d8e62993e5ecd4582703684c0d12e44&chksm=1bbff26d2cc87b7bf2504a8a4cafc60919d722b6e9acbcee81a626924d80f53a49301df9bd97&scene=18#wechat_redirect)** - -## 内容框架 - -### 一、[【关于 基础算法篇】那些你不知道的事](BasicAlgorithm/) - -- [【关于 过拟合和欠拟合】那些你不知道的事](BasicAlgorithm/过拟合和欠拟合.md) - - 一、过拟合和欠拟合 是什么? - - 二、过拟合/高方差(overfiting / high variance)篇 - - 2.1 过拟合是什么及检验方法? - - 2.2 导致过拟合的原因是什么? - - 2.3 过拟合的解决方法是什么? - - 三、欠拟合/高偏差(underfiting / high bias)篇 - - 3.1 欠拟合是什么及检验方法? - - 3.2 导致欠拟合的原因是什么? - - 3.3 过拟合的解决方法是什么? - -- [【关于 BatchNorm vs LayerNorm】那些你不知道的事](BasicAlgorithm/BatchNormVsLayerNorm.md) - - 一、动机篇 - - 1.1 独立同分布(independent and identically distributed)与白化 - - 1.2 ( Internal Covariate Shift,ICS) - - 1.3 ICS问题带来的后果是什么? - - 二、Normalization 篇 - - 2.1 Normalization 的通用框架与基本思想 - - 三、Batch Normalization 篇 - - 3.1 Batch Normalization(纵向规范化)是什么? - - 3.2 Batch Normalization(纵向规范化)存在什么问题? - - 3.3 Batch Normalization(纵向规范化)适用的场景是什么? - - 3.4 BatchNorm 存在什么问题? - - 四、Layer Normalization(横向规范化) 篇 - - 4.1 Layer Normalization(横向规范化)是什么? - - 4.2 Layer Normalization(横向规范化)有什么用? - - 五、BN vs LN 篇 - - 六、主流 Normalization 方法为什么有效? -- [【关于 激活函数】那些你不知道的事](BasicAlgorithm/激活函数.md) - - 一、动机篇 - - 1.1 为什么要有激活函数? - - 二、激活函数介绍篇 - - 2.1 sigmoid 函数篇 - - 2.1.1 什么是 sigmoid 函数? - - 2.1.2 为什么选 sigmoid 函数 作为激活函数? - - 2.1.3 sigmoid 函数 有什么缺点? - - 2.2 tanh 函数篇 - - 2.2.1 什么是 tanh 函数? - - 2.2.2 为什么选 tanh 函数 作为激活函数? - - 2.2.3 tanh 函数 有什么缺点? - - 2.3 relu 函数篇 - - 2.3.1 什么是 relu 函数? - - 2.3.2 为什么选 relu 函数 作为激活函数? - - 2.3.3 relu 函数 有什么缺点? - - 三、激活函数选择篇 -- [【关于 正则化】那些你不知道的事](BasicAlgorithm/正则化.md) - - 一、L0,L1,L2正则化 篇 - - 1.1 正则化 是什么? - - 1.2 什么是 L0 正则化 ? - - 1.3 什么是 L1 (稀疏规则算子 Lasso regularization)正则化 ? - - 1.4 什么是 L2 正则化(岭回归 Ridge Regression 或者 权重衰减 Weight Decay)正则化 ? - - 二、对比篇 - - 2.1 什么是结构风险最小化? - - 2.2 从结构风险最小化的角度理解L1和L2正则化 - - 2.3 L1 vs L2 - - 三、dropout 篇 - - 3.1 什么是 dropout? - - 3.2 dropout 在训练和测试过程中如何操作? - - 3.3 dropout 如何防止过拟合? -- [【关于 优化算法及函数】那些你不知道的事](BasicAlgorithm/优化算法及函数.md) - - 一、动机篇 - - 1.1 为什么需要 优化函数? - - 1.2 优化函数的基本框架是什么? - - 二、优化函数介绍篇 - - 2.1 梯度下降法是什么? - - 2.2 随机梯度下降法是什么? - - 2.3 Momentum 是什么? - - 2.4 SGD with Nesterov Acceleration 是什么? - - 2.5 Adagrad 是什么? - - 2.6 RMSProp/AdaDelta 是什么? - - 2.7 Adam 是什么? - - 2.8 Nadam 是什么? - - 三、优化函数学霸笔记篇 -- [【关于 归一化】那些你不知道的事](BasicAlgorithm/归一化.md) - - 一、动机篇 - - 1.1 为什么要归一化? - - 二、介绍篇 - - 2.1 归一化 有 哪些方法? - - 2.2 归一化 各方法 特点? - - 2.3 归一化 的 意义? - - 三、应用篇 - - 3.1 哪些机器学习算法 需要做 归一化? - - 3.2 哪些机器学习算法 不需要做 归一化? -- [【关于 判别式(discriminative)模型 vs. 生成式(generative)模型】 那些你不知道的事](BasicAlgorithm/判别式vs生成式.md) - - 一、判别式模型篇 - - 1.1 什么是判别式模型? - - 1.2 判别式模型是思路是什么? - - 1.3 判别式模型的优点是什么? - - 二、生成式模型篇 - - 2.1 什么是生成式模型? - - 2.2 生成式模型是思路是什么? - - 2.3 生成式模型的优点是什么? - - 2.4 生成式模型的缺点是什么? - -### 二、[【关于 机器学习算法篇】那些你不知道的事](MachineLearningAlgorithm) - -- [【关于 逻辑回归】那些你不知道的事](MachineLearningAlgorithm/逻辑回归.md) - - 一、介绍篇 - - 1.1什么是逻辑回归 - - 1.2逻辑回归的优势 - - 二、推导篇 - - 2.1逻辑回归推导 - - 2.2求解优化 -- [【关于 支持向量机】 那些你不知道的事](MachineLearningAlgorithm/支持向量机.md) - - 一、原理篇 - - 1.1 什么是SVM? - - Q.A - - 1.2 SVM怎么发展的? - - 1.3 SVM存在什么问题? - - Q.A - - 二、算法篇 - - 2.1 什么是块算法? - - 2.2 什么是分解算法? - - 2.3 什么是序列最小优化算法? - - 2.4 什么是增量算法? - - Q.A - - 三、其他SVM篇 - - 3.1 什么是最小二次支持向量机? - - 3.2 什么是模糊支持向量机? - - 3.3 什么是粒度支持向量机? - - 3.4 什么是多类训练算法? - - 3.5 什么是孪生支持向量机? - - 3.6 什么是排序支持向量机? - - Q.A - - 四、应用篇 - - 4.1 模式识别 - - 4.2 网页分类 - - 4.3 系统建模与系统辨识 - - 4.4 其他 - - 五、对比篇 - - 六、拓展篇 -- [【关于 集成学习】那些你不知道的事](MachineLearningAlgorithm/集成学习.md) - - 一、动机 - - 二、集成学习介绍篇 - - 2.1 介绍篇 - - 2.1.1 集成学习的基本思想是什么? - - 2.1.2 集成学习为什么有效? - - 三、 Boosting 篇 - - 3.1 用一句话概括 Boosting? - - 3.2 Boosting 的特点是什么? - - 3.3 Boosting 的基本思想是什么? - - 3.4 Boosting 的特点是什么? - - 3.5 GBDT 是什么? - - 3.6 Xgboost 是什么? - - 四、Bagging 篇 - - 4.1 用一句话概括 Bagging? - - 4.2 Bagging 的特点是什么? - - 4.3 Bagging 的基本思想是什么? - - 4.4 Bagging 的基分类器如何选择? - - 4.5 Bagging 的优点 是什么? - - 4.6 Bagging 的特点是什么? - - 4.7 随机森林 是什么? - - 五、 Stacking 篇 - - 5.1 用一句话概括 Stacking ? - - 5.2 Stacking 的特点是什么? - - 5.3 Stacking 的基本思路是什么? - - 六、常见问题篇 - - 6.1 为什么使用决策树作为基学习器? - - 6.2 为什么不稳定的学习器更适合作为基学习器? - - 6.3 哪些模型适合作为基学习器? - - 6.4 Bagging 方法中能使用线性分类器作为基学习器吗? Boosting 呢? - - 6.5 Boosting/Bagging 与 偏差/方差 的关系? - - 七、对比篇 - - 7.1 LR vs GBDT? - - 7.1.1 从机器学习三要素的角度 - - 7.1.1.1 从模型角度 - - 7.1.1.2 从策略角度 - - 7.1.1.2.1 从 Loss 角度 - - 7.1.1.2.2 从 特征空间 角度 - - 7.1.1.2.3 从 正则 角度 - - 7.1.1.3 从算法角度 - - 7.1.2 从特征的角度 - - 7.1.2.1 特征组合 - - 7.1.2.2 特特征的稀疏性 - - 7.1.3 数据假设不同 - - 7.1.3.1 LR - - 7.1.3.2 GBDT - - 参考 -### 三、[【关于 深度学习算法篇】那些你不知道的事](DeepLearningAlgorithm) - -- [【关于 CNN 】那些你不知道的事](DeepLearningAlgorithm/cnn/) - - 一、动机篇 - - 二、CNN 卷积层篇 - - 2.1 卷积层的本质是什么? - - 2.2 CNN 卷积层与全连接层的联系? - - 2.3 channel的含义是什么? - - 三、CNN 池化层篇 - - 3.1 池化层针对区域是什么? - - 3.2 池化层的种类有哪些? - - 3.3 池化层的作用是什么? - - 3.4 池化层 反向传播 是什么样的? - - 3.5 mean pooling 池化层 反向传播 是什么样的? - - 3.6 max pooling 池化层 反向传播 是什么样的? - - 四、CNN 整体篇 - - 4.1 CNN 的流程是什么? - - 4.2 CNN 的特点是什么? - - 4.3 卷积神经网络为什么会具有平移不变性? - - 4.4 卷积神经网络中im2col是如何实现的? - - 4.5 CNN 的局限性是什么? - - 五、Iterated Dilated CNN 篇 - - 5.1 什么是 Dilated CNN 空洞卷积? - - 5.2 什么是 Iterated Dilated CNN? - - 六、反卷积 篇 - - 6.1 解释反卷积的原理和用途? -- [【关于 Attention 】那些你不知道的事](DeepLearningAlgorithm/attention) - - 一、seq2seq 篇 - - 1.1 seq2seq (Encoder-Decoder)是什么? - - 1.2 seq2seq 中 的 Encoder 怎么样? - - 1.3 seq2seq 中 的 Decoder 怎么样? - - 1.4 在 数学角度上 的 seq2seq ,你知道么? - - 1.5 seq2seq 存在 什么 问题? - - 二、Attention 篇 - - 2.1 什么是 Attention? - - 2.2 为什么引入 Attention机制? - - 2.3 Attention 有什么作用? - - 2.4 Attention 流程是怎么样? - - 步骤一 执行encoder (与 seq2seq 一致) - - 步骤二 计算对齐系数 a - - 步骤三 计算上下文语义向量 C - - 步骤四 更新decoder状态 - - 步骤五 计算输出预测词 - - 2.5 Attention 的应用领域有哪些? - - 三、Attention 变体篇 - - 3.1 Soft Attention 是什么? - - 3.2 Hard Attention 是什么? - - 3.3 Global Attention 是什么? - - 3.4 Local Attention 是什么? - - 3.5 self-attention 是什么? -- [【关于 Transformer面试题】那些你不知道的事](DeepLearningAlgorithm/transformer) - - [【关于 Transformer】那些你不知道的事](DeepLearningAlgorithm/transformer/readme.md) - - 一、动机篇 - - 1.1 为什么要有 Transformer? - - 1.2 Transformer 作用是什么? - - 二、整体结构篇 - - 2.1 Transformer 整体结构是怎么样? - - 2.2 Transformer-encoder 结构怎么样? - - 2.3 Transformer-decoder 结构怎么样? - - 三、模块篇 - - 3.1 self-attention 模块 - - 3.1.1 传统 attention 是什么? - - 3.1.2 为什么 会有self-attention? - - 3.1.3 self-attention 的核心思想是什么? - - 3.1.4 self-attention 的目的是什么? - - 3.1.5 self-attention 的怎么计算的? - - 3.1.6 self-attention 为什么Q和K使用不同的权重矩阵生成,为何不能使用同一个值进行自身的点乘? - - 3.1.7 为什么采用点积模型的 self-attention 而不采用加性模型? - - 3.1.8 Transformer 中在计算 self-attention 时为什么要除以 $\sqrt{d}$? - - 3.1.9 self-attention 如何解决长距离依赖问题? - - 3.1.10 self-attention 如何并行化? - - 3.2 multi-head attention 模块 - - 3.2.1 multi-head attention 的思路是什么样? - - 3.2.2 multi-head attention 的步骤是什么样? - - 3.2.3 Transformer为何使用多头注意力机制?(为什么不使用一个头) - - 3.2.4 为什么在进行多头注意力的时候需要对每个head进行降维? - - 3.2.5 multi-head attention 代码介绍 - - 3.3 位置编码(Position encoding)模块 - - 3.3.1 为什么要 加入 位置编码(Position encoding) ? - - 3.3.2 位置编码(Position encoding)的思路是什么 ? - - 3.3.3 位置编码(Position encoding)的作用是什么 ? - - 3.3.4 位置编码(Position encoding)的步骤是什么 ? - - 3.3.5 Position encoding为什么选择相加而不是拼接呢? - - 3.3.6 Position encoding和 Position embedding的区别? - - 3.3.7 为何17年提出Transformer时采用的是 Position Encoder 而不是Position Embedding?而Bert却采用的是 Position Embedding ? - - 3.3.8 位置编码(Position encoding)的代码介绍 - - 3.4 残差模块模块 - - 3.4.1 为什么要 加入 残差模块? - - 3.5 Layer normalization 模块 - - 3.5.1 为什么要 加入 Layer normalization 模块? - - 3.5.2 Layer normalization 模块的是什么? - - 3.5.3 Batch normalization 和 Layer normalization 的区别? - - 3.5.4 Transformer 中为什么要舍弃 Batch normalization 改用 Layer normalization 呢? - - 3.5.5 Layer normalization 模块代码介绍 - - 3.6 Mask 模块 - - 3.6.1 什么是 Mask? - - 3.6.2 Transformer 中用到 几种 Mask? - - 3.6.3 能不能介绍一下 Transformer 中用到几种 Mask? - - [【关于 Transformer 问题及改进】那些你不知道的事](DeepLearningAlgorithm/transformer/transformer_error.md) - - 一、Transformer 问题篇 - - 1.1 既然 Transformer 怎么牛逼,是否还存在一些问题? - - 二、每个问题的解决方法是什么? - - 2.1 问题一:Transformer 不能很好的处理超长输入问题 - - 2.1.1 Transformer 固定了句子长度? - - 2.1.2 Transformer 固定了句子长度 的目的是什么? - - 2.1.3 Transformer 针对该问题的处理方法? - - 2.2 问题二:Transformer 方向信息以及相对位置 的 缺失 问题 - - 2.3 问题三:缺少Recurrent Inductive Bias - - 问题四:问题四:Transformer是非图灵完备的: 非图灵完备通俗的理解,就是无法解决所有的问题 - - 问题五:transformer缺少conditional computation; - - 问题六:transformer 时间复杂度 和 空间复杂度 过大问题; -- [【关于 生成对抗网络 GAN 】 那些你不知道的事](DeepLearningAlgorithm/adversarial_training_study/readme.md) - - 一、动机 - - 二、介绍篇 - - 2.1 GAN 的基本思想 - - 2.2 GAN 基本介绍 - - 2.2.1 GAN 的基本结构 - - 2.2.2 GAN 的基本思想 - - 三、训练篇 - - 3.1 生成器介绍 - - 3.2 判别器介绍 - - 3.3 训练过程 - - 3.4 训练所涉及相关理论基础 - - 四、总结 -- [【关于 RNN】那些你不知道的事](https://github.com/km1994/NLP-Interview-Notes/tree/main/DeepLearningAlgorithm/rnn#关于-rnn那些你不知道的事) - - 一、RNN 篇 - - 1.2 为什么需要 RNN? - - 1.2 RNN 结构是怎么样的? - - 1.3 RNN 前向计算公式? - - 1.4 RNN 存在什么问题? - - 二、长短时记忆网络(Long Short Term Memory Network, LSTM) 篇 - - 2.1 为什么 需要 LSTM? - - 2.2 LSTM 的结构是怎么样的? - - 2.3 LSTM 如何缓解 RNN 梯度消失和梯度爆炸问题? - - 2.3 LSTM 的流程是怎么样的? - - 2.4 LSTM 中激活函数区别? - - 2.5 LSTM的复杂度? - - 2.6 LSTM 存在什么问题? - - 三、GRU (Gated Recurrent Unit) - - 3.1 为什么 需要 GRU? - - 3.2 GRU 的结构是怎么样的? - - 3.3 GRU 的前向计算? - - 3.4 GRU 与其他 RNN系列模型的区别? - - 四、RNN系列模型篇 - - 4.1 RNN系列模型 有什么特点? - - 参考 + +> NLP 面无不过 面试交流群 (注:人满 可 添加 小编wx:yzyykm666 加群!) + -### 四、[【关于 NLP 学习算法】那些你不知道的事](NLPinterview) +## 四、NLP 学习算法 常见面试篇 -#### 4.1 [【关于 信息抽取】那些你不知道的事](NLPinterview/NER/) +#### 4.1 信息抽取 常见面试篇 -##### 4.1.1 [【关于 命名实体识别】那些你不知道的事](NLPinterview/NER/) +##### 4.1.1 命名实体识别 常见面试篇 -- [【关于 HMM->MEMM->CRF】那些你不知道的事](NLPinterview/ner/crf/) +- [隐马尔科夫算法 HMM 常见面试篇](https://articles.zsxq.com/id_1q8xawb5rjwk.html) - 一、基础信息 介绍篇 - 1.1 什么是概率图模型? - 1.2 什么是 随机场? @@ -432,6 +32,10 @@ - 3.2.2 隐马尔科夫算法 序列标注(解码)过程 是什么样的? - 3.2.3 隐马尔科夫算法 序列概率过程 是什么样的? - 3.3 隐马尔科夫算法 问题篇 + +> [点击查看答案](https://articles.zsxq.com/id_1q8xawb5rjwk.html) + +- [最大熵马尔科夫模型 MEMM 常见面试篇](https://articles.zsxq.com/id_gcfcvw10h89u.html) - 四、最大熵马尔科夫模型(MEMM)篇 - 4.1 最大熵马尔科夫模型(MEMM)动机篇 - 4.1.1 HMM 存在 什么问题? @@ -439,6 +43,10 @@ - 4.2.1 最大熵马尔科夫模型(MEMM) 是什么样? - 4.2.2 最大熵马尔科夫模型(MEMM) 如何解决 HMM 问题? - 4.3 最大熵马尔科夫模型(MEMM)问题篇 + +> [点击查看答案](https://articles.zsxq.com/id_gcfcvw10h89u.html) + +- [条件随机场(CRF) 常见面试篇](https://articles.zsxq.com/id_3votd06mbvxv.html) - 五、条件随机场(CRF)篇 - 5.1 CRF 动机篇 - 5.1.1 HMM 和 MEMM 存在什么问题? @@ -453,7 +61,10 @@ - 5.4 CRF 复现? - 六、对比篇 - 6.1 CRF模型 和 HMM和MEMM模型 区别? -- [【关于 DNN-CRF】那些你不知道的事](NLPinterview/ner/DNN/readme.md) + +> [点击查看答案](https://articles.zsxq.com/id_3votd06mbvxv.html) + +- [DNN-CRF 常见面试篇](https://articles.zsxq.com/id_8u0rtbsjt64l.html) - 一、基本信息 - 1.1 命名实体识别 评价指标 是什么? - 二、传统的命名实体识别方法 @@ -483,7 +94,10 @@ - 4.1 CNN-CRF vs BiLSTM-CRF vs IDCNN-CRF? - 4.2 为什么 DNN 后面要加 CRF? - 4.3 CRF in TensorFlow V.S. CRF in discrete toolkit? -- [【关于 中文领域 NER】 那些你不知道的事](NLPinterview/ner/ChineseNer/readme.md) + +> [点击查看答案](https://articles.zsxq.com/id_8u0rtbsjt64l.html) + +- [中文领域 NER 常见面试篇](https://articles.zsxq.com/id_sgbknf1i6zer.html) - 一、动机篇 - 1.1 中文命名实体识别 与 英文命名实体识别的区别? - 二、词汇增强篇 @@ -504,14 +118,17 @@ - 3.2 为什么说 「词汇/实体类型信息增强」 方法对于中文 NER 任务有效呢? - 3.3 词汇/实体类型信息增强 方法有哪些? - 3.4 什么是 LEX-BERT ? -- [【关于 命名实体识别 trick 】那些你不知道的事](NLPinterview/ner/NERtrick/NERtrick.md) + +> [点击查看答案](https://articles.zsxq.com/id_sgbknf1i6zer.html) + +- [命名实体识别 trick 常见面试篇](https://articles.zsxq.com/id_ik69rzw4ql5j.html) - trick 1:领域词典匹配 - trick 2:规则抽取 - trick 3:词向量选取:词向量 or 字向量? - trick 4:特征提取器 如何选择? - - trick 5:专有名称 怎么 处理?【注:这一点来自于 命名实体识别的几点心得 】 - - trick 6:标注数据 不足怎么处理?【这个问题可以说是现在很多小厂最头疼的问题】 - - trick 7:嵌套命名实体识别怎么处理 【注:参考 资料3】 + - trick 5:专有名称 怎么 处理? + - trick 6:标注数据 不足怎么处理? + - trick 7:嵌套命名实体识别怎么处理 - 7.1 什么是实体嵌套? - 7.2 与 传统命名实体识别任务的区别 - 7.3 解决方法: @@ -525,9 +142,11 @@ - trick 11: 给定两个命名实体识别任务,一个任务数据量足够,另外一个数据量很少,可以怎么做? - trick 12: NER 标注数据不均衡问题? -##### 4.1.2 [【关于 关系抽取】那些你不知道的事](NLPinterview/RelationExtraction/) +> [点击查看答案](https://articles.zsxq.com/id_ik69rzw4ql5j.html) + +##### 4.1.2 关系抽取 常见面试篇 -- [【关于 关系抽取】那些你不知道的事](NLPinterview/RelationExtraction/) +- [关系抽取 常见面试篇](https://articles.zsxq.com/id_0uqcsdxwhg8c.html) - 一、动机篇 - 1.1 什么是关系抽取? - 1.2 关系抽取技术有哪些类型? @@ -539,18 +158,7 @@ - 2.4 联合抽取是什么?难点在哪里? - 2.5 联合抽取总体上有哪些方法?各有哪些缺点? - 2.6 介绍基于共享参数的联合抽取方法? - - 依存结构树:End-to-End Relation Extraction using LSTMs on Sequences and Tree Structures - - 指针网络,Going out on a limb: Joint Extraction of Entity Mentions and Relations without Dependency Trees - - Copy机制+seq2seq:Extracting Relational Facts by an End-to-End Neural Model with Copy Mechanism19] - - 多头选择机制+sigmoid:Joint entity recognition and relation extraction as a multi-head selection problem - - SPO问题+指针网络,Joint Extraction of Entities and Relations Based on a Novel Decomposition Strategy - - 多轮对话+强化学习 :*Entity-Relation Extraction as Multi-Turn Question Answering* - - 输入端的片段排列: Span-Level Model for Relation Extraction - - 输出端的片段排列:SpERT:Span-based Joint Entity and Relation Extraction with Transformer Pre-training - 2.7 介绍基于联合解码的联合抽取方法? - - Joint extraction of entities and relations based on a novel tagging scheme - - Joint Extraction of Entities and Overlapping Relations Using Position-Attentive Sequence Labeling - - Joint extraction of entities and relations based on a novel tagging scheme - 2.8 实体关系抽取的前沿技术和挑战有哪些?如何解决低资源和复杂样本下的实体关系抽取? - 三、文档级关系抽取篇 - 3.1 文档级关系抽取与经典关系抽取有何区别? @@ -560,9 +168,11 @@ - 3.3.2 基于graph的文档关系抽取是怎么做的? - 3.4 文档级关系抽取常见数据集有哪些以及其评估方法? -##### 4.1.3 [【关于 事件抽取】那些你不知道的事](NLPinterview/EventExtraction/) +> [点击查看答案](https://articles.zsxq.com/id_0uqcsdxwhg8c.html) -- [【关于 事件抽取】那些你不知道的事](NLPinterview/EventExtraction/) +##### 4.1.3 事件抽取 常见面试篇 + +- [事件抽取 常见面试篇](NLPinterview/EventExtraction/) - 一、原理篇 - 1.1 什么是事件? - 1.2 什么是事件抽取? @@ -599,9 +209,9 @@ - 7.1 事件抽取论文综述 - 7.2 事件抽取常见问题 -#### 4.2 [【关于 NLP 预训练算法】那些你不知道的事](NLPinterview/PreTraining/) +#### 4.2 NLP 预训练算法 常见面试篇 -- [【关于TF-idf】那些你不知道的事](NLPinterview/PreTraining/tfidf) +- [【关于TF-idf】那些你不知道的事](https://articles.zsxq.com/id_8b6f6rux9dr0.html) - 一、one-hot 篇 - 1.1 为什么有 one-hot ? - 1.2 one-hot 是什么? @@ -616,7 +226,10 @@ - 2.6 TF-IDF 的优点是什么? - 2.7 TF-IDF 的缺点是什么? - 2.8 TF-IDF 的应用? -- [【关于word2vec】那些你不知道的事](NLPinterview/PreTraining/word2vec) + +> [点击查看答案](https://articles.zsxq.com/id_8b6f6rux9dr0.html) + +- [【关于word2vec】那些你不知道的事](https://articles.zsxq.com/id_2vpr5crbfbrp.html) - 一、Wordvec 介绍篇 - 1.1 Wordvec 指什么? - 1.2 Wordvec 中 CBOW 指什么? @@ -635,8 +248,11 @@ - 四、word2vec 实战篇 - 4.1 word2vec训练trick,window设置多大? - 4.1 word2vec训练trick,词向量纬度,大与小有什么影响,还有其他参数? -- [【关于FastText】那些你不知道的事](NLPinterview/PreTraining/fasttext) - - 一、fastText 动机篇 + +> [点击查看答案](https://articles.zsxq.com/id_2vpr5crbfbrp.html) + +- [【关于FastText】那些你不知道的事](https://articles.zsxq.com/id_tw45wd5ae23q.html) + - 一、fastText 动机篇 - 1.1 word-level Model 是什么? - 1.2 word-level Model 存在什么问题? - 1.3 Character-Level Model 是什么? @@ -656,7 +272,10 @@ - 3.2 层次化Softmax回归(Hierarchical Softmax) 的思想是什么? - 3.3 层次化Softmax回归(Hierarchical Softmax) 的步骤? - 四、fastText 存在问题? -- [【关于Elmo】那些你不知道的事](NLPinterview/PreTraining/elmo) + +> [点击查看答案](https://articles.zsxq.com/id_tw45wd5ae23q.html) + +- [【关于Elmo】那些你不知道的事](https://articles.zsxq.com/id_we1wwkpdrpfn.html) - 一、Elmo 动机篇 - 1.1 为什么会有 Elmo? - 二、Elmo 介绍篇 @@ -664,191 +283,86 @@ - 2.2 Elmo 的 思想是什么? - 三、Elmo 问题篇 - 3.1 Elmo 存在的问题是什么? -- [【关于Bert】那些你不知道的事](NLPinterview/PreTraining/bert) - - [【关于Bert】那些你不知道的事](NLPinterview/PreTraining/bert/readme.md) - - 一、动机篇 - - 1.1 【演变史】one-hot 存在问题? - - 1.2【演变史】wordvec 存在问题? - - 1.3【演变史】fastText 存在问题? - - 1.4【演变史】elmo 存在问题? - - 二、Bert 篇 - - 2.1 Bert 介绍篇 - - 2.1.1【BERT】Bert 是什么? - - 2.1.2【BERT】Bert 三个关键点? - - 2.2 Bert 输入输出表征篇 - - 2.2.1 【BERT】Bert 输入输出表征长啥样? - - 2.3 【BERT】Bert 预训练篇 - - 2.3.1 【BERT】Bert 预训练任务介绍 - - 2.3.2 【BERT】Bert 预训练任务 之 Masked LM 篇 - - 2.3.2.1 【BERT】 Bert 为什么需要预训练任务 Masked LM ? - - 2.3.2.2 【BERT】 Bert 预训练任务 Masked LM 怎么做? - - 2.3.2.3 【BERT】 Bert 预训练任务 Masked LM 存在问题? - - 2.3.2.4 【BERT】 预训练和微调之间的不匹配的解决方法? - - 2.3.3 【BERT】Bert 预训练任务 之 Next Sentence Prediction 篇 - - 2.3.3.1 【BERT】Bert 为什么需要预训练任务 Next Sentence Prediction ? - - 2.3.3.2 【BERT】 Bert 预训练任务 Next Sentence Prediction 怎么做? - - 2.4 【BERT】 fine-turning 篇? - - 2.4.1 【BERT】为什么 Bert 需要 fine-turning? - - 2.4.2 【BERT】 Bert 如何 fine-turning? - - 2.5 【BERT】 Bert 损失函数篇? - - 2.5.1 【BERT】BERT的两个预训练任务对应的损失函数是什么(用公式形式展示)? - - 三、 对比篇? - - 3.1 【对比】多义词问题是什么? - - 3.2 【对比】word2vec 为什么解决不了多义词问题? - - 3.3 【对比】GPT和BERT有什么不同? - - 3.4 【对比】为什么 elmo、GPT、Bert能够解决多义词问题?(以 elmo 为例) - - [【关于 Bert 源码解析I 之 主体篇】那些你不知道的事](NLPinterview/PreTraining/bert/bertCode1_modeling.md) - - 一、动机 - - 二、本文框架 - - 三、前言 - - 四、配置类 BertConfig - - 五、获取 词向量 (Embedding_lookup) - - 六、词向量 的后处理 (embedding_postprocessor) - - 6.1 介绍 - - 6.2 特点 - - 6.3 代码实现 - - 七、创建 attention mask (attention_mask) - - 7.1 作用 - - 7.2 代码 - - 八、注意力层(attention layer) - - 8.1 自注意力层(self-attention) - - 8.1.1 动机 - - 8.1.2 传统 Attention - - 8.1.3 核心思想 - - 8.1.4 目的 - - 8.1.5 公式 - - 8.1.6 步骤 - - 8.2 多头自注意力 (Multi-Headed Attention) - - 8.2.1 思路 - - 8.2.2 步骤 - - 8.3 代码讲解 - - 8.4 代码流程总结 - - 8.5 对比总结 - - 九、Transformer - - 9.1 介绍 - - 9.2 模型实现 - - 9.3 思路分析 - - 十、入口函数 BertModel() - - 10.1 模型实现 - - 10.2 流程介绍 - - 十一、总结 - - [【关于 Bert 源码解析II 之 预训练篇】那些你不知道的事](NLPinterview/PreTraining/bert/bertCode2_pretraining.md) - - 一、动机 - - 二、本文框架 - - 三、前言 - - 四、原始语料 预处理模块 (tokenization.py) - - 4.1 动机 - - 4.2 类别 - - 4.3 BasicTokenizer - - 4.4 WordpieceTokenizer - - 4.5 FullTokenizer - - 五、训练数据生成(create_pretraining_data.py) - - 5.1 作用 - - 5.2 参数设置 - - 5.3 main 入口 - - 5.4 定义训练样本类 (TrainingInstance) - - 5.5 构建训练实例 (create_training_instances) - - 5.6 从 document 中抽取 实例(create_instances_from_document) - - 5.6.1 作用 - - 5.6.2 代码讲解 - - 5.6.3 流程 - - 5.7 随机MASK(create_masked_lm_predictions) - - 5.7.1 介绍 - - 5.7.2 代码解析 - - 5.8 保存instance(write_instance_to_example_files) - - 六、预训练 - - 6.1 Masked LM 训练 (get_masked_lm_output) - - 6.2 获取 next sentence prediction(下一句预测) 部分的 loss 以及 log probs (get_next_sentence_output) - - 七、测试 - - 八、总结 - - [【关于 Bert 源码解析III 之 微调篇】那些你不知道的事](NLPinterview/PreTraining/bert/bertCode3_fineTune.md) - - 一、动机 - - 二、本文框架 - - 三、前言 - - 四、参数解析 - - 五、输入数据实例 - - 六、特定任务数据处理 - - 6.1 数据处理 接口 - - 6.2 推理任务 数据集处理 - - 6.3 二分类任务 数据集处理 - - 七、examples转换成features (file_based_convert_examples_to_features) - - 7.1 单例转化 - - 7.2 单例转化 - - 八、创建模型 - - 8.1 create_model 创建 分类模型 - - 8.2 model_fn_builder - - 九、主入口 - - 十、总结 - - [【关于 Bert 源码解析IV 之 句向量生成篇】那些你不知道的事](NLPinterview/PreTraining/bert/bertCode4_word2embedding.md) - - 一、动机 - - 二、本文框架 - - 三、前言 - - 四、配置类 (Config) - - 五、特征实例类 (InputExample) - - 六、Bert 句向量 类 (BertVector) - - 七、Bert 句向量 生成 实例 - - 八、总结 - - [【关于 Bert 源码解析V 之 文本相似度篇】那些你不知道的事](NLPinterview/PreTraining/bert/bertCode5_similarity.md) - - 一、动机 - - 二、本文框架 - - 三、前言 - - 四、配置类 (Config) - - 五、特征实例类 (InputExample) - - 六、数据预处理类 - - 6.1 DataProcessor - - 6.2 文本相似度任务 文本预处理 (SimProcessor) - - 6.2.1 数据格式 - - 6.2.2 数据预处理类 - - 七、基于 Bert 的 文本相似度 模型 - - 八、Bert 相似度 模型 使用 - - 九、总结 -- [【关于 小 Bert 模型系列算法】那些你不知道的事](NLPinterview/PreTraining/bert_zip) - - [【关于 小 Bert 模型系列算法】那些你不知道的事](NLPinterview/PreTraining/bert_zip) - - 一、Bert 模型压缩 动机篇 - - 二、Bert 模型压缩对比表 - - 三、 Bert 模型压缩方法介绍 - - 3.1 Bert 模型压缩方法 之 低秩因式分解&跨层参数共享 - - 3.1.1 什么是低秩因式分解? - - 3.1.2 什么是跨层参数共享? - - 3.1.3 ALBERT 所所用的方法? - - 3.2 Bert 模型压缩方法 之 蒸馏 - - 3.2.1 什么是蒸馏? - - 3.2.2 使用 模型蒸馏 的论文? - - 3.2.2.1 Extreme Language Model Compression withOptimal Subwords and Shared Projections 【蒸馏】 - - 3.2.2.2 DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter 【蒸馏】 - - 3.2.2.3 FastBERT: a Self-distilling BERT with Adaptive Inference Time 【蒸馏】 - - 3.2.2.4 TinyBERT: Distilling BERT for Natural Language Understanding 【蒸馏】 - - 3.3 Bert 模型压缩方法 之 量化 - - 3.3.1 什么是量化? - - 3.3.2 Q-BERT: Hessian Based Ultra Low Precision Quantization of BERT 【量化】 - - 3.4 Bert 模型压缩方法 之 剪枝 - - 3.4.1 什么是剪枝? - - 四、模型压缩存在问题? - - [【关于 Distilling Task-Specific Knowledge from BERT into Simple Neural Networks】那些你不知道的事](NLPinterview/PreTraining/bert_zip/BERTintoSimpleNeuralNetworks/) - - 一、动机 - - 二、论文思路 - - 三、模型框架讲解【以单句分类任务为例】 - - 3.1 Teacher 模型(Bert) 微调 - - 3.2 Student 模型(TextCNN、TextRNN)构建 - - 3.2.1 TextRNN 模型构建 - - 3.2.2 TextCNN 模型构建 - - 3.3 Distillation Objective - - 四、Data Augmentation for Distillation - - 五、单句分类任务 实验结果分析 - - 5.1 数据集介绍 - - 5.2 实验结果分析 - - 六、总结 -- [【关于 大 Bert 模型系列算法】 那些你不知道的事](NLPinterview/PreTraining/bert_big) - - 一、引言 - - 二、Bert 变大篇 - - 2.1 认识 XLNet 么?能不能讲一下? 和 Bert 的 区别在哪里? - - 2.2 认识 RoBERTa 么?能不能讲一下? 和 Bert 的 区别在哪里? - - 2.3 认识 SpanBERT 么?能不能讲一下? 和 Bert 的 区别在哪里? - - 2.4 认识 MASS 么?能不能讲一下? 和 Bert 的 区别在哪里? - -#### 4.3 [【关于 文本分类】那些你不知道的事](NLPinterview//textclassifier/) - -- [【关于 文本分类】那些你不知道的事](NLPinterview//textclassifier/TextClassification/) + +> [点击查看答案](https://articles.zsxq.com/id_we1wwkpdrpfn.html) + +#### 4.3 Bert 常见面试篇 + +- [Bert 常见面试篇](https://articles.zsxq.com/id_0ceqw3u9o2i5.html) + - 一、动机篇 + - 1.1 【演变史】one-hot 存在问题? + - 1.2【演变史】wordvec 存在问题? + - 1.3【演变史】fastText 存在问题? + - 1.4【演变史】elmo 存在问题? + - 二、Bert 篇 + - 2.1 Bert 介绍篇 + - 2.1.1【BERT】Bert 是什么? + - 2.1.2【BERT】Bert 三个关键点? + - 2.2 Bert 输入输出表征篇 + - 2.2.1 【BERT】Bert 输入输出表征长啥样? + - 2.3 【BERT】Bert 预训练篇 + - 2.3.1 【BERT】Bert 预训练任务介绍 + - 2.3.2 【BERT】Bert 预训练任务 之 Masked LM 篇 + - 2.3.2.1 【BERT】 Bert 为什么需要预训练任务 Masked LM ? + - 2.3.2.2 【BERT】 Bert 预训练任务 Masked LM 怎么做? + - 2.3.2.3 【BERT】 Bert 预训练任务 Masked LM 存在问题? + - 2.3.2.4 【BERT】 预训练和微调之间的不匹配的解决方法? + - 2.3.3 【BERT】Bert 预训练任务 之 Next Sentence Prediction 篇 + - 2.3.3.1 【BERT】Bert 为什么需要预训练任务 Next Sentence Prediction ? + - 2.3.3.2 【BERT】 Bert 预训练任务 Next Sentence Prediction 怎么做? + - 2.4 【BERT】 fine-turning 篇? + - 2.4.1 【BERT】为什么 Bert 需要 fine-turning? + - 2.4.2 【BERT】 Bert 如何 fine-turning? + - 2.5 【BERT】 Bert 损失函数篇? + - 2.5.1 【BERT】BERT的两个预训练任务对应的损失函数是什么(用公式形式展示)? + - 三、 对比篇? + - 3.1 【对比】多义词问题是什么? + - 3.2 【对比】word2vec 为什么解决不了多义词问题? + - 3.3 【对比】GPT和BERT有什么不同? + - 3.4 【对比】为什么 elmo、GPT、Bert能够解决多义词问题?(以 elmo 为例) + +> [点击查看答案](https://articles.zsxq.com/id_0ceqw3u9o2i5.html) + +- [【关于 Bert 源码解析I 之 主体篇】那些你不知道的事](https://articles.zsxq.com/id_918gk4sl2l8b.html) +- [【关于 Bert 源码解析II 之 预训练篇】那些你不知道的事](https://articles.zsxq.com/id_m1pcu7g25bd6.html) +- [【关于 Bert 源码解析III 之 微调篇】那些你不知道的事](https://articles.zsxq.com/id_uxcwvhqvvbes.html) +- [【关于 Bert 源码解析IV 之 句向量生成篇】那些你不知道的事](https://articles.zsxq.com/id_1ccw29hl80o8.html) +- [【关于 Bert 源码解析V 之 文本相似度篇】那些你不知道的事](https://articles.zsxq.com/id_vauhnwe9m7aj.html) + +##### 4.3.1 Bert 模型压缩 常见面试篇 + +- [Bert 模型压缩 常见面试篇](https://articles.zsxq.com/id_bknkkgtxj45f.html) + - 一、Bert 模型压缩 动机篇 + - 二、Bert 模型压缩对比表 + - 三、 Bert 模型压缩方法介绍 + - 3.1 Bert 模型压缩方法 之 低秩因式分解&跨层参数共享 + - 3.1.1 什么是低秩因式分解? + - 3.1.2 什么是跨层参数共享? + - 3.1.3 ALBERT 所所用的方法? + - 3.2 Bert 模型压缩方法 之 蒸馏 + - 3.2.1 什么是蒸馏? + - 3.2.2 使用 模型蒸馏 的论文 有哪些,稍微介绍一下? + - 3.3 Bert 模型压缩方法 之 量化 + - 3.3.1 什么是量化? + - 3.3.2 Q-BERT: Hessian Based Ultra Low Precision Quantization of BERT 【量化】 + - 3.4 Bert 模型压缩方法 之 剪枝 + - 3.4.1 什么是剪枝? + - 四、模型压缩存在问题? + +> [点击查看答案](https://articles.zsxq.com/id_bknkkgtxj45f.html) + +##### 4.3.2 Bert 模型系列 常见面试篇 + +- 认识 XLNet 么?能不能讲一下? 和 Bert 的 区别在哪里? +- 认识 RoBERTa 么?能不能讲一下? 和 Bert 的 区别在哪里? +- 认识 SpanBERT 么?能不能讲一下? 和 Bert 的 区别在哪里? +- 认识 MASS 么?能不能讲一下? 和 Bert 的 区别在哪里? + +> [点击查看答案](https://articles.zsxq.com/id_bsqbmanv6upr.html) + +#### 4.4 文本分类 常见面试篇 + +- [文本分类 常见面试篇](https://articles.zsxq.com/id_24linkt6tidj.html) - 一、 抽象命题 - 1.1 分类任务有哪些类别?它们都有什么特征? - 1.2 文本分类任务相较于其他领域的分类任务有何不同之处? @@ -917,92 +431,79 @@ - 六、模型评估和算法比较 - 6.1 文本分类任务使用的评估算法和指标有哪些? - 6.2 简单介绍混淆矩阵和kappa? -- [【关于 文本分类 trick 】那些你不知道的事](NLPinterview//textclassifier/ClassifierTrick/) - - 一、数据预处理问题 - - 1.1 vocab 构建问题 - - 1.2 模型输入问题 - - 1.3 噪声数据处理问题 - - 1.4 中文任务分词问题 - - 1.5 停用词处理问题 - - 二、模型篇 - - 2.1 模型选择 - - 2.2 词向量选择 - - 2.3 字 or 词向量 预训练 - - 三、参数篇 - - 3.1 正则化 - - 3.2 学习率 - - 四、任务篇 - - 4.1 二分类问题 - - 4.2 多标签分类 - - 4.3 长文本问题 - - 4.4 鲁棒性问题 - - 五、标签体系构建 - - 5.1 标签体系构建 - - 5.2 标签体系合理性评估 - - 六、策略构建 - - 6.1 算法策略构建 - - 6.2 特征挖掘策略 - - 6.3 数据不均衡问题 - - 6.3.1 重采样(re-sampling) - - 6.3.2 重加权(re-weighting) - - 6.3.3 数据增强 - - 6.4 预训练模型融合角度 - - 6.5 灾难性遗忘问题 - - 6.6 小模型大智慧 - - 6.6.1 模型蒸馏 - - 6.6.2 数据蒸馏 - -#### 4.4 [【关于 文本匹配】那些你不知道的事](NLPinterview/TextMatch/) - -- [【关于 文本匹配模型 ESIM 】那些你不知道的事](NLPinterview/TextMatch/ESIM/) - - 一、动机篇 - - 二、ESIM 模型篇 - - 2.1 模型介绍 - - 2.2 Input Encoding - - 2.3 Local Inference Modeling - - 2.4 Inference Composition - - 2.5 Prediction - - 2.6 模型训练 -- [【关于 语义相似度匹配任务中的 BERT】 那些你不知道的事](NLPinterview/TextMatch/bert_similairity/) - - 一、Sentence Pair Classification Task:使用 CLS] + +> [点击查看答案](https://articles.zsxq.com/id_24linkt6tidj.html) + +- [文本分类 trick 常见面试篇](https://articles.zsxq.com/id_jcs3manhpbd9.html) + - 一、文本分类数据预处理 如何做? + - 二、文本分类 预训练模型 如何选择? + - 三、文本分类 参数 如何优化? + - 四、文本分类 有哪些棘手任务? + - 五、文本分类 标签体系构建? + - 六、文本分类 策略构建? + +> [点击查看答案](https://articles.zsxq.com/id_jcs3manhpbd9.html) + +- [用检索的方式做文本分类 常见面试篇](https://articles.zsxq.com/id_tln637w4a3sg.html) + - 为什么需要用检索的方式做文本分类? + - 基于检索的方法做文本分类思路? + - 检索的方法的召回库如何构建? + - 检索的方法 的 训练阶段 如何做? + - 检索的方法 的 预测阶段 如何做? + - 用检索的方式做文本分类 方法 适用场景有哪些? + +> [点击查看答案](https://articles.zsxq.com/id_tln637w4a3sg.html) + +#### 4.5 文本匹配 常见面试篇 + +- [文本匹配模型 ESIM 常见面试篇](https://articles.zsxq.com/id_dfaagvc24cwa.html) + - 为什么需要 ESIM? + - 介绍一下 ESIM 模型? + +> [点击查看答案](https://articles.zsxq.com/id_dfaagvc24cwa.html) + +- [语义相似度匹配任务中的 BERT 常见面试篇](https://articles.zsxq.com/id_slnosr1n8a0z.html) + - 一、Sentence Pair Classification Task:使用 CLS - 二、cosine similairity - 三、长短文本的区别 - 四、sentence/word embedding - 五、siamese network 方式 -#### 4.5 [【关于 问答系统】那些你不知道的事](NLPinterview/QA/) - -##### 4.5.1 [【关于 FAQ 检索式问答系统】 那些你不知道的事](NLPinterview/QA/FAQ/) - -- [【关于 FAQ 检索式问答系统】 那些你不知道的事](NLPinterview/QA/FAQ/) - - 一、动机 - - 1.1 问答系统的动机? - - 1.2 问答系统 是什么? - - 二、FAQ 检索式问答系统介绍篇 - - 2.1 FAQ 检索式问答系统 是 什么? - - 2.2 query 匹配标准 QA 的核心是什么? - - 三、FAQ 检索式问答系统 方案篇 - - 3.1 常用 方案有哪些? - - 3.2 为什么 QQ 匹配比较常用? - - 3.2.1 QQ 匹配的优点有哪些? - - 3.2.2 QQ 匹配的语义空间是什么? - - 3.2.3 QQ 匹配的语料的稳定性是什么? - - 3.2.4 QQ 匹配的业务回答与算法模型的解耦是什么? - - 3.2.5 QQ 匹配的新问题发现与去重是什么? - - 3.2.6 QQ 匹配的上线运行速度是什么? - - 3.3 QQ 匹配一般处理流程是怎么样? 【假设 标准问题库 已处理好】 - - 四、FAQ 标准问题库构建篇 - - 4.1 如何发现 FAQ 中标准问题? - - 4.2 FAQ 如何做拆分? - - 4.3 FAQ 如何做合并? - - 4.4 FAQ 标准库如何实时更新? - - 五、FAQ 标准问题库答案优化篇 - - 5.1 FAQ 标准问题库答案如何优化? - - 参考 - -##### 4.5.2 [【关于 问答系统工具篇】 那些你不知道的事](NLPinterview/QA/Faiss/) - -- [【关于 Faiss 】 那些你不知道的事](NLPinterview/QA/Faiss/) +> [点击查看答案](https://articles.zsxq.com/id_slnosr1n8a0z.html) + +#### 4.6 问答系统 常见面试篇 + +##### 4.6.1 [FAQ 检索式问答系统 常见面试篇](https://articles.zsxq.com/id_vtkf1m0gq2or.html) + +- 一、动机 + - 1.1 问答系统的动机? + - 1.2 问答系统 是什么? +- 二、FAQ 检索式问答系统介绍篇 + - 2.1 FAQ 检索式问答系统 是 什么? + - 2.2 query 匹配标准 QA 的核心是什么? +- 三、FAQ 检索式问答系统 方案篇 + - 3.1 常用 方案有哪些? + - 3.2 为什么 QQ 匹配比较常用? + - 3.2.1 QQ 匹配的优点有哪些? + - 3.2.2 QQ 匹配的语义空间是什么? + - 3.2.3 QQ 匹配的语料的稳定性是什么? + - 3.2.4 QQ 匹配的业务回答与算法模型的解耦是什么? + - 3.2.5 QQ 匹配的新问题发现与去重是什么? + - 3.2.6 QQ 匹配的上线运行速度是什么? + - 3.3 QQ 匹配一般处理流程是怎么样? 【假设 标准问题库 已处理好】 +- 四、FAQ 标准问题库构建篇 + - 4.1 如何发现 FAQ 中标准问题? + - 4.2 FAQ 如何做拆分? + - 4.3 FAQ 如何做合并? + - 4.4 FAQ 标准库如何实时更新? +- 五、FAQ 标准问题库答案优化篇 + - 5.1 FAQ 标准问题库答案如何优化? + +> [点击查看答案](https://articles.zsxq.com/id_vtkf1m0gq2or.html) + +##### 4.6.2 问答系统工具篇 常见面试篇 + +- [Faiss 常见面试篇](NLPinterview/QA/Faiss/) - 一、动机篇 - 1.1 传统的相似度算法所存在的问题? - 二、介绍篇 @@ -1021,9 +522,9 @@ - 四、 Faiss 对比篇 - 4.1 sklearn cosine_similarity 和 Faiss 哪家强 -#### 4.6 [【关于 对话系统】那些你不知道的事](NLPinterview/DialogueSystem/) +#### 4.7 对话系统 常见面试篇 -- [【关于 对话系统】那些你不知道的事](NLPinterview/DialogueSystem/) +- [对话系统 常见面试篇](https://articles.zsxq.com/id_kz2t0faje3jw.html) - 一、对话系统 介绍篇 - 1.1 对话系统有哪几种? - 1.2 这几种对话系统的区别? @@ -1050,179 +551,336 @@ - 3.6.1 NLG(自然语言生成)是什么? - 3.6.2 NLG(自然语言生成)的输入输出是什么? - 3.6.3 NLG(自然语言生成)的实现方式? -- [【关于 RASA】那些你不知道的事](NLPinterview/DialogueSystem/Rasa/) - -#### 4.7 [【关于 知识图谱】那些你不知道的事](NLPinterview/KG/) - -##### 4.7.1 [【关于 知识图谱】 那些你不知道的事](NLPinterview/KG/) - -- [【关于 知识图谱】 那些你不知道的事](NLPinterview/KG/) - - 一、知识图谱简介 - - 1.1 引言 - - 1.2 什么是知识图谱呢? - - 1.2.1 什么是图(Graph)呢? - - 1.2.2 什么是 Schema 呢? - - 1.3 知识图谱的类别有哪些? - - 1.4 知识图谱的价值在哪呢? - - 二、怎么构建知识图谱呢? - - 2.1 知识图谱的数据来源于哪里? - - 2.2 信息抽取的难点在哪里? - - 2.3 构建知识图谱所涉及的技术? - - 2.4、知识图谱的具体构建技术是什么? - - 2.4.1 实体命名识别(Named Entity Recognition) - - 2.4.2 关系抽取(Relation Extraction) - - 2.4.3 实体统一(Entity Resolution) - - 2.4.4 指代消解(Disambiguation) - - 三、知识图谱怎么存储? - - 四、知识图谱可以做什么? - - 参考资料 - -##### 4.7.2 [【关于 KBQA】那些你不知道的事](NLPinterview/KG/KBQA/) - -- [【关于 KBQA】那些你不知道的事](NLPinterview/KG/KBQA/) - - 一、基于词典和规则的方法 - - 1.1 介绍 - - 1.1.1 开源知识图谱 - - 1.1.2 代表项目 - - 1.2 流程 - - 1.2.1. 句子输入 - - 1.2.2. 问句解析 - - 1.2.3. 查询语句生成 - - 1.2.4. 查询数据库和结果生成 - - 二、基于信息抽取的方法 - - 2.1 介绍 - - 2.1.1 开源知识图谱介绍 - - 2.1.2 评测标准 - - 2.2 流程 - - 2.2.1. 分类单跳和多跳问句 - - 2.2.2. 分类链式问句(二分类) - - 2.2.3. 主谓宾分类(三分类) - - 2.2.4. 实体提及(mention)识别 - - 2.2.5. 关系分类 (语义相似度计算,二分类问题) - - 2.2.6. 实体链指 【实体消歧】 - - 2.2.7. 候选查询路径生成及文本匹配 - - 2.2.8. 实体桥接及答案检索 - -##### 4.7.3 [【关于 Neo4j】那些你不知道的事](NLPinterview/KG/neo4j/) - -- [【关于 Neo4j】那些你不知道的事](NLPinterview/KG/neo4j/) - - 一、Neo4J 介绍与安装 - - 1.1 引言 - - 1.2 Neo4J 怎么下载? - - 1.3 Neo4J 怎么安装? - - 1.4 Neo4J Web 界面 介绍 - - 1.5 Cypher查询语言是什么? - - 二、Neo4J 增删查改篇 - - 2.1 引言 - - 2.2 Neo4j 怎么创建节点? - - 2.3 Neo4j 怎么创建关系? - - 2.4 Neo4j 怎么创建 出生地关系? - - 2.5 Neo4j 怎么查询? - - 2.6 Neo4j 怎么删除和修改? - - 三、如何利用 Python 操作 Neo4j 图数据库? - - 3.1 neo4j模块:执行CQL ( cypher ) 语句是什么? - - 3.2 py2neo模块是什么? - - 四、数据导入 Neo4j 图数据库篇 - - 参考资料 - -#### 4.8 [【关于 文本摘要】 那些你不知道的事](NLPinterview/summary/) - -- [【关于 文本摘要】 那些你不知道的事](NLPinterview/summary/) + +> [点击查看答案](https://articles.zsxq.com/id_kz2t0faje3jw.html) + +#### 4.8 知识图谱 常见面试篇 + +##### 4.8.1 [知识图谱 常见面试篇](https://articles.zsxq.com/id_360j8cpd0shj.html) + +- 一、知识图谱简介 + - 1.1 引言 + - 1.2 什么是知识图谱呢? + - 1.2.1 什么是图(Graph)呢? + - 1.2.2 什么是 Schema 呢? + - 1.3 知识图谱的类别有哪些? + - 1.4 知识图谱的价值在哪呢? +- 二、怎么构建知识图谱呢? + - 2.1 知识图谱的数据来源于哪里? + - 2.2 信息抽取的难点在哪里? + - 2.3 构建知识图谱所涉及的技术? + - 2.4、知识图谱的具体构建技术是什么? + - 2.4.1 实体命名识别(Named Entity Recognition) + - 2.4.2 关系抽取(Relation Extraction) + - 2.4.3 实体统一(Entity Resolution) + - 2.4.4 指代消解(Disambiguation) +- 三、知识图谱怎么存储? +- 四、知识图谱可以做什么? + +> [点击查看答案](https://articles.zsxq.com/id_360j8cpd0shj.html) + +##### 4.8.2 [KBQA 常见面试篇](https://articles.zsxq.com/id_u6seb5h3pnof.html) + +- 一、基于词典和规则的方法 + - 基于词典和规则的方法 实现 KBQA? + - 基于词典和规则的方法 实现 KBQA 流程? +- 二、基于信息抽取的方法 + - 基于信息抽取的方法 实现 KBQA 流程? + +> [点击查看答案](https://articles.zsxq.com/id_u6seb5h3pnof.html) + +##### 4.8.3 [Neo4j 常见面试篇](https://articles.zsxq.com/id_w6uxxvpj9fl0.html) + +- 一、Neo4J 介绍与安装 + - 1.1 引言 + - 1.2 Neo4J 怎么下载? + - 1.3 Neo4J 怎么安装? + - 1.4 Neo4J Web 界面 介绍 + - 1.5 Cypher查询语言是什么? +- 二、Neo4J 增删查改篇 + - 2.1 引言 + - 2.2 Neo4j 怎么创建节点? + - 2.3 Neo4j 怎么创建关系? + - 2.4 Neo4j 怎么创建 出生地关系? + - 2.5 Neo4j 怎么查询? + - 2.6 Neo4j 怎么删除和修改? +- 三、如何利用 Python 操作 Neo4j 图数据库? + - 3.1 neo4j模块:执行CQL ( cypher ) 语句是什么? + - 3.2 py2neo模块是什么? +- 四、数据导入 Neo4j 图数据库篇 + +> [点击查看答案](https://articles.zsxq.com/id_w6uxxvpj9fl0.html) + +#### 4.9 [文本摘要 常见面试篇](https://articles.zsxq.com/id_8ndah4nf876w.html) + +- 一、动机篇 + - 1.1 什么是文本摘要? + - 1.2 文本摘要技术有哪些类型? +- 二、抽取式摘要篇 + - 2.1 抽取式摘要是怎么做的? + - 2.1.1 句子重要性评估算法有哪些? + - 2.1.2 基于约束的摘要生成方法有哪些? + - 2.1.3 TextTeaser算法是怎么抽取摘要的? + - 2.1.4 TextRank算法是怎么抽取摘要的? + - 2.2 抽取式摘要的可读性问题是什么? +- 三、压缩式摘要篇 + - 3.1 压缩式摘要是怎么做的? +- 四、生成式摘要篇 + - 4.1 生成式摘要是怎么做的? + - 4.2 生成式摘要存在哪些问题? + - 4.3 Pointer-generator network解决了什么问题? +- 五、摘要质量评估方法 + - 5.1 摘要质量的评估方法有哪些类型? + - 5.2 什么是ROUGE? + - 5.3 几种ROUGE指标之间的区别是什么? + - 5.4 BLEU和ROUGE有什么不同? + +> [点击查看答案](https://articles.zsxq.com/id_8ndah4nf876w.html) + +#### 4.10 [文本纠错篇 常见面试篇](https://articles.zsxq.com/id_2retvz8l0es7.html) + +- 一、介绍篇 + - 1.1 什么是文本纠错? + - 1.2 常见的文本错误类型? + - 1.3 文本纠错 常用方法? +- 二、pipeline 方法 介绍篇 + - pipeline 中的 错误检测 如何实现? + - pipeline 中的 候选召回 如何实现? + - pipeline 中的 纠错排序 如何实现? + - pipeline 中的 ASR 回显优化 如何实现? + +> [点击查看答案](https://articles.zsxq.com/id_2retvz8l0es7.html) + +#### 4.11 [文本摘要 常见面试篇](https://articles.zsxq.com/id_8ndah4nf876w.html) + +- 一、动机篇 + - 1.1 什么是文本摘要? + - 1.2 文本摘要技术有哪些类型? +- 二、抽取式摘要篇 + - 2.1 抽取式摘要是怎么做的? + - 2.1.1 句子重要性评估算法有哪些? + - 2.1.2 基于约束的摘要生成方法有哪些? + - 2.1.3 TextTeaser算法是怎么抽取摘要的? + - 2.1.4 TextRank算法是怎么抽取摘要的? + - 2.2 抽取式摘要的可读性问题是什么? +- 三、压缩式摘要篇 + - 3.1 压缩式摘要是怎么做的? +- 四、生成式摘要篇 + - 4.1 生成式摘要是怎么做的? + - 4.2 生成式摘要存在哪些问题? + - 4.3 Pointer-generator network解决了什么问题? +- 五、摘要质量评估方法 + - 5.1 摘要质量的评估方法有哪些类型? + - 5.2 什么是ROUGE? + - 5.3 几种ROUGE指标之间的区别是什么? + - 5.4 BLEU和ROUGE有什么不同? + +> [点击查看答案](https://articles.zsxq.com/id_8ndah4nf876w.html) + +#### 4.12 文本生成 常见面试篇 + +- [生成模型的解码方法 常见面试篇](https://articles.zsxq.com/id_m3wckj5bhgu8.html) + - 什么是生成模型? + - 介绍一下 基于搜索的解码方法? + - 介绍一下 基于采样的解码方法? + +> [点击查看答案](https://articles.zsxq.com/id_m3wckj5bhgu8.html) + +## 三、深度学习算法篇 常见面试篇 + +- [CNN 常见面试篇](https://articles.zsxq.com/id_b3xp06wevahd.html) - 一、动机篇 - - 1.1 什么是文本摘要? - - 1.2 文本摘要技术有哪些类型? - - 二、抽取式摘要篇 - - 2.1 抽取式摘要是怎么做的? - - 2.1.1 句子重要性评估算法有哪些? - - 2.1.2 基于约束的摘要生成方法有哪些? - - 2.1.3 TextTeaser算法是怎么抽取摘要的? - - 2.1.4 TextRank算法是怎么抽取摘要的? - - 2.2 抽取式摘要的可读性问题是什么? - - 三、压缩式摘要篇 - - 3.1 压缩式摘要是怎么做的? - - 四、生成式摘要篇 - - 4.1 生成式摘要是怎么做的? - - 4.2 生成式摘要存在哪些问题? - - 4.3 Pointer-generator network解决了什么问题? - - 五、摘要质量评估方法 - - 5.1 摘要质量的评估方法有哪些类型? - - 5.2 什么是ROUGE? - - 5.3 几种ROUGE指标之间的区别是什么? - - 5.4 BLEU和ROUGE有什么不同? - -#### 4.9 [【关于 知识表示学习】那些你不知道的事](NLPinterview/KnowledgeRepresentation/) - -- [【关于 数据挖掘】那些你不知道的事](NLPinterview/KnowledgeRepresentation/) - - 一. 理论及研究现状 - - 1.1 理论 - - 1.1.1 知识表示学习的基本概念 - - 1.1.2 知识表示的理论基础 - - 1.1.3 知识表示学习的典型应用 - - 1.1.4 知识表示学习的主要优点 - - 1.2 研究现状 - - 二. 常见面试题 - - 2.1 Q: 知识表示相对于one-hot表示的优势是什么? - - 2.2 Q:有哪些文本表示模型?它们各有什么优缺点? - - 2.3 Q:word2vec与LDA模型之间的区别和联系? - - 2.4 Q:介绍下词向量空间中的平移不变现象? - - 2.5 Q:简要介绍下TransE模型的思想及优点? - - 2.6 Q:解释一下为什么TransE模型用于复杂关系建模时的性能较差? - - 2.7 Q:简述TransH、TransR和TransD模型的思想 - - 2.8 Q:简述deepwalk和node2vec模型的思想及其优点 - - 2.9 Q:简述Line模型的思想 - - 参考文献 - - -#### 4.10 [【关于 数据挖掘】那些你不知道的事](NLPinterview/TextMining/) - -- [【关于 数据挖掘】那些你不知道的事](NLPinterview/TextMining/) - - 一、什么是文本挖掘? - - 二、文本挖掘的作用是什么? - - 三、文本预处理 - - 3.1 中文分词 - - 3.2 去停用词 - - 3.3 低频词和高频词处理 - - 3.4 计算 N-gram 【这里采用 Bigrams】 - - 四、文本挖掘 - - 4.1 关键词提取 - - 4.2 LDA 主题模型分析 - - 4.3 情绪分析&LDA主题模型交叉分析 - - 4.4 ATM 模型 - - 4.5 词向量训练及关联词分析 - - 4.6 词聚类与词分类 - - 4.7 文本分类 - - 4.8 文本聚类 - - 4.9 信息检索 - -### 五、[【关于 NLP 技巧】那些你不知道的事](Trick) - -#### 5.1 [【关于 少样本问题】那些你不知道的事](Trick/SmallSampleProblem/) - -- [【关于 EDA 】那些你不知道的事](Trick/SmallSampleProblem/EDA/eda.md) + - 二、CNN 卷积层篇 + - 2.1 卷积层的本质是什么? + - 2.2 CNN 卷积层与全连接层的联系? + - 2.3 channel的含义是什么? + - 三、CNN 池化层篇 + - 3.1 池化层针对区域是什么? + - 3.2 池化层的种类有哪些? + - 3.3 池化层的作用是什么? + - 3.4 池化层 反向传播 是什么样的? + - 3.5 mean pooling 池化层 反向传播 是什么样的? + - 3.6 max pooling 池化层 反向传播 是什么样的? + - 四、CNN 整体篇 + - 4.1 CNN 的流程是什么? + - 4.2 CNN 的特点是什么? + - 4.3 卷积神经网络为什么会具有平移不变性? + - 4.4 卷积神经网络中im2col是如何实现的? + - 4.5 CNN 的局限性是什么? + - 五、Iterated Dilated CNN 篇 + - 5.1 什么是 Dilated CNN 空洞卷积? + - 5.2 什么是 Iterated Dilated CNN? + - 六、反卷积 篇 + - 6.1 解释反卷积的原理和用途? + +> [点击查看答案](https://articles.zsxq.com/id_b3xp06wevahd.html) + +- [RNN 常见面试篇](https://articles.zsxq.com/id_2et1rj7sn8c4.html) + - 一、RNN 篇 + - 1.2 为什么需要 RNN? + - 1.2 RNN 结构是怎么样的? + - 1.3 RNN 前向计算公式? + - 1.4 RNN 存在什么问题? + - 二、长短时记忆网络(Long Short Term Memory Network, LSTM) 篇 + - 2.1 为什么 需要 LSTM? + - 2.2 LSTM 的结构是怎么样的? + - 2.3 LSTM 如何缓解 RNN 梯度消失和梯度爆炸问题? + - 2.3 LSTM 的流程是怎么样的? + - 2.4 LSTM 中激活函数区别? + - 2.5 LSTM的复杂度? + - 2.6 LSTM 存在什么问题? + - 三、GRU (Gated Recurrent Unit) + - 3.1 为什么 需要 GRU? + - 3.2 GRU 的结构是怎么样的? + - 3.3 GRU 的前向计算? + - 3.4 GRU 与其他 RNN系列模型的区别? + - 四、RNN系列模型篇 + - 4.1 RNN系列模型 有什么特点? + +> [点击查看答案](https://articles.zsxq.com/id_2et1rj7sn8c4.html) + +- [Attention 常见面试篇](https://articles.zsxq.com/id_hs7zqva04b9g.html) + - 一、seq2seq 篇 + - 1.1 seq2seq (Encoder-Decoder)是什么? + - 1.2 seq2seq 中 的 Encoder 怎么样? + - 1.3 seq2seq 中 的 Decoder 怎么样? + - 1.4 在 数学角度上 的 seq2seq ,你知道么? + - 1.5 seq2seq 存在 什么 问题? + - 二、Attention 篇 + - 2.1 什么是 Attention? + - 2.2 为什么引入 Attention机制? + - 2.3 Attention 有什么作用? + - 2.4 Attention 流程是怎么样? + - 步骤一 执行encoder (与 seq2seq 一致) + - 步骤二 计算对齐系数 a + - 步骤三 计算上下文语义向量 C + - 步骤四 更新decoder状态 + - 步骤五 计算输出预测词 + - 2.5 Attention 的应用领域有哪些? + - 三、Attention 变体篇 + - 3.1 Soft Attention 是什么? + - 3.2 Hard Attention 是什么? + - 3.3 Global Attention 是什么? + - 3.4 Local Attention 是什么? + - 3.5 self-attention 是什么? + +> [点击查看答案](https://articles.zsxq.com/id_hs7zqva04b9g.html) + +- [生成对抗网络 GAN 常见面试篇](https://articles.zsxq.com/id_s5wm5safsqse.html) + - 一、动机 + - 二、介绍篇 + - 2.1 GAN 的基本思想 + - 2.2 GAN 基本介绍 + - 2.2.1 GAN 的基本结构 + - 2.2.2 GAN 的基本思想 + - 三、训练篇 + - 3.1 生成器介绍 + - 3.2 判别器介绍 + - 3.3 训练过程 + - 3.4 训练所涉及相关理论基础 + - 四、总结 + +> [点击查看答案](https://articles.zsxq.com/id_s5wm5safsqse.html) + +### 3.1 Transformer 常见面试篇 + +- [Transformer 常见面试篇](https://articles.zsxq.com/id_8nv1s9vsr2ow.html) - 一、动机篇 - - 1.1 什么是 数据增强? - - 1.2 为什么需要 数据增强? - - 二、常见的数据增强方法篇 - - 2.1 词汇替换篇 - - 2.1.1 什么是基于词典的替换方法? - - 2.1.2 什么是基于词向量的替换方法? - - 2.1.3 什么是基于 MLM 的替换方法? - - 2.1.4 什么是基于 TF-IDF 的词替换? - - 2.2 词汇插入篇 - - 2.2.1 什么是随机插入法? - - 2.3 词汇交换篇 - - 2.3.1 什么是随机交换法? - - 2.4 词汇删除篇 - - 2.4.1 什么是随机删除法? - - 2.5 回译篇 - - 2.5.1 什么是回译法? - - 2.6 交叉增强篇 - - 2.6.1 什么是 交叉增强篇 - - 2.7 语法树篇 - - 2.7.1 什么是语法树操作? - - 2.8 对抗增强篇 - - 2.8.1 什么是对抗增强? -- [【关于 主动学习 】那些你不知道的事](Trick/SmallSampleProblem/activeLearn/readme.md) + - 1.1 为什么要有 Transformer? + - 1.2 Transformer 作用是什么? + - 二、整体结构篇 + - 2.1 Transformer 整体结构是怎么样? + - 2.2 Transformer-encoder 结构怎么样? + - 2.3 Transformer-decoder 结构怎么样? + - 三、模块篇 + - 3.1 self-attention 模块 + - 3.1.1 传统 attention 是什么? + - 3.1.2 为什么 会有self-attention? + - 3.1.3 self-attention 的核心思想是什么? + - 3.1.4 self-attention 的目的是什么? + - 3.1.5 self-attention 的怎么计算的? + - 3.1.6 self-attention 为什么Q和K使用不同的权重矩阵生成,为何不能使用同一个值进行自身的点乘? + - 3.1.7 为什么采用点积模型的 self-attention 而不采用加性模型? + - 3.1.8 Transformer 中在计算 self-attention 时为什么要除以 $\sqrt{d}$? + - 3.1.9 self-attention 如何解决长距离依赖问题? + - 3.1.10 self-attention 如何并行化? + - 3.2 multi-head attention 模块 + - 3.2.1 multi-head attention 的思路是什么样? + - 3.2.2 multi-head attention 的步骤是什么样? + - 3.2.3 Transformer为何使用多头注意力机制?(为什么不使用一个头) + - 3.2.4 为什么在进行多头注意力的时候需要对每个head进行降维? + - 3.2.5 multi-head attention 代码介绍 + - 3.3 位置编码(Position encoding)模块 + - 3.3.1 为什么要 加入 位置编码(Position encoding) ? + - 3.3.2 位置编码(Position encoding)的思路是什么 ? + - 3.3.3 位置编码(Position encoding)的作用是什么 ? + - 3.3.4 位置编码(Position encoding)的步骤是什么 ? + - 3.3.5 Position encoding为什么选择相加而不是拼接呢? + - 3.3.6 Position encoding和 Position embedding的区别? + - 3.3.7 为何17年提出Transformer时采用的是 Position Encoder 而不是Position Embedding?而Bert却采用的是 Position Embedding ? + - 3.3.8 位置编码(Position encoding)的代码介绍 + - 3.4 残差模块模块 + - 3.4.1 为什么要 加入 残差模块? + - 3.5 Layer normalization 模块 + - 3.5.1 为什么要 加入 Layer normalization 模块? + - 3.5.2 Layer normalization 模块的是什么? + - 3.5.3 Batch normalization 和 Layer normalization 的区别? + - 3.5.4 Transformer 中为什么要舍弃 Batch normalization 改用 Layer normalization 呢? + - 3.5.5 Layer normalization 模块代码介绍 + - 3.6 Mask 模块 + - 3.6.1 什么是 Mask? + - 3.6.2 Transformer 中用到 几种 Mask? + - 3.6.3 能不能介绍一下 Transformer 中用到几种 Mask? + +> [点击查看答案](https://articles.zsxq.com/id_8nv1s9vsr2ow.html) + +- [【关于 Transformer 问题及改进】那些你不知道的事](DeepLearningAlgorithm/transformer/transformer_error.md) + - 一、Transformer 问题篇 + - 1.1 既然 Transformer 怎么牛逼,是否还存在一些问题? + - 二、每个问题的解决方法是什么? + - 2.1 问题一:Transformer 不能很好的处理超长输入问题 + - 2.1.1 Transformer 固定了句子长度? + - 2.1.2 Transformer 固定了句子长度 的目的是什么? + - 2.1.3 Transformer 针对该问题的处理方法? + - 2.2 问题二:Transformer 方向信息以及相对位置 的 缺失 问题 + - 2.3 问题三:缺少Recurrent Inductive Bias + - 问题四:问题四:Transformer是非图灵完备的: 非图灵完备通俗的理解,就是无法解决所有的问题 + - 问题五:transformer缺少conditional computation; + - 问题六:transformer 时间复杂度 和 空间复杂度 过大问题; + +## 五、NLP 技巧面 + +### 5.1 少样本问题面 + +#### 5.1.1 [数据增强(EDA) 面试篇](https://articles.zsxq.com/id_e043c3q53sbc.html) + +- 一、动机篇 + - 1.1 什么是 数据增强? + - 1.2 为什么需要 数据增强? +- 二、常见的数据增强方法篇 + - 2.1 词汇替换篇 + - 2.1.1 什么是基于词典的替换方法? + - 2.1.2 什么是基于词向量的替换方法? + - 2.1.3 什么是基于 MLM 的替换方法? + - 2.1.4 什么是基于 TF-IDF 的词替换? + - 2.2 词汇插入篇 + - 2.2.1 什么是随机插入法? + - 2.3 词汇交换篇 + - 2.3.1 什么是随机交换法? + - 2.4 词汇删除篇 + - 2.4.1 什么是随机删除法? + - 2.5 回译篇 + - 2.5.1 什么是回译法? + - 2.6 交叉增强篇 + - 2.6.1 什么是 交叉增强篇 + - 2.7 语法树篇 + - 2.7.1 什么是语法树操作? + - 2.8 对抗增强篇 + - 2.8.1 什么是对抗增强? + +> [点击查看答案](https://articles.zsxq.com/id_e043c3q53sbc.html) + +#### 5.1.2 [主动学习 面试篇](https://articles.zsxq.com/id_6sj7him8b4p1.html) - 一、动机篇 - 1.1 主动学习是什么? - 1.2 为什么需要主动学习? @@ -1235,56 +893,428 @@ - 3.2.1 测试集内选取“信息”量最大的数据标记 - 3.2.2 依赖不确定度的样本选取策略(Uncertainty Sampling, US) - 3.2.3 基于委员会查询的方法(Query-By-Committee,QBC) -- [【关于 数据增强 之 对抗训练】 那些你不知道的事](Trick/SmallSampleProblem/AdversarialTraining/AdversarialTraining.md) - - 一、介绍篇 - - 1.1 什么是 对抗训练 ? - - 1.2 为什么 对抗训练 能够 提高模型效果? - - 1.3 对抗训练 有什么特点? - - 1.4 对抗训练 的作用? - - 二、概念篇 - - 2.1 对抗训练的基本概念? - - 2.2 如何计算扰动? - - 2.3 如何优化? - - 三、实战篇 - - 3.1 NLP 中经典对抗训练 之 Fast Gradient Method(FGM) - - 3.2 NLP 中经典对抗训练 之 Projected Gradient Descent(PGD) - -#### 5.2 [【关于 脏数据】那些你不知道的事](Trick/noisy_label_learning/) - -- [【关于 “脏数据”处理】那些你不知道的事](Trick/noisy_label_learning/) - - 一、动机 - - 1.1 何为“脏数据”? - - 1.2 “脏数据” 会带来什么后果? - - 二、“脏数据” 处理篇 - - 2.1 “脏数据” 怎么处理呢? - - 2.2 置信学习方法篇 - - 2.2.1 什么是 置信学习方法? - - 2.2.2 置信学习方法 优点? - - 2.2.3 置信学习方法 怎么做? - - 2.2.4 置信学习方法 怎么用?有什么开源框架? - - 2.2.5 置信学习方法 的工作原理? -#### 5.3 [【关于 炼丹炉】那些你不知道的事](Trick/) +> [点击查看答案](https://articles.zsxq.com/id_6sj7him8b4p1.html) + +#### 5.1.3 [数据增强 之 对抗训练 面试篇](https://articles.zsxq.com/id_n5ugs6lig5td.html) + +- 一、介绍篇 + - 1.1 什么是 对抗训练 ? + - 1.2 为什么 对抗训练 能够 提高模型效果? + - 1.3 对抗训练 有什么特点? + - 1.4 对抗训练 的作用? +- 二、概念篇 + - 2.1 对抗训练的基本概念? + - 2.2 如何计算扰动? + - 2.3 如何优化? +- 三、实战篇 + - 3.1 NLP 中经典对抗训练 之 Fast Gradient Method(FGM) + - 3.2 NLP 中经典对抗训练 之 Projected Gradient Descent(PGD) + +> [点击查看答案](https://articles.zsxq.com/id_n5ugs6lig5td.html) + +### 5.2 [“脏数据”处理 面试篇](https://articles.zsxq.com/id_o903pl26wtgu.html) + +- 一、动机 + - 1.1 何为“脏数据”? + - 1.2 “脏数据” 会带来什么后果? +- 二、“脏数据” 处理篇 + - 2.1 “脏数据” 怎么处理呢? + - 2.2 置信学习方法篇 + - 2.2.1 什么是 置信学习方法? + - 2.2.2 置信学习方法 优点? + - 2.2.3 置信学习方法 怎么做? + - 2.2.4 置信学习方法 怎么用?有什么开源框架? + - 2.2.5 置信学习方法 的工作原理? + +> [点击查看答案](https://articles.zsxq.com/id_o903pl26wtgu.html) + +### 5.3 [batch_size设置 面试篇](https://articles.zsxq.com/id_64423hvlqv6w.html) + +- 一、训练模型时,batch_size的设置,学习率的设置? -- [【关于 batch_size设置】那些你不知道的事](Trick/batch_size/) - - 一、训练模型时,batch_size的设置,学习率的设置? +> [点击查看答案](https://articles.zsxq.com/id_64423hvlqv6w.html) -#### 5.4 [【关于 早停法 EarlyStopping 】那些你不知道的事](Trick/EarlyStopping/) +### 5.4 [早停法 EarlyStopping 面试篇](https://articles.zsxq.com/id_u31j73pqq773.html) -- [【关于 早停法 EarlyStopping 】那些你不知道的事](Trick/EarlyStopping/) - - 一、 为什么要用 早停法 EarlyStopping? - - 二、 早停法 EarlyStopping 是什么? - - 三、早停法 torch 版本怎么实现? +- 一、 为什么要用 早停法 EarlyStopping? +- 二、 早停法 EarlyStopping 是什么? +- 三、早停法 torch 版本怎么实现? -#### 5.5 [【关于 标签平滑法 LabelSmoothing 】那些你不知道的事](Trick/LabelSmoothing/) +> [点击查看答案](https://articles.zsxq.com/id_u31j73pqq773.html) -- [【关于 标签平滑法 LabelSmoothing 】那些你不知道的事](Trick/LabelSmoothing?/) - - 一、为什么要有 标签平滑法 LabelSmoothing? - - 二、 标签平滑法 是什么? - - 三、 标签平滑法 torch 怎么复现? +### 5.5 [标签平滑法 LabelSmoothing 面试篇](https://articles.zsxq.com/id_87tkbsbcwk1d.html) +- 一、为什么要有 标签平滑法 LabelSmoothing? +- 二、 标签平滑法 是什么? +- 三、 标签平滑法 torch 怎么复现? -### 六、[【关于 Python 】那些你不知道的事](python/) +> [点击查看答案](https://articles.zsxq.com/id_87tkbsbcwk1d.html) + +### 5.6 Bert Trick 面试篇 + +#### 5.6.1 [Bert 未登录词处理 面试篇](https://articles.zsxq.com/id_3gbrn1bn19am.html) + +- 什么是 Bert 未登录词? +- Bert 未登录词 如何处理? +- Bert 未登录词各种处理方法 有哪些优缺点? + +> [点击查看答案](https://articles.zsxq.com/id_3gbrn1bn19am.html) + +#### 5.6.2 [BERT在输入层引入额外特征 面试篇](https://articles.zsxq.com/id_gd208jzrpafg.html) + +- BERT在输入层如何引入额外特征? + +> [点击查看答案](https://articles.zsxq.com/id_gd208jzrpafg.html) + +#### 5.6.3 [关于BERT 继续预训练 面试篇](https://articles.zsxq.com/id_03lsi10e8iim.html) + +- 什么是 继续预训练? +- 为什么会存在 【数据分布/领域差异】大 问题? +- 如何进行 继续预训练? +- 还有哪些待解决问题? +- 训练数据问题解决方案? +- 知识缺乏问题解决方案? +- 知识理解缺乏问题解决方案? + +> [点击查看答案](https://articles.zsxq.com/id_03lsi10e8iim.html) + +#### 5.6.4 [BERT如何处理篇章级长文本 面试篇](https://articles.zsxq.com/id_e5aaclwgbwue.html) + +- 为什么 Bert 不能 处理 长文本? +- BERT 有哪些处理篇章级长文本? + +> [点击查看答案](https://articles.zsxq.com/id_e5aaclwgbwue.html) + +## 六、 Prompt Tuning 面试篇 + +### 6.1 [Prompt 面试篇](https://articles.zsxq.com/id_0dwe6olrn4uw.html) + +1. 什么是prompt? +2. 如何设计prompt? +3. prompt进阶——如何自动学习prompt? +4. Prompt 有哪些关键要点? +5. Prompt 如何实现? + +> [点击查看答案](https://articles.zsxq.com/id_0dwe6olrn4uw.html) + +### 6.2 [Prompt 文本生成 面试篇](https://articles.zsxq.com/id_po1gopdolinx.html) + +1. Prompt之文本生成评估手段有哪些? +2. Prompt文本生成具体任务有哪些? + +> [点击查看答案](https://articles.zsxq.com/id_po1gopdolinx.html) + +### 6.3 [LoRA 面试篇](https://articles.zsxq.com/id_da8pumsjwbqw.html) + +1. 什么是lora? +2. lora 是 怎么做的呢? +3. lora 为什么可以这样做? +4. 用一句话描述 lora? +5. lora 优点是什么? +6. lora 缺点是什么? +7. lora 如何实现? + +> [点击查看答案](https://articles.zsxq.com/id_da8pumsjwbqw.html) + +### 6.4 [PEFT(State-of-the-art Parameter-Efficient Fine-Tuning)面试篇](https://articles.zsxq.com/id_2r4w85eov81e.html) + +- 一、微调 Fine-tuning 篇 + - 1.1 什么是 微调 Fine-tuning ? + - 1.2 微调 Fine-tuning 基本思想是什么? +- 二、轻度微调(lightweight Fine-tuning)篇 + - 2.1 什么是 轻度微调(lightweight Fine-tuning)? +- 三、适配器微调(Adapter-tuning)篇 + - 3.1 什么 是 适配器微调(Adapter-tuning)? + - 3.2 适配器微调(Adapter-tuning)变体有哪些? +- 四、提示学习(Prompting)篇 + - 4.1 什么是 提示学习(Prompting)? + - 4.2 提示学习(Prompting)的目的是什么? + - 4.3 提示学习(Prompting) 代表方法有哪些? + - 4.3.1 前缀微调(Prefix-tining)篇 + - 4.3.1.1 什么是 前缀微调(Prefix-tining)? + - 4.3.1.2 前缀微调(Prefix-tining)的核心是什么? + - 4.3.1.3 前缀微调(Prefix-tining)的技术细节有哪些? + - 4.3.1.4 前缀微调(Prefix-tining)的优点是什么? + - 4.3.1.5 前缀微调(Prefix-tining)的缺点是什么? + - 4.3.2 指示微调(Prompt-tuning)篇 + - 4.3.2.1 什么是 指示微调(Prompt-tuning)? + - 4.3.2.2 指示微调(Prompt-tuning)的核心思想? + - 4.3.2.3 指示微调(Prompt-tuning)的 优点/贡献 是什么? + - 4.3.2.4 指示微调(Prompt-tuning)的 缺点 是什么? + - 4.3.2.5 指示微调(Prompt-tuning)与 Prefix-tuning 区别 是什么? + - 4.3.2.6 指示微调(Prompt-tuning)与 fine-tuning 区别 是什么? + - 4.3.3 P-tuning 篇 + - 4.3.3.1 P-tuning 动机是什么? + - 4.3.3.2 P-tuning 核心思想是什么? + - 4.3.3.3 P-tuning 做了哪些改进? + - 4.3.3.4 P-tuning 有哪些优点/贡献? + - 4.3.3.5 P-tuning 有哪些缺点? + - 4.3.4 P-tuning v2 篇 + - 4.3.4.1 为什么需要 P-tuning v2? + - 4.3.4.2 P-tuning v2 是什么? + - 4.3.4.3 P-tuning v2 有哪些优点? + - 4.3.4.4 P-tuning v2 有哪些缺点? + - 4.3.5 PPT 篇 + - 4.3.5.1 为什么需要 PPT ? + - 4.3.5.2 PPT 核心思想 是什么? + - 4.3.5.3 PPT 具体做法是怎么样? + - 4.3.5.4 常用的soft prompt初始化方法? + - 4.3.5.5 PPT 的优点是什么? + - 4.3.5.6 PPT 的缺点是什么? + - 4.4 提示学习(Prompting) 优点 是什么? + - 4.5 提示学习(Prompting) 本质 是什么? +- 五、指令微调(Instruct-tuning)篇 + - 5.1 为什么需要 指令微调(Instruct-tuning)? + - 5.2 指令微调(Instruct-tuning)是什么? + - 5.3 指令微调(Instruct-tuning)的优点是什么? + - 5.4 指令微调(Instruct-tuning) vs 提升学习(Prompting)? + - 5.5 指令微调(Instruct-tuning) vs 提升学习(Prompting) vs Fine-tuning? +- 六、指令提示微调(Instruct Prompt tuning)篇 + - 6.1 为什么需要 指令微调(Instruct-tuning)? + - 6.2 指令微调(Instruct-tuning) 是什么? + - 6.3 指令微调(Instruct-tuning) 在不同任务上性能? +- 七、self-instruct篇 + - 7.1 什么是 self-instruct? +- 八、Chain-of-Thought 篇 + - 8.1 为什么需要 Chain-of-Thought ? + - 8.2 什么是 Chain-of-Thought ? + - 8.3 Chain-of-Thought 的思路是怎么样的? + - 8.4 Chain-of-Thought 的优点是什么? + - 8.5 为什么 chain-of-thought 会成功? +- 九、LoRA 篇 + - 9.1 LoRA 篇 + - 9.1.1 LoRA 核心思想是什么? + - 9.1.2 LoRA 具体思路是什么? + - 9.1.3 LoRA 优点是什么? + - 9.1.4 LoRA 缺点是什么? + - 9.2 AdaLoRA 篇 + - 9.2.1 AdaLoRA 核心思想是什么? + - 9.2.2 AdaLoRA 实现思路是什么? + - 9.3 DyLoRA 篇 + - 9.3.1 AdaLoRA 动机是什么? + - 9.3.2 AdaLoRA 核心思想是什么? + - 9.3.3 AdaLoRA 优点是什么? +- 十、BitFit 篇 + - 10.1 AdaLoRA 核心思想是什么? + - 10.2 AdaLoRA 优点是什么? + - 10.3 AdaLoRA 缺点是什么? + +> [点击查看答案](https://articles.zsxq.com/id_2r4w85eov81e.html) + +## 七、LLMs 面试篇 + +### 7.1 [【现在达模型LLM,微调方式有哪些?各有什么优缺点?](https://articles.zsxq.com/id_i6uv0mtg4mah.html) + +- 现在达模型LLM,微调方式有哪些?各有什么优缺点? + +> [点击查看答案](https://articles.zsxq.com/id_i6uv0mtg4mah.html) + +### 7.2 [GLM:ChatGLM的基座模型 常见面试题](https://articles.zsxq.com/id_bwx8btw6h2p1.html) + +- GLM 的 核心是什么? +- GLM 的 模型架构是什么? +- GLM 如何进行 多任务训练? +- 在进行 NLG 时, GLM 如何保证 生成长度的未知性? +- GLM 的 多任务微调方式有什么差异? +- GLM 的 多任务微调方式有什么优点? + +> [点击查看答案](https://articles.zsxq.com/id_bwx8btw6h2p1.html) + +## 一、基础算法 常见面试篇 + +- [过拟合和欠拟合 常见面试篇](https://articles.zsxq.com/id_0xjh0m6e44br.html) + - 一、过拟合和欠拟合 是什么? + - 二、过拟合/高方差(overfiting / high variance)篇 + - 2.1 过拟合是什么及检验方法? + - 2.2 导致过拟合的原因是什么? + - 2.3 过拟合的解决方法是什么? + - 三、欠拟合/高偏差(underfiting / high bias)篇 + - 3.1 欠拟合是什么及检验方法? + - 3.2 导致欠拟合的原因是什么? + - 3.3 过拟合的解决方法是什么? + +> [点击查看答案](https://articles.zsxq.com/id_0xjh0m6e44br.html) + +- [BatchNorm vs LayerNorm 常见面试篇](https://articles.zsxq.com/id_wbep87ht600b.html) + - 一、动机篇 + - 1.1 独立同分布(independent and identically distributed)与白化 + - 1.2 ( Internal Covariate Shift,ICS) + - 1.3 ICS问题带来的后果是什么? + - 二、Normalization 篇 + - 2.1 Normalization 的通用框架与基本思想 + - 三、Batch Normalization 篇 + - 3.1 Batch Normalization(纵向规范化)是什么? + - 3.2 Batch Normalization(纵向规范化)存在什么问题? + - 3.3 Batch Normalization(纵向规范化)适用的场景是什么? + - 3.4 BatchNorm 存在什么问题? + - 四、Layer Normalization(横向规范化) 篇 + - 4.1 Layer Normalization(横向规范化)是什么? + - 4.2 Layer Normalization(横向规范化)有什么用? + - 五、BN vs LN 篇 + - 六、主流 Normalization 方法为什么有效? + +> [点击查看答案](https://articles.zsxq.com/id_wbep87ht600b.html) + +- [激活函数 常见面试篇](BasicAlgorithm/激活函数.md) + - 一、动机篇 + - 1.1 为什么要有激活函数? + - 二、激活函数介绍篇 + - 2.1 sigmoid 函数篇 + - 2.1.1 什么是 sigmoid 函数? + - 2.1.2 为什么选 sigmoid 函数 作为激活函数? + - 2.1.3 sigmoid 函数 有什么缺点? + - 2.2 tanh 函数篇 + - 2.2.1 什么是 tanh 函数? + - 2.2.2 为什么选 tanh 函数 作为激活函数? + - 2.2.3 tanh 函数 有什么缺点? + - 2.3 relu 函数篇 + - 2.3.1 什么是 relu 函数? + - 2.3.2 为什么选 relu 函数 作为激活函数? + - 2.3.3 relu 函数 有什么缺点? + - 三、激活函数选择篇 + + +- [正则化常见面试篇](https://articles.zsxq.com/id_g6mir08c0s8d.html) + - 一、L0,L1,L2正则化 篇 + - 1.1 正则化 是什么? + - 1.2 什么是 L0 正则化 ? + - 1.3 什么是 L1 (稀疏规则算子 Lasso regularization)正则化 ? + - 1.4 什么是 L2 正则化(岭回归 Ridge Regression 或者 权重衰减 Weight Decay)正则化 ? + - 二、对比篇 + - 2.1 什么是结构风险最小化? + - 2.2 从结构风险最小化的角度理解L1和L2正则化 + - 2.3 L1 vs L2 + - 三、dropout 篇 + - 3.1 什么是 dropout? + - 3.2 dropout 在训练和测试过程中如何操作? + - 3.3 dropout 如何防止过拟合? + +> [点击查看答案](https://articles.zsxq.com/id_g6mir08c0s8d.html) + +- [优化算法及函数 常见面试篇](https://articles.zsxq.com/id_hqd9p17b6afk.html) + - 一、动机篇 + - 1.1 为什么需要 优化函数? + - 1.2 优化函数的基本框架是什么? + - 二、优化函数介绍篇 + - 2.1 梯度下降法是什么? + - 2.2 随机梯度下降法是什么? + - 2.3 Momentum 是什么? + - 2.4 SGD with Nesterov Acceleration 是什么? + - 2.5 Adagrad 是什么? + - 2.6 RMSProp/AdaDelta 是什么? + - 2.7 Adam 是什么? + - 2.8 Nadam 是什么? + - 三、优化函数学霸笔记篇 + +> [点击查看答案](https://articles.zsxq.com/id_hqd9p17b6afk.html) + +- [归一化 常见面试篇](https://articles.zsxq.com/id_8iemf392t53n.html) + - 一、动机篇 + - 1.1 为什么要归一化? + - 二、介绍篇 + - 2.1 归一化 有 哪些方法? + - 2.2 归一化 各方法 特点? + - 2.3 归一化 的 意义? + - 三、应用篇 + - 3.1 哪些机器学习算法 需要做 归一化? + - 3.2 哪些机器学习算法 不需要做 归一化? + +> [点击查看答案](https://articles.zsxq.com/id_8iemf392t53n.html) + +- [判别式(discriminative)模型 vs. 生成式(generative)模型 常见面试篇](https://articles.zsxq.com/id_siv7mtg3573r.html) + - 一、判别式模型篇 + - 1.1 什么是判别式模型? + - 1.2 判别式模型是思路是什么? + - 1.3 判别式模型的优点是什么? + - 二、生成式模型篇 + - 2.1 什么是生成式模型? + - 2.2 生成式模型是思路是什么? + - 2.3 生成式模型的优点是什么? + - 2.4 生成式模型的缺点是什么? + +> [点击查看答案](https://articles.zsxq.com/id_siv7mtg3573r.html) + +## 二、机器学习算法篇 常见面试篇 + +- [逻辑回归 常见面试篇](https://articles.zsxq.com/id_98g8ef7zir1q.html) + - 一、介绍篇 + - 1.1什么是逻辑回归 + - 1.2逻辑回归的优势 + - 二、推导篇 + - 2.1逻辑回归推导 + - 2.2求解优化 + +> [点击查看答案](https://articles.zsxq.com/id_98g8ef7zir1q.html) + +- [支持向量机 常见面试篇](https://articles.zsxq.com/id_nqeiewjxovjq.html) + - 一、原理篇 + - 1.1 什么是SVM? + - Q.A + - 1.2 SVM怎么发展的? + - 1.3 SVM存在什么问题? + - Q.A + - 二、算法篇 + - 2.1 什么是块算法? + - 2.2 什么是分解算法? + - 2.3 什么是序列最小优化算法? + - 2.4 什么是增量算法? + - Q.A + - 三、其他SVM篇 + - 3.1 什么是最小二次支持向量机? + - 3.2 什么是模糊支持向量机? + - 3.3 什么是粒度支持向量机? + - 3.4 什么是多类训练算法? + - 3.5 什么是孪生支持向量机? + - 3.6 什么是排序支持向量机? + - Q.A + - 四、应用篇 + - 4.1 模式识别 + - 4.2 网页分类 + - 4.3 系统建模与系统辨识 + - 4.4 其他 + - 五、对比篇 + - 六、拓展篇 + +> [点击查看答案](https://articles.zsxq.com/id_nqeiewjxovjq.html) + +- [集成学习 常见面试篇](https://articles.zsxq.com/id_iqq9rzq9ctcd.html) + - 一、动机 + - 二、集成学习介绍篇 + - 2.1 介绍篇 + - 2.1.1 集成学习的基本思想是什么? + - 2.1.2 集成学习为什么有效? + - 三、 Boosting 篇 + - 3.1 用一句话概括 Boosting? + - 3.2 Boosting 的特点是什么? + - 3.3 Boosting 的基本思想是什么? + - 3.4 Boosting 的特点是什么? + - 3.5 GBDT 是什么? + - 3.6 Xgboost 是什么? + - 四、Bagging 篇 + - 4.1 用一句话概括 Bagging? + - 4.2 Bagging 的特点是什么? + - 4.3 Bagging 的基本思想是什么? + - 4.4 Bagging 的基分类器如何选择? + - 4.5 Bagging 的优点 是什么? + - 4.6 Bagging 的特点是什么? + - 4.7 随机森林 是什么? + - 五、 Stacking 篇 + - 5.1 用一句话概括 Stacking ? + - 5.2 Stacking 的特点是什么? + - 5.3 Stacking 的基本思路是什么? + - 六、常见问题篇 + - 6.1 为什么使用决策树作为基学习器? + - 6.2 为什么不稳定的学习器更适合作为基学习器? + - 6.3 哪些模型适合作为基学习器? + - 6.4 Bagging 方法中能使用线性分类器作为基学习器吗? Boosting 呢? + - 6.5 Boosting/Bagging 与 偏差/方差 的关系? + - 七、对比篇 + - 7.1 LR vs GBDT? + +> [点击查看答案](https://articles.zsxq.com/id_iqq9rzq9ctcd.html) + +## 九、[【关于 Python 】那些你不知道的事](python/) - [【关于 Python 】那些你不知道的事](python/) - 一、什么是*args 和 **kwargs? @@ -1333,7 +1363,7 @@ - 7.3 GIL有什么影响? - 7.4 如何避免GIL带来的影响? -### 七、[【关于 Tensorflow 】那些你不知道的事](Tensorflow/) +## 十、[【关于 Tensorflow 】那些你不知道的事](Tensorflow/) - [【关于 Tensorflow 损失函数】 那些你不知道的事](Tensorflow/loss_study/) - 一、动机 @@ -1352,4 +1382,5 @@ - (4)加权交叉熵损失函数 - (5)Softmax交叉熵损失函数 - (6) SparseCategoricalCrossentropy vs sparse_categorical_crossentropy - - 五、总结 \ No newline at end of file + - 五、总结 + diff --git a/Trick/batch_size/img/batch_size.png b/Trick/batch_size/img/batch_size.png deleted file mode 100644 index b43d656..0000000 Binary files a/Trick/batch_size/img/batch_size.png and /dev/null differ diff --git a/Trick/batch_size/readme.md b/Trick/batch_size/readme.md deleted file mode 100644 index a524708..0000000 --- a/Trick/batch_size/readme.md +++ /dev/null @@ -1,15 +0,0 @@ -# 【关于 batch_size设置】那些你不知道的事 - -- [【关于 batch_size设置】那些你不知道的事](#关于-batch_size设置那些你不知道的事) - - [一、训练模型时,batch_size的设置,学习率的设置?](#一训练模型时batch_size的设置学习率的设置) - - -## 一、训练模型时,batch_size的设置,学习率的设置? - -1. cs224里说过,因为NVIDIA底层的并行计算架构,一般的训练batchsize32和64是效果最好的~好像也有实验支持。如果是训练GAN的话越大越好,biggan那篇paper有做过实验。学习率的设置就是调参的一部分啦,一般训练中会设置学习率衰减 - -![](img/batch_size.png) - -2. 传入的时候是矩阵,宏观上是同时,微观上就是硬件底层运算,biggan的batchsize是2048,我记得作者做过实验再大的话就会训练不稳定并且提升已经很低了。 -3. batch一般选取2^n,主要是为了符合计算机内部的计算 -4. 大的batchsize减少训练时间,提高稳定性,计算更加稳定,因为模型训练曲线会更加平滑,但是会导致模型泛化能力下降,而小的batchsize会会有更好的泛化能力从而逃离sharp minimum,当我们增加batchsize为原来的N倍时,要保证经过同样的样本后更新的权重相等,按照线性缩放规则,学习率应该增加为原来的N倍,但是如果要保证权重的方差不变,则学习率应该增加为原来的sqrt(N)倍 diff --git "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417142112.png" "b/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417142112.png" deleted file mode 100644 index 428cc8c..0000000 Binary files "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417142112.png" and /dev/null differ diff --git "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417144331.png" "b/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417144331.png" deleted file mode 100644 index 1d753b1..0000000 Binary files "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417144331.png" and /dev/null differ diff --git "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417144658.png" "b/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417144658.png" deleted file mode 100644 index f0fee06..0000000 Binary files "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417144658.png" and /dev/null differ diff --git "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417151022.png" "b/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417151022.png" deleted file mode 100644 index 538d3cb..0000000 Binary files "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417151022.png" and /dev/null differ diff --git "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417152434.png" "b/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417152434.png" deleted file mode 100644 index fb2b5cb..0000000 Binary files "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417152434.png" and /dev/null differ diff --git "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417155034.png" "b/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417155034.png" deleted file mode 100644 index 05b177d..0000000 Binary files "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417155034.png" and /dev/null differ diff --git "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417155546.png" "b/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417155546.png" deleted file mode 100644 index e1a2cc6..0000000 Binary files "a/Trick/cross_validation/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210417155546.png" and /dev/null differ diff --git a/Trick/cross_validation/readme.md b/Trick/cross_validation/readme.md deleted file mode 100644 index ee3d7bd..0000000 --- a/Trick/cross_validation/readme.md +++ /dev/null @@ -1,154 +0,0 @@ -# 【关于 交叉验证】 那些你不知道的事 - -> 作者:杨夕 -> -> 面筋地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -## 一、为什么需要交叉验证? - -### 1.1 引言 - -学习预测函数的参数,并在相同数据集上进行测试是一种错误的做法: 一个仅给出测试用例标签的模型将会获得极高的分数,但对于尚未出现过的数据它则无法预测出任何有用的信息。 这种情况称为 overfitting(过拟合). - -![](img/微信截图_20210417142112.png) - -### 1.2 The Validation Set Approach - -#### 1.2.1 The Validation Set Approach介绍 - -为了避免这种情况,在进行(监督)机器学习实验时,通常取出部分可利用数据作为 test set(测试数据集) X_test, y_test。需要强调的是这里说的 “experiment(实验)” 并不仅限于学术(academic),因为即使是在商业场景下机器学习也往往是从实验开始的。 - -![](img/微信截图_20210417144331.png) - -#### 1.2.2 The Validation Set Approach scikit-learn 实现 - -在 scikit-learn 包中 有 train_test_split 辅助函数可以很快地将实验数据集划分为任何训练集(training sets)和测试集(test sets)。 - -```s - >>> import numpy as np - >>> from sklearn.model_selection import train_test_split - >>> from sklearn import datasets - >>> from sklearn import svm - - >>> iris = datasets.load_iris() - >>> iris.data.shape, iris.target.shape - ((150, 4), (150,)) -``` - -#### 1.2.3 The Validation Set Approach 存在问题 - -1. 模型性能强依赖于 划分的方式。也就是划分的不同,最后效果存在很大的差异。 - -![](img/微信截图_20210417144658.png) - -> 注:右边是十种不同的训练集和测试集划分方法得到的test MSE,可以看到,在不同的划分方法下,test MSE的变动是很大的,而且对应的最优degree也不一样。所以如果我们的训练集和测试集的划分方法不够好,很有可能无法选择到最好的模型与参数。 - -2. 只有部分数据参与模型训练。由于将原始数据分为3个数据集合,我们就大大减少了可用于模型学习的样本数量, 并且得到的结果依赖于集合对(训练,验证)的随机选择。 - -## 二、 什么是 Cross-Validation 方法? - -### 2.1 前言 - -第一章 已经 介绍了 The Validation Set Approach,并分析 该方法 所存在问题,那么 有什么方法 可以 解决 该问题呢? - -### 2.2 什么是 Cross-Validation 方法? - -Cross Validation:简言之,就是进行多次train_test_split划分;每次划分时,在不同的数据集上进行训练、测试评估,从而得出一个评价结果。 - -### 2.3 Cross-Validation 方法 的 目的 是什么? - -1. 从有限的学习数据中获取尽可能多的有效信息; -2. 交叉验证从多个方向开始学习样本的,可以有效地避免陷入局部最小值; -3. 可以在一定程度上避免过拟合问题; - -## 三、Cross-Validation 方法有哪些方法? - -### 3.1 Leave-one-out cross-validation(LOOCV) - -#### 3.1.1 LOOCV 方法介绍 - -将数据集分成 N 份,然后 每次从中选取 一份 作为 测试集,其他的作为 训练集,循环重复步骤 N 次,如下图所示: - -![](img/微信截图_20210417151022.png) - -这种方法 的优点是能够 训练 n 个 不同的模型,并得到 一个 MSE,最后将 这 n 个 MSE 取平均 得到 最终的 test MES。 - -![](img/微信截图_20210417152434.png) - -#### 3.1.2 LOOCV 方法 实现方式 - -```s - >>> from sklearn.model_selection import LeaveOneOut - - >>> X = [1, 2, 3, 4] - >>> loo = LeaveOneOut() - >>> for train, test in loo.split(X): - ... print("%s %s" % (train, test)) - [1 2 3] [0] - [0 2 3] [1] - [0 1 3] [2] - [0 1 2] [3] -``` - -#### 3.1.3 LOOCV 方法 的 优缺点 - -- 优点: - -1. 该方法是 循环 N 次选取,每一份数据集都可以作为 测试集 进行测试,所以 该方法 不受 划分方式 的 影响; -2. 因为能够 循环 N 次训练,所以所有数据 都可以参与 模型训练; - -- 缺点: - -1. 由于 要 循环 计算 N 次,所以 计算量过高; - -### 3.2 K-fold Cross Validation - -#### 3.2.1 前言 - -上一节 介绍了 LOOCV 方法,该方法 由于需要 将 数据集 分成 N 份,并抽取其中一份 作为 验证集,循环 N 次,这种方式虽然能够解决 The Validation Set Approach 问题,但是 计算复杂度太高,那么 有没有 更好的Cross Validation方式呢? - -因为该问题,有了 K折交叉验证方法(K-fold Cross Validation)。 - -#### 3.2.2 K-fold Cross Validation 介绍 - -将数据集划分为互斥的K个集合,用K-1个集合做训练,然后剩下的一个做验证。 - -这种方式和 LOOCV 的区别在于 该方法每次 选取 K 份数据【eg:一般 k=5】 - -![](img/微信截图_20210417155546.png) - -#### 3.2.3 K-fold Cross Validation 思路【以 k=5 为例】 - -1. 将 数据集 分割成 5 份; -2. 每次从中选取不同的样本作为 验证集,而其他部分作为训练集用于训练模型,得到 不同 的 $MSE_i$; -3. 对 5 次 $MSE_i$ 取平均值作为最后 的 MSE; - -![](img/微信截图_20210417155034.png) - -```s - >>> import numpy as np - >>> from sklearn.model_selection import RepeatedKFold - >>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]]) - >>> random_state = 12883823 - >>> rkf = RepeatedKFold(n_splits=2, n_repeats=2, random_state=random_state) - >>> for train, test in rkf.split(X): - ... print("%s %s" % (train, test)) - ... - [2 3] [0 1] - [0 1] [2 3] - [0 2] [1 3] - [1 3] [0 2] -``` - -## 参考 - -1. [交叉验证:评估估算器的表现](https://sklearn.apachecn.org/docs/master/30.html) -2. [【机器学习】Cross-Validation(交叉验证)详解](https://zhuanlan.zhihu.com/p/24825503) -3. [几种交叉验证(cross validation)方式的比较](https://cloud.tencent.com/developer/article/1093322) - diff --git a/Trick/early_stopping/img/20210523220743.png b/Trick/early_stopping/img/20210523220743.png deleted file mode 100644 index a80c505..0000000 Binary files a/Trick/early_stopping/img/20210523220743.png and /dev/null differ diff --git "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210301212242.png" "b/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210301212242.png" deleted file mode 100644 index 577020b..0000000 Binary files "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210301212242.png" and /dev/null differ diff --git "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602203923.png" "b/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602203923.png" deleted file mode 100644 index a48b81f..0000000 Binary files "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602203923.png" and /dev/null differ diff --git "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204003.png" "b/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204003.png" deleted file mode 100644 index 40b6053..0000000 Binary files "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204003.png" and /dev/null differ diff --git "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204205.png" "b/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204205.png" deleted file mode 100644 index b947a08..0000000 Binary files "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204205.png" and /dev/null differ diff --git "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204441.png" "b/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204441.png" deleted file mode 100644 index 98c3d12..0000000 Binary files "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204441.png" and /dev/null differ diff --git "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204518.png" "b/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204518.png" deleted file mode 100644 index b15d432..0000000 Binary files "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204518.png" and /dev/null differ diff --git "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204551.png" "b/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204551.png" deleted file mode 100644 index e95d299..0000000 Binary files "a/Trick/early_stopping/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204551.png" and /dev/null differ diff --git a/Trick/early_stopping/readme.md b/Trick/early_stopping/readme.md deleted file mode 100644 index 07418f4..0000000 --- a/Trick/early_stopping/readme.md +++ /dev/null @@ -1,98 +0,0 @@ -# 【关于 早停法 EarlyStopping 】那些你不知道的事 - -> 作者:杨夕 -> -> 论文学习项目地址:https://github.com/km1994/nlp_paper_study -> -> 《NLP 百面百搭》地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> - -![](img/微信截图_20210301212242.png) - -> NLP && 推荐学习群【人数满了,加微信 blqkm601 】 - -![](img/20210523220743.png) - -- [【关于 早停法 EarlyStopping 】那些你不知道的事](#关于-早停法-earlystopping-那些你不知道的事) - - [一、 为什么要用 早停法 EarlyStopping?](#一-为什么要用-早停法-earlystopping) - - [二、 早停法 EarlyStopping 是什么?](#二-早停法-earlystopping-是什么) - - [三、早停法 torch 版本怎么实现?](#三早停法-torch-版本怎么实现) - -## 一、 为什么要用 早停法 EarlyStopping? - -模型训练过程中,训练 loss 和 验证 loss 在训练初期都是 呈下降趋势;当训练到达一定程度之后, 验证 loss 并非继续随 训练 loss 一样下降,而是 出现上升的趋势,此时,如果继续往下训练,容易出现 模型性能下降问题,也就是我们所说的过拟合问题。 - -那么,有什么办法可以避免模型出现该问题呢? - -这个就是本节 所介绍的方法 —— 早停法 - -## 二、 早停法 EarlyStopping 是什么? - -早停法 就是在训练中计算模型在验证集上的表现,当模型在验证集上的表现开始下降的时候,停止训练,这样就能避免模型由于继续训练而导致过拟合的问题。所以说 早停法 结合交叉验证法可以防止模型过拟合。 - -## 三、早停法 torch 版本怎么实现? - -```python -import torch -import numpy as np -# 早停法 -class EarlyStopping: - """Early stops the training if validation loss doesn't improve after a given patience.""" - def __init__(self, patience=7, verbose=False, delta=0): - """ - Args: - patience (int): How long to wait after last time validation loss improved. - Default: 7 - verbose (bool): If True, prints a message for each validation loss improvement. - Default: False - delta (float): Minimum change in the monitored quantity to qualify as an improvement. - Default: 0 - """ - self.patience = patience - self.verbose = verbose - self.counter = 0 - self.best_score = None - self.early_stop = False - self.val_loss_min = np.Inf - self.delta = delta - - def __call__(self, val_loss, model, model_path): - ''' - 功能:早停法 计算函数 - input: - val_loss 验证损失 - model 模型 - model_path 模型保存地址 - ''' - score = -val_loss - - if self.best_score is None: - self.best_score = score - self.save_checkpoint(val_loss, model, model_path) - elif score < self.best_score + self.delta: - self.counter += 1 - print(f'EarlyStopping counter: {self.counter} out of {self.patience}') - if self.counter >= self.patience: - self.early_stop = True - else: - self.best_score = score - self.save_checkpoint(val_loss, model, model_path) - self.counter = 0 - - # 功能:当验证损失减少时保存模型 - def save_checkpoint(self, val_loss, model, model_path): - ''' - 功能:当验证损失减少时保存模型 - input: - val_loss 验证损失 - model 模型 - model_path 模型保存地址 - ''' - if self.verbose: - print(f'Validation loss decreased ({self.val_loss_min:.6f} --> {val_loss:.6f}). Saving model ...') - # torch.save(model.state_dict(), 'checkpoint_loss.pt') - torch.save(model, open(model_path, "wb")) - self.val_loss_min = val_loss -``` diff --git a/Trick/label_smoothing/img/20210523220743.png b/Trick/label_smoothing/img/20210523220743.png deleted file mode 100644 index a80c505..0000000 Binary files a/Trick/label_smoothing/img/20210523220743.png and /dev/null differ diff --git "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210301212242.png" "b/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210301212242.png" deleted file mode 100644 index 577020b..0000000 Binary files "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210301212242.png" and /dev/null differ diff --git "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602203923.png" "b/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602203923.png" deleted file mode 100644 index a48b81f..0000000 Binary files "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602203923.png" and /dev/null differ diff --git "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204003.png" "b/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204003.png" deleted file mode 100644 index 40b6053..0000000 Binary files "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204003.png" and /dev/null differ diff --git "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204205.png" "b/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204205.png" deleted file mode 100644 index b947a08..0000000 Binary files "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204205.png" and /dev/null differ diff --git "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204441.png" "b/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204441.png" deleted file mode 100644 index 98c3d12..0000000 Binary files "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204441.png" and /dev/null differ diff --git "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204518.png" "b/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204518.png" deleted file mode 100644 index b15d432..0000000 Binary files "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204518.png" and /dev/null differ diff --git "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204551.png" "b/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204551.png" deleted file mode 100644 index e95d299..0000000 Binary files "a/Trick/label_smoothing/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210602204551.png" and /dev/null differ diff --git a/Trick/label_smoothing/readme.md b/Trick/label_smoothing/readme.md deleted file mode 100644 index 4497f19..0000000 --- a/Trick/label_smoothing/readme.md +++ /dev/null @@ -1,99 +0,0 @@ -# 【关于 标签平滑法 LabelSmoothing 】那些你不知道的事 - -> 作者:杨夕 -> -> 论文学习项目地址:https://github.com/km1994/nlp_paper_study -> -> 《NLP 百面百搭》地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> - -![](img/微信截图_20210301212242.png) - -> NLP && 推荐学习群【人数满了,加微信 blqkm601 】 - -![](img/20210523220743.png) - -- [【关于 标签平滑法 LabelSmoothing 】那些你不知道的事](#关于-标签平滑法-labelsmoothing-那些你不知道的事) - - [一、为什么要有 标签平滑法 LabelSmoothing?](#一为什么要有-标签平滑法-labelsmoothing) - - [二、 标签平滑法 是什么?](#二-标签平滑法-是什么) - - [三、 标签平滑法 torch 怎么复现?](#三-标签平滑法-torch-怎么复现) - - [参考](#参考) - -## 一、为什么要有 标签平滑法 LabelSmoothing? - -- 交叉熵损失函数在多分类任务中存在的问题 - -多分类任务中,神经网络会输出一个当前数据对应于各个类别的置信度分数,将这些分数通过softmax进行归一化处理,最终会得到当前数据属于每个类别的概率。 - -然后计算交叉熵损失函数: - -![](img/微信截图_20210602203923.png) - -训练神经网络时,最小化预测概率和标签真实概率之间的交叉熵,从而得到最优的预测概率分布。最优的预测概率分布是: - -![](img/微信截图_20210602204003.png) - -**神经网络会促使自身往正确标签和错误标签差值最大的方向学习,在训练数据较少,不足以表征所有的样本特征的情况下,会导致网络过拟合。** - -## 二、 标签平滑法 是什么? - -label smoothing可以解决上述问题,这是一种正则化策略,主要是通过 soft one-hot 来加入噪声,减少了真实样本标签的类别在计算损失函数时的权重,最终起到抑制过拟合的效果。 - -![](img/微信截图_20210602204205.png) - -增加label smoothing后真实的概率分布有如下改变: - -![](img/微信截图_20210602204441.png) - -交叉熵损失函数的改变如下: - -![](img/微信截图_20210602204518.png) - -最优预测概率分布如下: - -![](img/微信截图_20210602204551.png) - -## 三、 标签平滑法 torch 怎么复现? - -```python -import torch.nn as nn -from torch.autograd import Variable -# 标签平滑发 -class LabelSmoothing(nn.Module): - def __init__(self, size, smoothing=0.0): - super(LabelSmoothing, self).__init__() - ''' - nn.KLDivLoss : KL 散度 - 功能: 计算input和target之间的KL散度( Kullback–Leibler divergence) - ''' - self.criterion = nn.KLDivLoss(size_average=False) - #self.padding_idx = padding_idx - self.confidence = 1.0 - smoothing #if i=y的公式 - self.smoothing = smoothing - self.size = size - self.true_dist = None - - def forward(self, x, target): - """ - input: - x 表示输入 (N,M)N个样本,M表示总类数,每一个类的概率log P - target表示label(M,) - return: - Loos - """ - assert x.size(1) == self.size - true_dist = x.data.clone()#先深复制过来 - true_dist.fill_(self.smoothing / (self.size - 1))#otherwise的公式 - # 变成one-hot编码,1表示按列填充, - # target.data.unsqueeze(1)表示索引,confidence表示填充的数字 - true_dist.scatter_(1, target.data.unsqueeze(1), self.confidence) - self.true_dist = true_dist - return self.criterion(x, Variable(true_dist, requires_grad=False)) -``` - -## 参考 - -1. [label smoothing(标签平滑)学习笔记](https://zhuanlan.zhihu.com/p/116466239) -2. [标签平滑&深度学习:Google Brain解释了为什么标签平滑有用以及什么时候使用它](https://zhuanlan.zhihu.com/p/101553787) diff --git "a/Trick/new_word_find/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206161631.png" "b/Trick/new_word_find/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206161631.png" deleted file mode 100644 index ccbd9a2..0000000 Binary files "a/Trick/new_word_find/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206161631.png" and /dev/null differ diff --git a/Trick/new_word_find/readme.md b/Trick/new_word_find/readme.md deleted file mode 100644 index 1c22423..0000000 --- a/Trick/new_word_find/readme.md +++ /dev/null @@ -1,162 +0,0 @@ -# 【关于 新词发现】那些你不知道的事 - -> 作者:杨夕 -> -> 面筋地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210206161631.png) - -## 一、动机篇 - -### 1.1 什么是 “未登录词”? - -- 未登录词 or 新词:NLP 任务中存在一些 之前之前没见过的词,这些词即为 “未登录词”(新词); - -### 1.2 什么是 “未登录词”(新词) 对于 NLP 任务的影响? - -1. 对于“未登录词”(新词)的发现,主流的深度学习框架CNN/LSTM/Attention和BERT/RoBERTa/Albert等都无法解决这个问题; -2. 如果无法 发现这些“未登录词”(新词),那么 会 影响 训练模型的性能; - -## 二、方法篇 - -### 2.1 常用的解决 “未登录词”(新词) 问题的方法? - -- 方法类型:无监督任务 -- 常用方法:自信息 and 互信息 - -### 2.2 如何 衡量 当前词 是 “未登录词”(新词) 呢? - -- 常用的衡量 字符串 是 新词 的方法: - - 自信息(信息熵):Entropy - - 互信息:MI(Mutual Information) - -### 2.3 做 分词处理 需要考虑的问题是什么? - -- 动机:在做新词发现时,需要解决 特殊字符 做带来的噪声影响。比如在做 新词发现时,需要设置 滑动窗口,当 存在 阿拉伯数字 or 英文字符时,会导致几个数字或者几个英文字母随便组合一下,他们的程度就大于5,造成的问题是 有些数字会被识别为新词,新发现的英文单词最大程度为5。此外,在这两种情况下,它们对前后字符串的分词也会造成不利的影响。 -- 解决方法:需要 将 连续的数字或英文字母看出一个字 【采用 Bert 中 的 tokenization.py】 -- 代码 - -```s -class BasicTokenizer(object): - """Runs basic tokenization (punctuation splitting, lower casing, etc.).""" - - def __init__(self, do_lower_case=True): - """Constructs a BasicTokenizer. - Args: - do_lower_case: Whether to lower case the input. - """ - self.do_lower_case = do_lower_case - - def tokenize(self, text): - """Tokenizes a piece of text.""" - text = convert_to_unicode(text) - text = self._clean_text(text) - - # This was added on November 1st, 2018 for the multilingual and Chinese - # models. This is also applied to the English models now, but it doesn't - # matter since the English models were not trained on any Chinese data - # and generally don't have any Chinese data in them (there are Chinese - # characters in the vocabulary because Wikipedia does have some Chinese - # words in the English Wikipedia.). - text = self._tokenize_chinese_chars(text) - - orig_tokens = whitespace_tokenize(text) - split_tokens = [] - for token in orig_tokens: - if self.do_lower_case: - token = token.lower() - token = self._run_strip_accents(token) - split_tokens.extend(self._run_split_on_punc(token)) - - output_tokens = whitespace_tokenize(" ".join(split_tokens)) - return output_tokens - - def _run_strip_accents(self, text): - """Strips accents from a piece of text.""" - text = unicodedata.normalize("NFD", text) - output = [] - for char in text: - cat = unicodedata.category(char) - if cat == "Mn": - continue - output.append(char) - return "".join(output) - - def _run_split_on_punc(self, text): - """Splits punctuation on a piece of text.""" - chars = list(text) - i = 0 - start_new_word = True - output = [] - while i < len(chars): - char = chars[i] - if _is_punctuation(char): - output.append([char]) - start_new_word = True - else: - if start_new_word: - output.append([]) - start_new_word = False - output[-1].append(char) - i += 1 - - return ["".join(x) for x in output] - - def _tokenize_chinese_chars(self, text): - """Adds whitespace around any CJK character.""" - output = [] - for char in text: - cp = ord(char) - if self._is_chinese_char(cp): - output.append(" ") - output.append(char) - output.append(" ") - else: - output.append(char) - return "".join(output) - - def _is_chinese_char(self, cp): - """Checks whether CP is the codepoint of a CJK character.""" - # This defines a "chinese character" as anything in the CJK Unicode block: - # https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block) - # - # Note that the CJK Unicode block is NOT all Japanese and Korean characters, - # despite its name. The modern Korean Hangul alphabet is a different block, - # as is Japanese Hiragana and Katakana. Those alphabets are used to write - # space-separated words, so they are not treated specially and handled - # like the all of the other languages. - if ((cp >= 0x4E00 and cp <= 0x9FFF) or # - (cp >= 0x3400 and cp <= 0x4DBF) or # - (cp >= 0x20000 and cp <= 0x2A6DF) or # - (cp >= 0x2A700 and cp <= 0x2B73F) or # - (cp >= 0x2B740 and cp <= 0x2B81F) or # - (cp >= 0x2B820 and cp <= 0x2CEAF) or - (cp >= 0xF900 and cp <= 0xFAFF) or # - (cp >= 0x2F800 and cp <= 0x2FA1F)): # - return True - - return False - - def _clean_text(self, text): - """Performs invalid character removal and whitespace cleanup on text.""" - output = [] - for char in text: - cp = ord(char) - if cp == 0 or cp == 0xfffd or _is_control(char): - continue - if _is_whitespace(char): - output.append(" ") - else: - output.append(char) - return "".join(output) -``` - - - - diff --git a/Trick/noisy_label_learning/img/20210122113000.png b/Trick/noisy_label_learning/img/20210122113000.png deleted file mode 100644 index 55df20f..0000000 Binary files a/Trick/noisy_label_learning/img/20210122113000.png and /dev/null differ diff --git "a/Trick/noisy_label_learning/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206161111.png" "b/Trick/noisy_label_learning/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206161111.png" deleted file mode 100644 index d6da420..0000000 Binary files "a/Trick/noisy_label_learning/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210206161111.png" and /dev/null differ diff --git a/Trick/noisy_label_learning/readme.md b/Trick/noisy_label_learning/readme.md deleted file mode 100644 index ff730d4..0000000 --- a/Trick/noisy_label_learning/readme.md +++ /dev/null @@ -1,106 +0,0 @@ -# 【关于 “脏数据”处理】那些你不知道的事 - -> 作者:杨夕 -> -> 面筋地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210206161111.png) - -## 一、动机 - -### 1.1 何为“脏数据”? - -在 生产中,我们从 标注人员那边 所得到的数据,可能并不是“干净数据”,而有可能存在 一小部分 “脏数据”。 - -- 那么,何为“脏数据”: - - 数据标注规范不统一【eg:一开始设定了标注规范,但是标一般之后发现不对,然后修改了规范,但是没有改之前处理的数据,sad!!!】 - - 标注歧义问题 【eg:同一条数据,可能被标注为不同的标签】 - -### 1.2 “脏数据” 会带来什么后果? - -神经网络的成功通常建立在大量、干净的数据上,标注错误过多必然会影响性能表现。 - -## 二、“脏数据” 处理篇 - -### 2.1 “脏数据” 怎么处理呢? - -- 如何寻找“脏数据”? - - 人工清洗? 【眼瞎】 - - 重标? 【标注人员和平相处五项原则】 - - 自己改? 【外号 “算法工程师” 的 “标注工程师”】 - -- 那有没有好点的方法呢? - - 置信学习方法 - - ... - -### 2.2 置信学习方法篇 - -#### 2.2.1 什么是 置信学习方法? - -- 置信学习方法 其实就是 计算 每一个样本的 标签的置信度,以识别标签错误、表征标签噪声并应用于带噪学习(noisy label learning)。【注:模型找出的置信度低的样本,并不一定就是错误样本,而只是一种不确定估计的选择方法】 -- 举例说明: - - 在某些场景下,对训练集通过交叉验证来找出一些可能存在错误标注的样本,然后交给人工去纠正。 - -#### 2.2.2 置信学习方法 优点? - -- 发现 “可能错误的样本” 【注:这个只能说是相对的,因为模型找出的置信度低的样本,并不一定就是错误样本,而只是一种不确定估计的选择方法】; -- 置信学习开源工具 cleanlab -- 可直接估计噪声标签与真实标签的联合分布,具有理论合理性。 -- 不需要超参数,只需使用交叉验证来获得样本外的预测概率。 -- 不需要做随机均匀的标签噪声的假设(这种假设在实践中通常不现实)。 -- 与模型无关,可以使用任意模型,不像众多带噪学习与模型和训练过程强耦合。 - -#### 2.2.3 置信学习方法 怎么做? - -1. Count:估计噪声标签和真实标签的联合分布; -2. Clean:找出并过滤掉错误样本; -3. Re-Training:过滤错误样本后,重新调整样本类别权重,重新训练; - -![](img/20210122113000.png) - -#### 2.2.4 置信学习方法 怎么用?有什么开源框架? - -- 置信学习开源工具: [cleanlab](https://github.com/cgnorthcutt/cleanlab) -- 使用文档:[cleanlab 操作手册](https://l7.curtisnorthcutt.com/cleanlab-python-package) -- 使用 - -1. cleanlab在MINIST数据集中找出的错误样本 -```s - from cleanlab.pruning import get_noise_indices - # 输入 - # s:噪声标签 - # psx: n x m 的预测概率概率,通过交叉验证获得 - ordered_label_errors = get_noise_indices( - s=numpy_array_of_noisy_labels, - psx=numpy_array_of_predicted_probabilities, - sorted_index_method='normalized_margin', # Orders label errors - ) -``` - -2. 找出错误样本后,clean 点,重新训练 - -```s - from cleanlab.classification import LearningWithNoisyLabels - from sklearn.linear_model import LogisticRegression - ​ - # 其实可以封装任意一个你自定义的模型. - lnl = LearningWithNoisyLabels(clf=LogisticRegression()) - lnl.fit(X=X_train_data, s=train_noisy_labels) - # 对真实世界进行验证. - predicted_test_labels = lnl.predict(X_test) -``` - -#### 2.2.5 置信学习方法 的工作原理? - -1. 置信学习方法 主要是通过 寻找出 标注数据中的 “脏数据”,然后抛弃掉这些数据后重新训练,也就是直接估计噪声标签和真实标签的联合分布,而不是修复噪声标签或者修改损失权重。 - -## 参考 - -1. [标注数据存在错误怎么办?MIT&Google提出用置信学习找出错误标注(附开源实现)](https://zhuanlan.zhihu.com/p/146557232) -2. [Confident Learning: Estimating Uncertainty in Dataset Labels](https://arxiv.org/abs/1911.00068) \ No newline at end of file diff --git a/Trick/readme.md b/Trick/readme.md deleted file mode 100644 index e69de29..0000000 diff --git a/Trick/small_sample_problem/AdversarialTraining/AdversarialTraining.md b/Trick/small_sample_problem/AdversarialTraining/AdversarialTraining.md deleted file mode 100644 index 98eb8bb..0000000 --- a/Trick/small_sample_problem/AdversarialTraining/AdversarialTraining.md +++ /dev/null @@ -1,211 +0,0 @@ -# 【关于 数据增强 之 对抗训练】 那些你不知道的事 - -> 作者:杨夕 -> -> 面筋地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210210200952.png) - -## 一、介绍篇 - -### 1.1 什么是 对抗训练 ? - -对抗训练 从 CV 引入到 NLP 领域,作为一种防御机制,能够在修改部分信息的情况下,提高模型的泛化能力。 - -### 1.2 为什么 对抗训练 能够 提高模型效果? - -对抗样本可以用来攻击和防御,而对抗训练其实是“对抗”家族中防御的一种方式,其基本的原理呢,就是通过添加扰动构造一些对抗样本,放给模型去训练,以攻为守,提高模型在遇到对抗样本时的鲁棒性,同时一定程度也能提高模型的表现和泛化能力。 - -### 1.3 对抗训练 有什么特点? - -- 对抗样本一般需要具有两个特点: - - 相对于原始输入,所添加的扰动是微小的; - - 能使模型犯错 - -### 1.4 对抗训练 的作用? - -1. 提高模型应对恶意对抗样本时的鲁棒性; -2. 作为一种regularization,减少overfitting,提高泛化能力。 - -## 二、概念篇 - -### 2.1 对抗训练的基本概念? - -在原始输入样本 x 上加一个扰动 $r_adv$ ,得到对抗样本后,用其进行训练。也就是说,问题可以被抽象成这么一个模型: - -![](img/微信截图_20210117001405.png) - -> 注: y 为gold label, θ 为模型参数 - -### 2.2 如何计算扰动? - -- 动机:神经网络由于其线性的特点,很容易受到线性扰动的攻击 -- 方法:FGSM - -![](img/微信截图_20210117001650.png) - -> 注: sgn 为符号函数, L 为损失函数。Goodfellow发现,令 ε=0.25 ,用这个扰动能给一个单层分类器造成99.9%的错误率。 - -### 2.3 如何优化? - -- 动机:将问题重新定义成了一个找鞍点的问题 -- 方法:Min-Max公式 - -![](img/微信截图_20210117001955.png) - -> 注:公式由两部分构成:一个是内部损失函数的最大化,一个是外部经验风险的最小化 -> 内部max是为了找到worst-case的扰动,也就是攻击,其中, L 为损失函数, S 为扰动的范围空间。 -> 外部min是为了基于该攻击方式,找到最鲁棒的模型参数,也就是防御,其中 D 是输入样本的分布。 - -## 三、实战篇 - -### 3.1 NLP 中经典对抗训练 之 Fast Gradient Method(FGM) - -- 方法:假设输入的文本序列的embedding vectors [v1,v2,...,vT] 为 x ,embedding的扰动为: - -![](img/微信截图_20210117002233.png) - -> 注:实际上就是取消了符号函数,用二范式做了一个scale,需要注意的是:这里的norm计算的是,每个样本的输入序列中出现过的词组成的矩阵的梯度norm。原作者提供了一个TensorFlow的实现 [10],在他的实现中,公式里的 x 是embedding后的中间结果(batch_size, timesteps, hidden_dim),对其梯度 g 的后面两维计算norm,得到的是一个(batch_size, 1, 1)的向量 $||g||_2$ 。为了实现插件式的调用,笔者将一个batch抽象成一个样本,一个batch统一用一个norm,由于本来norm也只是一个scale的作用,影响不大。 - -- 代码实现: - -1. FGM 类实现 - -```s - import torch - class FGM(): - def __init__(self, model): - self.model = model - self.backup = {} - - def attack(self, epsilon=1., emb_name='emb.'): - # emb_name这个参数要换成你模型中embedding的参数名 - for name, param in self.model.named_parameters(): - if param.requires_grad and emb_name in name: - self.backup[name] = param.data.clone() - norm = torch.norm(param.grad) - if norm != 0 and not torch.isnan(norm): - r_at = epsilon * param.grad / norm - param.data.add_(r_at) - - def restore(self, emb_name='emb.'): - # emb_name这个参数要换成你模型中embedding的参数名 - for name, param in self.model.named_parameters(): - if param.requires_grad and emb_name in name: - assert name in self.backup - param.data = self.backup[name] - self.backup = {} -``` - -2. FGM 类调用 - -```s - # 初始化 - fgm = FGM(model) - for batch_input, batch_label in data: - # 正常训练 - loss = model(batch_input, batch_label) - loss.backward() # 反向传播,得到正常的grad - # 对抗训练 - fgm.attack() # 在embedding上添加对抗扰动 - loss_adv = model(batch_input, batch_label) - loss_adv.backward() # 反向传播,并在正常的grad基础上,累加对抗训练的梯度 - fgm.restore() # 恢复embedding参数 - # 梯度下降,更新参数 - optimizer.step() - model.zero_grad() -``` - -> 注:PyTorch为了节约内存,在backward的时候并不保存中间变量的梯度。因此,如果需要完全照搬原作的实现,需要用register_hook接口[11]将embedding后的中间变量的梯度保存成全局变量,norm后面两维,计算出扰动后,在对抗训练forward时传入扰动,累加到embedding后的中间变量上,得到新的loss,再进行梯度下降。 - -### 3.2 NLP 中经典对抗训练 之 Projected Gradient Descent(PGD) - -- 动机:内部max的过程,本质上是一个非凹的约束优化问题,FGM解决的思路其实就是梯度上升,那么FGM简单粗暴的“一步到位”,是不是有可能并不能走到约束内的最优点呢? -- 方法:用Projected Gradient Descent(PGD)的方法,简单的说,就是“小步走,多走几步”,如果走出了扰动半径为 ε 的空间,就映射回“球面”上,以保证扰动不要过大: - -![](img/微信截图_20210117002650.png) - -- 代码实现: - -1. PGD 类实现 - -```s - import torch - class PGD(): - def __init__(self, model): - self.model = model - self.emb_backup = {} - self.grad_backup = {} - - def attack(self, epsilon=1., alpha=0.3, emb_name='emb.', is_first_attack=False): - # emb_name这个参数要换成你模型中embedding的参数名 - for name, param in self.model.named_parameters(): - if param.requires_grad and emb_name in name: - if is_first_attack: - self.emb_backup[name] = param.data.clone() - norm = torch.norm(param.grad) - if norm != 0 and not torch.isnan(norm): - r_at = alpha * param.grad / norm - param.data.add_(r_at) - param.data = self.project(name, param.data, epsilon) - - def restore(self, emb_name='emb.'): - # emb_name这个参数要换成你模型中embedding的参数名 - for name, param in self.model.named_parameters(): - if param.requires_grad and emb_name in name: - assert name in self.emb_backup - param.data = self.emb_backup[name] - self.emb_backup = {} - - def project(self, param_name, param_data, epsilon): - r = param_data - self.emb_backup[param_name] - if torch.norm(r) > epsilon: - r = epsilon * r / torch.norm(r) - return self.emb_backup[param_name] + r - - def backup_grad(self): - for name, param in self.model.named_parameters(): - if param.requires_grad: - self.grad_backup[name] = param.grad.clone() - - def restore_grad(self): - for name, param in self.model.named_parameters(): - if param.requires_grad: - param.grad = self.grad_backup[name] -``` - -2. FGM 类调用 - -```s - pgd = PGD(model) - K = 3 - for batch_input, batch_label in data: - # 正常训练 - loss = model(batch_input, batch_label) - loss.backward() # 反向传播,得到正常的grad - pgd.backup_grad() - # 对抗训练 - for t in range(K): - pgd.attack(is_first_attack=(t==0)) # 在embedding上添加对抗扰动, first attack时备份param.data - if t != K-1: - model.zero_grad() - else: - pgd.restore_grad() - loss_adv = model(batch_input, batch_label) - loss_adv.backward() # 反向传播,并在正常的grad基础上,累加对抗训练的梯度 - pgd.restore() # 恢复embedding参数 - # 梯度下降,更新参数 - optimizer.step() - model.zero_grad() -``` - - -## 参考 - -1. [【炼丹技巧】功守道:NLP中的对抗训练 + PyTorch实现](https://zhuanlan.zhihu.com/p/91269728) \ No newline at end of file diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230214346.png" "b/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230214346.png" deleted file mode 100644 index 55f695c..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230214346.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230214955.png" "b/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230214955.png" deleted file mode 100644 index ab80897..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230214955.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215334.png" "b/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215334.png" deleted file mode 100644 index 34daf4d..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215334.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215453.png" "b/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215453.png" deleted file mode 100644 index 31ae697..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215453.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215528.png" "b/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215528.png" deleted file mode 100644 index d7eb20f..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/QQ\346\210\252\345\233\27620201230215528.png" and /dev/null differ diff --git a/Trick/small_sample_problem/AdversarialTraining/img/eda.drawio b/Trick/small_sample_problem/AdversarialTraining/img/eda.drawio deleted file mode 100644 index a0264b7..0000000 --- a/Trick/small_sample_problem/AdversarialTraining/img/eda.drawio +++ /dev/null @@ -1 +0,0 @@ -7VrbduMmFP0aVtsHZ+lu6VGynRnPmnbNjNtm2jciEYtGEh4Zx/Z8fUFCN4Rjp/FlkvTFCw4XAXvvwwEMzFG6eZfDRfwriVACDC3aAHMMDGM41NgvN2xLg2UNS8M8x1Fp0hvDDH9HwijazVc4QstORUpIQvGiawxJlqGQdmwwz8m6W+2OJN2vLuAc9QyzECZ96w2OaCysuuM1Be8RnsfVpx3bKktSWNUWU1nGMCLrlsmcAHOUE0LLVLoZoYQvXrUwZbvrHaX1yHKU0UMa/J1B93MYz67/eH8znn6j5Hb6fSAG+wCTlZixGCzdVkvAxr3gybsEbXy+pMAMUBaJ5DhM4HKJQ2aMaZowg16U03z7lWW0KvMXz1zZVXa8aReOtyLXn5OY5pKs8hA9MpGKHDCfI/pIPbOsh6IO7mLF3iGSIjYeVmHdoG0LAOMWzpUtRwmk+KHLFihIN6+7q7/wiWA2M0MT+qjJIeRR91t1Uc5btGqDK3c0lDrSpI7Khel1xBKtaTemgjtP4JGu4JGTsMUK7kgxzjso4HO+rTjjAzCxgT8BLktYIBgDz2yVtQlYGXlHg2XhIXxWQXcXm3YLZ1726gDXBR4bjwPTBbNkt8tFWaEYzqqpaQPPAd6IN/FHwK9HzBagqWVov338tKszVrOcXlVZkg5FG9oVxpLm5B6NSEJyZslIhvjMcJJIJpjgecbVxYSAmD14QDnFzC/5oiDFUcQ/E6xjTNFsUS7vmjlhZsvJKotQtE9UvE+0eVQGVakp08su8y2Z1HXaOjG13ZLocPCphDN2Ei7CD0r+hOUKc+7k89ufDZ23Bwb7vCalf+GZAvtbGN7Pi9UcSM35xESLTrJpm+AMDaq14M0MS8nYPTr5HadsA2Q0RGv2+4WkMDuGUJZbxrRtynvmSnBHwLV30ro2F2u7g+xd0qlo2dLBEThpeF1O6lW+zUmV73ZOxUnzJTvBIW8S6Gon2O3mf4/IAlnP2+8RLf00HvHDBOFrcz24iT//+QVPp9ksDwZ6P3TjUc5MZElOYzInGUwmjVVal6bOR0IWAqB/EKVbEZnDFSVSpLfB9Gsr3YrzWK4J83imG+VJIdjesE896X7Yp6xnqcE8OHx7HjLn9wvG436By95gTn8MKVzH/LTDLIEG3OvigyPA2F0mAqtIuMBl+wRzEKzasBjdGPhOUeQBnxWZvIJrvEQ/0BO9goq7IyOruwuZql3IU+xC1sn8gPUG/YD5TH2rT1WuLYErhw7HO1XtnlXHcUwLYFdReURlBDO0dFsEm5QyIA2tUXSxkDRD+dXrVZ/lSABZffUZqnPJ6dRnv0H1PXd3PUx9ln5e9fXvxqZhLPSHUc4VlmI+3hSxo17KEvcJT2WVDGEy+LRHggcdk44rEa8fqNa3R+cJVJ1LSOSIdLcPDDqdSwaddo+9H36CmB/3RybwPc7hMsU//oBCzmOSiV0DZRAXBI+q7eQHYrBlKRh8qsun3cB2A/peaN2yDIHnA9dqBdvsyK3xEJpfPerAN58YY18KCfcQJPRzIjHcg8QI+O5hkNTnnz42LwAJpVfXzomE+1xNHOsA+sNAcrA47BNB4vUh6W28ex7yjrhrXvahTbostgxJB4c+tPXCqTMfCXXVJfMTQf2vr7OqU4Z+rjPGoTd99iVppkvssOUjy8HvubrE13PTTLWxFm6Y74xDEFyDIOD+2A2KR4PXesFgynK3jau+W7cUjJIdzPGOT6qdtg8N2ycnfKt8O9Aobl7PC4xiv1UA44DABF7/mujVAlPvtZcCpuq4A0zluhpgKqheLTBD+a1CcVt6XmAUL2O143rLwFzalVVBpXSaKx3XGwbGOp1iWLb5L2gZxjX/qDUn/wI= \ No newline at end of file diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201231235616.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201231235616.png" deleted file mode 100644 index cb536d5..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201231235616.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102160355.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102160355.png" deleted file mode 100644 index f5f2dcb..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102160355.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161002.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161002.png" deleted file mode 100644 index 124ee72..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161002.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161058.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161058.png" deleted file mode 100644 index 8d8cc92..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161058.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161342.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161342.png" deleted file mode 100644 index db713e7..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161342.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001405.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001405.png" deleted file mode 100644 index d6cf892..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001405.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001650.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001650.png" deleted file mode 100644 index 676ae7a..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001650.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001955.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001955.png" deleted file mode 100644 index 208cd0c..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001955.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002233.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002233.png" deleted file mode 100644 index b08beae..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002233.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002650.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002650.png" deleted file mode 100644 index fd940a8..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002650.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200952.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200952.png" deleted file mode 100644 index 6a4cc47..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210200952.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\346\225\260\346\215\256\345\242\236\345\274\272 EDA.xmind" "b/Trick/small_sample_problem/AdversarialTraining/img/\346\225\260\346\215\256\345\242\236\345\274\272 EDA.xmind" deleted file mode 100644 index 0d3cff2..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\346\225\260\346\215\256\345\242\236\345\274\272 EDA.xmind" and /dev/null differ diff --git "a/Trick/small_sample_problem/AdversarialTraining/img/\346\225\260\346\215\256\345\242\236\345\274\272EDA.png" "b/Trick/small_sample_problem/AdversarialTraining/img/\346\225\260\346\215\256\345\242\236\345\274\272EDA.png" deleted file mode 100644 index 28aa7d8..0000000 Binary files "a/Trick/small_sample_problem/AdversarialTraining/img/\346\225\260\346\215\256\345\242\236\345\274\272EDA.png" and /dev/null differ diff --git a/Trick/small_sample_problem/CategoryImbalance/readme.md b/Trick/small_sample_problem/CategoryImbalance/readme.md deleted file mode 100644 index 5fafa08..0000000 --- a/Trick/small_sample_problem/CategoryImbalance/readme.md +++ /dev/null @@ -1,51 +0,0 @@ -# 【关于 类别不均衡问题】 那些你不知道的事 - -## 1. 什么是类别不均衡? - -机器学习中常常会遇到数据的类别不平衡(class imbalance),也叫数据偏斜(class skew)。 - -> 以常见的二分类问题为例,我们希望预测病人是否得了某种罕见疾病。但在历史数据中,阳性的比例可能很低(如百分之0.1)。在这种情况下,学习出好的分类器是很难的,而且在这种情况下得到结论往往也是很具迷惑性的。 - -以上面提到的场景来说,如果我们的分类器总是预测一个人未患病,即预测为反例,那么我们依然有高达99.9%的预测准确率。然而这种结果是没有意义的,这提出了今天的第一个问题,如何有效在类别不平衡的情况下评估分类器? - -## 2. 什么是类别不均衡? - -- 数据均衡场景: - - 方法:准确率(accuracy) - - 前提:**“数据是平衡的,正例与反例的重要性一样,二分类器的阈值是0.5。”** - -- 数据不均衡场景: - - 动机:准确率(accuracy)容易出现迷惑性(eg:正例有99条,负例1条,那么acc = 99%,然而这种结果是没有意义的) - - 主流的评估方法: - - ROC是一种常见的替代方法,全名receiver operating curve,计算ROC曲线下的面积是一种主流方法 - - Precision-recall curve和ROC有相似的地方,但定义不同,计算此曲线下的面积也是一种方法 - - Precision@n是另一种方法,特制将分类阈值设定得到恰好n个正例时分类器的precision - - Average precision也叫做平均精度,主要描述了precision的一般表现,在异常检测中有时候会用 - - 直接使用Precision也是一种想法,但此时的假设是分类器的阈值是0.5,因此意义不大 - - 如何选择:至于哪种方法更好,一般来看我们在极端类别不平衡中更在意“少数的类别”,因此ROC不像precision-recall curve那样更具有吸引力。在这种情况下,Precision-recall curve不失为一种好的评估标准,相关的分析可以参考[2]。还有一种做法是,仅分析ROC曲线左边的一小部分,从这个角度看和precision-recall curve有很高的相似性。 - -> 注:precision 使用 注意点:
-> 没有特殊情况,不要用准确率(accuracy),一般都没什么帮助
-> 如果使用precision,请注意调整分类阈值,precision@n更有意义
- -## 3. 解决类别不平衡中的“奇淫巧技”有什么? - -1. **SMOTE算法**:对数据进行采用的过程中通过相似性同时生成并插样“少数类别数据”,叫做SMOTE算法 -2. **聚类算法做欠采样**:对数据先进行聚类,再将大的簇进行随机欠采样或者小的簇进行数据生成 -3. **阈值调整(threshold moving)**,将原本默认为0.5的阈值调整到 较少类别/(较少类别+较多类别)即可 - 1. 介绍:简单的调整阈值,不对数据进行任何处理。此处特指将分类阈值从0.5调整到正例比例 -4. **无监督学习问题**:把监督学习变为无监督学习,舍弃掉标签把问题转化为一个无监督问题,如异常检测 -5. **集成学习**: 先对多数类别进行随机的欠采样,并结合boosting算法进行集成学习 -6. 重构分类器角度 - 1. 将大类压缩为小类; - 2. 使用 One Class 分类器(将小类作为异常点); - 3. 使用集成方式,训练多个分类器,联合这些分类器进行分类; - 4. 将二分类改为多分类问题; -7. 使用其他 Loss 函数 - 1. Focal Loss: 对 CE Loss 增加了一个调制系数来降低容易样本的权值,使其训练过程更加关注困难样本 - -> 注:第一种和第二种方法都会明显的改变数据分布,我们的训练数据假设不再是真实数据的无偏表述。在第一种方法中,我们浪费了很多数据。而第二类方法中有无中生有或者重复使用了数据,会导致过拟合的发生。 - -## 参考 - -1. [如何处理数据中的「类别不平衡」?](https://zhuanlan.zhihu.com/p/32940093) \ No newline at end of file diff --git a/Trick/small_sample_problem/EDA/eda.md b/Trick/small_sample_problem/EDA/eda.md deleted file mode 100644 index b56af8f..0000000 --- a/Trick/small_sample_problem/EDA/eda.md +++ /dev/null @@ -1,266 +0,0 @@ -# 【关于 EDA 】那些你不知道的事 - -> 作者:杨夕 -> -> 面筋地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -## 目录 - -![](img/数据增强EDA.png) - -## 一、动机篇 - -### 1.1 什么是 数据增强? - -数据增强 是通过采用一些策略 增加 训练样本的数据量,提高模型的训练效果。 - -### 1.2 为什么需要 数据增强? - -在医疗、金融、法律等领域,高质量的标注数据十分稀缺、昂贵,我们通常面临少样本低资源问题。 - -## 二、常见的数据增强方法篇 - -### 2.1 词汇替换篇 - -#### 2.1.1 什么是基于词典的替换方法? - -- 介绍:基于同义词替换的方法是从句子中以一定的概率随机选取一个单词,利用一些同义词数据库(注:英文可以用 WordNet 数据库,中文可以用 synonyms python 同义词词典) 将其替换成对应的同义词。 -- 举例说明: - -![](img/QQ截图20201230214346.png) - -> 注:对 句子 “我 喜欢 NLP ” 随机选取 其中一个词 利用 synonyms 包进行替换,可以替换为 “我 喜爱 NLP ”。 - -#### 2.1.2 什么是基于词向量的替换方法? - -- 介绍:通过利用预先训练好的词向量(eg:Word2Vec、GloVe、FastText等),使用嵌入空间中最近的相邻单词替换句子中的某些单词。 -- 思路: - -1. 预先训练好的词向量(eg:Word2Vec、GloVe、FastText等); -2. 使用嵌入空间中最近的相邻单词,如下图,在嵌入空间中,与词 “awesome” 最近的相邻单词为 amazing、perfect等 - -![](img/QQ截图20201230214955.png) -> 嵌入空间 - -3. 随机选取三个 与 词 “awesome” 最相近的单词替换 词 “awesome”,如下图: - -![](img/QQ截图20201230215334.png) - -- 实现: - -```s - import synonyms - # 功能:同义词替换,替换一个语句中的n个单词为其同义词 - def synonym_replacement(words, alpha, num_words, stop_words): - n = max(1, int(alpha * num_words)) - new_words = words.copy() - random_word_list = list(set([word for word in words if word not in stop_words])) - random.shuffle(random_word_list) - num_replaced = 0 - for random_word in random_word_list: - synonyms = get_synonyms(random_word) - if len(synonyms) >= 1: - synonym = random.choice(synonyms) - new_words = [synonym if word == random_word else word for word in new_words] - num_replaced += 1 - if num_replaced >= n: - break - sentence = ' '.join(new_words) - new_words = sentence.split(' ') - return new_words - - # 功能:获取与 word 最相近的同义词 - def get_synonyms(word): - return synonyms.nearby(word)[0] - -``` - -#### 2.1.3 什么是基于 MLM 的替换方法? - -- 介绍:像BERT、ROBERTA和ALBERT这样的Transformer模型已经接受了大量的文本训练,使用一种称为“Masked Language Modeling”的预训练,即模型必须根据上下文来预测遮盖的词汇。这可以用来扩充一些文本。例如,我们可以使用一个预训练的BERT模型并屏蔽文本的某些部分。然后,我们使用BERT模型来预测遮蔽掉的token。 - -![](img/QQ截图20201230215453.png) - -使用mask预测来生成文本的变体。与之前的方法相比,生成的文本在语法上更加连贯,因为模型在进行预测时考虑了上下文。 - -![](img/QQ截图20201230215528.png) - -- 实现: - -> 注:使用开源库这很容易实现,如Hugging Face的transformers。你可以将你想要替换的token设置为并生成预测。 - -```s - from transformers import pipeline - nlp = pipeline('fill-mask') - nlp('This is cool') - [{'score': 0.515411913394928, - 'sequence': ' This is pretty cool', - 'token': 1256}, - {'score': 0.1166248694062233, - 'sequence': ' This is really cool', - 'token': 269}, - {'score': 0.07387523353099823, - 'sequence': ' This is super cool', - 'token': 2422}, - {'score': 0.04272908344864845, - 'sequence': ' This is kinda cool', - 'token': 24282}, - {'score': 0.034715913236141205, - 'sequence': ' This is very cool', - 'token': 182}] -``` -> 注:这种方法的一个问题是,决定要屏蔽文本的哪一部分并不是一件小事。你必须使用启发式的方法来决定掩码,否则生成的文本将不保留原句的含义。 - -#### 2.1.4 什么是基于 TF-IDF 的词替换? - -- 动机:对于 query 里面 TF-IDF 值较小的词语,一般对 query 的贡献度较少 -- 基本思想:针对 TF-IDF值较低的词语贡献度低问题,所以在不影响句子所属类别的情况下替换,可以达到数据增强的作用。 - -![](img/微信截图_20201231235616.png) - -### 2.2 词汇插入篇 - -#### 2.2.1 什么是随机插入法? - -- 方法:通过在 query 里面随机插入一个或多个新词汇、相应的拼写错误、符号等噪声的方式提高 训练模型的健壮性。 -- 代码实现: - -```s - import random - import synonyms - # 功能:随机插入,随机在语句中插入n个词 - def random_insertion(words, alpha, num_words, stop_words): - n = max(1, int(alpha * num_words)) - new_words = words.copy() - for _ in range(n): - self.add_word(new_words) - return new_words - - # 功能:插入新词 - def add_word(new_words): - synonyms = [] - counter = 0 - while len(synonyms) < 1: - random_word = new_words[random.randint(0, len(new_words)-1)] - synonyms = get_synonyms(random_word) - counter += 1 - if counter >= 10: - return - random_synonym = random.choice(synonyms) - random_idx = random.randint(0, len(new_words)-1) - new_words.insert(random_idx, random_synonym) - - # 功能:获取同义词 - def get_synonyms(word): - return synonyms.nearby(word)[0] -``` - -### 2.3 词汇交换篇 - -#### 2.3.1 什么是随机交换法? - -- 方法:通过在 query 里面随机交换一个或多个词汇的方式提高 训练模型的健壮性。 -- 代码实现: - -```s - import random - # 功能:随机交换:随机交换句子中的两个词 - def random_swap(words, alpha, num_words, stop_words): - n = max(1, int(alpha * num_words)) - new_words = words.copy() - for _ in range(n): - new_words = swap_word(new_words) - return new_words - - # 功能:随机交换两个词 - def swap_word(new_words): - random_idx_1 = random.randint(0, len(new_words)-1) - random_idx_2 = random_idx_1 - counter = 0 - while random_idx_2 == random_idx_1: - random_idx_2 = random.randint(0, len(new_words)-1) - counter += 1 - if counter > 3: - return new_words - new_words[random_idx_1], new_words[random_idx_2] = new_words[random_idx_2], new_words[random_idx_1] - return new_words -``` - -### 2.4 词汇删除篇 - -#### 2.4.1 什么是随机删除法? - -- 方法:通过在 query 里面随机删除一个或多个词汇的方式提高 训练模型的健壮性。 -- 代码实现: - -```s - import random - # 功能:随机删除,以概率p删除语句中的词 - def random_deletion( words, alpha, num_words, stop_words): - if len(words) == 1: - return words - new_words = [] - for word in words: - r = random.uniform(0, 1) - if r > alpha: - new_words.append(word) - if len(new_words) == 0: - rand_int = random.randint(0, len(words)-1) - return [words[rand_int]] - return new_words -``` - - -### 2.5 回译篇 - -#### 2.5.1 什么是回译法? - -- 方法:利用百度翻译、谷歌翻译等在线翻译器来解释文本,并重新训练文本; -- 思路: -1. 将待数据增强的句子(如中文句子)翻译成另外一种语言,如英语、日语等; -2. 然后将翻译后的句子回译回中文句子; -3. 检查新句子是否与原来的句子不同。如果是,那么我们使用这个新句子作为原始文本的数据增强。 - -![](img/微信截图_20210102160355.png) - -### 2.6 交叉增强篇 - -#### 2.6.1 什么是 交叉增强篇 - -- 方法:借鉴遗传学中染色体交叉操作的方式进行数据增强。 -- 思路:将 tweets 切分未为两部分,两个具有相同极性的随机推文(即正面/负面)进行交换。这个方法的假设是,即使结果是不符合语法和语义的,新文本仍将保留情感的极性。 - -![](img/微信截图_20210102161002.png) - -- 实验结果分析:这一技术对准确性没有影响,但有助于论文中极少数类的F1分数,如tweets较少的中性类。 - -![](img/微信截图_20210102161058.png) - -### 2.7 语法树篇 - -#### 2.7.1 什么是语法树操作? - -- 思路:这项技术已经在Coulombe的论文中使用。其思想是解析和生成原始句子的依赖关系树,使用规则对其进行转换,并生成改写后的句子。 -- 举例说明:在不改变句子的含义的情况下将句子从主动转化为被动语态的方式,也是一种数据增强方式。 - -![](img/微信截图_20210102161342.png) - -- 实现方式:要使用上述所有方法,可以使用名为nlpaug的python库:https://github.com/makcedward/nlpaug。它提供了一个简单且一致的API来应用这些技术。 - -### 2.8 对抗增强篇 - -#### 2.8.1 什么是对抗增强? - -- 方法:NLP中通常在词向量上添加扰动并进行对抗训练,文献[10]NLP中的对抗训练方法FGM, PGD, FreeAT, YOPO, FreeLB等进行了总结。 - - -## 参考 - -1. [NLP中数据增强的综述,快速的生成大量的训练数据](https://zhuanlan.zhihu.com/p/142168215) -2. [NLP中的少样本困境问题探究](https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=2247519324&idx=2&sn=e561d9280cc12756b91288adc858c47c&chksm=ebb7b488dcc03d9e7092729c23ba8f8a986d32bbfde194c6f180357f1c5ad8c5c6e1791966c6&mpshare=1&scene=22&srcid=1208UwySgB0phVjDfti3dPP1&sharer_sharetime=1607390532506&sharer_shareid=da84f0d2d31380d783922b9e26cacfe2#rd) \ No newline at end of file diff --git "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230214346.png" "b/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230214346.png" deleted file mode 100644 index 55f695c..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230214346.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230214955.png" "b/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230214955.png" deleted file mode 100644 index ab80897..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230214955.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215334.png" "b/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215334.png" deleted file mode 100644 index 34daf4d..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215334.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215453.png" "b/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215453.png" deleted file mode 100644 index 31ae697..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215453.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215528.png" "b/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215528.png" deleted file mode 100644 index d7eb20f..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/QQ\346\210\252\345\233\27620201230215528.png" and /dev/null differ diff --git a/Trick/small_sample_problem/EDA/img/eda.drawio b/Trick/small_sample_problem/EDA/img/eda.drawio deleted file mode 100644 index a0264b7..0000000 --- a/Trick/small_sample_problem/EDA/img/eda.drawio +++ /dev/null @@ -1 +0,0 @@ -7VrbduMmFP0aVtsHZ+lu6VGynRnPmnbNjNtm2jciEYtGEh4Zx/Z8fUFCN4Rjp/FlkvTFCw4XAXvvwwEMzFG6eZfDRfwriVACDC3aAHMMDGM41NgvN2xLg2UNS8M8x1Fp0hvDDH9HwijazVc4QstORUpIQvGiawxJlqGQdmwwz8m6W+2OJN2vLuAc9QyzECZ96w2OaCysuuM1Be8RnsfVpx3bKktSWNUWU1nGMCLrlsmcAHOUE0LLVLoZoYQvXrUwZbvrHaX1yHKU0UMa/J1B93MYz67/eH8znn6j5Hb6fSAG+wCTlZixGCzdVkvAxr3gybsEbXy+pMAMUBaJ5DhM4HKJQ2aMaZowg16U03z7lWW0KvMXz1zZVXa8aReOtyLXn5OY5pKs8hA9MpGKHDCfI/pIPbOsh6IO7mLF3iGSIjYeVmHdoG0LAOMWzpUtRwmk+KHLFihIN6+7q7/wiWA2M0MT+qjJIeRR91t1Uc5btGqDK3c0lDrSpI7Khel1xBKtaTemgjtP4JGu4JGTsMUK7kgxzjso4HO+rTjjAzCxgT8BLktYIBgDz2yVtQlYGXlHg2XhIXxWQXcXm3YLZ1726gDXBR4bjwPTBbNkt8tFWaEYzqqpaQPPAd6IN/FHwK9HzBagqWVov338tKszVrOcXlVZkg5FG9oVxpLm5B6NSEJyZslIhvjMcJJIJpjgecbVxYSAmD14QDnFzC/5oiDFUcQ/E6xjTNFsUS7vmjlhZsvJKotQtE9UvE+0eVQGVakp08su8y2Z1HXaOjG13ZLocPCphDN2Ei7CD0r+hOUKc+7k89ufDZ23Bwb7vCalf+GZAvtbGN7Pi9UcSM35xESLTrJpm+AMDaq14M0MS8nYPTr5HadsA2Q0RGv2+4WkMDuGUJZbxrRtynvmSnBHwLV30ro2F2u7g+xd0qlo2dLBEThpeF1O6lW+zUmV73ZOxUnzJTvBIW8S6Gon2O3mf4/IAlnP2+8RLf00HvHDBOFrcz24iT//+QVPp9ksDwZ6P3TjUc5MZElOYzInGUwmjVVal6bOR0IWAqB/EKVbEZnDFSVSpLfB9Gsr3YrzWK4J83imG+VJIdjesE896X7Yp6xnqcE8OHx7HjLn9wvG436By95gTn8MKVzH/LTDLIEG3OvigyPA2F0mAqtIuMBl+wRzEKzasBjdGPhOUeQBnxWZvIJrvEQ/0BO9goq7IyOruwuZql3IU+xC1sn8gPUG/YD5TH2rT1WuLYErhw7HO1XtnlXHcUwLYFdReURlBDO0dFsEm5QyIA2tUXSxkDRD+dXrVZ/lSABZffUZqnPJ6dRnv0H1PXd3PUx9ln5e9fXvxqZhLPSHUc4VlmI+3hSxo17KEvcJT2WVDGEy+LRHggcdk44rEa8fqNa3R+cJVJ1LSOSIdLcPDDqdSwaddo+9H36CmB/3RybwPc7hMsU//oBCzmOSiV0DZRAXBI+q7eQHYrBlKRh8qsun3cB2A/peaN2yDIHnA9dqBdvsyK3xEJpfPerAN58YY18KCfcQJPRzIjHcg8QI+O5hkNTnnz42LwAJpVfXzomE+1xNHOsA+sNAcrA47BNB4vUh6W28ex7yjrhrXvahTbostgxJB4c+tPXCqTMfCXXVJfMTQf2vr7OqU4Z+rjPGoTd99iVppkvssOUjy8HvubrE13PTTLWxFm6Y74xDEFyDIOD+2A2KR4PXesFgynK3jau+W7cUjJIdzPGOT6qdtg8N2ycnfKt8O9Aobl7PC4xiv1UA44DABF7/mujVAlPvtZcCpuq4A0zluhpgKqheLTBD+a1CcVt6XmAUL2O143rLwFzalVVBpXSaKx3XGwbGOp1iWLb5L2gZxjX/qDUn/wI= \ No newline at end of file diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201231235616.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201231235616.png" deleted file mode 100644 index cb536d5..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20201231235616.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102160355.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102160355.png" deleted file mode 100644 index f5f2dcb..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102160355.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161002.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161002.png" deleted file mode 100644 index 124ee72..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161002.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161058.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161058.png" deleted file mode 100644 index 8d8cc92..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161058.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161342.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161342.png" deleted file mode 100644 index db713e7..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210102161342.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001405.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001405.png" deleted file mode 100644 index d6cf892..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001405.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001650.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001650.png" deleted file mode 100644 index 676ae7a..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001650.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001955.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001955.png" deleted file mode 100644 index 208cd0c..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117001955.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002233.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002233.png" deleted file mode 100644 index b08beae..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002233.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002650.png" "b/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002650.png" deleted file mode 100644 index fd940a8..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210117002650.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\346\225\260\346\215\256\345\242\236\345\274\272 EDA.xmind" "b/Trick/small_sample_problem/EDA/img/\346\225\260\346\215\256\345\242\236\345\274\272 EDA.xmind" deleted file mode 100644 index 0d3cff2..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\346\225\260\346\215\256\345\242\236\345\274\272 EDA.xmind" and /dev/null differ diff --git "a/Trick/small_sample_problem/EDA/img/\346\225\260\346\215\256\345\242\236\345\274\272EDA.png" "b/Trick/small_sample_problem/EDA/img/\346\225\260\346\215\256\345\242\236\345\274\272EDA.png" deleted file mode 100644 index 28aa7d8..0000000 Binary files "a/Trick/small_sample_problem/EDA/img/\346\225\260\346\215\256\345\242\236\345\274\272EDA.png" and /dev/null differ diff --git a/Trick/small_sample_problem/activeLearn/img/20201026103601.png b/Trick/small_sample_problem/activeLearn/img/20201026103601.png deleted file mode 100644 index 36c4486..0000000 Binary files a/Trick/small_sample_problem/activeLearn/img/20201026103601.png and /dev/null differ diff --git a/Trick/small_sample_problem/activeLearn/img/20201026103839.png b/Trick/small_sample_problem/activeLearn/img/20201026103839.png deleted file mode 100644 index 5cdad87..0000000 Binary files a/Trick/small_sample_problem/activeLearn/img/20201026103839.png and /dev/null differ diff --git a/Trick/small_sample_problem/activeLearn/img/20201026104224.png b/Trick/small_sample_problem/activeLearn/img/20201026104224.png deleted file mode 100644 index 1bc07e3..0000000 Binary files a/Trick/small_sample_problem/activeLearn/img/20201026104224.png and /dev/null differ diff --git a/Trick/small_sample_problem/activeLearn/img/20201026104844.png b/Trick/small_sample_problem/activeLearn/img/20201026104844.png deleted file mode 100644 index d5fd080..0000000 Binary files a/Trick/small_sample_problem/activeLearn/img/20201026104844.png and /dev/null differ diff --git a/Trick/small_sample_problem/activeLearn/img/20201026112155.png b/Trick/small_sample_problem/activeLearn/img/20201026112155.png deleted file mode 100644 index cbd8eb3..0000000 Binary files a/Trick/small_sample_problem/activeLearn/img/20201026112155.png and /dev/null differ diff --git "a/Trick/small_sample_problem/activeLearn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210108222507.png" "b/Trick/small_sample_problem/activeLearn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210108222507.png" deleted file mode 100644 index 69f20f0..0000000 Binary files "a/Trick/small_sample_problem/activeLearn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210108222507.png" and /dev/null differ diff --git "a/Trick/small_sample_problem/activeLearn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210194424.png" "b/Trick/small_sample_problem/activeLearn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210194424.png" deleted file mode 100644 index 4eb322d..0000000 Binary files "a/Trick/small_sample_problem/activeLearn/img/\345\276\256\344\277\241\346\210\252\345\233\276_20210210194424.png" and /dev/null differ diff --git a/Trick/small_sample_problem/activeLearn/readme.md b/Trick/small_sample_problem/activeLearn/readme.md deleted file mode 100644 index 8e429d8..0000000 --- a/Trick/small_sample_problem/activeLearn/readme.md +++ /dev/null @@ -1,106 +0,0 @@ -# 【关于 主动学习】 那些你不知道的事 - -> 作者:杨夕、芙蕖、李玲、陈海顺、twilight、LeoLRH、JimmyDU、艾春辉、张永泰、金金金 -> -> 面筋地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人笔记:https://github.com/km1994/nlp_paper_study -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> -> 【注:手机阅读可能图片打不开!!!】 - -![](img/微信截图_20210210194424.png) - -## 一、动机篇 - -### 1.1 主动学习是什么? - -- 类型:机器学习算法 -- 思路: - - 通过主动找到最有价值的训练样本加入训练集,如果该样本是未标记的,则会自动要求人工标注,然后再用于模型训练; -- 目标:以更少的训练样本训练出性能尽可能高的模型; - -### 1.2 为什么需要主动学习? - -- 数据标注成本高,尤其是专业知识领域; -- 数据量巨大,难以全量训练 ,或训练机器/时间有限; - -## 二、主动学习篇 - -### 2.1 主动学习的思路是什么? - -该方法首先筛选出条的未标记样本,然后对其手动标记,然后采用该标记过的数据训练实体识别模型,接着,用训练后的模型标记未标记数据;最后,利用主动学习的样本抽取策略计算未标记样本的价值量后排序,挑拣条价值含量最高的未标记数据,手工标记后合并标记样本,并作为新的训练集。循环实行以上步骤,当被检测指标满足预设范围后停止循环。 - -![](img/微信截图_20210108222507.png) - -### 2.2 主动学习方法 的价值点在哪里? - -- 主动学习能减少样本标注量来节约成本,包括标注成本和训练资源成本;并且主动学习能在同等数据量下提升模型性能。 - -> 未标注的样本池有1000w个样本,应用主动学习从中挑出200w样本进行标注后训练,便能训练出性能与1000w训练相当的模型。通常认为,主动学习能减少一半以上的样本标注量。有时主动学习挑选数据集子集进行训练,模型性能能超越全量训练。 - -## 三、样本选取策略篇 - -### 3.1 以未标记样本的获取方式的差别进行划分 - -- 成员查询的样本选取策略主要是从未标记样本中选取出能有效提升训练模型实体识别效果的样本,并对其进行手工标记,虽然该方法操作起来比较方便,但是容易挑选出比较多的无价值样本。 -- 基于流的样本选取策略将未标记样本排列成一个队列,而后每一时刻对当前队头样本标记。 -- 基于池的样本选取策略从未标记样本集中选取一部分样本置于待标记样本池中,方便后期抽取。 - -### 3.2 测试集内选取“信息”量最大的数据标记 - -#### 3.2.1 测试集内选取“信息”量最大的数据标记 - -- 依赖委员会的样本选取策略(Query by committee, QBC):首先利用当前已标记样本集训练得到多个NER模型组建委员会;然后委员会成员分别根据自己的经验判断未标记样本中每个词可能属于的类型;而后统计样本中每个词的不同类型选项所获得的成员票数;最后,抽取出所获得的选票最不统一的样本标记。如果未标记样本带有信息量较高时,容易误导委员会中不同成员对其的判断,使其做出不正确的反应,NER模型通过这些标记好的信息量最多的样本,能够为当前NER模型带来较大的泛化能力提升。 -- 依赖不确定度的样本选取策略(Uncertainty Sampling, US):利用信息熵方法评估标记样本的不稳定性。该方法首先通过已标记样本集对实体识别模型进行训练,然后利用该模型计算样本中每个字符隶属于不同实体类型的概率,最后,标记不稳定性高的数据,通过利用这些不稳定性高的数据训练实体识别模型,能够提高模型预能力。 -- 依赖代表性大的样本选取策略(Representative Sampling, RS):首先计算未标记样本中不同样本的向量化表示,然后,采用聚类分析使样本聚类成多个簇,最后从聚类所得到的不同簇中挑出离中心点最近的样本进行标记。一般而言,未标记样本集中某些样本具有一些相同的特征,聚类分析方法能够根据这些特征,将其划分到不同的簇中。离该簇中心点越近的样本点,具有能够很好的代表该样本所在簇的其他样本,所以对该样本点进行学习,能提高NER模型对该簇中其他未标记样本的实体识别能力。 - -#### 3.2.2 依赖不确定度的样本选取策略(Uncertainty Sampling, US) - -- 思想:不确定性越大,蕴含信息量越大,越有训练价值; -- 流程: -1. 用已打标的数据子集训练模型,用该模型预测剩余未打标样本; -2. 根据预测结果使用不确定性衡量标准找出最不确定的样本; -3. 交给打标人员标注; -4. 加入训练集训练模型,再用该模型进行数据挑选,反复迭代; -- 代表方法 - -1. least confident(LC) - 1. 关注模型预测时置信度值很大,“可信度”依旧很低的样本; - 2. 缺点:没关注易混淆的样本; - 3. 公式: - -![](img/20201026103601.png) - -> P(yi|x):样本 x 分类为 yi 的概率,即模型输出的 score 值; - -2. smallest margin(SM) - 1. 关注置信度最大的两个值的差(margin)最小的样本,即易混淆的样本,该方案是针对LC的缺点进行的改进。 - 2. 公式 - -![](img/20201026103839.png) - -> P(y1|x):样本 x 分类为 y1 的概率,即模型输出的 score 值;
-> P(y2|x):样本 x 分类为 y2 的概率,即模型输出的 score 值;
- -3. entropy(ENT) - 1. 关注综合信息量最大的样本 - 2. 公式: - -![](img/20201026104224.png) - -#### 3.2.3 基于委员会查询的方法(Query-By-Committee,QBC) - -- 思想:将优化ML模型看成是版本空间搜索,QBC通过压缩版本空间的搜索范围,找到最优秀ML模型。 -- 流程:相同训练集训练多个同结构的模型,模型投票选出争议样本,将争议样本打标后训练模型,反复迭代。 -- 计算公式 - -![](img/20201026104844.png) - -> C 分类类别数; -> Vot(yi) 是 类别 yi 所获得票数; - -## 参考资料 - -1. [主动学习方法实践:让模型变“主动”](https://developer.aliyun.com/article/766940) \ No newline at end of file diff --git a/Trick/warm_up/readme.md b/Trick/warm_up/readme.md deleted file mode 100644 index e4cf368..0000000 --- a/Trick/warm_up/readme.md +++ /dev/null @@ -1,49 +0,0 @@ -# 【关于 Warm up 】那些你不知道的事 - -> 作者:杨夕 -> -> 论文学习项目地址:https://github.com/km1994/nlp_paper_study -> -> 《NLP 百面百搭》地址:https://github.com/km1994/NLP-Interview-Notes -> -> 个人介绍:大佬们好,我叫杨夕,该项目主要是本人在研读顶会论文和复现经典论文过程中,所见、所思、所想、所闻,可能存在一些理解错误,希望大佬们多多指正。 -> - -![](img/微信截图_20210301212242.png) - -> NLP && 推荐学习群【人数满了,加微信 blqkm601 】 - -![](img/20210523220743.png) - -- [【关于 Warm up 】那些你不知道的事](#关于-warm-up-那些你不知道的事) - - [一、 什么是 Warm up?](#一-什么是-warm-up) - - [二、为什么需要 Warm up?](#二为什么需要-warm-up) - - [参考](#参考) - -## 一、 什么是 Warm up? - -Warmup 是在 ResNet 论文中提到的一种学习率预热的方法,它在训练开始的时候先选择使用一个较小的学习率,训练了一些 epoches 或者 steps (比如 4 个 epoches,10000steps),再修改为预先设置的学习来进行训练。 - -## 二、为什么需要 Warm up? - -- **在训练的开始阶段,模型权重迅速改变**。 刚开始模型对数据的“分布”理解为零,或者是说“均匀分布”(当然这取决于你的初始化);在第一轮训练的时候,每个数据点对模型来说都是新的,模型会很快地进行数据分布修正,**如果这时候学习率就很大,极有可能导致开始的时候就对该数据“过拟合”,后面要通过多轮训练才能拉回来,浪费时间。**当训练了一段时间(比如两轮、三轮)后,模型已经对每个数据点看过几遍了,或者说对当前的batch而言有了一些正确的先验,较大的学习率就不那么容易会使模型学偏,所以可以适当调大学习率。这个过程就可以看做是warmup。那么为什么之后还要decay呢?当模型训到一定阶段后(比如十个epoch),模型的分布就已经比较固定了,或者说能学到的新东西就比较少了。如果还沿用较大的学习率,就会破坏这种稳定性,用我们通常的话说,就是已经接近loss的local optimal了,为了靠近这个point,我们就要慢慢来。 - -- **mini-batch size较小,样本方差较大**。第二种情况其实和第一种情况是紧密联系的。在训练的过程中,**如果有mini-batch内的数据分布方差特别大,这就会导致模型学习剧烈波动,使其学得的权重很不稳定**,这在训练初期最为明显,最后期较为缓解(所以我们要对数据进行scale也是这个道理)。 - - - - -## 参考 - -1. [神经网络中 warmup 策略为什么有效;有什么理论解释么?](https://www.zhihu.com/question/338066667) -2. [AdaBelief-更稳定的优化器](https://xv44586.github.io/2020/10/25/adabelief/) -3. [深度神经网络模型训练中的最新 tricks 总结【原理与代码汇总】](https://bbs.cvmart.net/articles/3320/vote_count?) -4. [【基础知识】Warmup预热学习率_菜鸟起飞-程序员宅基地](http://www.cxyzjd.com/article/nefetaria/110212564) -5. [”预热学习率“ 的搜索结果](http://www.cxyzjd.com/searchArticle?qc=%E9%A2%84%E7%83%AD%E5%AD%A6%E4%B9%A0%E7%8E%87&page=1) -6. [ICML 2020 | 摆脱warm-up!巧置LayerNorm使Transformer加速收敛](https://www.msra.cn/zh-cn/news/features/pre-ln-transformer) -7. [深度學習Warm up策略在幹什麼?](https://chih-sheng-huang821.medium.com/%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92warm-up%E7%AD%96%E7%95%A5%E5%9C%A8%E5%B9%B9%E4%BB%80%E9%BA%BC-95d2b56a557f) -8. [深度学习深度学习模型训练的tricks总结](https://www.codenong.com/cs105809498/) - - - - diff --git a/img/20230408151226.jpg b/img/20230408151226.jpg new file mode 100644 index 0000000..e44a527 Binary files /dev/null and b/img/20230408151226.jpg differ diff --git a/img/zfb.jpg b/img/zfb.jpg new file mode 100644 index 0000000..e2fb247 Binary files /dev/null and b/img/zfb.jpg differ diff --git "a/img/\345\276\256\344\277\241\345\233\276\347\211\207_20230908090442.jpg" "b/img/\345\276\256\344\277\241\345\233\276\347\211\207_20230908090442.jpg" new file mode 100644 index 0000000..da918c9 Binary files /dev/null and "b/img/\345\276\256\344\277\241\345\233\276\347\211\207_20230908090442.jpg" differ diff --git "a/img/\345\276\256\344\277\241\346\210\252\345\233\276_20230918094559.png" "b/img/\345\276\256\344\277\241\346\210\252\345\233\276_20230918094559.png" new file mode 100644 index 0000000..690cc1a Binary files /dev/null and "b/img/\345\276\256\344\277\241\346\210\252\345\233\276_20230918094559.png" differ diff --git "a/img/\345\276\256\344\277\241\346\210\252\345\233\276_20230919230619.png" "b/img/\345\276\256\344\277\241\346\210\252\345\233\276_20230919230619.png" new file mode 100644 index 0000000..8bf8969 Binary files /dev/null and "b/img/\345\276\256\344\277\241\346\210\252\345\233\276_20230919230619.png" differ