cbow原理及实现

目录

1、one-hot编码

2、cbow原理

3、cbow模型的训练过程

4、代码示例


1、one-hot编码

在机器学习和自然语言处理(NLP)中,one-hot 编码是一种常用于将类别数据(如单词)转换为机器学习模型可以处理的数值形式的方法。one-hot 编码会为每个类别分配一个全为零的向量,除了该类别的索引位置为1之外。因为单词通常被视为离散的类别,所以这种方法在处理文本数据时特别有用。

假设我们有一个简单的词汇表 ["cat", "dog", "tree"],并且我们想要为这些单词创建one-hot编码。

  • "cat" 可能会编码为 [1, 0, 0]
  • "dog" 可能会编码为 [0, 1, 0]
  • "tree" 可能会编码为 [0, 0, 1]

2、cbow原理

CBOW模型的核心思想是通过上下文中的词来预测目标词。具体而言,CBOW模型通过将上下文中的词的词向量相加,得到一个上下文向量,然后通过一个隐藏层将上下文向量映射到目标词的概率分布。在训练过程中,CBOW模型通过最大化预测目标词的概率来学习到每个词的词向量表示。

3、cbow模型的训练过程

 1.当前词的上下文词语的one-hot编码输入到输入层。
2.这些词分别乘以同一个矩阵W*N后分别得到各自的1*N 向量。
3.将多个这些1*N 向量取平均为一个1*N 向量。
4.将这个1*N 向量乘矩阵 W’v*N,变成一个1*V 向量。
5.将1*V 向量softmax归一化后输出取每个词的概率向量1*V
6.将概率值最大的数对应的词作为预测词。
7.将预测的结果1*V 向量和真实标签1*V 向量(真实标签中的V个值中有一个是1,其他是0)计算误差
8.在每次前向传播之后反向传播误差,不断调整 W*n和 W’v*矩阵的值。

4、代码示例

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from tqdm import tqdm,trange
import numpy as np

# 设置上下文词的个数和原始文本内容
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)
word_to_idx= {word:i for i,word in enumerate(vocab)}
idx_to_word = {i: word for i, word in enumerate(vocab)}

data =[]#获取上下文词,将上下文词作为输入,目标词作为输出。构建训练数据集。
for i in range(CONTEXT_SIZE,len(raw_text)-CONTEXT_SIZE):
    context = (
        [raw_text[i - (2 - j)] for j in range(CONTEXT_SIZE)]
        + [raw_text[i + j + 1] for j in range(CONTEXT_SIZE)]
    )
    target = raw_text[i]  
    data.append((context,target))

#将上下文词转换为one-hot编码
def make_context_vector(context,word_to_ix):
    idxs = [word_to_ix[w] for w in context]
    return torch.tensor(idxs, dtype=torch.long)

make_context_vector(data[0][0],word_to_idx)

# 定义CBOW模型
class CBOW(nn.Module):#
    def __init__(self,vocab_size,embedding_dim):
        super(CBOW, self).__init__()
        self.embeddings = nn.Embedding(vocab_size,embedding_dim)  # vocab si2
        self.proj=nn.Linear(embedding_dim,128)
        self.output =nn.Linear(128,vocab_size)

    def forward(self, inputs):
        embeds = sum(self.embeddings(inputs)).view(1,-1)  # cnn
        out = F.relu(self.proj(embeds))
        out = self.output(out)
        nll_prob =F.log_softmax(out,dim=-1)
        return nll_prob

device = "cuda" if torch.cuda.is_available() else "map" if torch.backends.mps.is_available() else "cpu"
print(f"Using {device} device")

# 实例化模型并设置优化器和损失函数
model=CBOW(vocab_size,10).to(device)
optimizer =optim.Adam(model.parameters(),lr=0.001)
losses=[]
loss_function =nn.NLLLoss()

# 训练模型
for epoch in trange(200):
    total_loss = 0
    for context, target in tqdm(data):
        context_vector = make_context_vector(context, word_to_idx).to(device)
        target = torch.tensor([word_to_idx[target]]).to(device)
        model.zero_grad()  # 梯度清委
        # 开始前向传播
        train_predict = model(context_vector)  # 可以不与forward
        loss =loss_function(train_predict,target)
        # 反向传播
        optimizer.zero_grad()# 梯度值清零
        loss.backward()  # 反向传播计算得到每个参数的度值
        optimizer.step()# 根据梯度更新网络参数
        total_loss += loss.item()
    losses.append(total_loss)

# 获取词向量表示
context = ['People','create','to','direct']
context_vector = make_context_vector(context, word_to_idx).to(device)

model.eval()
predict =model(context_vector)
max_idx = predict.argmax(1)

print("cBOW embedding'weight=", model.embeddings.weight)
W=model.embeddings.weight.cpu().detach().numpy()#
print(W)

#'保存训练后的词向量为npz文件"
np.savez('word2vec实现.npz',file_1=W)
data = np.load('word2vec实现.npz')
print(data.files)

这段代码实现了一个简单的CBOW模型,用于学习词向量表示。代码首先准备数据,构建词汇表并生成训练数据集。然后定义了CBOW模型类,包括Embedding层、线性映射层和输出层。接着使用Adam优化器和负对数似然损失函数进行模型训练,迭代多个epoch。最后,给定上下文词列表,模型预测目标词的词向量表示,并将训练得到的词向量保存为npz文件。整体而言,这段代码展示了如何使用PyTorch实现CBOW模型进行词向量表示学习。

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值