【Pytorch】 Pytorch实例:基于词向量的语言模型实现

在Pytorch中,词嵌入使用函数nn.embedding:

class torch.nn.Embedding(num_embeddings, embedding_dim, padding_idx=None, max_norm=None, norm_type=2, scale_grad_by_freq=False, sparse=False)

embedding使用的参数如下:

  • num_embeddings:词嵌入的字典大小
  • embedding_dim:词嵌入的维度
  • padding_idx:可选项,如果选择,对该index上的结果填充0
  • max_norm:可选项,如果选择,对词嵌入归一化时,设置归一化的最大值
  • norm_type:可选项,如果选择,对词嵌入归一化时,设置p-norm的p值
  • scale_grad_by_freq:可选项,如果选择,在mini-batch时,根据词频对梯度进行规整
  • sparse:可选项,如果选择,梯度w.r.t权值矩阵将是一个稀疏张量

词嵌入的简单使用例子如下:

import torch 
import torch.nn as nn
import torch.aurtograd as aotugrad

word_to_idx = {"hello":0, "pytorch":1}
embeds = nn.Embedding(2,5)  # 2 words in vocab, 5 dimensional embeddings
lookup_tensor = torch.LongTensor([word_to_idx["pytorch"]])
hello_embed = embeds(autograd.Variable(lookup_tensor))

注意!这里建立的词向量只是初始的词向量,并没有经过任何修改优化,我们需要建立神经网络,通过训练修改word embedding中的参数,使得word embedding每一个词向量能够表示每一个不同的词。

下面使用pytorch实现一个基于词向量的语言模型,具体代码如下:

1.加载库和设置参数

import torch
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

torch.manual_seed(1)
CONTEXT_SIZE = 2   # 希望由前面2个单词来预测这个单词
EMBEDDIND_DIM = 10
N_EPOCHES = 10

2.数据准备:需要将单词三个分组,每个组前两个作为传入的数据,最后一个作为预测的结果。接下来要给每个单词编码,也就是用数字表示每个单词,这样才能传入word embedding得到词向量

test_sentence = """ fada djahg j hajgf  jags  jghf  jga ... fad as das """.split()
# 三元模型语料准备
trigrams = [(test_sentence[i], test_sentence[i+1], test_sentence[i+2])
	for i in range (len(test sentence) - 2)]
vocab = set(test_sentenxe)   # 集合,去重的作用
word_to_ix = {word:i for i, word in enumerate(vocab)}

3.语言模型

class NGramLanguageModeler(nn.Module):
	def __init__(self, vocab_size, embedding_dim, context_size):
		super(NGramLanguageModeler, self).__init__()
		self.embeddings = nn.Embedding(vocab_size, embedding_dim)
		self.linear1 = nn.Linear(context_size * embedding_dim, 128)
		self.linear2 = nn.Linear(128, vocab_size)
	
	def forward(self, inputs):
		embeds = self.embeddings(inputs).view((1,-1))
		out = F.relu(self.linear1(embeds))
		out = self.linear2(out)
		log_probs = F.log_softmax(out)
		return log_probs

model = NGramLanguageModeler(len(vocab), EMBEDDING_DIM, CONTEXT_SIZE)

在前向传播中,首先传入单词得到词向量,比如在该模型中传入两个词,得到的词向量是(2, 200),然后将词向量展开成(1, 200),接着传入一个线性模型,经过ReLU激活函数再传入一个线性模型,输出的维数是单词总数,可以看成一个分类问题,要最大化预测单词的概率,最后经过一个log softmax函数。

4.定义loss函数和优化器

losses = []
loss_function = nn.NLLLoss()
optimizer = optim.SGD(model.parameters(), lr = 0.001)

5.训练语言模型

for epoch in range(N_EPOCHES):
	total_loss = torch.Tensor([0])
	for context, target in trigrams:
	
		# step1: 准备数据
		context_idxs = [word_to_ix[w] for w in context]
		target_idxs = [word_to_ix[target]]
		context_var = autograd.Variable(torch.LongTensor(context_idxs))
		target_var = autograd.Variable(torch.LongTensor(target_idxs))

		# step2:梯度初始化
		model.zero_grad()

		# step3:前向传播
		log_probs = model(context_var)

		# step4:计算loss
		loss = loss_function(log_prob, target_var)

		# step5:反向传播
		loss.backward()

		# step6:梯度更新
		optimizer.step()

		# step7:total_loss
		total_loss += loss.data

6.预测结果

word, lable = trigram[3]
word = autograd.Variable(torch.LongTensor([word_to_ix[i] for i in word]))
out = model(word)
_, predict_label = torch.max(out, 1)   # 按维度1返回最大值
predict_word = idx_to_word[predict_label.data[0][0]]

参考资料:PyTorch机器学习从入门到实战

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值