RNN的PyTorch实现
官方实现
PyTorch已经实现了一个RNN类,就在torch.nn工具包中,通过torch.nn.RNN调用。
使用步骤:
- 实例化类;
- 将输入层向量和隐藏层向量初始状态值传给实例化后的对象,获得RNN的输出。
在实例化该类时,需要传入如下属性:
- input_size:输入层神经元个数;
- hidden_size:每层隐藏层的神经元个数;
- num_layers:隐藏层层数,默认设置为1层;
- nonlinearity:激活函数的选择,可选是'tanh'或者'relu',默认设置为'tanh';
- bias:偏置系数,可选是'True'或者'False',默认设置为'True';
- batch_first:可选是'True'或者'False',默认设置为'False';
- dropout:默认设置为0。若为非0,将在除最后一层的每层RNN输出上引入Dropout层,dropout概率就是该非零值;
- bidirectional:默认设置为False。若为True,即为双向RNN。
RNN的输入有两个,一个是input,一个是h0。input就是输入层向量,h0就是隐藏层初始状态值。
若没有采用批量输入,则输入层向量的形状为(L, Hin);
若采用批量输入,且batch_first为False,则输入层向量的形状为(L, N, Hin);
若采用批量输入,且batch_first为True,则输入层向量的形状为(N, L, Hin);
对于(N, L, Hin),在文本输入时,可以按顺序理解为(每次输入几句话,每句话有几个字,每个字由多少维的向量表示)。
若没有采用批量输入,则隐藏层向量的形状为(D * num_layers, Hout);
若采用批量输入,则隐藏层向量的形状为(D * num_layers, N, Hout);
注意,batch_first的设置对隐藏层向量的形状不起作用。
RNN的输出有两个,一个是output,一个是hn。output包含了每个时间步最后一层的隐藏层状态,hn包含了最后一个时间步每层的隐藏层状态。
若没有采用批量输入,则输出层向量的形状为(L, D * Hout);
若采用批量输入,且batch_first为False,则输出层向量的形状为(L, N, D * Hout);
若采用批量输入,且batch_first为True,则输出层向量的形状为(N, L, D * Hout)。
参数解释:
- N代表的是批量大小;
- L代表的是输入的序列长度;
- 若是双向RNN,则D的值为2;若是单向RNN,则D的值为1;
- Hin在数值上是输入层神经元个数;
- Hout在数值上是隐藏层神经元个数。
import torch
import torch.nn as nn
rnn = nn.RNN(10, 20, 1, batch_first=True) # 实例化一个单向单层RNN
input = torch.randn(5, 3, 10)
h0 = torch.randn(1, 5, 20)
output, hn = rnn(input, h0)
手写复现
复现代码
import torch
import torch.nn as nn
class MyRNN(nn.Module):
def __init__(self, input_size, hidden_size):
super().__init__()
self.input_size = input_size
self.hidden_size = hidden_size
self.weight_ih = torch.randn(self.hidden_size, self.input_size) * 0.01
self.weight_hh = torch.randn(self.hidden_size, self.hidden_size) * 0.01
self.bias_ih = torch.randn(self.hidden_size)
self.bias_hh = torch.randn(self.hidden_size)
def forward(self, input, h0):
N, L, input_size = input.shape
output = torch.zeros(N, L, self.hidden_size)
for t in range(L):
x = input[:, t, :].unsqueeze(2) # 获得当前时刻的输入特征,[N, input_size, 1]。unsqueeze(n),在第n维上增加一维
w_ih_batch = self.weight_ih.unsqueeze(0).tile(N, 1, 1) # [N, hidden_size, input_size]
w_hh_batch = self.weight_hh.unsqueeze(0).tile(N, 1, 1) # [N, hidden_size, hidden_size]
w_times_x = torch.bmm(w_ih_batch, x).squeeze(-1) # [N, hidden_size]。squeeze(n),在第n维上减小一维
w_times_h = torch.bmm(w_hh_batch, h0.unsqueeze(2)).squeeze(-1) # [N, hidden_size]
h0 = torch.tanh(w_times_x + self.bias_ih + w_times_h + self.bias_hh)
output[:, t, :] = h0
return output, h0.unsqueeze(0)
验证正确性
my_rnn = MyRNN(10, 20)
input = torch.randn(5, 3, 10)
h0 = torch.randn(5, 20)
my_output, my_hn = my_rnn(input, h0)
print(output.shape == my_output.shape, hn.shape == my_hn.shape)
True True
主要参考
RNN的PyTorch实现的更多相关文章
- Pytorch基础——使用 RNN 生成简单序列
一.介绍 内容 使用 RNN 进行序列预测 今天我们就从一个基本的使用 RNN 生成简单序列的例子中,来窥探神经网络生成符号序列的秘密. 我们首先让神经网络模型学习形如 0^n 1^n 形式的上下文无 ...
- pytorch_08_RNN
1.循环神经网络的提出是基于记忆模型的想法,期望网络能够记住前面出现的特征,并依据特征推断后面的结果,而且整体的网络结构不断循环,因而得名循环神经网络. 2.循环神经网络的基本结构特别简单,就是将网络 ...
- “你什么意思”之基于RNN的语义槽填充(Pytorch实现)
1. 概况 1.1 任务 口语理解(Spoken Language Understanding, SLU)作为语音识别与自然语言处理之间的一个新兴领域,其目的是为了让计算机从用户的讲话中理解他们的意图 ...
- Pytorch系列教程-使用字符级RNN生成姓名
前言 本系列教程为pytorch官网文档翻译.本文对应官网地址:https://pytorch.org/tutorials/intermediate/char_rnn_generation_tutor ...
- Pytorch系列教程-使用字符级RNN对姓名进行分类
前言 本系列教程为pytorch官网文档翻译.本文对应官网地址:https://pytorch.org/tutorials/intermediate/char_rnn_classification_t ...
- pytorch实现rnn并且对mnist进行分类
1.RNN简介 rnn,相比很多人都已经听腻,但是真正用代码操练起来,其中还是有很多细节值得琢磨. 虽然大家都在说,我还是要强调一次,rnn实际上是处理的是序列问题,与之形成对比的是cnn,cnn不能 ...
- pytorch中如何处理RNN输入变长序列padding
一.为什么RNN需要处理变长输入 假设我们有情感分析的例子,对每句话进行一个感情级别的分类,主体流程大概是下图所示: 思路比较简单,但是当我们进行batch个训练数据一起计算的时候,我们会遇到多个训练 ...
- pytorch之 RNN 参数解释
上次通过pytorch实现了RNN模型,简易的完成了使用RNN完成mnist的手写数字识别,但是里面的参数有点不了解,所以对问题进行总结归纳来解决. 总述:第一次看到这个函数时,脑袋有点懵,总结了下总 ...
- PyTorch快速入门教程七(RNN做自然语言处理)
以下内容均来自: https://ptorch.com/news/11.html word embedding也叫做word2vec简单来说就是语料中每一个单词对应的其相应的词向量,目前训练词向量的方 ...
- pytorch rnn 2
import torch import torch.nn as nn import numpy as np import torch.optim as optim class RNN(nn.Modul ...
随机推荐
- re.sub()用法
原文链接:https://blog.csdn.net/jackandsnow/article/details/103885422
- byte[]数组转换string类型
byte[] OutData = new byte[2048];//交易返回数据 string pBusiCardInfoStr = Encoding.Default.GetString(OutDat ...
- void指针;函数指针
void 类型指针 void => 空类型 void* => 空类型指针,只存储地址的值,丢失类型,无法访问,要访问其值,我们必须对这个指针做出正确的 类型转换,然后再间接引用指针.voi ...
- 萌新码农的第一篇:MarkDown的使用方法
MarkDown的使用方法 使用的编辑软件Typora 1.标题的使用方法 输入''#''然后空格,输入标题名字即可生成标题. 随着''#''的增多,标题的大小会依次减小,最多到六级标题 2.排字 字 ...
- 8.云原生之Docker容器镜像构建最佳实践浅析
转载自:https://www.bilibili.com/read/cv15220861/?from=readlist 本章目录 0x02 Docker 镜像构建最佳实践浅析 1.Dockerfile ...
- 使用filebeat过滤掉部分字段
host,agent,ecs三个字段也是不让drop的 processors: - drop_fields: fields: ["log","input",&q ...
- PAT (Basic Level) Practice 1017 A除以B 分数 20
本题要求计算 A/B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数.你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立. 输入格式: 输入在一行中依次给出 A 和 B,中间以 ...
- NOIP2003 普及组 洛谷P1045 麦森数 (快速幂+高精度)
有两个问题:求位数和求后500位的数. 求位数:最后减去1对答案的位数是不影响的,就是求2p的位数,直接有公式log10(2)*p+1; 求后500位的数:容易想到快速幂和高精度: 1 #includ ...
- 动态编译库 Natasha 5.0 兼容版本发布
Natasha 5.0 版本已于 2022/10/10 日发布, 此次大版本更迭带来了兼容性支持, 目前 Natasha 可以兼容 standard2.0 及 coreapp3.1 以上版本. 下载使 ...
- C语言小白刷题
1.有n个评委,他们给出score个分数,请用代码写出平均值,ave代表平均值 2022-10-15 13:17:10 int main() { int n, i =1, score, sum = 0 ...