当前位置: 首页 > news >正文

02- pytorch 实现 RNN

一 导包

import torch
from torch import nn
from torch.nn import functional as F
import dltools

1.1 导入训练数据

batch_size, num_steps = 32, 35
# 更改了默认的文件下载方式,需要将 article 文件放入该文件夹
train_iter, vocab = dltools.load_data_time_machine(batch_size, num_steps)

1.2 构造神经网络

num_hiddens = 256
# 构造了一个具有256个隐藏神经单元的单隐藏层的循环神经网络
rnn_layer = nn.RNN(len(vocab), num_hiddens)

构造了一个 循环神经网络 (RNN)  层,该 RNN 层具有以下特性:

  • num_hiddens = 256: 这行代码定义了 RNN 层中的隐藏单元数量,即 RNN 层内部神经元的数量。在这个例子中,设置为 256,意味着 RNN 层将有 256 个隐藏神经单元。

  • nn.RNN(len(vocab), num_hiddens): 这行代码 创建了一个 RNN 层 的实例。它的参数如下:

    • len(vocab): 这是 输入数据的特征维度。在循环神经网络中,输入数据通常是一个序列,每个时间步的输入是一个向量。len(vocab) 表示词汇表的大小,它代表了序列中的每个时间步可能的输入的数量。在自然语言处理任务中,词汇表的大小通常对应于词汇表中不同词汇的数量。

    • num_hiddens: 这是 RNN 层内部的 隐藏单元数量,根据之前定义的值为 256。

综上所述,这段代码创建了一个 具有 256 个隐藏神经单元的单隐藏层的循环神经网络层。这个 RNN 层可以用来处理序列数据,例如文本数据,在文本数据中,每个时间步可以对应一个词汇表中的一个词或一个词的嵌入表示。

1.3 初始化隐藏状态

# 初始化隐藏状态
state = torch.zeros((1, batch_size, num_hiddens))

创建了一个 全零的张量作为隐藏状态。张量的形状是 (1, batch_size, num_hiddens),其中:

  • 1 表示时间步的数量,这里初始化的是一个初始时间步的隐藏状态。
  • batch_size 表示批量大小,即一次处理的样本数量。
  • num_hiddens 表示每个时间步的隐藏单元数量,即隐藏状态的维度。

二 构建一个完整的循环神经网络

# 构建一个完整的循环神经网络
class RNNModel(nn.Module):def __init__(self, rnn_layer, vocab_size, **kwargs):super().__init__(**kwargs)self.rnn = rnn_layerself.vocab_size = vocab_sizeself.num_hiddens = self.rnn.hidden_sizeif not self.rnn.bidirectional:self.num_directions = 1self.linear = nn.Linear(self.num_hiddens, self.vocab_size)else:self.num_directions = 2self.linear = nn.Linear(self.num_hiddens * 2, self.vocab_size)# 前向传播def forward(self, inputs, state):X = F.one_hot(inputs.T.long(), self.vocab_size)X = X.to(torch.float32)Y, state = self.rnn(X, state)output = self.linear(Y.reshape(-1, Y.shape[-1]))return output, state# 初始化隐藏状态def begin_state(self, device, batch_size=1):return torch.zeros((self.num_directions * self.rnn.num_layers, batch_size, self.num_hiddens), device=device)

该部分定义了一个名为 RNNModel 的 PyTorch 模型类,该模型是一个循环神经网络 (RNN) 模型,用于处理序列数据。

  1. __init__ 方法:这是类的构造函数,用于初始化模型的各个组件。在这里,做了以下工作:

    • super().__init__(**kwargs) 调用了父类的构造函数,确保正确初始化模型。
    • self.rnn = rnn_layer 存储了 传入的 RNN 层
    • self.vocab_size = vocab_size 存储了 词汇表的大小
    • self.num_hiddens = self.rnn.hidden_size 获取了 RNN 层的隐藏状态大小
    • 根据 RNN 是否是双向的,选择性地创建一个线性层,用于将 RNN 输出映射到词汇表大小的空间。如果是双向 RNN,则输入的维度是隐藏状态大小的两倍。
  2. forward 方法:这个方法定义了 前向传播 过程。它接受输入 inputs 和当前的隐藏状态 state。在前向传播中,它执行以下操作:

    • 使用 F.one_hot 将输入 inputs 转化为 独热编码,以便与词汇表大小匹配。然后将其转换为浮点数张量。
    • 将输入数据和隐藏状态传递给 RNN 层,以获得输出 Y 和新的 隐藏状态 state
    • 将 RNN 输出 Y 重塑成 二维张量,然后通过线性层 self.linear 将其映射到词汇表大小的空间,并返回输出结果。
  3. begin_state 方法:这个方法用于 初始化隐藏状态,返回一个全零的张量,其形状取决于 RNN 的层数、方向数、隐藏单元数以及批量大小。

2.1 实例化模型

# 在训练前,跑下模型
device = dltools.try_gpu()
net = RNNModel(rnn_layer, vocab_size=len(vocab))
net = net.to(device)

创建了一个 RNNModel对象,该对象接受一个rnn_layer和一个词汇表大小作为参数。最后,它将模型移动到之前确定的设备上

三 执行训练

# 训练
num_epochs, lr = 200, 0.1
dltools.train_ch8(net, train_iter, vocab, lr, num_epochs, device)

3.1 执行预测

dltools.predict_ch8('time traveller', 10, net, vocab, device)
http://www.lryc.cn/news/167616.html

相关文章:

  • 算法课作业1
  • linux文本处理 两行变一行
  • 第二次面试 9.15
  • 基于matlab实现的平面波展开法二维声子晶体能带计算程序
  • Minio入门系列【2】纠删码
  • 基于永磁同步发电机的风力发电系统研究(Simulink实现)
  • 5.后端·新建子模块与开发(自动模式)
  • vue的data为什么要写成data(return{})这样而不是data:{}这样?
  • MySQL基础运维知识点大全
  • javascript获取样式表的规则及读取与写入
  • 什么是promise?
  • 从零开始学习软件测试-第45天笔记
  • visual studio常用快捷键
  • 数据变换:数据挖掘的准备工作之一
  • Go语言实践案例之简单字典
  • 笔试面试相关记录(3)
  • 第6章_瑞萨MCU零基础入门系列教程之串行通信接口(SCI)
  • 开源免费的流程图软件draw.io
  • Python绘图系统19:添加时间轴以实现动态绘图
  • 深度解析shell脚本的命令的原理之rm
  • RPA机器人流程自动化专题培训大纲(供大家参考使用)
  • Python用若干列的数据多条件筛选、去除Excel数据并批量绘制直方图
  • 驱动开发,IO多路复用实现过程,epoll方式
  • java在mysql中查询内容无法塞入实体类中,报错 all elements are null
  • Linux 挂载
  • [面试] 15道最典型的k8s面试题
  • lintcode 552 · 创建最大数 【算法 数组 贪心 hard】
  • ModbusTCP服务端
  • Middleware ❀ Hadoop功能与使用详解(HDFS+YARN)
  • Matlab图像处理-从RGB转换为HSV