pyTorch自然语言处理简单例子
最近在学pyTorch的实际应用例子。这次说个简单的例子:给定一句话,判断是什么语言。这个例子是比如给定一句话:
Give it to me
判断是 ENGLISH
me gusta comer en la cafeteria
判断是 SPANISH
就是这么简单的例子。
来看怎么实现: 准备数据 格式 [(语句,类型),...] data是train的时候用的语句,test_data是test的时候用的语句
data = [ ("me gusta comer en la cafeteria".split(), "SPANISH"), ("Give it to me".split(), "ENGLISH"), ("No creo que sea una buena idea".split(), "SPANISH"), ("No it is not a good idea to get lost at sea".split(), "ENGLISH") ] test_data = [("Yo creo que si".split(), "SPANISH"), ("it is lost on me".split(), "ENGLISH")]
因为文本计算机室识别不出来的,他们只认识01串,也就是数字。所以我们得把文本映射到数字上。
word_to_ix = {}for sent, _ in data + test_data: f
or word in sent:
if word not in word_to_ix: word_to_ix[word] = len(word_to_ix) print(word_to_ix)
输出word_to_ix (意思是word to index)是:
{'me': 0, 'gusta': 1, 'comer': 2, 'en': 3, 'la': 4, 'cafeteria': 5, 'Give': 6, 'it': 7, 'to': 8, 'No': 9, 'creo': 10, 'que': 11, 'sea': 12, 'una': 13, 'buena': 14, 'idea': 15, 'is': 16, 'not': 17, 'a': 18, 'good': 19, 'get': 20, 'lost': 21, 'at': 22, 'Yo': 23, 'si': 24, 'on': 25}
这里先提前设置下接下来要用到的参数
VOCAB_SIZE = len(word_to_ix) NUM_LABELS = 2#只有两类 ENGLISH SPANISH
固定模板
def init(self, num_labels, vocab_size):初始化,就是输入和输出的大小。这里我们要输入是一个句子,句子最大就是拥有所有字典的词,这里也就是vocab_size(下面再说怎么将一句话根据字典转换成一个数字序列的),输出就是分类,这里分为2类,即num_labels。这里我们用的是线性分类 ,即nn.Linear()。
def forward(self, bow_vec):bow_vec是一个句子的数字化序列,经过self.linear()得到一个线性结果(也就是预测结果),之后对这个结果进行softmax(这里用log_softmax是因为下面的损失函数用的是NLLLoss() 即负对数似然损失,需要log以下)
class BoWClassifier(nn.Module):
#nn.Module 这是继承torch的神经网络模板
def __init__(self, num_labels, vocab_size):
super(BoWClassifier, self).__init__()
self.linear = nn.Linear(vocab_size, num_labels)
def forward(self, bow_vec):
return F.log_softmax(self.linear(bow_vec))
def make_bow_vector(sentence, word_to_ix)
大概能看懂什么意思吧。就是把一个句子sentence通过word_to_ix转换成数字化序列.比如 sentence=我 是 一只 小 小 鸟 word_to_id={你:0,我:1,他:2,不:3,是:4,大:5,小:6,猪:7,鸟:8,,} make_bow_vector之后的结果是[0,1,0,0,1,0,2,0,1] view()就是改变下向量维数。这里是讲len(word_to_ix)1->1len(word_to_ix)
def make_bow_vector(sentence, word_to_ix): vec = torch.zeros(len(word_to_ix)) for word in sentence: vec[word_to_ix[word]] += 1 return vec.view(1, -1)
这个就不用说了吧 一样。(如果想知道torch.LongTensor啥意思的话。可以看看。Torch中,Tensor主要有ByteTensor(无符号char),CharTensor(有符号),ShortTensor(shorts), IntTensor(ints), LongTensor(longs), FloatTensor(floats), DoubleTensor(doubles),默认存放为double类型,如果需要特别指出,通过torch.setdefaulttensortype()方法进行设定。例如torch.setdefaulttensortype(‘torch.FloatTensor’)。 )
def make_target(label, label_to_ix): return torch.LongTensor([label_to_ix[label]])
这里再介绍下model.parameters()这个函数。他的返回结果是model里的所有参数。这里我们用的是线性函数,所以就是f(x)=Ax+b中的A和b(x即输入的数据),这些参数在之后的反馈和更新参数需要的。
model = BoWClassifier(NUM_LABELS, VOCAB_SIZE)
for param in model.parameters():
print("param:", param)
可以看出A是2len(vocab_size),b是21
param: Parameter containing:Columns 0 to 9 0.0786 0.1596 0.1259 0.0054 0.0558 -0.0911 -0.1804 -0.1526 -0.0287 -0.1086-0.0651 -0.1096 -0.1807 -0.1907 -0.0727 -0.0179 0.1530 -0.0910 0.1943 -0.1148Columns 10 to 19 0.0452 -0.0786 0.1776 0.0425 0.1194 -0.1330 -0.1877 -0.0412 -0.0269 -0.1572-0.0361 0.1909 0.1558 0.1309 0.1461 -0.0822 0.1078 -0.1354 -0.1877 0.0184Columns 20 to 25 0.1818 -0.1401 0.1118 0.1002 0.1438 0.0790 0.1812 -0.1414 -0.1876 0.1569 0.0804 -0.1897
[torch.FloatTensor of size 2x26]param: Parameter containing: 0.1859 0.1245[torch.FloatTensor of size 2]
我们再看看model的def forward(self, bow_vec):怎么用。这里就想下面的代码一样,直接在mode()填一个参数即可,就调用forward函数。
sample = data[0] bow_vector = make_bow_vector(sample[0], word_to_ix) log_probs = model(autograd.Variable(bow_vector))
print("log_probs", log_probs)
输出是:(就是log_softmax后的值)
log_probs Variable containing:-0.6160 -0.7768[torch.FloatTensor of size 1x2]
我们这里看看在test上的预测
label_to_ix = { "SPANISH": 0, "ENGLISH": 1 }
for instance, label in test_data:
bow_vec = autograd.Variable(make_bow_vector(instance, word_to_ix))
log_probs = model(bow_vec)
print log_probsprint next(model.parameters())[:,word_to_ix["creo"]]
结果是
Variable containing:
-0.5431 -0.8698
[torch.FloatTensor of size 1x2]
Variable containing:
-0.7405 -0.6480
[torch.FloatTensor of size 1x2]
Variable containing:
-0.0467 0.1065
[torch.FloatTensor of size 2]
下面就该进行重要的部分了。循环训练和更新参数 这里我们用的损失函数是nn.NLLLoss()负对数似然损失 优化依然用的最常见的optim.SGD() 梯度下降法 一般训练5-30次最终优化基本不再变化
每一步过程: a.首先都要model.zero_grad(),因为接下来要极端梯度,得清零,以防问题 b.将数据向量化(也可以说是数字序列化,转成计算机能看懂的形式) c.得到预测值 d.求损失loss_function e.求梯度loss.backward() f.更新参数optimizer.step()
loss_function = nn.NLLLoss() optimizer = optim.SGD(model.parameters(), lr=0.1)for epoch in range(100): for instance, label in data: model.zero_grad() bow_vec = autograd.Variable(make_bow_vector(instance, word_to_ix)) target = autograd.Variable(make_target(label, label_to_ix)) log_probs = model(bow_vec) loss = loss_function(log_probs, target) loss.backward() optimizer.step()
在测试集上测试
for instance, label in test_data:
bow_vec = autograd.Variable(make_bow_vector(instance, word_to_ix))
log_probs = model(bow_vec)
print log_probs
我们在结果上很容易看到第一个例子预测是SPANISH最大,第二个是ENGLISH最大。成功了。
Variable containing:-0.0842 -2.5161[torch.FloatTensor of size 1x2]Variable containing:-2.4886 -0.0867[torch.FloatTensor of size 1x2]
- 【深入研究】使用RNN预测股票价格系列二
- 教你用一行Python代码实现并行(附代码)
- 在美国国会图书馆标题表的SKOS上运行Apache Spark GraphX算法
- 【精选】破解波动性突破实盘系统
- 从程序员的角度看神经网络的激活功能
- 在线矩阵微积分工具,可以生成 Python/Latex 代码哦!
- 机器学习应用区块链系列(一)——如何开发一套自己的智能合约系统
- 使用Botkit和Rasa NLU构建智能聊天机器人
- 【量化投资】缠论面面观(附Python源码)
- 独家 | 教你用Q学习算法训练神经网络玩游戏(附源码)
- 使用重采样评估Python中机器学习算法的性能
- Autofac正式发布2.1版
- DataDirectory是什么?
- android的消息通知栏
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python计算大文件行数方法及性能比较
- docker容器部署Prometheus服务——云平台监控利器
- ASP.NET Core 奇技淫巧之接口代理转发
- 基于CDH(Cloudera Distribution Hadoop)的大数据平台搭建
- troubleshoot之:用control+break解决线程死锁问题
- Docker 三剑客之docker-compose
- 腾讯云 Severless-Express 项目开发和灰度发布最佳实践
- 在Docker中使用Redis
- 基于实际业务场景下的Flume部署
- troubleshoot之:使用JFR解决内存泄露
- 一个ABAP和JavaScript这两种编程语言的横向比较
- WebRTC & Android 开发学习环境搭建~
- word模板和XML数据源是如何合并生成最后的word文档的详细过程
- Angular路由跳转时,如何传递信息
- Angular里的购物车页面实现