目录
一、CBOW模型
二、程序说明
1.输入与预处理模块
2.训练模块
参数设置
模型结构
训练过程
3.测试模块
4.输出处理模块
5.可视化模块
三、实验结果
中文结果可视化:
英文结果可视化:
四、疑问与思考
1.cbow模型与词向量是什么关系
2.keras如何实现cbow
3.jieba分词:
4.关于训练负样本的问题
5.为什么中文语料要加载停用词
学校自然语言处理第二次大作业,训练中英文语料获得词向量,那我们开始吧~、
![]()
作业要求:选一种词向量模型,训练一份中文语料以及一份英文预料,提交报告以及词向量训练结果
代码链接:https://download.csdn.net/download/qq_39328436/41932914
代码结构/使用说明:
连续词袋模型(continuous bag of words, CBOW)
本程序共分为5个模块,首先对语料进行输入以及预处理,然后送入模型进行训练,训练完成后便获得了词向量矩阵。简单对训练好的CBOW模型进行测试,即判断输入周围词获得的中心预测值是否和标签一致。最后将词向量存储在txt文件中,并挑选1000个词向量在降为2维之后绘制在平面图中。
相较于英文语料,加载中文语料时需要过滤一遍停用词,这是因为中文语料中会出现较多的特殊符号以及语气助词,例如:“啊,哎呀,哎哟”等,这些词语会干扰训练。
另外处理中文语料的一个难点是分词,即将一句话如“我超级想学习”,分割成“我 超级 想 学习”,常用的分词方法是jieba结巴分词(在本篇报告的最后一部分有介绍),由于提供的中文语料已经完成了分词操作,因此这边不再赘述。
读入数据之后还需要将其处理以便于训练,在第一部分在对CBOW的介绍中有提到这个模型是根据周围词来预测中心词,因此周围词是输出,中心词是标签。需要按照{[w1,w2,w4,w5],"label"}的格式构造一个词表,如:“the present food surplus can specifically.....”,可以构造(['the', 'present', 'surplus', 'can'], 'food') 以及(['present', 'food', 'can', 'specifically'],'surplus')可以理解为一个滑动窗口的机制,至于窗口多大根据训练要求确定的。
class CBOW(nn.Module): def __init__(self, vocab_size, embedding_dim): super(CBOW, self).__init__() self.embeddings = 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.embeddings(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 |
for epoch in trange(epochs): total_loss = 0 for context, target in tqdm(data): context_vector = make_context_vector(context, word_to_idx).to(device) # 把训练集的上下文和标签都放到cpu中 target = torch.tensor([word_to_idx[target]]) model.zero_grad() # 梯度清零 train_predict = model(context_vector) # 开始前向传播 loss = loss_function(train_predict, target) loss.backward() # 反向传播 optimizer.step() # 更新参数 total_loss += loss.item() losses.append(total_loss) |
训练时需要注意,输入的上下文以及标签中心词都应该是张量形式,经过模型处理后输出值与标签都送入损失函数计算损失,损失向后传播并更新参数。经过十轮训练后,将embedding层的weight变量取出,里面存储的即为训练好的词向量
由于实验不要求模型的准确率,所以测试模块仅做简单的预判。模型输出最大值即为预测值的下标。
词向量矩阵中某个词的索引所对应的那一列即为所该词的词向量,将生成的词向量结果将保存在txt文件中,每一个词都由100维(100个浮点数)表示。
词向量设定为100维度,为将词向量进行可视化,首先要将维度降到2维,以便在坐标系中进行表示,用到的降维方法为PCA。考虑到可视化的效果,只取1000个词进行可视化。另外,为了将中文标签正确在figure中显示,需要设置plt.rcParams['font.sans-serif'] = ['SimHei'] 。
从零开始学自然语言处理(十三)——CBOW原理详解
词向量矩阵是CBOW模型的参数,CBOW本身的作用是用来进行中心词预测,当模型训练好了之后,说明参数矩阵经过损失传播调整以及优化后也收敛到了最佳状态,对于目标语料产生了最佳的词向量表示。
从零开始学自然语言处理(二)——手把手带你用代码实现word2vec
从零开始学自然语言处理(一)—— jieba 分词
CBOW 是用周围词去预测中心词。怎么预测呢?就比如给了一个训练语料“我/出生/在/中国/。”,当给定[“我”,“出生”,“中国”,“。”]时,此时我的训练目标就是要预测“在”这个词的概率要大于其它所有词(即语料库中所有除了“在”的所有词)的概率。
但是词库中的词可能会有几十万个,这样训练下去想要收敛就会变得十分困难。因此提出 word2vec 的神人们就想出了一个取巧的方法:我给它要求降低一点,我不要求模型从几十万个词找到那个正确的中心词,我只要求模型能从十几个词中找到正确的中心词就可以了。因此就用到了 negtive sampling。
那为什么我们的代码中没有负样本一说呢,这是由于本次实验的目标是并不是测试模型效果,并且模型的规模也有限。
停用词是指在信息检索中,为节省存储空间和提高搜索效率,在处理自然语言数据(或文本)之前或之后会自动过滤掉某些字或词,这些字或词即被称为Stop Words(停用词)。这些停用词都是人工输入、非自动化生成的,生成后的停用词会形成一个停用词表。