【自然语言处理】(2) --Word2Vec实现

文章目录

  • Word2Vec实现
    • 一、训练模型
      • [1. 数据预处理](#1. 数据预处理)
      • [2. 构建训练数据](#2. 构建训练数据)
      • [3. 搭建word2vec网络(CBOW)](#3. 搭建word2vec网络(CBOW))
      • [4. 装配设备](#4. 装配设备)
      • [5. 构建训练模型](#5. 构建训练模型)
      • [6. 优化器](#6. 优化器)
      • [7. 损失函数](#7. 损失函数)
      • [8. 迭代模型](#8. 迭代模型)
    • 二、测试模型
      • [1. 预测单词](#1. 预测单词)
      • [2. 生成词嵌入词典](#2. 生成词嵌入词典)
      • [3. 保存训练后的词向量](#3. 保存训练后的词向量)
  • 总结

Word2Vec实现

Word2Vec 是一种用于自然语言处理(NLP)的深度学习技术,主要用于将词汇表中的单词或短语从词汇空间映射到向量的实数空间 ,这些向量通常称为词向量(word vectors)。生成的词向量能够捕捉单词之间的语义和语法关系,极大地促进了 NLP 任务的性能和准确性。

一、训练模型

1. 数据预处理

对语料库进行去重(利用集合的特性,进行去重),然后对每个单词进行编号:

python 复制代码
"""-----语料库去重-----"""
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. 构建训练数据

将每个中心词的前两个与后两个词放在一起作为特征将中心词作为标签

python 复制代码
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)

python 复制代码
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. 装配设备

python 复制代码
# 模拟在cuda训练
device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu"
print(device)
-----------
cuda

5. 构建训练模型

python 复制代码
model = CBOW(vocab_size,10).to(device)

6. 优化器

python 复制代码
optimizer = optim.Adam(model.parameters(),lr=0.001)

7. 损失函数

NLLLoss损失函数(当分类列表比较多的情况),将多个类别分别分成0,1两个类别:

python 复制代码
"""-----损失函数-----"""
losses = [] # 存储损失的集合
loss_function = nn.NLLLoss() # NLLLoss损失函数(当分类列表比较多的情况),将多个类别分别分成0,1两个类别

8. 迭代模型

python 复制代码
"""-----迭代模型参数权重-----"""
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. 预测单词

python 复制代码
"""-----测试-----"""
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. 生成词嵌入词典

获取每个词的词向量,将对应的词同词向量一一对应以字典类型存放:

python 复制代码
"""-----生成词嵌入字典-----"""
# 获取词向量,这个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库中的一种数据格式,它是一种压缩文件,可以保存多个数组和元数据。

  • 保存方法:
python 复制代码
np.savez("文件名称格式",文件)
  • 调用方法:
python 复制代码
data = np.load("文件名")
python 复制代码
np.savez("word2vec实现.npz",file_1=w)
data = np.load("word2vec实现.npz")
print(data.files)
------------
['file_1']

总结

本篇介绍了:

  1. 如何实现Word2Vec,从而搭建网络模型进行对词的预测。
  2. 生成词典:将每个单词同它对应的词向量在字典中存放在一起。
  3. 保存训练好的词典:将生成好的词典,保存进.npz文件中。
相关推荐
新手小白勇闯新世界1 小时前
特征描述子 EFPH(扩展点特征直方图)---既包括几何关系又包括空间关系
人工智能·深度学习·机器学习
墨染辉3 小时前
pdf处理1
人工智能
矿枝5 小时前
自然语言处理(NLP)技术
自然语言处理
sp_fyf_20245 小时前
【大语言模型-论文精读】谷歌-BERT:用于语言理解的预训练深度双向Transformers
人工智能·语言模型·bert
算家云6 小时前
PhotoMaker部署文档
人工智能·aigc·conda·图像生成·comfyui·工作流·文本转图像
小猪包3337 小时前
ai论文写作软件哪个好?分享5款ai论文题目生成器
人工智能·深度学习·计算机视觉·ai写作
云翼时代科技8 小时前
【探索艺术新纪元:Midjourney中文版,让创意无界!】
人工智能
坚持学习的你8 小时前
Jax(Random、Numpy)常用函数
人工智能·pytorch·python·jax
KGback8 小时前
【项目记录】大模型基于llama.cpp在Qemu-riscv64向量扩展指令下的部署
人工智能·llama·riscv
ZPC82108 小时前
Pytorch详解-Pytorch核心模块
人工智能·pytorch·python·深度学习·机器学习