词向量——预训练词嵌入

预训练词嵌入是在一个任务中学习到的嵌入,可用于解决另一个类似的任务。这些嵌入在大型数据集上进行训练、保存,然后用于解决其他任务。这就是为什么预训练的词嵌入是迁移学习的一种形式。

迁移学习,顾名思义,就是将一项任务的学习转移到另一项任务。学习可以是权重或嵌入。在我们的例子中,学习就是嵌入。因此,这个概念被称为预训练词嵌入,在权重的情况下,这个概念被称为预训练模型。

但是,为什么我们首先需要预训练的词向量呢?为什么我们不能从头开始学习词向量呢?

案例研究:从头开始学习词嵌入与预训练词嵌入

让我们通过一个案例研究来比较从头开始学习词嵌入与预训练词嵌入的性能。我们还将旨在了解使用预训练词嵌入是否会提高 NLP 模型的性能。

那么,让我们研究一下文本分类问题------电影评论的情感分析。从这里下载电影评论数据集。

将数据集加载到我们的 Jupyter Notebook 中

python 复制代码
#importing libraries
import pandas as pd
import numpy as np

#reading csv files
train = pd.read_csv('Train.csv')
valid = pd.read_csv('Valid.csv')             

#train_test split
x_tr, y_tr = train['text'].values, train['label'].values
x_val, y_val = valid['text'].values, valid['label'].values
准备数据
python 复制代码
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences

#Tokenize the sentences
tokenizer = Tokenizer()

#preparing vocabulary
tokenizer.fit_on_texts(list(x_tr))

#converting text into integer sequences
x_tr_seq  = tokenizer.texts_to_sequences(x_tr) 
x_val_seq = tokenizer.texts_to_sequences(x_val)

#padding to prepare sequences of same length
x_tr_seq  = pad_sequences(x_tr_seq, maxlen=100)
x_val_seq = pad_sequences(x_val_seq, maxlen=100)

让我们看一下训练数据中唯一单词的数量:

python 复制代码
#Create a variable for the size of vocab
size_of_vocabulary=len(tokenizer.word_index) + 1 #+1 for padding
print(size_of_vocabulary)

输出:112204

我们将构建两个具有相同架构的不同 NLP 模型。第一个模型从头开始学习嵌入,第二个模型使用预训练的词嵌入。

定义架构------从头开始学习嵌入
python 复制代码
#deep learning library
from keras.models import *
from keras.layers import *
from keras.callbacks import *

model=Sequential()

#embedding layer
model.add(Embedding(size_of_vocabulary,300,input_length=100,trainable=True)) 

#lstm layer
model.add(LSTM(128,return_sequences=True,dropout=0.2))

#Global Maxpooling
model.add(GlobalMaxPooling1D())

#Dense Layer
model.add(Dense(64,activation='relu')) 
model.add(Dense(1,activation='sigmoid')) 

#Add loss function, metrics, optimizer
model.compile(optimizer='adam', loss='binary_crossentropy',metrics=["acc"]) 

#Adding callbacks
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1,patience=3)  
mc=ModelCheckpoint('best_model.h5', monitor='val_acc', mode='max', save_best_only=True,verbose=1)  

#Print summary of model
print(model.summary())

输出

python 复制代码
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 embedding (Embedding)       (None, 100, 300)          33661200  
                                                                 
 lstm (LSTM)                 (None, 100, 128)          219648    
                                                                 
 global_max_pooling1d (Glob  (None, 128)               0         
 alMaxPooling1D)                                                 
                                                                 
 dense (Dense)               (None, 64)                8256      
                                                                 
 dense_1 (Dense)             (None, 1)                 65        
                                                                 
=================================================================
Total params: 33889169 (129.28 MB)
Trainable params: 33889169 (129.28 MB)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________
None

该模型中可训练参数总数为 33,889,169,其中 Embedding 层贡献了 33,661,200 个参数。这非常庞大!

训练模型
python 复制代码
import numpy as np
history = model.fit(np.array(x_tr_seq),np.array(y_tr),batch_size=128,epochs=10,validation_data=(np.array(x_val_seq),np.array(y_val)),verbose=1,callbacks=[es,mc])
评估模型性能
python 复制代码
#loading best model
from keras.models import load_model
model = load_model('best_model.h5')

#evaluation 
_,val_acc = model.evaluate(x_val_seq,y_val, batch_size=128)
print(val_acc)

输出:0.866599977016449

现在,是时候使用 GloVe 预训练的词嵌入构建版本 II 了。让我们将 GloVe 嵌入加载到我们的环境中:

python 复制代码
# load the whole embedding into memory
embeddings_index = dict()
f = open('glove.6B.300d.txt')

for line in f:
    values = line.split()
    word = values[0]
    coefs = np.asarray(values[1:], dtype='float32')
    embeddings_index[word] = coefs

f.close()
print('Loaded %s word vectors.' % len(embeddings_index))
通过使用预训练的词嵌入分配词汇来创建嵌入矩阵
python 复制代码
# create a weight matrix for words in training docs
embedding_matrix = np.zeros((size_of_vocabulary, 300))

for word, i in tokenizer.word_index.items():
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
        embedding_matrix[i] = embedding_vector
定义架构------预训练嵌入
python 复制代码
model=Sequential()

#embedding layer
model.add(Embedding(size_of_vocabulary,300,weights=[embedding_matrix],input_length=100,trainable=False)) 

#lstm layer
model.add(LSTM(128,return_sequences=True,dropout=0.2))

#Global Maxpooling
model.add(GlobalMaxPooling1D())

#Dense Layer
model.add(Dense(64,activation='relu')) 
model.add(Dense(1,activation='sigmoid')) 

#Add loss function, metrics, optimizer
model.compile(optimizer='adam', loss='binary_crossentropy',metrics=["acc"]) 

#Adding callbacks
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1,patience=3)  
mc=ModelCheckpoint('best_model.h5', monitor='val_acc', mode='max', save_best_only=True,verbose=1)  

#Print summary of model
print(model.summary())
输出:
python 复制代码
Model: "sequential_1"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 embedding_1 (Embedding)     (None, 100, 300)          33661200  
                                                                 
 lstm_1 (LSTM)               (None, 100, 128)          219648    
                                                                 
 global_max_pooling1d_1 (Gl  (None, 128)               0         
 obalMaxPooling1D)                                               
                                                                 
 dense_2 (Dense)             (None, 64)                8256      
                                                                 
 dense_3 (Dense)             (None, 1)                 65        
                                                                 
=================================================================
Total params: 33889169 (129.28 MB)
Trainable params: 227969 (890.50 KB)
Non-trainable params: 33661200 (128.41 MB)
_________________________________________________________________
None

如你所见,可训练参数的数量只有 227,969。与嵌入层相比,这是一个巨大的下降。

训练模型
python 复制代码
history = model.fit(np.array(x_tr_seq),np.array(y_tr),batch_size=128,epochs=10,validation_data=(np.array(x_val_seq),np.array(y_val)),verbose=1,callbacks=[es,mc])
评估模型的性能:
python 复制代码
#loading best model
from keras.models import load_model
model = load_model('best_model.h5')

#evaluation 
_,val_acc = model.evaluate(x_val_seq,y_val, batch_size=128)
print(val_acc)

输出:0.8827999830245972

与从头开始学习嵌入相比,使用预训练的词嵌入性能有所提高。您可以运行代码,进行一些更改,甚至可以使用机器学习进行尝试。

相关推荐
AIGCmagic社区10 小时前
AI多模态技术介绍:理解多模态大语言模型的原理
人工智能·语言模型·自然语言处理
开放知识图谱13 小时前
论文浅尝 | HippoRAG:神经生物学启发的大语言模型的长期记忆(Neurips2024)
人工智能·语言模型·自然语言处理
i查拉图斯特拉如是19 小时前
基于MindSpore NLP的PEFT微调
人工智能·自然语言处理
野蛮的大西瓜1 天前
BigBlueButton视频会议 vs 钉钉视频会议系统的详细对比
人工智能·自然语言处理·自动化·音视频·实时音视频·信息与通信·视频编解码
Hugging Face2 天前
欢迎 PaliGemma 2 – 来自 Google 的新视觉语言模型
人工智能·语言模型·自然语言处理
宝贝儿好2 天前
【NLP】第七章:Transformer原理及实操
人工智能·深度学习·自然语言处理·transformer
新加坡内哥谈技术2 天前
OpenAI发布全新AI模型 o3 与 o3-mini:推理与编码能力迎来重大突破. AGI 来临
大数据·人工智能·语言模型·自然语言处理
三月七(爱看动漫的程序员)2 天前
Knowledge Graph Prompting for Multi-Document Question Answering
人工智能·gpt·学习·语言模型·自然语言处理·机器人·知识图谱
sp_fyf_20242 天前
【大语言模型】ACL2024论文-28 TTM-RE: 增强记忆的文档级关系抽取
人工智能·深度学习·机器学习·计算机视觉·语言模型·自然语言处理·数据挖掘
sp_fyf_20242 天前
【大语言模型】ACL2024论文-33 Johnny 如何说服大型语言模型越狱:通过人性化 LLMs 重新思考挑战 AI 安全性的说服技巧
人工智能·深度学习·机器学习·语言模型·自然语言处理·数据挖掘