简单有趣的 NLP 教程:手把手教你用 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:

for 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.1148

Columns 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.0184

Columns 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_probs

print 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]

本文作者:AI研习社 2017-06-20 15:41

简单有趣的 NLP 教程:手把手教你用 PyTorch 辨别自然语言(附代码)相关推荐

  1. [github 教程]手把手教你最简单的开源项目托管GitHub入门教程_github 教程

    [github 教程]手把手教你最简单的开源项目托管GitHub入门教程--简介 自从google code关闭了下载服务了之后,GitHub作为了目前最好用的免费 开源 项目托管站点,众多开源项目都 ...

  2. graphpad两组t检验_Graphpad 作图教程 | 手把手教你绘制森林图

    森林图 (forest plots) 是以估计模型 (固定效应模型或是随机效应模型) 结果为基础绘制出的图型.它以一条垂直的直线 (横坐标刻度为 1 或 0) 为中心,用平行于横轴的多条线段描述了每个 ...

  3. 小白都能看懂的实战教程 手把手教你Python Web全栈开发(DAY 3)

    小白都能看懂的实战教程 手把手教你Python Web全栈开发 Flask(Python Web)实战系列之在线论坛系统 第三讲 这是小白都能看懂的实战教程 手把手教你Python Web全栈开发 的 ...

  4. 阿里云服务器使用教程手把手教你搭建网站by阿里云服务器

    阿里云服务器使用教程是用户比较关心的问题,其实很简单,阿里云百科告诉大家如何使用云服务器ECS,如何使用阿里云服务器搭建网站,从服务器购买到网站上线一站式教程: 阿里云服务器购买方面,阿里云百科建议大 ...

  5. 苹果手机怎么在照片上添加文字_手机照片如何添加文字?原来方法这么简单,花1分钟手把手教...

    手机照片如何添加文字?原来方法这么简单,花1分钟手把手教 最近很多人私信笔者,手机拍摄的照片怎样添加好看的文字,今天笔者准备了4种方法,一起来看看吧! 1.自带水印功能(安卓手机) 一般人都是直接拍照 ...

  6. 镜播无人直播带货教程,手把手教你如何搭建直播间

    镜播无人直播带货新手教程,手把手教你如何搭建直播间 如果你一个人在家里面直播,没有直播中控来辅助你一个情况下怎么办?来教你一个什么叫做镜播.用镜子来做一个直播的辅助.在你的面前放一面镜子,下面是产品, ...

  7. linux下运行mcnp6安装教程,JBPM6教程-手把手教你安装JBPM

    JBPM6教程-手把手教你安装JBPM 1. 安装JBPM的先决条件: (1)JDK 1.6+以上,没有安装的话,猛击这里. (2)Ant 1.7+以上,没有安装的话,看看这里. 2. 下载JBPM安 ...

  8. 小白都能看懂的实战教程 手把手教你Python Web全栈开发(DAY 1)

    小白都能看懂的实战教程 手把手教你Python Web全栈开发 Flask(Python Web)实战系列之在线论坛系统 第一讲 博主博客文章内容导航(实时更新) 更多优质文章推荐: 收藏!最详细的P ...

  9. 网课答案公众号小白教程——手把手教你创建自己的大学查题公众号

    网课答案公众号小白教程--手把手教你创建自己的大学查题公众号 1.很多新手想搭建属于自己的查题公众号! 所以我来写一个搜题公众号搭建教程,如果你想要做公众号方面的引流之类的,这个就非常不错! 废话不多 ...

最新文章

  1. CentOS6.5挂载windows共享文件夹
  2. Scala数值类型转换
  3. 提交svn的时候,提示丢失了预定增加的xxxx
  4. visual studio 2019 (vs) 显示右侧缩略图
  5. 设置路由器端口转发功能如何操作
  6. Failed to load resource: the server responded with a status of 500 (Internal Server Error)
  7. 数据库工具一段时间后打开报错:远程过程调用失败0x800706be
  8. Nunit中如何进行事务性单元测试
  9. HDU 1422 重温世界杯 (dp)
  10. 电脑开机svchost.exe报错
  11. 怎样学好python编程-3个月学好Python有多简单?
  12. python文本筛选html,从html页面的列表元素中筛选数据
  13. Git小乌龟汉化步骤
  14. 学成在线首页——静态页面(html+css)素材链接放在文章结尾了
  15. ps滑动鼠标放大缩小
  16. 钉钉群机器人关键词自动回复_企业微信营销机器人怎么接入?
  17. 一文读懂十大数据存储加密技术
  18. 一位高中竞赛蒟蒻的大学C++学习日记-第三篇-数组、字符、字符串
  19. 财务需求分析师需要了解的财务知识
  20. 前端开发中聊天场景的体验优化

热门文章

  1. 文本编辑器创建状态栏
  2. 设置自增递增零开始_MySQL中如何设置自动递增id主键重新计数从1开始?
  3. 多元统计分析最短距离法_聚醚多元醇的合成
  4. springboot session默认失效时间_Spring Boot 整合 Redis,用起来真简单
  5. php-dev离线安装,局域网 pm2 离线安装
  6. 深入浅出让你理解什么是LLVM
  7. ROW_NUMBER() OVER (PARTITION BY 字段1 ORDER BY 字段2 DESC)
  8. shell 取中间行的第一列_shell脚本的使用该熟练起来了,你说呢?(篇三)
  9. java知识点思维导图_思维导图结构化梳理java
  10. 150. Leetcode 860. 柠檬水找零 (贪心算法-基础题目)