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

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

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



参考地址: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_size
        self.num_layers = num_layers
        self.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)
        
        # 通过 GRU
        out, _ = 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 模型,展示了其在文本分类中的应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

985小水博一枚呀

祝各位老板前程似锦!财源滚滚!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值