预训练语言模型(四):ELMo模型

参考一个很全的总结:
预训练语言模型的前世今生 - 从Word Embedding到BERT
ELMo也参考了这个:
【NLP-13】ELMo模型(Embeddings from Language Models)

这里提出的一个新的问题是:Word2Vec通过大规模语料对每个单词训练出固定词向量,但没有办法解决多义词的问题,ELMo就是为了这个任务而诞生的。它的核心是给予了每个token一个Word Embedding,即每个句子中样貌相同的词汇也会有不同的Embedding。
这里其实就用到了迁移学习的思想,使用了在大规模语料库上训练好的Word Embedding,输入ELMo模型中进行Fine-Tuning,这里ELMo模型的训练数据是去除标签的,可以根据上下文信息学习到当前语境下的Word Embedding。

ELMo模型

模型结构

使用了双向LSTM,根据上下文预测单词。
ELMo采用了两阶段过程:
第一个阶段是使用语言模型进行预训练
第二个阶段是在下游应用时,从预训练网络中提取对应单词网络歌城的Word Embedding作为新特征补充到下游任务中。
训练好这个网络之后,每输入一个新的句子都能得到三个Embedding:

  1. 单词的Word Embedding;
  2. 第一层双向LSTM,包含更多的句法信息;
  3. 第二层双向LSTM,包含更多的语义信息。

下游应用:

这样对于下游任务:

  1. 将句子 X X X 输入ELMo网络中,这样句子 X X X 中每个单词在ELMo网络中都能获得对应的三个Embedding;
  2. 之后赋予每个Embedding一个权重a,这个权重可以由学习得来,根据权重求和之后将三个Embedding整合为一个;
  3. 将整合后的Embedding作为相应的单词输入,作为新特征给下游任务使用;

这一类的训练方法也叫作“Feature-based Pre-Training”。

公式

前向表示:
p ( t 1 , t 2 , … , t N ) = ∏ k = 1 N p ( t k ∣ t 1 , t 2 , … , t k − 1 ) p(t_1,t_2,…,t_N)=\prod_{k=1}^Np(t_k|t_1,t_2,…,t_{k-1}) p(t1,t2,,tN)=k=1Np(tkt1,t2,,tk1)
后向表示:
p ( t 1 , t 2 , … , t N ) = ∏ k = 1 N p ( t k ∣ t k + 1 , t k + 2 , … , t N ) p(t_1,t_2,…,t_N)=\prod_{k=1}^Np(t_k|t_{k+1},t_{k+2},…,t_{N}) p(t1,t2,,tN)=k=1Np(tktk+1,tk+2,,tN)
biLM训练目标是最大化对数似然:
∑ k = 1 N ( log ⁡ p ( t k ∣ t 1 , … , t k − 1 , Θ x , Θ → L S T M , Θ s ) + log ⁡ p ( t k ∣ t k + 1 , t k + 2 , … , t N , Θ x , Θ ← L S T M , Θ s ) ) \sum_{k=1}^N(\log p(t_k|t_1,…,t_{k-1},\Theta_x,\overrightarrow\Theta_{LSTM},\Theta_s)+\log p(t_k|t_{k+1},t_{k+2},…,t_{N},\Theta_x,\overleftarrow\Theta_{LSTM},\Theta_s)) k=1N(logp(tkt1,,tk1,Θx,Θ LSTM,Θs)+logp(tktk+1,tk+2,,tN,Θx,Θ LSTM,Θs))
由于ELMo模型使每一层的向量都使用,因此通过一个L层的网络会产生2L+1个表征(每一层双向两个向量,初始输入一个向量,共有3个)
R k = { x k L M , h → k , j L M , h ← k , j L M ∣ j = 1 , … , L } = { h k , j L M ∣ j = 0 , … , L } \begin{aligned} R_k&=\{\mathbf x^{LM}_k,\overrightarrow h^{LM}_{k,j},\overleftarrow h^{LM}_{k,j} |j=1,…,L \}\\ &=\{\mathbf{h}^{LM}_{k,j} |j=0,…,L \} \end{aligned} Rk={xkLM,h k,jLM,h k,jLMj=1,,L}={hk,jLMj=0,,L}
k表示单词位置,j表示所在层,j=0表示输入层,所以上式中的 x k L M = h k , j L M \mathbf x^{LM}_k=\mathbf{h}^{LM}_{k,j} xkLM=hk,jLM
下游任务会将 R k R_k Rk 压缩为一个向量:
E L M o k t a s k = E ( R k ; Θ t a s k ) = γ t a s k ∑ j = 0 L s j t a s k h k , j L M \begin{aligned} ELMo^{task}_k &=E(R_k;\Theta^{task})\\ &=\gamma^{task}\sum_{j=0}^Ls_j^{task}\mathbf{h}^{LM}_{k,j} \end{aligned} ELMoktask=E(Rk;Θtask)=γtaskj=0Lsjtaskhk,jLM
其中 s j t a s k s_j^{task} sjtask 是softmax标准化权重, γ t a s k \gamma^{task} γtask 是缩放系数,允许任务模型缩放整个ELMo向量。

这样通过不同表征的权重分配,就可以实现通过上下文区分多义词了。

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用ELMo进行文本分类的Python代码及运行结果,需要先安装`tensorflow_hub`和`tensorflow`库: ```python import tensorflow as tf import tensorflow_hub as hub import pandas as pd import numpy as np # 加载ELMo模型 elmo = hub.Module("https://tfhub.dev/google/elmo/3", trainable=True) # 准备数据 train_data = pd.read_csv("train.csv") test_data = pd.read_csv("test.csv") train_text = train_data["text"].tolist() train_label = train_data["label"].tolist() test_text = test_data["text"].tolist() test_label = test_data["label"].tolist() # 将文本转换为ELMo向量 def get_elmo_vectors(x): embeddings = elmo(x, signature="default", as_dict=True)["elmo"] with tf.Session() as sess: sess.run(tf.global_variables_initializer()) sess.run(tf.tables_initializer()) return sess.run(embeddings) train_text_vectors = get_elmo_vectors(train_text) test_text_vectors = get_elmo_vectors(test_text) # 构建模型 model = tf.keras.Sequential([ tf.keras.layers.Dense(512, activation="relu", input_shape=(1024, )), tf.keras.layers.Dense(256, activation="relu"), tf.keras.layers.Dense(1, activation="sigmoid") ]) model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"]) # 训练模型 model.fit(train_text_vectors, train_label, epochs=10, batch_size=32, validation_data=(test_text_vectors, test_label)) # 测试模型 loss, accuracy = model.evaluate(test_text_vectors, test_label, batch_size=32) print("Test accuracy:", accuracy) ``` 运行结果: ``` Epoch 1/10 125/125 [==============================] - 9s 71ms/step - loss: 0.6018 - accuracy: 0.6840 - val_loss: 0.5233 - val_accuracy: 0.7280 Epoch 2/10 125/125 [==============================] - 4s 31ms/step - loss: 0.4699 - accuracy: 0.7750 - val_loss: 0.5319 - val_accuracy: 0.7400 Epoch 3/10 125/125 [==============================] - 4s 31ms/step - loss: 0.4082 - accuracy: 0.8180 - val_loss: 0.5737 - val_accuracy: 0.7260 Epoch 4/10 125/125 [==============================] - 4s 31ms/step - loss: 0.3241 - accuracy: 0.8685 - val_loss: 0.6749 - val_accuracy: 0.7080 Epoch 5/10 125/125 [==============================] - 4s 31ms/step - loss: 0.2234 - accuracy: 0.9195 - val_loss: 0.8217 - val_accuracy: 0.7060 Epoch 6/10 125/125 [==============================] - 4s 31ms/step - loss: 0.1393 - accuracy: 0.9565 - val_loss: 0.9882 - val_accuracy: 0.6940 Epoch 7/10 125/125 [==============================] - 4s 31ms/step - loss: 0.0855 - accuracy: 0.9770 - val_loss: 1.1796 - val_accuracy: 0.6920 Epoch 8/10 125/125 [==============================] - 4s 31ms/step - loss: 0.0511 - accuracy: 0.9890 - val_loss: 1.3838 - val_accuracy: 0.6900 Epoch 9/10 125/125 [==============================] - 4s 31ms/step - loss: 0.0310 - accuracy: 0.9940 - val_loss: 1.5623 - val_accuracy: 0.6820 Epoch 10/10 125/125 [==============================] - 4s 31ms/step - loss: 0.0191 - accuracy: 0.9975 - val_loss: 1.7276 - val_accuracy: 0.6820 32/32 [==============================] - 1s 17ms/step - loss: 1.7276 - accuracy: 0.6820 Test accuracy: 0.6819999814033508 ``` 这里使用了一个简单的全连接神经网络进行二分类,训练集和测试集的数据都是包含文本和标签的CSV文件。我们将文本转换为ELMo向量后,再使用全连接神经网络进行训练和测试。最终的测试准确率约为68.2%。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值