官方实现

PyTorch已经实现了一个RNN类,就在torch.nn工具包中,通过torch.nn.RNN调用。

使用步骤:

  1. 实例化类;
  2. 将输入层向量和隐藏层向量初始状态值传给实例化后的对象,获得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实现的更多相关文章

  1. Pytorch基础——使用 RNN 生成简单序列

    一.介绍 内容 使用 RNN 进行序列预测 今天我们就从一个基本的使用 RNN 生成简单序列的例子中,来窥探神经网络生成符号序列的秘密. 我们首先让神经网络模型学习形如 0^n 1^n 形式的上下文无 ...

  2. pytorch_08_RNN

    1.循环神经网络的提出是基于记忆模型的想法,期望网络能够记住前面出现的特征,并依据特征推断后面的结果,而且整体的网络结构不断循环,因而得名循环神经网络. 2.循环神经网络的基本结构特别简单,就是将网络 ...

  3. “你什么意思”之基于RNN的语义槽填充(Pytorch实现)

    1. 概况 1.1 任务 口语理解(Spoken Language Understanding, SLU)作为语音识别与自然语言处理之间的一个新兴领域,其目的是为了让计算机从用户的讲话中理解他们的意图 ...

  4. Pytorch系列教程-使用字符级RNN生成姓名

    前言 本系列教程为pytorch官网文档翻译.本文对应官网地址:https://pytorch.org/tutorials/intermediate/char_rnn_generation_tutor ...

  5. Pytorch系列教程-使用字符级RNN对姓名进行分类

    前言 本系列教程为pytorch官网文档翻译.本文对应官网地址:https://pytorch.org/tutorials/intermediate/char_rnn_classification_t ...

  6. pytorch实现rnn并且对mnist进行分类

    1.RNN简介 rnn,相比很多人都已经听腻,但是真正用代码操练起来,其中还是有很多细节值得琢磨. 虽然大家都在说,我还是要强调一次,rnn实际上是处理的是序列问题,与之形成对比的是cnn,cnn不能 ...

  7. pytorch中如何处理RNN输入变长序列padding

    一.为什么RNN需要处理变长输入 假设我们有情感分析的例子,对每句话进行一个感情级别的分类,主体流程大概是下图所示: 思路比较简单,但是当我们进行batch个训练数据一起计算的时候,我们会遇到多个训练 ...

  8. pytorch之 RNN 参数解释

    上次通过pytorch实现了RNN模型,简易的完成了使用RNN完成mnist的手写数字识别,但是里面的参数有点不了解,所以对问题进行总结归纳来解决. 总述:第一次看到这个函数时,脑袋有点懵,总结了下总 ...

  9. PyTorch快速入门教程七(RNN做自然语言处理)

    以下内容均来自: https://ptorch.com/news/11.html word embedding也叫做word2vec简单来说就是语料中每一个单词对应的其相应的词向量,目前训练词向量的方 ...

  10. pytorch rnn 2

    import torch import torch.nn as nn import numpy as np import torch.optim as optim class RNN(nn.Modul ...

随机推荐

  1. Linux_etc-passwd文件总结

    文件内容 ## # User Database # # Note that this file is consulted directly only when the system is runnin ...

  2. Mysql阶段性项目——QQ数据库管理

    MySql 数据库设计与应用 第七章项目练习 阶段项目--QQ数据库管理 任务概述: 模拟QQ在线聊天系统 后台数据库的创建 基本数据表的创建 表约束. 表间关系的添加 进行数据增加. 删除. 修改. ...

  3. 聊聊单点登录(SSO)中的CAS认证

    SSO介绍 背景 随着企业的发展,一个大型系统里可能包含 n 多子系统, 用户在操作不同的系统时,需要多次登录,很麻烦,我们需要一种全新的登录方式来实现多系统应用群的登录,这就是单点登录. web 系 ...

  4. pod(一):Kubernetes(k8s)创建pod的两种方式

    目录 一.系统环境 二.前言 三.pod 四.创建pod 4.1 环境介绍 4.2 使用命令行的方式创建pod 4.2.1 创建最简单的pod 4.2.2 创建pod,指定镜像下载策略 4.2.3 创 ...

  5. MinIO Server配置指南

    MinIO server在默认情况下会将所有配置信息存到 ${HOME}/.minio/config.json 文件中. 以下部分提供每个字段的详细说明以及如何自定义它们. 配置目录 默认的配置目录是 ...

  6. 请求体: Request Body

    官方文档地址:https://fastapi.tiangolo.com/zh/tutorial/body/ # -*- coding: UTF-8 -*- from fastapi import Fa ...

  7. MySQL 数据更新过程

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247486441&idx=1&sn=fcf93709 ...

  8. 清理rook-ceph

    官方步骤文档:https://rook.io/docs/rook/v1.8/ceph-teardown.html 请注意需要清理的以下资源: rook-ceph namespace: The Rook ...

  9. HTML&CSS-盒模型运用居中方式合集

    方法:定位,外边距,内边距,层级,边框: 一个元素: 两个元素: 三个元素. <!DOCTYPE html> <html lang="en"> <he ...

  10. 驱动开发:内核取ntoskrnl模块基地址

    模块是程序加载时被动态装载的,模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程 ...