循环神经网络(RNN)简单介绍—包括TF和PyTorch源码,并给出详细注释

news2024/12/28 22:17:00

文章目录

  • 循环神经网络(RNN)入门教程
    • 1. 循环神经网络的原理
    • 2. 循环神经网络的应用
    • 3. 使用keras框架实现循环神经网络
        • 3.1导入对应的库及加载数据集
        • 3.2.数据预处理
        • 3.3定义RNN模型
        • 3.4训练模型
        • 3.5测试模型
    • 4.使用PyTorch框架实现上述功能—注释详细
    • 5.结论

循环神经网络(RNN)入门教程

循环神经网络(Recurrent Neural Networks,RNN)是一类具有记忆功能的神经网络,主要应用于序列数据的建模和处理,例如自然语言文本和音频、视频。与前馈神经网络不同,RNN网络中的神经元可以接受自身过去的输出作为输入,从而实现对序列数据的记忆和预测。常见的RNN模型包括基本循环神经网络、长短期记忆网络(LSTM)和门控循环单元(GRU)等。

在本教程中,我们将介绍循环神经网络的基本原理和应用,以及如何使用keras框架和pytorch框架实现一个简单的循环神经网络模型。

1. 循环神经网络的原理

循环神经网络的主要特点是它可以处理具有时间序列结构的数据。它的神经元之间存在循环连接,使得当前时刻的输入和前一时刻的输出可以共同影响当前时刻的输出。这种结构使得循环神经网络可以处理变长的时间序列数据,而且不需要预先确定时间序列的长度。

给出简单的循环神经网络结构图,包括5个时间步长和一个输入序列 ( x 1 , x 2 , . . . , x 5 ) (x1, x2, ..., x5) (x1,x2,...,x5),以及对应的隐藏状态 ( h 0 , h 1 , . . . , h 5 ) (h0, h1, ..., h5) (h0,h1,...,h5) 和输出序列 ( y 1 , y 2 , . . . , y 5 ) (y1, y2, ..., y5) (y1,y2,...,y5) ,循环神经网络的基本结构如下图所示:

请添加图片描述

循环神经网络(RNN)是一种通过逐个处理序列中的元素来处理序列的神经网络。在每个时间步长t,RNN都会根据当前的输入 x t x_{t} xt和先前的隐藏状态 h t − 1 h_{t-1} ht1计算出新的隐藏状态 h t h_{t} ht和输出 y t y_{t} yt。我们可以使用以下公式来表示RNN的计算过程:
h t = f h ( W x x t + W h h t − 1 + b h ) h_t = f_{h}(W_{x}x_{t} + W_{h}h_{t-1} + b_h) ht=fh(Wxxt+Whht1+bh)

y t = f y ( W y h t + b y ) y_t = f_{y}(W_{y}h_t + b_y) yt=fy(Wyht+by)

其中, W x W_{x} Wx W h W_{h} Wh是输入和隐藏状态之间的权重矩阵, W y W_{y} Wy是隐藏状态和输出之间的权重矩阵, b h b_h bh b y b_y by是偏置项, f h f_{h} fh f y f_{y} fy是激活函数,通常是tanh或ReLU。

这个公式表示了RNN在一个时间步长t如何计算新的隐藏状态 h t h_{t} ht和输出 y t y_{t} yt。在这个公式中,我们首先将输入 x t x_{t} xt和先前的隐藏状态 h t − 1 h_{t-1} ht1合并起来,使用权重矩阵相乘,然后加上偏置项 b h b_{h} bh。接下来我们通过激活函数 f h f_{h} fh来对这个合并后的向量进行非线性变换,从而得到新的隐藏状态 h t h_{t} ht。最后,我们使用新的隐藏状态 h t h_{t} ht和权重矩阵 W y W_{y} Wy来计算输出 y t y_{t} yt,并通过激活函数 f y f_{y} fy对其进行非线性变换。

通过重复使用这个公式来处理序列中的每个元素,我们可以构建一个循环神经网络,并使用它来预测具有时序特征的数据。

当用于多分类问题时,其中 f y f_y fy就会变成softmax的激活函数,如下:
y t = s o f t m a x ( W y h t + b y ) y_t = softmax(W_{y}h_t + b_y) yt=softmax(Wyht+by)

2. 循环神经网络的应用

循环神经网络可以应用于多种任务,包括:

  • 语言模型:预测下一个单词或字符
  • 机器翻译:将一种语言翻译成另一种语言
  • 语音识别:将语音转换成文本
  • 图像描述生成:根据图像生成相应的文字描述
  • 情感分析:根据文本判断情感是积极还是消极

3. 使用keras框架实现循环神经网络

我们使用Python和Keras框架来实现一个简单的循环神经网络模型。我们将使用MNIST数据集来演示模型的训练和测试。

3.1导入对应的库及加载数据集

首先,我们需要导入所需的库:

from keras.datasets import mnist  # 从keras.datasets中导入MNIST数据集
from keras.models import Sequential  # 导入Sequential模型
from keras.layers import SimpleRNN, Dense  # 导入SimpleRNN层和Dense层
from keras.utils import to_categorical  # 导入to_categorical函数

接下来,我们需要加载MNIST数据集并进行预处理:

# 加载MNIST数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()

3.2.数据预处理

# 数据预处理,将每个像素点的值归一化到0到1之间,并将标签进行独热编码
x_train = x_train.reshape(-1, 28, 28) / 255.0
x_test = x_test.reshape(-1, 28, 28) / 255.0
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

在上面的代码中,我们使用mnist.load_data()函数加载MNIST数据集,并对数据进行预处理,将每个像素点的值归一化到0到1之间,并将标签进行独热编码。

3.3定义RNN模型

接下来,我们定义一个简单的循环神经网络模型:

# 定义一个简单的循环神经网络模型
model = Sequential()  # 定义顺序模型
model.add(SimpleRNN(units=32, input_shape=(28, 28)))  # 添加SimpleRNN层
model.add(Dense(units=10, activation='softmax'))  # 添加全连接层
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])  # 编译模型,指定损失函数、优化器和评价指标

在上面的代码中,我们使用Sequential类定义一个顺序模型,并添加一个SimpleRNN层和一个全连接层。SimpleRNN层有32个神经元,输入维度为(28,28),表示输入是28个时间步长,每个时间步长的输入维度为28。全连接层有10个神经元,使用softmax作为激活函数,表示输出的概率分布。我们使用categorical_crossentropy作为损失函数,adam作为优化器,并将准确率作为评价指标。

3.4训练模型

接下来,我们训练模型:

# 训练模型
model.fit(x_train, y_train, batch_size=64, epochs=10, validation_data=(x_test, y_test))

在上面的代码中,我们使用fit方法对模型进行训练,将训练数据集和标签作为输入,设置批量大小为64,迭代次数为10次,并将测试数据集作为验证集。训练过程中,模型会输出每个epoch的损失和准确率。

3.5测试模型

最后,我们使用测试数据集对模型进行测试:

# 使用测试数据集对模型进行测试
loss, accuracy = model.evaluate(x_test, y_test)
print('Test loss:', loss)
print('Test accuracy:', accuracy)

在上面的代码中,我们使用evaluate方法对模型进行测试,并输出测试集的损失和准确率。

4.使用PyTorch框架实现上述功能—注释详细

import torch  # 导入PyTorch
import torch.nn as nn  # 导入PyTorch的神经网络模块
import torchvision.datasets as dsets  # 导入PyTorch的数据集模块
import torchvision.transforms as transforms  # 导入PyTorch的数据预处理模块

# 定义超参数
input_size = 28  # 输入层大小,图片大小为28x28
sequence_length = 28  # 序列长度,每个序列表示一行像素
num_layers = 1  # 网络层数
hidden_size = 32  # 隐藏层大小
num_classes = 10  # 输出类别数量
batch_size = 64  # 每个小批次大小
num_epochs = 10  # 迭代次数
learning_rate = 0.001  # 学习率

# 加载MNIST数据集
train_dataset = dsets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True)  # 加载训练集
test_dataset = dsets.MNIST(root='./data', train=False, transform=transforms.ToTensor())  # 加载测试集
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)  # 创建训练数据加载器
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)  # 创建测试数据加载器

# 定义一个简单的循环神经网络模型
class RNN(nn.Module):  # 定义RNN类,继承自nn.Module
    def __init__(self, input_size, hidden_size, num_layers, num_classes):
        super(RNN, self).__init__()  # 调用父类的构造函数
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)  # 定义RNN层
        self.fc = nn.Linear(hidden_size, num_classes)  # 定义全连接层

    def forward(self, x):
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)  # 初始化隐藏状态h0
        out, _ = self.rnn(x, h0)  # 前向传播,输出out和最终隐藏状态
        out = self.fc(out[:, -1, :])  # 取最后一个时间步的输出,传入全连接层
        return out

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')  # 判断是否支持GPU加速
model = RNN(input_size, hidden_size, num_layers, num_classes).to(device)  # 定义模型,并将其移动到GPU上
criterion = nn.CrossEntropyLoss()  # 定义损失函数
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)  # 定义优化器

# 训练模型
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        images = images.reshape(-1, sequence_length, input_size).to(device)  # 将图片数据reshape成[batch_size, sequence_length, input_size]大小,并移动到GPU上
        labels = labels.to(device)  # 将标签数据移动到GPU上
        outputs = model(images)  # 前向传播,计算模型输出
        loss = criterion(outputs, labels)  # 计算损失
        optimizer.zero_grad()  # 清空梯度
        loss.backward()  # 反向传播,计算梯度
        optimizer.step()  # 更新权重和偏置
        if (i+1) % 100 == 0:  # 每训练100个小批次,输出一次信息
            print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, len(train_loader), loss.item()))

# 测试模型
with torch.no_grad():  # 禁用梯度计算,加速推理过程
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = images.reshape(-1, sequence_length, input_size).to(device)  # 将图片数据reshape成[batch_size, sequence_length, input_size]大小,并移动到GPU上
        labels = labels.to(device)  # 将标签数据移动到GPU上
        outputs = model(images)  # 前向传播,计算模型输出
        _, predicted = torch.max(outputs.data, 1)  # 取最大值作为预测结果
        total += labels.size(0)  # 累加样本数量
        correct += (predicted == labels).sum().item()  # 累加正确预测的样本数量

    print('Accuracy of the model on the test images: {} %'.format(100 * correct / total))  # 输出模型测试精度

5.结论

在本教程中,我们介绍了循环神经网络的基本原理和应用,以及如何使用Python和Keras框架实现一个简单的循环神经网络模型。循环神经网络是一种强大的神经网络结构,可以处理具有时间序列结构的数据,并且在自然语言处理、语音识别、图像处理等领域具有广泛的应用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动静态库的制作和使用

动静态库 一,什么是库二,静态库的制作静态库原理 三,动态库的制作四,动态库的配置五,动态库的加载 一,什么是库 🚀库这个东西我们一直在使用,举个简单了例子,无论你是用…

netplan, NetworkManager, systemd-networkd简介

1、systemd-networkd简介 systemd-networkd是systemd 的一部分 ,负责 systemd 生态中的网络配置部分(systemd-networkd.service, systemd-resolved.service)。使用 systemd-networkd,你可以为网络设备配置基础的 DHCP/静态IP网络等,还可以配…

U8W/U8W-Mini使用与常见问题解决

U8W/U8W-Mini使用与常见问题解决 U8WU8W/U8W-mini简介准备工作U8W/U8W-mini在线联机下载U8W/U8W-mini脱机下载第一步,把程序下载到U8W/U8W-mini烧录器中:第二步,用U8W/U8W-mini烧录器给目标单片机脱机下载 U8W/U8W-mini烧录器使用中常见的问题…

初识Linux运维

一.初识Linux 1.Linux系统内核 内核提供了Linux系统的主要功能,如硬件调度管理的能力。 Linux内核是免费开源的,任何人都可以查看内核的源代码,甚至是贡献源代码。 2.Linux系统发行版 内核无法被用户直接使用,需要配合应用程…

淘宝iOS拍立淘微距能力探索与实现

画面模糊问题的源头也是来自用户的微距体验不佳,我们对问题深入分析,适当拆解。通过 Apple Development Doc 的查阅及实践,一步步抽丝剥茧,最终完美解决用户的体验痛点,也为我们自身沉淀了展示微距的能力。 前言 在最近…

Unix和Linux

UNIX 诞生于 20 世纪 60 年代末 Windows 诞生于 20 世纪 80 年代中期 Linux 诞生于 20 世纪 90 年代初 1965 年,贝尔实验室、美国麻省理工学院和通用电气公司联合发起了Multics 工程计划,目标是开发一种交互式的、具有多道程序处理能力的分时操作系统&a…

NTP服务与SSH服务

NTP:时间同步服务,采用UDP协议,端口号为123。 配置NTP时间服务器,确保客户端主机能和服务主机同步时间 首先,我们必须确保服务端与客户端在同一时区。 更改时区:timedatectl set-timezone asia/shanghai …

隋唐洛阳“西宫”:上阳宫的GIS视角

隋唐洛阳城简介 营建 隋大业元年(605年),在隋炀帝的授意下,隋代著名城市设计师宇文恺,在汉魏故城以西重新选址,历时8个月,日役劳工200万,兴建新都洛阳城。 城和苑 隋唐洛阳城采用…

页面注册案例

效果图: 分析业务模块: 发送验证码模块各个表单验证模块勾选已经阅读同意模块下一步验证全部模块:只要上面有一个input验证不通过就不同意提交 业务 1 :发送验证码 用户点击之后,显示05秒后重新获取时间到了&…

大国护眼学习笔记01

第一天(23.4.17) 2—11节什么是近视? 1、“近视离焦”是指成像点落在视网膜的哪里? 前面 2、“远视离焦”是指成像点落在视网膜的哪里? 后面 3、眼轴变长时,成像点会往前移还是往后移? 前移 4、…

毛灵栋 : 以兴趣为壤,育能力之实 | 提升之路系列(一)

导读 为了发挥清华大学多学科优势,搭建跨学科交叉融合平台,创新跨学科交叉培养模式,培养具有大数据思维和应用创新的“π”型人才,由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

【RP-RV1126】Ubuntu上配置Buildroot Qt 开发板远程开发调试环境(SSH)

文章目录 一、前提二、基础设置建设Buildroot编译Qt5配置SSHBuildroot文件系统添加账号密码开发板联网Buildroot文件系统构建时打开rsync功能 三、QtCreator配置3.1 配置Qt交叉编译套件(Kits)配置Kits里面的交叉编译器配置Kits里面的qmake工具最后配置Kits 3.2 配置远程部署设备…

VLAN基础实验

实验要求: 1、PC1和PC3所在接口为Access接口 PC2/4/5/6处于同一网段:其中PC2可以访问PC4/5/6 PC4可以访问PC5,但不能访问PC6 PC5不能访问PC6 2、PC1/3与PC2/4/5/6不再同一网段 3、所有PC通过DHCP获取IP地址,且PC1/3可以正常访问PC2/4/5/6 实…

tkinter-TinUI-xml实战(9)crosschat客户端

tkinter-TinUI-xml实战(9)crosschat客户端 引言声明文件结构核心代码服务端连接登录界面主页面主文件 结语 引言 CrossChat(十字街)是一个线上匿名群聊平台,类似Hack.Chat。 现在通过websocket简单地构建一个cc的客户…

随机蛙跳算法 (SFLA)简单实现(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 随着计算机科学与技术的迅速发展,人类生存空间的扩大以及认识与改造世界范围的拓宽,人们对科学技术提出了新的和更高的要求,其…

android中线程池的选择

线程池是把一个或多个线程通过统一的方式进行调度和重复使用的技术。 避免了因为线程过多而带来使用上的开销。 在安卓开发中,为了更好的性能体验,我们在选择线程池的时候,需要从具体需求来考虑,主要考虑以下几方面: …

计算机类专业的普通校招生毕业如何“卷”一份好工作?

毕业差不多两年的校招生有感 一、为什么写这篇文章?二、我 → 一名普通的校招生前身三、我 → 一名普通的校招生养成四、校招如何拿到offer?五、总结 一、为什么写这篇文章? 一开始我写CSDN是为了记录自己学习技术的小日记,小总结…

JavaScript运算符与表达式

目录 一、 二、|| 三、??与?. ?? ?. 四、... 五、[] {} [] {} 一、 严格相等运算符,用作逻辑判断 1 1 // 返回 true 1 1 // 返回 true,会先将右侧的字符串转为数字,再做比较 1 1 // 返回 false,类型不等…

每日学术速递4.22

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Reference-based Image Composition with Sketch via Structure-aware Diffusion Model 标题:通过结构感知扩散模型与草图进行基于参考的图像合成 作者:Kang…

PDF转PPT:省时省力的高效方式

PDF和PPT是日常工作和学习中常见的文件格式,但是它们的使用场景不同,很多时候需要将PDF文件转换为PPT文件才能更好地展示内容。本文将介绍如何使用PDF转PPT工具来实现快速转换,省时省力。 一、为什么需要将PDF文件转换为PPT文件 1.PPT文件更…