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

【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU)详细理解并附实现代码。

【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU)

【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU)


文章目录

  • 【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU)
  • 1.门控循环单元 (Gated Recurrent Units, GRU) 原理详解
    • 1.1 GRU 概述
    • 1.2 GRU 的门控机制
    • 1.3 GRU 的优缺点
    • 1.4 GRU 的应用
  • 2.Python 实现 GRU 的实例
    • 2.1GRU 实现及应用实例
    • 2.2 代码解释
  • 3.总结


参考地址:https://www.asimovinstitute.org/neural-network-zoo/
论文地址:https://arxiv.org/pdf/1412.3555v1

欢迎宝子们点赞、关注、收藏!欢迎宝子们批评指正!

1.门控循环单元 (Gated Recurrent Units, GRU) 原理详解

---

1.1 GRU 概述

GRU 是 LSTM(长短期记忆网络)的变体。与 LSTM 类似,GRU 也是为了解决 RNN 中的 梯度消失 和 梯度爆炸 问题而设计的,但 GRU 相比 LSTM 结构更为简单。GRU 去除了 LSTM 中的输出门,并结合了输入门和遗忘门为一个更新门。这使得 GRU 在某些情况下比 LSTM 更高效。

1.2 GRU 的门控机制

GRU 有两个门:更新门 (update gate) 和 重置门 (reset gate)

  • 更新门 (update gate): 控制当前隐藏状态中保留多少信息,决定保留多少先前的状态,以及从当前输入中引入多少新信息。
  • 重置门 (reset gate): 决定如何将新信息与之前的记忆结合起来,类似于 LSTM 的遗忘门,但工作方式稍有不同。

GRU 的公式为:

  • 更新门:
    z t = σ ( W z x t + U z h t − 1 ) z_t=σ(W_zx_t+U_zh_{t-1}) zt=σ(Wzxt+Uzht1)
  • 重置门:
    r t = σ ( W r x t + U r h t − 1 ) r_t=σ(W_rx_t+U_rh_{t-1}) rt=σ(Wrxt+Urht1)
  • 候选隐藏状态:
    h ~ t = t a n h ( W h x t + U h ( r t ⊙ h t − 1 ) ) \widetilde{h}_t=tanh(W_hx_t+U_h(r_t⊙h_{t-1})) h t=tanh(Whxt+Uh(rtht1))
  • 隐藏状态更新:
    h t = z t ⊙ h t − 1 + ( 1 − z t ) ⊙ h ~ t h_t=z_t⊙h_{t-1}+(1-z_t)⊙\widetilde{h}_t ht=ztht1+(1zt)h t

其中:

  • z t z_t zt是更新门,控制先前状态和当前候选状态的平衡。
  • r t r_t rt是重置门,控制前一时刻隐藏状态的影响程度。
  • h ~ t \widetilde{h}_t h t是候选的隐藏状态,使用当前输入和前一时刻的隐藏状态生成。
  • h t h_t ht是当前的隐藏状态。

1.3 GRU 的优缺点

  • 优点: 结构更简单,计算量较小,比 LSTM 更快,适合不需要复杂表达能力的场景。
  • 缺点: 由于少了一个门控机制(没有输出门),在某些任务中表现略逊于 LSTM。

1.4 GRU 的应用

GRU 和 LSTM 类似,广泛应用于序列数据处理任务,包括:

  • 自然语言处理 (NLP):如机器翻译、文本生成等。
  • 语音识别:处理连续的语音数据。
  • 时间序列预测:用于预测未来的趋势,例如股票预测等。

2.Python 实现 GRU 的实例

我们使用 PyTorch 实现一个基于 GRU 的文本分类模型。与前面 RNN 实例类似,我们将训练一个二分类模型。

2.1GRU 实现及应用实例

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset# 构造简单的示例数据集
# 假设有两个类别的句子,分别标注为 0 和 1
X = [[1, 2, 3, 4],     # "I love machine learning"[5, 6, 7, 8],     # "deep learning is great"[1, 9, 10, 11],   # "I hate spam emails"[12, 13, 14, 15]  # "phishing attacks are bad"
]
y = [0, 0, 1, 1]  # 标签# 转换为 Tensor 格式
X = torch.tensor(X, dtype=torch.long)
y = torch.tensor(y, dtype=torch.long)# 定义数据集和数据加载器
dataset = TensorDataset(X, y)
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)# 定义 GRU 模型
class GRUModel(nn.Module):def __init__(self, input_size, hidden_size, output_size, num_layers):super(GRUModel, self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layersself.embedding = nn.Embedding(input_size, hidden_size)  # 嵌入层self.gru = nn.GRU(hidden_size, hidden_size, num_layers, batch_first=True)  # GRU 层self.fc = nn.Linear(hidden_size, output_size)  # 全连接层def forward(self, x):# 初始化隐藏状态h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)# 嵌入层out = self.embedding(x)# 通过 GRUout, _ = self.gru(out, h0)# 取最后一个时间步的隐藏状态out = out[:, -1, :]# 全连接层进行分类out = self.fc(out)return out# 模型参数
input_size = 16  # 假设词汇表有 16 个词
hidden_size = 8  # 隐藏层维度
output_size = 2  # 输出为二分类
num_layers = 1   # GRU 层数# 创建模型
model = GRUModel(input_size, hidden_size, output_size, num_layers)# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)# 训练模型
num_epochs = 20
for epoch in range(num_epochs):for data, labels in dataloader:# 前向传播outputs = model(data)loss = criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch+1) % 5 == 0:print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')# 测试模型
with torch.no_grad():test_sentence = torch.tensor([[1, 2, 3, 4]])  # 测试句子 "I love machine learning"prediction = model(test_sentence)predicted_class = torch.argmax(prediction, dim=1)print(f'Predicted class: {predicted_class.item()}')

2.2 代码解释

1.定义 GRU 模型:

  • self.embedding = nn.Embedding(input_size, hidden_size):将输入的单词索引转换为高维向量表示。
  • self.gru = nn.GRU(hidden_size, hidden_size, num_layers, batch_first=True):定义 GRU 层,输入和输出维度为 hidden_sizebatch_first=True 表示输入序列按批次为第一维度。
  • self.fc = nn.Linear(hidden_size, output_size):全连接层将 GRU 输出映射为分类输出。

2.GRU 的前向传播:

  • h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device):初始化 GRU 的隐藏状态。
  • out, _ = self.gru(out, h0):通过 GRU 层,out 是每个时间步的输出。
  • out = out[:, -1, :]:取最后一个时间步的隐藏状态作为最终输出。
  • out = self.fc(out):通过全连接层进行分类。

3.数据集与加载器:

  • 使用简单的二分类文本数据,将其转换为 PyTorch 的 TensorDatasetDataLoader

4.训练与测试:

  • 使用 Adam 优化器和交叉熵损失函数训练模型,在每 5 个 epoch 打印一次损失。
  • 测试阶段输入测试句子,输出分类结果。

3.总结

GRU 是一种简化的循环神经网络,与 LSTM 类似,适用于处理时间序列数据或具有顺序依赖的任务。

相比于 LSTM,GRU 计算效率更高,但表达能力稍弱。在实际应用中,GRU 常用于自然语言处理、语音识别和时间序列预测等领域。通过 Python 和 PyTorch 实现的 GRU 模型,展示了其在文本分类中的应用。


http://www.mrgr.cn/news/36678.html

相关文章:

  • 万能分销商城源码系统 源码开源可二开 带完整的安装代码包以及搭建部署教程
  • web前端(本地存储问题超过5MB不继续保存解决办法)
  • Spring异常处理-@ExceptionHandler-@ControllerAdvice-全局异常处理
  • AI应用开发中智能体编排应用是什么?
  • AI绘画美女指令大全,5个技巧让你的画作惊艳四座,美得令人窒息
  • Javascript编译原理
  • 浅谈C++之指针
  • 力扣(LeetCode)每日一题 2535. 数组元素和与数字和的绝对差
  • svn add代码时,忽略node_modules
  • 江科大笔记——新建工程
  • 代码随想录算法训练营第55天 | 寻找存在的路径
  • 大数据毕业设计选题推荐-租房数据分析系统-Hive-Hadoop-Spark
  • 浅谈C++之线程管理
  • 神经网络(五):U2Net图像分割网络
  • CSP-J 2024 入门级 第一轮(初赛) 阅读程序(1)
  • 【高阶数据结构】平衡二叉树(AVL)的插入(4种旋转方法+精美图解+完整代码)
  • PHP实现的纵横四海程序
  • 神经网络(四):UNet图像分割网络
  • 你了解文档透明加密系统吗?介绍7款顶尖文档透明加密软件,热门推荐!
  • Linux系统sersync数据实时同步