域名买好了怎么做网站,网站开发项目比赛,做淘宝内部优惠券网站要钱么,营销软文范例500文章目录 0 前言0.1 课程视频链接#xff1a;0.2 课件下载地址#xff1a; 1 Basic RNN1.1 复习DNN和CNN1.2 直观认识RNN1.3 RNN Cell的内部计算方式 2 具体什么是一个RNN#xff1f;3 使用pytorch构造一个RNN3.1 手动构造一个RNN Cell来实现RNN3.2 直接使用torch中现有的RN… 文章目录 0 前言0.1 课程视频链接0.2 课件下载地址 1 Basic RNN1.1 复习DNN和CNN1.2 直观认识RNN1.3 RNN Cell的内部计算方式 2 具体什么是一个RNN3 使用pytorch构造一个RNN3.1 手动构造一个RNN Cell来实现RNN3.2 直接使用torch中现有的RNN模块来实现RNNinput维度h0维度output维度hn维度numLayers的解释代码注释参数配置模型构造输入序列的构造隐藏层的构造输出的解释最后一个隐藏层输出的解释执行代码的结果 例子1训练一个RNN 做seq2seq任务第1步 字符向量化参数配置准备数据设计模型构造损失函数和优化器设置训练Cycle改变数据Embedding 例12-3 使用embedding和线性层的RNN构造模型、损失函数、优化器训练练习1LSTM联系2GRU 0 前言
0.1 课程视频链接
《PyTorch深度学习实践》完结合集 大佬的笔记大佬的笔记 pytorch0.4
0.2 课件下载地址
链接https://pan.baidu.com/s/1_J1f5VSyYl-Jj2qIuc1pXw 提取码wyhu
1 Basic RNN 1.1 复习DNN和CNN
全连接网络也称为稠密网络Dense Network也称为Deep Neural Network 现在有一个表里面的数据是每天每隔一个小时的天气数据平均温度气压预测目标是是否下雨
根据某一时刻的温度和气压数据预测该时刻是否下雨这件事情意义不太大预测下雨这件事应提前进行预测。
我们需要若干天如3天的数据作为模型的输入其中每一天的数据应该包含若干个如3个特征。 使用全连接进行预测。如果序列很长且x1x2x3的维度很高的话这对网络的训练是一个很大的挑战原因是全连接网络是稠密的网络里面的权重是最多的。 CNN中输入通道是128输出通道是64使用的是5×5的卷积权重为25×2^1320w 全连接层假设输入是4096输出是1024则全连接权重为4096*1024420w这样的比较CNN使用的参数要少得多 因此在使用神经网络时需要明确一点全连接网络的参数在神经网络中所占的比例是最大的所以之后计算存储、推理很大的瓶颈是来自全连接层 CNN中使用的参数为什么较少呢有 权重共享的概念
假如在处理视频时每一帧的图像如果都使用全连接网络去处理那参数量将是天文数字这种方法是不可行的 RNN是专门处理序列型的数据也会使用权重共享的概念减少需要训练的权重的数量
x1x2x3是一个序列是有先后顺序x2部分依赖x1x3部分依赖x2RNN来处理序列相关的数据类似于语言、天气、股票
理解语言需要依赖文字的顺序
回顾一下CNN
1.2 直观认识RNN
例如输入xt的维度是3维的经过RNN Cell之后输出的ht是5维的那么RNN Cell本质上还是一个线性层但是和普通的线性层的区别是RNN Cell这个线性层的权重是共享的。 h0是先验知识如果有先验知识的话就需要将先验知识作为h0输入给RNN如图生文本CNNFC处理图像生成h0再传给RNN此时即可做“看图说话” 如果没有先验知识的话直接将h0的维度设置为和ht的维度一样然后设置成0向量即可。 上图中的RNN Cell是同一个 用代码来表示是上面这样的x是需要从X中循环的
1.3 RNN Cell的内部计算方式 Whhht-1bhh 和Wihxtbih是两个线性层他们可以合并成一个线性层见上图的红色公式 即上式可以简写。
2 具体什么是一个RNN
把RNN Cell以循环的方法把序列送进去依次算出隐层的过程称为一个循环神经网络。
3 使用pytorch构造一个RNN
两种方法1、自己构造RNN Cell然后写来处理序列的循环 2、直接使用RNN
3.1 手动构造一个RNN Cell来实现RNN
创建一个Cell的方式 创建一个RNN Cell需要的参数输入的维度隐藏层的维度 构造完cell之后一个cell的输入是x和上一个隐藏状态两者的维度要求见下图 例如一个RNNCell的配置为 因此输入的构造见下图 隐藏状态的构造见下图 序列数据的维度的构造应该如下 代码 torch.randn用法torch.randn()函数 示例代码
import torch# 定义配置项
batch_size 5
seq_len 3
input_size 4
hidden_size 2# 构造一个RNN Cell
cell torch.nn.RNNCell(input_size input_size, hidden_size hidden_size)print(cell)# 生成5个序列长度为3每个token的为4的张量作为1个batch
dataset torch.randn(seq_len, batch_size, input_size)
print(dataset)hidden torch.zeros(batch_size, hidden_size)
print(hidden)for idx, input in enumerate(dataset):print(*20, idx, *20)print(input size:, input.shape)hidden cell(input, hidden)print(output size:, hidden.shape)print(hidden)输出
D:\Anaconda3\envs\env_pytorch04\python.exe D:/000 简历/000 自己的项目/3 刘二教程/第12节课 手动定义一个RNN Cell.py
RNNCell(4, 2)
tensor([[[ 0.4408, -0.7577, 0.9077, -0.0779],[ 0.5080, -0.1057, 0.5581, -0.4546],[ 0.8382, 1.3444, 1.1445, -2.0313],[ 0.4016, 1.0184, 0.0556, 0.6046],[ 1.9827, 0.6735, -0.6609, -0.0764]],[[-0.8133, -1.3837, -0.6933, -0.6390],[ 0.7617, -0.2478, -0.1682, -1.2478],[ 0.1389, -0.5334, 1.7906, 0.8992],[-0.7540, 0.0293, -0.5835, 1.0606],[-0.5817, 0.2823, -1.0507, 0.3087]],[[-0.5872, 0.1241, -0.2446, -0.5430],[-0.6749, 0.6816, -0.1754, -1.1233],[ 0.1708, -1.6483, 0.8012, 0.3567],[-0.1961, -1.0277, -0.2133, -0.7144],[-1.3309, 0.6177, 1.5205, -0.4169]]])
tensor([[0., 0.],[0., 0.],[0., 0.],[0., 0.],[0., 0.]])0
input size: torch.Size([5, 4])
output size: torch.Size([5, 2])
tensor([[-0.2558, -0.4498],[-0.3951, 0.0840],[ 0.1652, 0.9352],[-0.8041, -0.1019],[-0.6620, 0.7436]], grad_fnTanhBackward0)1
input size: torch.Size([5, 4])
output size: torch.Size([5, 2])
tensor([[-0.8441, -0.6020],[-0.6114, 0.6291],[-0.3331, -0.8504],[-0.9706, -0.8207],[-0.9807, -0.4315]], grad_fnTanhBackward0)2
input size: torch.Size([5, 4])
output size: torch.Size([5, 2])
tensor([[-0.8825, -0.1003],[-0.9137, 0.3993],[-0.2900, -0.8324],[-0.7844, -0.2764],[-0.7202, -0.4915]], grad_fnTanhBackward0)进程已结束退出代码为 0注意输出中的下列张量每一个块儿是一个batch一个块儿是5个向量表示1个batch是5个输入
tensor([[[ 0.4408, -0.7577, 0.9077, -0.0779],[ 0.5080, -0.1057, 0.5581, -0.4546],[ 0.8382, 1.3444, 1.1445, -2.0313],[ 0.4016, 1.0184, 0.0556, 0.6046],[ 1.9827, 0.6735, -0.6609, -0.0764]],[[-0.8133, -1.3837, -0.6933, -0.6390],[ 0.7617, -0.2478, -0.1682, -1.2478],[ 0.1389, -0.5334, 1.7906, 0.8992],[-0.7540, 0.0293, -0.5835, 1.0606],[-0.5817, 0.2823, -1.0507, 0.3087]],[[-0.5872, 0.1241, -0.2446, -0.5430],[-0.6749, 0.6816, -0.1754, -1.1233],[ 0.1708, -1.6483, 0.8012, 0.3567],[-0.1961, -1.0277, -0.2133, -0.7144],[-1.3309, 0.6177, 1.5205, -0.4169]]])假如有数据集 1、我爱你 2、我恨你 3、我吃了 4、我没吃 5、我饿了 。。。。还有其他数据 分词之后 1、“我”“爱”“你” 2、“我”“恨”“你” 3、“我”“吃”“了” 4、“我”“没”“吃” 5、“我”“饿”“了” … 每个词有各自的词向量 配置项中设置每个batch的大小是5选择前5句话作为1个batch每句话的序列长度都是3其中每个词的维度都是4 则1个batch用数字表示就是
tensor([[[ 0.4408, -0.7577, 0.9077, -0.0779], # 我 【1】[ 0.5080, -0.1057, 0.5581, -0.4546], # 我 [ 0.8382, 1.3444, 1.1445, -2.0313], # 我[ 0.4016, 1.0184, 0.0556, 0.6046], # 我[ 1.9827, 0.6735, -0.6609, -0.0764]], # 我[[-0.8133, -1.3837, -0.6933, -0.6390], # 爱 【1】[ 0.7617, -0.2478, -0.1682, -1.2478], # 恨[ 0.1389, -0.5334, 1.7906, 0.8992], # 吃[-0.7540, 0.0293, -0.5835, 1.0606], # 没[-0.5817, 0.2823, -1.0507, 0.3087]], # 饿[[-0.5872, 0.1241, -0.2446, -0.5430], # 你 【1】[-0.6749, 0.6816, -0.1754, -1.1233], # 你[ 0.1708, -1.6483, 0.8012, 0.3567], # 了[-0.1961, -1.0277, -0.2133, -0.7144], # 吃 [-1.3309, 0.6177, 1.5205, -0.4169]]]) # 了暂时忽略同一个词不同词向量这个问题以上只示意
3.2 直接使用torch中现有的RNN模块来实现RNN
cell torch.nn.RNN(input_size inputsize, hidden_size hidden_size, num_layers num_layers) num_layers可以设置RNN是多少层的层数也不能选太多因为比较耗时
outhidden cell(inputshidden) inputs是包含整个输入序列out就是输出的整个序列h1,h2,…,hN第1个hidden就是hN第2个hidden就是h0具体可以见下图 总结上图中cell输入h0x1x2…xN输出h1h2…hN和hN
维度要求见下图 其中numLayers指的就是RNN是多少层的这个确实有指明的必要因为RNN有多少层h就得有多少层
input维度 h0维度 output维度 hn维度 numLayers的解释
同一种颜色的cell是同一个cell下面例子中的模型看着很复杂实际就只是3个线性层
代码注释
参数配置 模型构造 输入序列的构造 隐藏层的构造 输出的解释 最后一个隐藏层输出的解释 执行代码的结果 batch_first设置为True的话在构造数据时需要将batch_size和seq_len进行交换为什么有这个选项是因为有些时候这种方式更方便构造数据集具体原因可再细查见下图 将batch_first设置为True的情况代码和代码执行结果见下图 可以看出batch_size和seq_len交换了位置
例子1训练一个RNN 做seq2seq任务
任务训练一个RNN模型输入是hello输出是ohlol
第1步 字符向量化
使用one-hot表示每个字符使用词表大小的向量来表示 inputsize 4 输入的向量维度为4输出的应该是这4个字符的类别因此可以令输出向量的维度也为4这样通过一个softmax即可进行多分类下图中的输出上写的数字是每个每个输出应该被分类的类别如o应该被归为第3类l应该被归类为第1类等等 预测的向量与真实的向量做一个交叉熵损失值如下图
参数配置 准备数据
idx2char是一个字典值为字符可使用索引作为键 lookup是一个查询表例如词表中e的索引为0则e使用one-hot表示就是lookup中第0行的向量o的索引为3则o使用one-hot表示就是lookup中第3行的向量 x_one_hot是将x_data中每个索引对应的字符都表示为one-hot向量它的维度应该是seq_len×inputsize因为x_data的维度是seq_lenone-hot向量的维度是inputsize 下面这个图中所写的seqLen1应该是写错了没有写batchsize的大小 实际上应该写成seqLenbatchSizehiddenSize即-114为什么这么写的原因可以见下图
设计模型
1、初始化参数 2、RNNCell的输入输出维度要求 3、初始化h0 这里面的参数有一个batch_size只有在构造h0的时候才会需要用到在初始化和forward的时候不会用到这个参数
构造损失函数和优化器
使用交叉熵作为损失函数Adam作为优化器
设置训练Cycle
optimizer.zero_grad()优化器的梯度归零 每一个epoch开始之后先算一个h0对于每一步的损失值都加到一起loss.backup进行梯度的反向传播参数更新 注意下列数据的维度大小 lable只要给出类别数字即可不需要one-hot原因在于交叉熵的过程这个地方需要查一下CrossEntropyLoss()的操作 hidden.max()就是找hidden中的找最大值,hidden是4维的向量 例2 使用RNN Module
改变数据 训练结果如下
Embedding
associatev.联系;联合;联想;交往;表示同意;(尤指)混在一起;表明支持; one-hot表示的缺点 1、维度太高字符级字符集ASIIC 128维 单词级几万维 2、过于稀疏 3、硬编码的这个词向量并不是学习出来的 Embedding层是将高维的稀疏的样本向量映射到低维的稠密的空间中这就是降维 嵌入层降维的方式:输入一个索引通过查表来找到对应的向量找的方法是通过将lookup表与一个one-hot向量进行想乘然后得出最后的嵌入向量
例12-3 使用embedding和线性层的RNN
有时候的输出的隐藏层h的维度与类别的维度o不一致所以可以添加Linear Layer将h的维度映射为o的维度 下面的batch_first True只要知道有这种用法即可 参数配置 输入和输出
构造模型、损失函数、优化器 训练 出现ohlol比以前更早了是因为使用了更厉害的模型学习能力更强
练习1LSTM
LSTM中的这些个门儿实际上这么多次专业名词总会使人感觉到这个模型很难学习实际不难只需看公式即可
为什么有用 因为提供了下面这样的路径有利于梯度传播有了记忆单元所以减少梯度消失 LSTM比RNN效果好得多因为计算复杂时间复杂度高
联系2GRU
GRU是一个折中的方法比LSTM的计算速度快 以上学习RNN需要重视的是 1、了解序列数据的维度情况 2、循环过程用到的权重共享机制