文章目录
- Word2Vec实现
- 一、训练模型
- 1. 数据预处理
- 2. 构建训练数据
- 3. 搭建word2vec网络(CBOW)
- 4. 装配设备
- 5. 构建训练模型
- 6. 优化器
- 7. 损失函数
- 8. 迭代模型
- 二、测试模型
- 1. 预测单词
- 2. 生成词嵌入词典
- 3. 保存训练后的词向量
- 总结
Word2Vec实现
Word2Vec 是一种用于自然语言处理(NLP)的深度学习技术,主要用于将词汇表中的单词或短语从词汇空间映射到向量的实数空间,这些向量通常称为词向量(word vectors)。生成的词向量能够捕捉单词之间的语义和语法关系,极大地促进了 NLP 任务的性能和准确性。
一、训练模型
1. 数据预处理
对语料库进行去重(利用集合的特性,进行去重),然后对每个单词进行编号:
"""-----语料库去重-----"""
CONTEXT_SIZE = 2 # 设置词左边和右边选择的个数
raw_text = """We are about to study the idea of a computational process.
Computational processes are abstract beings that inhabit computers.
As they evolve, processes manipulate other abstract things called data.
The evolution of a process is directed by a pattern of rules
called a program. People create programs to direct processes. In effect,
we conjure the spirits of the computer with our spells.""".split()
vocab = set(raw_text) # 将列表转化为集合,去重
vocab_size = len(vocab)
"""-----对每个单词编号-----"""
# for循环的复合写法,第一次循环,i得到的索引号,word得到第1个单词
word_to_idx = {word:i for i,word in enumerate(vocab)}
idx_to_word = {i:word for i,word in enumerate(vocab)}
2. 构建训练数据
将每个中心词的前两个与后两个词放在一起作为特征,将中心词作为标签:
data = [] # 获取上下文词,将上下文词作为输入,目标词作为输出,构建训练数据集
for i in range(CONTEXT_SIZE,len(raw_text) - CONTEXT_SIZE):
context = (
[raw_text[i - (2-j)] for j in range(CONTEXT_SIZE)] # [we,are]
+ [raw_text[i + j + 1] for j in range(CONTEXT_SIZE)] # [to,study]
) # 元组,获取上下文词(['we','are','to','study'])
target = raw_text[i] # 获取目标词'about'
data.append((context,target)) # 将上下文词和目标词保存到data中[((['we','are','to','study']),'about')]
def make_context_vector(context,word_to_ix):
idxs = [word_to_ix[w] for w in context]
return torch.tensor(idxs,dtype=torch.long)
print(make_context_vector(data[0][0],word_to_idx))
-------------
tensor([22, 9, 31, 30])
3. 搭建word2vec网络(CBOW)
class CBOW(nn.Module):
def __init__(self,vocab_size,embedding_dim):
super(CBOW,self).__init__()
self.embedding = nn.Embedding(vocab_size,embedding_dim) # 词嵌入层,得到词向量信息
self.proj = nn.Linear(embedding_dim,128)
self.output = nn.Linear(128,vocab_size)
def forward(self,inputs):
embeds = sum(self.embedding(inputs)).view(1,-1)
out = F.relu(self.proj(embeds))
out = self.output(out)
nll_prob = F.log_softmax(out,dim=-1)
return nll_prob
4. 装配设备
# 模拟在cuda训练
device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu"
print(device)
-----------
cuda
5. 构建训练模型
model = CBOW(vocab_size,10).to(device)
6. 优化器
optimizer = optim.Adam(model.parameters(),lr=0.001)
7. 损失函数
NLLLoss损失函数(当分类列表比较多的情况),将多个类别分别分成0,1两个类别:
"""-----损失函数-----"""
losses = [] # 存储损失的集合
loss_function = nn.NLLLoss() # NLLLoss损失函数(当分类列表比较多的情况),将多个类别分别分成0,1两个类别
8. 迭代模型
"""-----迭代模型参数权重-----"""
for epoch in tqdm(range(200)):
total_loss = 0
for context,target in data:
context_vector = make_context_vector(context,word_to_idx).to(device)
target = torch.tensor([word_to_idx[target]]).to(device)
# 开始前向传播
train_predict = model(context_vector)
loss = loss_function(train_predict,target)
# 反向传播
optimizer.zero_grad() # 梯度值清零
loss.backward() # 反向传播计算得到每个参数的梯度值
optimizer.step()# 根据梯度更新网络参数
total_loss += loss.item()
losses.append(total_loss)
----------------------
100%|██████████| 200/200 [00:24<00:00, 8.11it/s]
二、测试模型
1. 预测单词
"""-----测试-----"""
context = ['process','is','by','a']
context_vector = make_context_vector(context,word_to_idx).to(device)
# 预测的值
model.eval() # 进入测试模式
predict = model(context_vector)
max_idx = predict.argmax(1)
# 预测的单词
keys = [key for key, value in word_to_idx.items() if value == max_idx]
print("process is by a中间的是"," ".join(keys))
----------------
process is by a中间的是 directed
2. 生成词嵌入词典
获取每个词的词向量,将对应的词同词向量一一对应以字典类型存放:
"""-----生成词嵌入字典-----"""
# 获取词向量,这个Embedding就是我们需要的词向量,他只是一个模型的中间过程
print("CBOW embedding'weight = ",model.embedding.weight)
w = model.embedding.weight.cpu().detach().numpy()
print(w)
word_2_vec = {}
for word in word_to_idx.keys():
# 词向量矩阵中某个词的索引所对应的那一列即为该词的词向量
word_2_vec[word] = w[word_to_idx[word],:]
print('结束')
3. 保存训练后的词向量
训练后的词向量保存为npz文件:npz文件是numpy库中的一种数据格式,它是一种压缩文件,可以保存多个数组和元数据。
- 保存方法:
np.savez("文件名称格式",文件)
- 调用方法:
data = np.load("文件名")
np.savez("word2vec实现.npz",file_1=w)
data = np.load("word2vec实现.npz")
print(data.files)
------------
['file_1']
总结
本篇介绍了:
- 如何实现Word2Vec,从而搭建网络模型进行对词的预测。
- 生成词典:将每个单词同它对应的词向量在字典中存放在一起。
- 保存训练好的词典:将生成好的词典,保存进.npz文件中。