course-nlp——6-rnn-english-numbers

本文参考自https://github.com/fastai/course-nlp。

使用 RNN 预测数字的英文单词版本

在上一课中,我们将 RNN 用作语言模型的一部分。今天,我们将深入了解 RNN 是什么以及它们如何工作。我们将使用尝试预测数字的英文单词版本的问题来实现这一点。

让我们预测这个序列中接下来应该是什么:

eight thousand one , eight thousand two , eight thousand three , eight thousand four , eight thousand five , eight thousand six , eight thousand seven , eight thousand eight , eight thousand nine , eight thousand ten , eight thousand eleven , eight thousand twelve…

Jeremy 创建了这个合成数据集,以便有更好的方法来检查事情是否正常、调试和了解发生了什么。在尝试新想法时,最好有一个较小的数据集来这样做,以便快速了解你的想法是否有前途(有关其他示例,请参阅 Imagenette 和 Imagewoof)这个英文单词数字将作为学习 RNN 的良好数据集。我们今天的任务是预测计数时接下来会出现哪个单词。

在深度学习中,有两种类型的数字

参数是学习到的数字。激活是计算出的数字(通过仿射函数和元素非线性)。

当你学习深度学习中的任何新概念时,问问自己:这是一个参数还是一个激活?

提醒自己:指出隐藏状态,从没有 for 循环的版本转到 for 循环。这是人们感到困惑的步骤。

Data

from fastai.text import *
bs=64
path = untar_data(URLs.HUMAN_NUMBERS)
path.ls()
[PosixPath('/home/racheltho/.fastai/data/human_numbers/models'),PosixPath('/home/racheltho/.fastai/data/human_numbers/valid.txt'),PosixPath('/home/racheltho/.fastai/data/human_numbers/train.txt')]
def readnums(d): return [', '.join(o.strip() for o in open(path/d).readlines())]

train.txt 为我们提供了以英文单词写出的数字序列:

train_txt = readnums('train.txt'); train_txt[0][:80]
'one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirt'
valid_txt = readnums('valid.txt'); valid_txt[0][-80:]
' nine thousand nine hundred ninety eight, nine thousand nine hundred ninety nine'
train = TextList(train_txt, path=path)
valid = TextList(valid_txt, path=path)src = ItemLists(path=path, train=train, valid=valid).label_for_lm()
data = src.databunch(bs=bs)
train[0].text[:80]
'xxbos one , two , three , four , five , six , seven , eight , nine , ten , eleve'
len(data.valid_ds[0][0].data)
13017

bptt 代表时间反向传播。这告诉我们正在考虑多少历史步骤。

data.bptt, len(data.valid_dl)
(70, 3)

我们的验证集中有 3 个批次:

13017 个标记,每行文本中约有 ~70 个标记,每批次有 64 行文本。

13017/70/bs
2.905580357142857

我们将每个批次存储在单独的变量中,这样我们就可以通过这个过程更好地理解 RNN 在每个步骤中的作用:

it = iter(data.valid_dl)
x1,y1 = next(it)
x2,y2 = next(it)
x3,y3 = next(it)
it.close()
x1
tensor([[ 2, 19, 11,  ..., 36,  9, 19],[ 9, 19, 11,  ..., 24, 20,  9],[11, 27, 18,  ...,  9, 19, 11],...,[20, 11, 20,  ..., 11, 20, 10],[20, 11, 20,  ..., 24,  9, 20],[20, 10, 26,  ..., 20, 11, 20]], device='cuda:0')
numel() is a PyTorch method to return the number of elements in a tensor:
x1.numel()+x2.numel()+x3.numel()
13440
x1.shape, y1.shape
(torch.Size([64, 70]), torch.Size([64, 70]))
x2.shape, y2.shape
(torch.Size([64, 70]), torch.Size([64, 70]))
x3.shape, y3.shape
(torch.Size([64, 70]), torch.Size([64, 70]))
v = data.valid_ds.vocab
v.itos
['xxunk','xxpad','xxbos','xxeos','xxfld','xxmaj','xxup','xxrep','xxwrep',',','hundred','thousand','one','two','three','four','five','six','seven','eight','nine','twenty','thirty','forty','fifty','sixty','seventy','eighty','ninety','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen']
x1[:,0]
tensor([ 2,  9, 11, 12, 13, 11, 10,  9, 10, 14, 19, 25, 19, 15, 16, 11, 19,  9,10,  9, 19, 25, 19, 11, 19, 11, 10,  9, 19, 20, 11, 26, 20, 23, 20, 20,24, 20, 11, 14, 11, 11,  9, 14,  9, 20, 10, 20, 35, 17, 11, 10,  9, 17,9, 20, 10, 20, 11, 20, 11, 20, 20, 20], device='cuda:0')
y1[:,0]
tensor([19, 19, 27, 10,  9, 12, 32, 19, 26, 10, 11, 15, 11, 10,  9, 15, 11, 19,26, 19, 11, 18, 11, 18,  9, 18, 21, 19, 10, 10, 20,  9, 11, 16, 11, 11,13, 11, 13,  9, 13, 14, 20, 10, 20, 11, 24, 11,  9,  9, 16, 17, 20, 10,20, 11, 24, 11, 19,  9, 19, 11, 11, 10], device='cuda:0')
v.itos[9], v.itos[11], v.itos[12], v.itos[13], v.itos[10]
(',', 'thousand', 'one', 'two', 'hundred')
v.textify(x1[0])
'xxbos eight thousand one , eight thousand two , eight thousand three , eight thousand four , eight thousand five , eight thousand six , eight thousand seven , eight thousand eight , eight thousand nine , eight thousand ten , eight thousand eleven , eight thousand twelve , eight thousand thirteen , eight thousand fourteen , eight thousand fifteen , eight thousand sixteen , eight thousand seventeen , eight'
v.textify(x1[1])
', eight thousand forty six , eight thousand forty seven , eight thousand forty eight , eight thousand forty nine , eight thousand fifty , eight thousand fifty one , eight thousand fifty two , eight thousand fifty three , eight thousand fifty four , eight thousand fifty five , eight thousand fifty six , eight thousand fifty seven , eight thousand fifty eight , eight thousand fifty nine ,'
v.textify(x2[1])
'eight thousand sixty , eight thousand sixty one , eight thousand sixty two , eight thousand sixty three , eight thousand sixty four , eight thousand sixty five , eight thousand sixty six , eight thousand sixty seven , eight thousand sixty eight , eight thousand sixty nine , eight thousand seventy , eight thousand seventy one , eight thousand seventy two , eight thousand seventy three , eight thousand'
v.textify(y1[0])
'eight thousand one , eight thousand two , eight thousand three , eight thousand four , eight thousand five , eight thousand six , eight thousand seven , eight thousand eight , eight thousand nine , eight thousand ten , eight thousand eleven , eight thousand twelve , eight thousand thirteen , eight thousand fourteen , eight thousand fifteen , eight thousand sixteen , eight thousand seventeen , eight thousand'
v.textify(x2[0])
'thousand eighteen , eight thousand nineteen , eight thousand twenty , eight thousand twenty one , eight thousand twenty two , eight thousand twenty three , eight thousand twenty four , eight thousand twenty five , eight thousand twenty six , eight thousand twenty seven , eight thousand twenty eight , eight thousand twenty nine , eight thousand thirty , eight thousand thirty one , eight thousand thirty two ,'
v.textify(x3[0])
'eight thousand thirty three , eight thousand thirty four , eight thousand thirty five , eight thousand thirty six , eight thousand thirty seven , eight thousand thirty eight , eight thousand thirty nine , eight thousand forty , eight thousand forty one , eight thousand forty two , eight thousand forty three , eight thousand forty four , eight thousand forty five , eight thousand forty six , eight'
v.textify(x1[1])
', eight thousand forty six , eight thousand forty seven , eight thousand forty eight , eight thousand forty nine , eight thousand fifty , eight thousand fifty one , eight thousand fifty two , eight thousand fifty three , eight thousand fifty four , eight thousand fifty five , eight thousand fifty six , eight thousand fifty seven , eight thousand fifty eight , eight thousand fifty nine ,'
v.textify(x2[1])
'eight thousand sixty , eight thousand sixty one , eight thousand sixty two , eight thousand sixty three , eight thousand sixty four , eight thousand sixty five , eight thousand sixty six , eight thousand sixty seven , eight thousand sixty eight , eight thousand sixty nine , eight thousand seventy , eight thousand seventy one , eight thousand seventy two , eight thousand seventy three , eight thousand'
v.textify(x3[1])
'seventy four , eight thousand seventy five , eight thousand seventy six , eight thousand seventy seven , eight thousand seventy eight , eight thousand seventy nine , eight thousand eighty , eight thousand eighty one , eight thousand eighty two , eight thousand eighty three , eight thousand eighty four , eight thousand eighty five , eight thousand eighty six , eight thousand eighty seven , eight thousand eighty'
v.textify(x3[-1])
'ninety , nine thousand nine hundred ninety one , nine thousand nine hundred ninety two , nine thousand nine hundred ninety three , nine thousand nine hundred ninety four , nine thousand nine hundred ninety five , nine thousand nine hundred ninety six , nine thousand nine hundred ninety seven , nine thousand nine hundred ninety eight , nine thousand nine hundred ninety nine xxbos eight thousand one , eight'
data.show_batch(ds_type=DatasetType.Valid)

在这里插入图片描述
我们将迭代地考虑一些不同的模型,构建更传统的 RNN。

单一全连接模型

data = src.databunch(bs=bs, bptt=3)
x,y = data.one_batch()
x.shape,y.shape
(torch.Size([64, 3]), torch.Size([64, 3]))
nv = len(v.itos); nv
39
nh=64
def loss4(input,target): return F.cross_entropy(input, target[:,-1])
def acc4 (input,target): return accuracy(input, target[:,-1])
x[:,0]
tensor([13, 13, 10,  9, 18,  9, 11, 11, 13, 19, 16, 23, 24,  9, 12,  9, 13, 14,15, 11, 10, 22, 15,  9, 10, 14, 11, 16, 10, 28, 11,  9, 20,  9, 15, 15,11, 18, 10, 28, 23, 24,  9, 16, 10, 16, 19, 20, 12, 10, 22, 16, 17, 17,17, 11, 24, 10,  9, 15, 16,  9, 18, 11])

Layer names:

  • i_h: input to hidden
  • h_h: hidden to hidden
  • h_o: hidden to output
  • bn: batchnorm
class Model0(nn.Module):def __init__(self):super().__init__()self.i_h = nn.Embedding(nv,nh)  # green arrowself.h_h = nn.Linear(nh,nh)     # brown arrowself.h_o = nn.Linear(nh,nv)     # blue arrowself.bn = nn.BatchNorm1d(nh)def forward(self, x):h = self.bn(F.relu(self.i_h(x[:,0])))if x.shape[1]>1:h = h + self.i_h(x[:,1])h = self.bn(F.relu(self.h_h(h)))if x.shape[1]>2:h = h + self.i_h(x[:,2])h = self.bn(F.relu(self.h_h(h)))return self.h_o(h)
learn = Learner(data, Model0(), loss_func=loss4, metrics=acc4)
learn.fit_one_cycle(6, 1e-4)

在这里插入图片描述

循环也一样

让我们重构一下,使用 for 循环。它的作用和之前一样:

class Model1(nn.Module):def __init__(self):super().__init__()self.i_h = nn.Embedding(nv,nh)  # green arrowself.h_h = nn.Linear(nh,nh)     # brown arrowself.h_o = nn.Linear(nh,nv)     # blue arrowself.bn = nn.BatchNorm1d(nh)def forward(self, x):h = torch.zeros(x.shape[0], nh).to(device=x.device)for i in range(x.shape[1]):h = h + self.i_h(x[:,i])h = self.bn(F.relu(self.h_h(h)))return self.h_o(h)

这是展开的 RNN 图(我们之前的 RNN 图)和卷起的 RNN 图(我们现在的 RNN 图)之间的区别:

learn = Learner(data, Model1(), loss_func=loss4, metrics=acc4)
learn.fit_one_cycle(6, 1e-4)

在这里插入图片描述
我们的准确性大致相同,因为我们做的事情与以前相同。

多重全连接模型

之前,我们只是预测一行文本中的最后一个单词。给定 70 个标记,标记 71 是什么?这种方法会丢弃大量数据。为什么不根据标记 1 预测标记 2,然后预测标记 3,然后预测标记 4,依此类推?我们将修改模型来做到这一点。

data = src.databunch(bs=bs, bptt=20)
x,y = data.one_batch()
x.shape,y.shape
(torch.Size([64, 20]), torch.Size([64, 20]))
class Model2(nn.Module):def __init__(self):super().__init__()self.i_h = nn.Embedding(nv,nh)self.h_h = nn.Linear(nh,nh)self.h_o = nn.Linear(nh,nv)self.bn = nn.BatchNorm1d(nh)def forward(self, x):h = torch.zeros(x.shape[0], nh).to(device=x.device)res = []for i in range(x.shape[1]):h = h + self.i_h(x[:,i])h = F.relu(self.h_h(h))res.append(self.h_o(self.bn(h)))return torch.stack(res, dim=1)
learn = Learner(data, Model2(), metrics=accuracy)

在这里插入图片描述

请注意,我们的准确率现在变差了,因为我们在做一项更艰巨的任务。当我们预测单词 k(k<70)时,我们能获得的历史记录比我们仅预测单词 71 时要少。(Model2每次forward调用时都重新初始化h)

维持状态

为了解决这个问题,让我们保留上一行文本的隐藏状态,这样我们就不会在每一行新文本上重新开始。

class Model3(nn.Module):def __init__(self):super().__init__()self.i_h = nn.Embedding(nv,nh)self.h_h = nn.Linear(nh,nh)self.h_o = nn.Linear(nh,nv)self.bn = nn.BatchNorm1d(nh)self.h = torch.zeros(bs, nh).cuda()def forward(self, x):res = []h = self.hfor i in range(x.shape[1]):h = h + self.i_h(x[:,i])h = F.relu(self.h_h(h))res.append(self.bn(h))self.h = h.detach()res = torch.stack(res, dim=1)res = self.h_o(res)return res
learn = Learner(data, Model3(), metrics=accuracy)
earn.fit_one_cycle(20, 3e-3)

在这里插入图片描述
现在我们获得的准确性比以前更高了!(h.detach()防止累积梯度回传)

nn.RNN

class Model4(nn.Module):def __init__(self):super().__init__()self.i_h = nn.Embedding(nv,nh)self.rnn = nn.RNN(nh,nh, batch_first=True)self.h_o = nn.Linear(nh,nv)self.bn = BatchNorm1dFlat(nh)self.h = torch.zeros(1, bs, nh).cuda()def forward(self, x):res,h = self.rnn(self.i_h(x), self.h)self.h = h.detach()return self.h_o(self.bn(res))
learn = Learner(data, Model4(), metrics=accuracy)
learn.fit_one_cycle(20, 3e-3)

在这里插入图片描述

2-layer GRU

当你拥有较长的时间尺度和较深的网络时,这些就变得无法训练。解决这个问题的一种方法是添加 mini-NN 来决定保留多少绿色箭头和多少橙色箭头。这些 mini-NN 可以是 GRU 或 LSTM。我们将在后面的课程中介绍更多细节。

class Model5(nn.Module):def __init__(self):super().__init__()self.i_h = nn.Embedding(nv,nh)self.rnn = nn.GRU(nh, nh, 2, batch_first=True)self.h_o = nn.Linear(nh,nv)self.bn = BatchNorm1dFlat(nh)self.h = torch.zeros(2, bs, nh).cuda()def forward(self, x):res,h = self.rnn(self.i_h(x), self.h)self.h = h.detach()return self.h_o(self.bn(res))
learn = Learner(data, Model5(), metrics=accuracy)
learn.fit_one_cycle(10, 1e-2)

在这里插入图片描述

Connection to ULMFit

在上一课中,我们基本上用分类器替换了 self.h_o 来对文本进行分类。

结尾

RNN 只是一个重构的全连接神经网络。

你可以使用相同的方法处理任何序列标记任务(词性、分类材料是否敏感等)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/848842.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K210视觉识别模块学习笔记4: (MaixHub)训练与使用自己的模型_识别字母

今日开始学习K210视觉识别模块: 模型训练与使用_识别字母 亚博智能的K210视觉识别模块...... 固件库: maixpy_v0.6.2_52_gb1a1c5c5d_minimum_with_ide_support.bin 文章提供测试代码讲解、完整代码贴出、测试效果图、测试工程下载 这里也算是正式开始进入到视觉识别的领域了…

【Python】教你彻底了解Python中的正则表达式

​​​​ 文章目录 一、正则表达式的基本概念1. 元字符2. 特殊序列 二、Python中正则表达式的使用方法1. 导入re模块2. 匹配&#xff08;match&#xff09;3. 搜索&#xff08;search&#xff09;4. 查找所有匹配&#xff08;findall&#xff09;5. 替换&#xff08;sub&#…

linux实验报告

实验一&#xff1a;Linux操作系统的安装与配置 实验目的&#xff1a; 1.掌握虚拟机技术&#xff1b; 2.掌握Linux的安装步骤&#xff1b; 3.掌握安装过程中的基本配置要求。 4.掌握正确启动Linux的方法&#xff1b; 5.掌握正确退出Linux的方法&#xff1b; 6.熟悉已安装…

在人工智能背景下,程序员要有什么职业素养,怎么改进

文章目录 1. 持续学习和适应能力原因改善方法 2. 跨学科知识原因改善方法 3. 高效的计算资源利用原因改善方法 4. 模型解释性和可控性原因改善方法 5. 数据隐私和安全意识原因改善方法 在AI大模型的背景下&#xff0c;程序员要有什么职业素养&#xff0c;怎么改进&#xff0c;才…

激活函数对比

激活函数 sigmoid / tanh / relu / leaky relu / elu / gelu / swish 1、sigmoid 优缺点 1) 均值!0&#xff0c;导致fwxb求导时&#xff0c;方向要么全正要么全负 可以通过batch批量训练来缓解 2) 输入值大于一定范围梯度就会消失 3) 运算复杂 2、tanh 优缺点 1) 均值0 2)…

使用jspdf将html页面生成pdf文件

1、下载jspdf插件包 npm i jspdf2、在utils文件夹下创建一个单独的文件&#xff08;名字无具体要求&#xff09; // 页面导出为pdf格式&#xff0c;title表示为下载的标题&#xff0c;html表示要下载的页面 import html2Canvas from html2canvas // 不用单独去下载这个包&…

【Mybatis】动态SQL标签2

choose (when, otherwise)标签是使用举例 类似switch...case&#xff0c;从上到下匹配&#xff0c;找到匹配的条件&#xff0c;就结束匹配其他的&#xff01; set标签是使用举例 set这个标签是用在更新操作上的 set标签代替sql中的set关键字&#xff0c;可以把set语句后多余的…

大模型产品层出不穷,如何慧眼识珠?

先预祝亲爱的读者们“端午安康“ 大模型百花齐放&#xff0c;选择难上加难 面对眼前层出不穷的大模型产品&#xff0c;许多人会不禁感到困惑&#xff1a;哪个才是真正适合自己的爆款大模型?在中国本土 alone&#xff0c;就有百来个大模型产品&#xff0c;简直是五花八门&…

python怎么下载numpy

安装Python step1&#xff1a;官网下载安装包&#xff1b; https://www.python.org/ 我下载的是python-3.4.4.msi step2&#xff1a;python环境变量配置&#xff1b; 计算机-属性-高级系统设置-环境变量-系统变量 找到PATH&#xff0c;点击编辑&#xff0c;加英文分号;在…

【Text2SQL 论文】T5-SR:使用 T5 生成中间表示来得到 SQL

论文&#xff1a;T5-SR: A Unified Seq-to-Seq Decoding Strategy for Semantic Parsing ⭐⭐⭐ 北大 & 中科大&#xff0c;arXiv:2306.08368 文章目录 一、论文速读二、中间表示&#xff1a;SSQL三、Score Re-estimator四、总结 一、论文速读 本文设计了一个 NL 和 SQL 的…

【设计模式深度剖析】【3】【行为型】【职责链模式】| 以购物中心客户服务流程为例加深理解

&#x1f448;️上一篇:命令模式 设计模式-专栏&#x1f448;️ 文章目录 职责链模式定义英文原话直译如何理解呢&#xff1f; 职责链模式的角色1. Handler&#xff08;抽象处理者&#xff09;2. ConcreteHandler&#xff08;具体处理者&#xff09;3. Client&#xff08;客户…

【Vue】普通组件的注册使用-局部注册

文章目录 一、组件注册的两种方式二、使用步骤三、练习 一、组件注册的两种方式 局部注册&#xff1a;只能在注册的组件内使用 ① 创建 .vue 文件 (三个组成部分) 以.vue结尾的组件&#xff0c;一般也叫做 单文件组件&#xff0c;即一个组件就是组件里的全部内容 ② 在使用的组…

Qt窗口与对话框

目录 Qt窗口 1.菜单栏 2.工具栏 3.状态栏 4.滑动窗口 QT对话框 1.基础对话框QDiaog 创建新的ui文件 模态对话框与非模态对话框 2.消息对话框 QMessageBox 3.QColorDialog 4.QFileDialog文件对话框 5.QFontDialog 6.QInputDialog Qt窗口 前言&#xff1a;之前以上…

Linux驱动开发笔记(三)平台设备驱动

文章目录 前言一、Linux的设备模型1. 总线1.1 bus_type结构体1.2 注册/注销总线 2. 设备2.1 device结构体2.2 内核注册/注销设备 3. 驱动3.1 device_driver结构体3.2 注册/注销驱动 4. attribute属性文件4.1 attribute_group结构体4.2 设备属性文件4.3 驱动属性文件4.3. 总线属…

数组array 和 array的区别

问题 对于数组 array和&array有什么区别呢? 先说答案 array: 指向数组第一个数地址的指针 &array: 指向整个数组地址的指针 所以直接打印的话, 地址是一样的. 但是如果1的话, 那么array是增加sizeof(int)大小, &array是增加sizeof(int) * array.size() 测试 #i…

必应bing国内广告账户如何注册推广呢?

作为全球第二大搜索引擎&#xff0c;必应Bing以其庞大的用户基础和精准的定向能力&#xff0c;为企业提供了拓展市场的绝佳平台。对于许多企业来说&#xff0c;必应Bing广告账户的注册与推广流程可能显得复杂而繁琐。此时&#xff0c;您不妨考虑携手云衔科技&#xff0c;共同开…

程序员职业素养:AI新时代下的机遇与挑战

目录 一、引言二、程序员职业素养的五大要点1. 技术能力2. 沟通能力3. 团队合作4. 责任心5. 敬业精神 三、实际案例解析四、程序员职业素养在实际工作中的应用五、AI新时代的程序员的职业发展建议六、总结七、结语 一、引言 在当今这个科技飞速发展的时代&#xff0c;程序员这…

景区ar互动大屏游戏化体验提升营销力度

从20世纪60年代的初步构想&#xff0c;到如今全球范围内无数企业的竞相投入&#xff0c;AR增强现实技术已成为引领科技潮流的重要力量。而在这一浪潮中&#xff0c;中国的AR公司正以其独特的魅力和创新力&#xff0c;崭露头角。 中国的AR市场正在迎来前所未有的发展机遇。如今&…

将现有web项目打包成electron桌面端教程(一)vue3+vite+js版

说明&#xff1a;后续项目需要web端和桌面端&#xff0c;为了提高开发效率&#xff0c;准备直接将web端的代码打包成桌面端&#xff0c;在此提前记录一下demo打包的过程&#xff0c;需要注意的是vue2或者vue3vitets或者vue-cli的打包方式各不同&#xff0c;如果你的项目不是vue…

CasaOS玩客云如何部署小雅AList并结合内网穿透远程访问海量资源

文章目录 前言1. 本地部署AList2. AList挂载网盘3. 部署小雅alist3.1 Token获取3.2 部署小雅3.3 挂载小雅alist到AList中 4. Cpolar内网穿透安装5. 创建公网地址6. 配置固定公网地址 前言 本文主要介绍如何在安装了CasaOS的玩客云主机中部署小雅AList&#xff0c;并在AList中挂…