【从0到1搞懂大模型】RNN基础(4)

news/2025/3/18 14:12:58/

先说几个常用的可以下载数据集的地方

  • 平台:kaggle(https://www.kaggle.com/datasets)

和鲸社区(https://www.heywhale.com/home)

阿里天池(https://tianchi.aliyun.com/)

  • 其他:海量公开数据集汇总-CSDN博客

下面使用的数据集来源与计算股票数据集 | Kaggle

普通神经网络处理序列数据

我们尝试一下用普通神经网络处理序列数据,下面是一个股票相关的序列数据

import pandas as pd
import os,math
from sklearn.preprocessing import MinMaxScaler
from sklearn import metrics
import numpy  as np
import pandas as pdimport matplotlib.pyplot as pltdata = pd.read_csv('SH600519.csv') 
data

我们取其中一列作为预测的 y 值,图像大概如下所示 

dataset = data.iloc[:, 2:3].values  
plt.plot(dataset)

下面对数据进行预处理

max_value = np.max(dataset)
min_value = np.min(dataset)
scalar = max_value - min_value   #也可以直接用MinMaxScaler(feature_range=(0, 1))
dataset = list(map(lambda x: x / scalar, dataset))def create_dataset(dataset, look_back=5):dataX, dataY = [], []for i in range(len(dataset) - look_back):a = dataset[i:(i + look_back)]dataX.append(a)dataY.append(dataset[i + look_back])return np.array(dataX), np.array(dataY)# 创建好输入输出
data_X, data_Y = create_dataset(dataset)
data_X =data_X.reshape(-1,5)
# 划分训练集和测试集,70% 作为训练集
train_size = int(len(data_X) * 0.7)
test_size = len(data_X) - train_size
train_X = data_X[:train_size]
train_Y = data_Y[:train_size]
test_X = data_X[train_size:]
test_Y = data_Y[train_size:]look_back = 5train_x = torch.from_numpy(train_X)
train_y = torch.from_numpy(train_Y)
test_x = torch.from_numpy(test_X)

构建普通神经网络

class FullyConnected(nn.Module):def __init__(self, x_size, hidden_size, output_size=1):super(FullyConnected, self).__init__()self.hidden_size = hidden_sizeself.linear_with_tanh = nn.Sequential(nn.Linear(x_size, self.hidden_size), # 线性层1nn.Tanh(),  # 激活函数nn.Linear(self.hidden_size, self.hidden_size),  #线性层2nn.Tanh(),  #激活函数nn.Linear(self.hidden_size, output_size)  #线性层)def forward(self, x):yhat = self.linear_with_tanh(x)return yhat

开始训练

fc_model = FullyConnected(x_size=5, hidden_size = 3)
criterion = nn.MSELoss()  #损失函数类型:多分类(CrossEntropyLoss),均方误差(MSELoss),二分类(BCELoss)
optimizer = torch.optim.Adam(fc_model.parameters(), lr=1e-2)## 开始训练
for e in range(1000):# 前向传播for i in range(len(train_x)):x_train = train_x[i]y_train = train_y[i]out = fc_model(x_train)loss = criterion(out, y_train)# 反向传播optimizer.zero_grad()loss.backward()optimizer.step()if (e + 1) % 100 == 0: # 每 100 次输出结果print('Epoch: {}, Loss: {:.5f}'.format(e + 1, loss.item()))fc_model = fc_model.eval() # 转换成测试模式
data_X = torch.from_numpy(data_X)
var_data = Variable(data_X)
pred_test = fc_model(var_data) # 测试集的预测结果# 改变输出的格式
pred_test = pred_test.view(-1).data.numpy()
# 画出实际结果和预测的结果
plt.plot(pred_test, 'r', label='prediction')
plt.plot(dataset, 'b', label='real')
plt.legend(loc='best')

这里插播一下之前讲过的梯度下降方法,其实只需要改成下面代码就够了【从0到1搞懂大模型】神经网络长什么样子?参数又是如何变化的?(2)-CSDN博客

  • 普通梯度下降:torch.optim.SGD
  • adagrad:torch.optim.Adagrad
  • RMSprop:torch.optim.RMSprop
  • Adam:torch.optim.Adam

最终得到的曲线如下

 

 我们可以发现,普通神经网络对于这样一个小小的序列数据预测效果还是很差的,那怎么办呢?下面引出我们的循环神经网络——RNN

RNN

在实际应用中,我们会遇到很多序列数据  如:

  • 自然语言处理问题。x1可以看做是第一个单词,x2可以看做是第二个单词,依次类推。
  • 语音处理。此时,x1、x2、x3……是每帧的声音信号。
  • 时间序列问题。例如每天的股票价格等等。

序列形的数据不太好用原始的神经网络处理了。

为了建模序列问题,RNN引入了隐状态h(hidden state)的概念,h可以对序列形的数据提取特征,接着再转换为输出。

先从h1的计算开始看:

其实整体来说就是每次处理新数据时,它会结合当前的输入和之前的“记忆”(即隐藏状态)。

接下来我们用 RNN 再对刚才的数据集做预测

import pandas as pd
import os,math
from sklearn.preprocessing   import MinMaxScaler
from sklearn import metrics
import numpy  as np
import pandas as pdimport matplotlib.pyplot as pltdata = pd.read_csv('SH600519.csv') 
dataset = data.iloc[:, 2:3].values  
plt.plot(dataset)
dataset = dataset.astype('float32')
max_value = np.max(dataset)
min_value = np.min(dataset)
scalar = max_value - min_value
dataset = list(map(lambda x: x / scalar, dataset))def create_dataset(dataset, look_back=5):dataX, dataY = [], []for i in range(len(dataset) - look_back):a = dataset[i:(i + look_back)]dataX.append(a)dataY.append(dataset[i + look_back])return np.array(dataX), np.array(dataY)data_X, data_Y = create_dataset(dataset)
# 划分训练集和测试集,70% 作为训练集
train_size = int(len(data_X) * 0.7)
test_size = len(data_X) - train_size
train_X = data_X[:train_size]
train_Y = data_Y[:train_size]
test_X = data_X[train_size:]
test_Y = data_Y[train_size:]train_X = train_X.reshape(-1, 1, 5)
train_Y = train_Y.reshape(-1, 1, 1)
test_X = test_X.reshape(-1, 1, 5)train_x = torch.from_numpy(train_X)   #如果是把torch转为numpy则用array = torch_data.numpy()
train_y = torch.from_numpy(train_Y)
test_x = torch.from_numpy(test_X)# 定义模型
class rnn_reg(nn.Module):def __init__(self, input_size, hidden_size, output_size=1, num_layers=2):super(rnn_reg, self).__init__()self.rnn = nn.RNN(input_size, hidden_size, num_layers) # rnnself.reg = nn.Linear(hidden_size, output_size) # 线性层def forward(self, x):x, _ = self.rnn(x) # (seq, batch, hidden)s, b, h = x.shapex = x.view(s*b, h) # 转换成线性层的输入格式x = self.reg(x)x = x.view(s, b, -1)return xnet = rnn_reg(5, 3)criterion = nn.MSELoss()  
optimizer = torch.optim.Adam(net.parameters(), lr=1e-2)for e in range(1000):# 前向传播out = net(train_x)loss = criterion(out, train_y)# 反向传播optimizer.zero_grad()loss.backward()optimizer.step()if (e + 1) % 100 == 0: # 每 100 次输出结果print('Epoch: {}, Loss: {:.5f}'.format(e + 1, loss.item()))net = net.eval() # 转换成测试模式
data_X = data_X.reshape(-1, 1, 5)
data_X = torch.from_numpy(data_X)
var_data = Variable(data_X)
pred_test = net(var_data) # 测试集的预测结果# 改变输出的格式
pred_test = pred_test.view(-1).data.numpy()
# 画出实际结果和预测的结果
plt.plot(pred_test, 'r', label='prediction')
plt.plot(dataset, 'b', label='real')
plt.legend(loc='best')

这次用了 RNN,预测结果如下 

可以看到对于序列数据,RNN 效果比普通神经网络好很多!

具体来说,RNN有三个核心特点:

  1. 自带记忆功能
    每次处理新数据时,它会结合当前的输入和之前的“记忆”(即隐藏状态)。比如分析“我想吃北京烤鸭”这句话,读到“吃”时,RNN会记住前面有个“我”,从而推测后面大概率是食物名词

  2. 适合序列任务
    像语言翻译、股票预测这类需要联系前后信息的任务,传统神经网络处理不好,而RNN能捕捉时间或顺序的关联性。比如预测明天的气温,它会把今天、昨天的温度变化趋势都考虑进去

  3. 结构简单但有局限
    虽然基础版RNN结构不复杂(输入层+循环隐藏层+输出层),但它容易“记不住太久远的事”。比如分析长篇文章时,可能只记得最近几段的内容,早期的信息会被淡化

举个生活中的例子:​就像你背古诗,背到第五句时可能记不清第二句,但能根据第四句推测第五句的内容。RNN也是这样——短期记忆强,但对特别长的序列处理效果会打折扣(后来人们发明了LSTM等改进版解决了这个问题),下次我们就讲一下 LSTM~


http://www.ppmy.cn/news/1580088.html

相关文章

Uniapp 从入门到精通:动画与过渡效果的运用

Uniapp 从入门到精通:动画与过渡效果的运用 前言一、引言1.1 Uniapp 简介1.2 动画与过渡效果的重要性二、Uniapp 基础回顾2.1 开发环境搭建2.2 基础语法与组件三、动画与过渡效果基础3.1 CSS 动画基础3.2 Vue 过渡效果四、Uniapp 中的动画与过渡效果高级应用4.1 使用 uni.crea…

MyBatis 如何解析 XML 配置文件和 SQL 映射文件

MyBatis 使用 SAX(Simple API for XML)解析器来解析 XML 文件,SAX 是一种基于事件驱动的 XML 解析方式,具有高效、低内存消耗的优点。 MyBatis 主要解析两种类型的 XML 文件: 核心配置文件 (mybatis-config.xml): 定…

UnitTest框架管理测试用例——python自动化测试

UnitTest框架 UnitTest是Python自带一个单元测试框架,常用它来做单元测试。 注意:对于测试来说,UnitTest框架的作用是 自动化脚本(用例代码)执行框架————(使用UnitTest框架来管理 运行多个测试用例的) 为什么使用UnitTest框架 能够组织多个用例去执…

Android视频渲染SurfaceView强制全屏与原始比例切换

1.创建UI添加强制全屏与播放按钮 2.SurfaceView控件设置全屏显示 3.全屏点击事件处理实现 4.播放点击事件处理 5.使用接口更新强制全屏与原始比例文字 强制全屏/原始比例 点击实现

力扣hot100二刷——二叉树

第二次刷题不在idea写代码,而是直接在leetcode网站上写,“逼”自己掌握常用的函数。 标志掌握程度解释办法⭐Fully 完全掌握看到题目就有思路,编程也很流利⭐⭐Basically 基本掌握需要稍作思考,或者看到提示方法后能解答⭐⭐⭐Sl…

完善 Django 框架以实现传递视频、图片给算法模块进行识别分析

要完善 Django 框架以实现传递视频、图片给算法模块进行识别分析,可按以下步骤进行: 1. 项目初始化 首先,确保你已经安装了 Django 和其他必要的库(如 Pillow 用于图片处理)。创建一个新的 Django 项目和应用&#x…

甲骨文找回二次验证的方法(超简单)

因为更换手机丢失了二次验证。 然后给客服沟通,获得了找到二次验证的办法,希望对你有用。 1、登录到账号登陆界面,查看地址栏当中自己的IDCE地址(yourIDCS_Stripe_here)部分,并复制。 https://idcs-yourID…

ZooKeeper的五大核心作用及其在分布式系统中的关键价值

引言 在分布式系统的复杂架构中,协调多个节点的一致性、可靠性和高可用性始终是技术挑战的核心。​Apache ZooKeeper作为业界广泛采用的分布式协调服务,凭借其简洁的树形数据模型(ZNode)和高效的原子广播协议(ZAB&…