【深度学习实验】循环神经网络(二):使用循环神经网络(RNN)模型进行序列数据的预测

目录

一、实验介绍

二、实验环境

1. 配置虚拟环境

2. 库版本介绍

三、实验内容

0. 导入必要的工具包

1. RNN模型

a. 初始化__init__

b. 前向传播方法forward

2. 训练和预测

a. 超参数

b. 创建模型实例

c. 模型训练

d. 预测结果可视化

3. 代码整合


        经验是智慧之父,记忆是智慧之母。

——谚语

一、实验介绍

        本实验实现了一个简单的循环神经网络(RNN)模型,并使用该模型进行序列数据的预测,本文将详细介绍代码各个部分的实现,包括模型的定义、训练过程以及预测结果的可视化。

        在前馈神经网络中,信息的传递是单向的,这种限制虽然使得网络变得更容易学习,但在一定程度上也减弱了神经网络模型的能力.在生物神经网络中,神经元之间的连接关系要复杂得多.前馈神经网络可以看作一个复杂的函数,每次输入都是独立的,即网络的输出只依赖于当前的输入.但是在很多现实任务中, 网络的输出不仅和当前时刻的输入相关,也和其过去一段时间的输出相关.比如一个有限状态自动机,其下一个时刻的状态(输出)不仅仅和当前输入相关,也和当前状态(上一个时刻的输出)相关.此外,前馈网络难以处理时序数据,比如视频、语音、文本等.时序数据的长度一般是不固定的,而前馈神经网络要求输入和输出的维数都是固定的,不能任意改变.因此,当处理这一类和时序数据相关 的问题时,就需要一种能力更强的模型. 循环神经网络(Recurrent Neural Network,RNN)是一类具有短期记忆能力的神经网络

        在循环神经网络中,神经元不但可以接受其他神经元的信息,也可以接受自身的信息,形成具有环路的网络结构.和前馈神经网络相比,循环神经网络更加符合生物神经网络的结构.循环神经网络已经被广泛应用在语音识别、语言模型以及自然语言生成等任务上.循环神经网络的参数学习可以通过随时间反向传播算法[Werbos, 1990]来学习.随时间反向传播算法即按照时间的逆序将错误信息一步步地往前传递.

二、实验环境

        本系列实验使用了PyTorch深度学习框架,相关操作如下:

1. 配置虚拟环境

conda create -n DL python=3.7 
conda activate DL
pip install torch==1.8.1+cu102 torchvision==0.9.1+cu102 torchaudio==0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
conda install matplotlib
 conda install scikit-learn

2. 库版本介绍

软件包本实验版本目前最新版
matplotlib3.5.33.8.0
numpy1.21.61.26.0
python3.7.16
scikit-learn0.22.11.3.0
torch1.8.1+cu1022.0.1
torchaudio0.8.12.0.2
torchvision0.9.1+cu1020.15.2

三、实验内容

0. 导入必要的工具包

import torch
from torch import nn
import matplotlib.pyplot as plt
import numpy as np

1. RNN模型

class Rnn(nn.Module):def __init__(self, input_size):super(Rnn, self).__init__()# 定义RNN网络## hidden_size是自己设置的,取值都是32,64,128这样来取值## num_layers是隐藏层数量,超过2层那就是深度循环神经网络了self.rnn = nn.RNN(input_size=input_size,hidden_size=32,num_layers=1,batch_first=True  # 输入形状为[批量大小, 数据序列长度, 特征维度])# 定义全连接层self.out = nn.Linear(32, 1)# 定义前向传播函数def forward(self, x, h_0):r_out, h_n = self.rnn(x, h_0)# print("数据输出结果;隐藏层数据结果", r_out, h_n)# print("r_out.size(), h_n.size()", r_out.size(), h_n.size())outs = []# r_out.size=[1,10,32]即将一个长度为10的序列的每个元素都映射到隐藏层上for time in range(r_out.size(1)):# print("映射", r_out[:, time, :])# 依次抽取序列中每个单词,将之通过全连接层并输出.r_out[:, 0, :].size()=[1,32] -> [1,1]outs.append(self.out(r_out[:, time, :]))# print("outs", outs)# stack函数在dim=1上叠加:10*[1,1] -> [1,10,1] 同时h_n已经被更新return torch.stack(outs, dim=1), h_n

a. 初始化__init__

  • 定义了RNN网络和全连接层。
    • self.rnn是一个RNN层:使用nn.RNN创建。
      • input_size参数表示输入数据的特征维度
      • hidden_size表示隐藏状态的维度
      • num_layers表示RNN层的堆叠层数
      • batch_first=True表示输入的形状为[批量大小, 数据序列长度, 特征维度]。
    • self.out是一个全连接层,将RNN的输出映射到1维输出。

b. 前向传播方法forward

  • 接受输入数据x和初始隐藏状态h_0作为参数。
    • 将输入数据和隐藏状态传入RNN层,得到输出r_out和最终隐藏状态h_n
    • 通过循环将序列中的每个时间步的输出经过全连接层,并将结果添加到outs列表中。
    • 使用torch.stack函数将outs列表中的结果在维度1上叠加,得到最终的预测结果,并返回预测结果和最终隐藏状态。

2. 训练和预测

a. 超参数

    TIME_STEP = 10INPUT_SIZE = 1LR = 0.02
  • TIME_STEP表示序列的长度
  • INPUT_SIZE表示输入数据的特征维度
  • LR表示学习率

b. 创建模型实例

    model = Rnn(INPUT_SIZE)print(model)

c. 模型训练

        使用正弦和余弦序列数据作为输入和目标输出,通过迭代训练,模型通过反向传播和优化器来不断调整参数以最小化预测结果与目标输出之间的损失。

    loss_func = nn.MSELoss()optimizer = torch.optim.Adam(model.parameters(), lr=LR)h_state = None  # 初始化h_state为Nonefor step in range(300):# 人工生成输入和输出,输入x.size=[1,10,1],输出y.size=[1,10,1]start, end = step * np.pi, (step + 1) * np.pi# np.linspace生成一个指定大小,指定数据区间的均匀分布序列,TIME_STEP是生成数量steps = np.linspace(start, end, TIME_STEP, dtype=np.float32)# print("steps", steps)x_np = np.sin(steps)y_np = np.cos(steps)# print("x_np,y_np", x_np, y_np)# 从numpy.ndarray创建一个张量 np.newaxis增加新的维度x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis])y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis])# print("x,y", x,y)# 将x通过网络,长度为10的序列通过网络得到最终隐藏层状态h_state和长度为10的输出prediction:[1,10,1]prediction, h_state = model(x, h_state)h_state = h_state.data# 这一步只取了h_state.data.因为h_state包含.data和.grad 舍弃了梯度# print("precision, h_state.data", prediction, h_state)# print("prediction.size(), h_state.size()", prediction.size(), h_state.size())# 反向传播loss = loss_func(prediction, y)optimizer.zero_grad()loss.backward()# 更新优化器参数optimizer.step()
  • 损失函数loss_func为均方误差损失(MSELoss)。
  • 优化器optimizer,使用Adam优化算法来更新模型的参数。
  • 初始化隐藏状态h_state为None。
  • 进行训练循环,共迭代300次:
    • 生成输入数据和目标输出数据。通过在每个迭代步骤中生成一个时间步长范围内的正弦和余弦函数值来构造序列数据。
    • 将生成的数据转换为张量形式,并添加新的维度。
    • 将输入数据通过模型进行前向传播,得到预测结果和最终隐藏状态。
    • 计算预测结果与目标输出之间的损失。
    • 清零优化器的梯度。
    • 执行反向传播,计算梯度。
    • 更新优化器的参数。

d. 预测结果可视化

    plt.plot(steps, y_np.flatten(), 'r-')plt.plot(steps, prediction.data.numpy().flatten(), 'b-')plt.show()

        将真实的目标输出数据和模型的预测结果进行可视化展示。

3. 代码整合

# 导入必要的工具包
import torch
from torch import nn
import matplotlib.pyplot as plt
import numpy as np# 定义RNN模型
class Rnn(nn.Module):def __init__(self, input_size):super(Rnn, self).__init__()# 定义RNN网络## hidden_size是自己设置的,取值都是32,64,128这样来取值## num_layers是隐藏层数量,超过2层那就是深度循环神经网络了self.rnn = nn.RNN(input_size=input_size,hidden_size=32,num_layers=1,batch_first=True  # 输入形状为[批量大小, 数据序列长度, 特征维度])# 定义全连接层self.out = nn.Linear(32, 1)# 定义前向传播函数def forward(self, x, h_0):r_out, h_n = self.rnn(x, h_0)# print("数据输出结果;隐藏层数据结果", r_out, h_n)# print("r_out.size(), h_n.size()", r_out.size(), h_n.size())outs = []# r_out.size=[1,10,32]即将一个长度为10的序列的每个元素都映射到隐藏层上for time in range(r_out.size(1)):# print("映射", r_out[:, time, :])# 依次抽取序列中每个单词,将之通过全连接层并输出.r_out[:, 0, :].size()=[1,32] -> [1,1]outs.append(self.out(r_out[:, time, :]))# print("outs", outs)# stack函数在dim=1上叠加:10*[1,1] -> [1,10,1] 同时h_n已经被更新return torch.stack(outs, dim=1), h_nif __name__ == '__main__':TIME_STEP = 10INPUT_SIZE = 1LR = 0.02model = Rnn(INPUT_SIZE)print(model)# 此处使用的是均方误差损失loss_func = nn.MSELoss()optimizer = torch.optim.Adam(model.parameters(), lr=LR)h_state = None  # 初始化h_state为Nonefor step in range(300):# 人工生成输入和输出,输入x.size=[1,10,1],输出y.size=[1,10,1]start, end = step * np.pi, (step + 1) * np.pi# np.linspace生成一个指定大小,指定数据区间的均匀分布序列,TIME_STEP是生成数量steps = np.linspace(start, end, TIME_STEP, dtype=np.float32)# print("steps", steps)x_np = np.sin(steps)y_np = np.cos(steps)# print("x_np,y_np", x_np, y_np)# 从numpy.ndarray创建一个张量 np.newaxis增加新的维度x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis])y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis])# print("x,y", x,y)# 将x通过网络,长度为10的序列通过网络得到最终隐藏层状态h_state和长度为10的输出prediction:[1,10,1]prediction, h_state = model(x, h_state)h_state = h_state.data# 这一步只取了h_state.data.因为h_state包含.data和.grad 舍弃了梯度# print("precision, h_state.data", prediction, h_state)# print("prediction.size(), h_state.size()", prediction.size(), h_state.size())# 反向传播loss = loss_func(prediction, y)optimizer.zero_grad()loss.backward()# 更新优化器参数optimizer.step()# 对最后一次的结果作图查看网络的预测效果plt.plot(steps, y_np.flatten(), 'r-')plt.plot(steps, prediction.data.numpy().flatten(), 'b-')plt.show()

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

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

相关文章

磁盘满了对日志打印(Logback)的影响

背景 我们生产环境有一个服务半夜报警:磁盘剩余空间不足10%,请及时处理。排查后发现是新上线的一个功能,日志打太多导致的,解决方法有很多,就不赘述了。领导担心报警不及时、或者报警遗漏,担心磁盘满了对线…

【Monorepo实战】pnpm+turbo+vitepress构建公共组件库文档系统

Monorepo架构可以把多个独立的系统放到一起联调,本文记录基于pnpm > workspace功能,如何构建将vitepress和组件库进行联调,并且使用turbo进行任务顺序编排。 技术栈清单: pnpm 、vitepress 、turbo 一、需求分析 1、最终目标…

“高级Vue状态管理 - Vuex的魅力与应用“

目录 引言1. Vuex的简介1.1 什么是Vuex?1.2 Vuex的核心概念 2. Vuex的值获取与改变(综合案例)3. Vuex的异步请求总结 引言 在现代Web开发中,前端应用变得越来越复杂。随着应用规模的扩大和数据流的复杂性增加,有效地管理应用的状态成为了一项…

澳大利亚教育部宣布ChatGPT将被允许在澳学校使用!

教育部长最近宣布,从 2024 年起,包括 ChatGPT 在内的人工智能将被允许在所有澳大利亚学校使用。 (图片来源:卫报) 而早些时候,澳洲各高校就已经在寻找与Chatgpt之间的平衡了。 之前,悉尼大学就…

【例题】逆波兰表达式求值(图解+代码)

【例题】逆波兰表达式求值(图解代码) 这里写目录标题 【例题】逆波兰表达式求值(图解代码)逆波兰表达式解释优点转换计算代码 题目描述 : 逆波兰表示法是一种将运算符(operator)写在操作数(operand)后面的描述程序(算式…

java过滤非中英文的特殊字符,四字节表情字符

过滤非中英文的特殊字符 /*** 过滤特殊字符* param str str* return String*/ public static String filterStr(String str) {if (StringUtils.isBlank(str)) {return str;}String regEx "[~!#$%^&*()|{}:;,\\[\\].<>/?~&#xff01;#&#xffe5;%……&…

Android---Synchronized 和 ReentrantLock

Synchronized 基本使用 1. 修饰实例方法 public class SynchronizedMethods{private int sum 0;public synchronized void calculate(){sum sum 1;} } 这种情况下的锁对象是当前实例对象&#xff0c;因此只有同一个实例对象调用此方法才会产生互斥效果&#xff1b;不同的…

Jenkins 添加节点Node报错JNI error has occurred UnsupportedClassVersionError

节点日志 报错信息如下 Error: A JNI error has occurred, please check your installation and try again Exception in thread “main” java.lang.UnsupportedClassVersionError: hudson/remoting/Launcher has been compiled by a more recent version of the Java Runtime…

LeetCode【300】最长递增子序列

题目&#xff1a; 思路&#xff1a; 通常来说&#xff0c;子序列不要求连续&#xff0c;而子数组或子字符串必须连续&#xff1b;对于子序列问题&#xff0c;第一种动态规划方法是&#xff0c;定义 dp 数组&#xff0c;其中 dp[i] 表示以 i 结尾的子序列的性质。在处理好每个…

vue3+ts项目02-安装eslint、prettier和sass

创建项目 项目创建 安装eslint yarn add eslint -D生成配置文件 npx eslint --init安装其他插件 yarn add -D eslint-plugin-import eslint-plugin-vue eslint-plugin-node eslint-plugin-prettier eslint-config-prettier eslint-plugin-node babel/eslint-parser vue-e…

关于IDEA中gradle项目bootrun无法进入断点以及gradle配置页面不全的解决方案

问题背景 在使用gradle编写的bootrun&#xff0c;采用debug方式启动项目时&#xff0c;无法进入断点&#xff0c;程序正常运行 并发现象1 此处无法识别为大象图标 点击右键后&#xff0c;没有圈中的这个选项 并发现象2 图片圈中的位置缺失 问题原因 正常的 run 命令是通过…

小程序, 多选项

小程序, 多选项 <view class"my-filter-btnwrap"><block wx:for"{{archiveList}}" wx:key"index"><view class"my-filter-btnitem text-ellipsis {{item.checked ? active : }}" data-index"{{index}}" wx…

CTF 全讲解:[SWPUCTF 2021 新生赛]Do_you_know_http

文章目录 参考环境题目hello.php雾现User-Agent伪造 User-AgentHackBarHackBar 插件的获取修改请求头信息 雾散 a.php雾现本地回环地址与客户端 IP 相关的 HTTP 请求头X-Forwarded-For 雾散 参考 项目描述搜索引擎Bing、GoogleAI 大模型文心一言、通义千问、讯飞星火认知大模型…

什么是全流程的UI设计?它与单页面的视觉设计有什么区别?

在软件产品研发流程中&#xff0c;产品交互设计一般是根据项目需求&#xff0c;做出设计方案&#xff0c;以求解决某个问题。而全流程的设计不再局限于短暂或者单个页面的视觉优化&#xff0c;而是追求持续性地参与&#xff0c;以全局性整体性地提升产品体验。 在软件内的信息传…

广州华锐互动:候车室智能数字孪生系统实现交通信息可视化

随着科技的不断发展&#xff0c;数字化技术在各个领域得到了广泛的应用。智慧车站作为一种新型的交通服务模式&#xff0c;通过运用先进的数字化技术&#xff0c;为乘客提供了更加便捷、舒适的出行体验。 将智慧车站与数字孪生大屏结合&#xff0c;可以将实际现实世界的实体车站…

【Overload游戏引擎分析】从视图投影矩阵提取视锥体及overload对视锥体的封装

overoad代码中包含一段有意思的代码&#xff0c;可以从视图投影矩阵逆推出摄像机的视锥体&#xff0c;本文来分析一下原理 一、平面的方程 视锥体是用平面来表示的&#xff0c;所以先看看平面的数学表达。 平面方程可以由其法线N&#xff08;A, B, C&#xff09;和一个点Q(x0,…

【运维】一些团队开发相关的软件安装。

gitlab 安装步骤 (1) 下载镜像&#xff0c;并且上传到服务器 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-16.2.8-ce.0.el7.x86_64.rpm &#xff08;2&#xff09;rpm -i gitlab-ce-16.2.8-ce.0.el7.x86_64.rpm &#xff08;3&#xff09;安装成功后…

【Vuex】入门使用---详细介绍

一&#xff0c;Vuex入门 1.1 什么是Vuex Vuex是一个专门为Vue.js应用程序开发的状态管理库。它用于管理应用程序中的共享状态&#xff0c;它采用集中式存储管理应用的所有组件的状态&#xff0c;使得状态的管理变得简单和可预测 官方解释&#xff1a;Vuex 是一个专为 Vue.js 应…

导入导出Excel

一、Springboot Easyexcel读取写入数据&#xff0c;多头行数&#xff0c;多sheet&#xff0c;复杂表头简单实现 1. 导入依赖&#xff0c;阿里的easyexcel插件 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId>…

Springboot整合Druid:数据库密码加密的实现

ps:Springboot项目&#xff0c;为了防止某些人反编译看到yml里面的数据库密码&#xff0c;对密码进行加密处理&#xff0c;隐藏公钥形式。&#xff08;总有人想扒掉你的底裤看看你屁股长什么样&#xff09; 1.引入依赖&#xff08;以前有依赖就不用了&#xff09; 2.找到Druid…