之前已经介绍过fasttext的基本概念从零开始学自然语言处理(十四)——Fasttext原理详解,这里给出实现fasttext的pytorch版本。思想很简单,但这里就不给出数据预处理的代码了,毕竟大家使用的具体场景不一样。小编尽量给出每一行代码的注释。
import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
设计fasttext的代码结构。思想很简单,就是先将词转换为向量形式,然后将这些向量加起来求平均。再去分类。
class FastText(nn.Module):
def __init__(self, vocab, w2v_dim, classes, hidden_size):
super(FastText, self).__init__()
#创建embedding
self.embed = nn.Embedding(len(vocab), w2v_dim) #embedding初始化,需要两个参数,词典大小、词向量维度大小
self.embed.weight.requires_grad = True #需要计算梯度,即embedding层需要被训练
self.fc = nn.Sequential( #序列函数
nn.Linear(w2v_dim, hidden_size), #这里的意思是先经过一个线性转换层
nn.BatchNorm1d(hidden_size), #再进入一个BatchNorm1d
nn.ReLU(inplace=True), #再经过Relu激活函数
nn.Linear(hidden_size, classes)#最后再经过一个线性变换
)
def forward(self, x):
x = self.embed(x) #先将词id转换为对应的词向量
out = self.fc(torch.mean(x, dim=1)) #这使用torch.mean()将向量进行平均
return out
训练模型,主要要将网络的模式设置为训练模式。
def train_model(net, epoch, lr, data, label): #训练模型
print("begin training")
net.train() # 将模型设置为训练模式,很重要!
optimizer = optim.Adam(net.parameters(), lr=lr) #设置优化函数
Loss = nn.CrossEntropyLoss() #设置损失函数
for i in range(epoch): # 循环
optimizer.zero_grad() # 清除所有优化的梯度
output = net(data) # 传入数据,前向传播,得到预测结果
loss = Loss(output, target) #计算预测值和真实值之间的差异,得到loss
loss.backward() #loss反向传播
optimizer.step() #优化器优化参数
# 打印状态信息
print("train epoch=" + str(i) + ",loss=" + str(loss.item()))
print('Finished Training')
验证代码,检测模型训练效果。同时,记得将网络模式调整为验证模式。
def model_test(net, test_data, test_label):
net.eval() # 将模型设置为验证模式
correct = 0
total = 0
with torch.no_grad():
outputs = net(test_data)
# torch.max()[0]表示最大值的值,troch.max()[1]表示回最大值的每个索引
_, predicted = torch.max(outputs.data, 1) # 每个output是一行n列的数据,取一行中最大的值
total += test_label.size(0)
correct += (predicted == test_label).sum().item()
print('Accuracy: %d %%' % (100 * correct / total))
整个代码基本就写好了,现在来写一下main函数。这里没有写具体数据预处理的方法,下面的代码中,data,label为训练数据和训练标签。test_data, test_label为验证数据和验证标签。
if __name__ == "__main__":
#这里没有写具体数据的处理方法,毕竟大家所做的任务不一样
batch_size = 64
epoch = 10 # 迭代次数
w2v_dim = 300 # 词向量维度
lr = 0.001
hidden_size = 128
classes = 2
# 定义模型
net = FastText(vocab=vocab, w2v_dim=w2v_dim, classes=classes, hidden_size=hidden_size)
# 训练
print("开始训练模型")
train_model(net, epoch, lr, data, label)
# 保存模型
print("开始测试模型")
model_test(net, test_data, test_label)
整个代码就写好了。代码整体来讲还是很简单的,pytorch的初学者可以用这个代码来试试手。
后台回复“资料福利”领取一份干货,数百技术电子书等你。