【Datawhale AI 夏令营】基于术语词典干预的机器翻译挑战赛——GRU门控循环单元
什么是GRU?
GRU(Gated Recurrent Unit,门控循环单元)是循环神经网络(RNN)的一种变体,旨在解决RNN在处理长序列数据时遇到的梯度消失和梯度爆炸问题。GRU通过引入更新门(Update Gate)和重置门(Reset Gate)两个门控机制,有效地控制信息的流动和记忆。
GRU的基本构成
GRU包含两个主要的门:更新门和重置门。它们分别用于决定保留多少旧信息和忘记多少旧信息。
更新门(Update Gate)
更新门控制了多少过去的状态需要被保留下来,以及多少新的状态需要被添加。更新门的输出值在0到1之间,接近1表示更多地保留旧信息,接近0表示更多地引入新信息。
公式为:
zt=σ(Wz⋅[ht−1,xt])zt=σ(Wz⋅[ht−1,xt])zt=σ(Wz⋅[ht−1,xt]) z_t=σ(Wz⋅[ht−1,x_t])z_t = \sigma(W_z \cdot [h_{t-1}, x_t])zt=σ(Wz⋅[h_{t−1},x_t]) zt=σ(Wz⋅[ht−1,xt])zt=σ(Wz⋅[ht−1,xt])zt=σ(Wz⋅[ht−1,xt])
其中:
- zt是更新门的输出。 z_t是更新门的输出。 zt是更新门的输出。
- sigma是sigmoid激活函数。 sigma是sigmoid激活函数。 sigma是sigmoid激活函数。
- Wz是更新门的权重矩阵。 W_z 是更新门的权重矩阵。 Wz是更新门的权重矩阵。
- ht−1是前一个时间步的隐状态。 h_{t-1}是前一个时间步的隐状态。 ht−1是前一个时间步的隐状态。
- xt是当前时间步的输入。 x_t 是当前时间步的输入。 xt是当前时间步的输入。
重置门(Reset Gate)
重置门决定了在计算当前隐状态时,有多少以前的信息需要被忘记。重置门的输出值也在0到1之间,接近0表示需要忘记更多的旧信息,接近1表示保留更多的旧信息。
公式为:
rt=σ(Wr⋅[ht−1,xt]) r_t = \sigma(W_r \cdot [h_{t-1}, x_t]) rt=σ(Wr⋅[ht−1,xt])
其中:
- rt是重置门的输出。 r_t 是重置门的输出。 rt是重置门的输出。
- Wr是重置门的权重矩阵。 W_r 是重置门的权重矩阵。 Wr是重置门的权重矩阵。
候选隐状态(Candidate Hidden State)
候选隐状态结合了当前输入和上一个时间步的隐状态,并通过重置门来控制。候选隐状态的计算公式为:
h~t=tanh(W⋅[rt⊙ht−1,xt]) \tilde{h}_t = \tanh(W \cdot [r_t \odot h_{t-1}, x_t]) h~t=tanh(W⋅[rt⊙ht−1,xt])
其中:
- h~t是候选隐状态。 \tilde{h}_t 是候选隐状态。 h~t是候选隐状态。
- W是权重矩阵。 W 是权重矩阵。 W是权重矩阵。
- ⊙表示元素级别的乘法。 \odot 表示元素级别的乘法。 ⊙表示元素级别的乘法。
最终隐状态(Final Hidden State)
最终隐状态是由更新门来决定的,它结合了上一时间步的隐状态和当前时间步的候选隐状态。公式为:
ht=(1−zt)⊙ht−1+zt⊙h~t h_t = (1 - z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t ht=(1−zt)⊙ht−1+zt⊙h~t
GRU的工作流程
-
计算更新门和重置门:
zt=σ(Wz⋅[ht−1,xt]) z_t = \sigma(W_z \cdot [h_{t-1}, x_t]) zt=σ(Wz⋅[ht−1,xt])rt=σ(Wr⋅[ht−1,xt]) r_t = \sigma(W_r \cdot [h_{t-1}, x_t]) rt=σ(Wr⋅[ht−1,xt])
-
计算候选隐状态:
h~t=tanh(W⋅[rt⊙ht−1,xt]) \tilde{h}_t = \tanh(W \cdot [r_t \odot h_{t-1}, x_t]) h~t=tanh(W⋅[rt⊙ht−1,xt]) -
计算最终隐状态:
ht=(1−zt)⊙ht−1+zt⊙h~t h_t = (1 - z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t ht=(1−zt)⊙ht−1+zt⊙h~t
代码实现
下面是一个使用PyTorch实现GRU的代码示例:
import torch
import torch.nn as nn
class GRUCell(nn.Module):
def __init__(self, input_size, hidden_size):
super(GRUCell, self).__init__()
self.hidden_size = hidden_size
self.reset_gate = nn.Linear(input_size + hidden_size, hidden_size)
self.update_gate = nn.Linear(input_size + hidden_size, hidden_size)
self.candidate_layer = nn.Linear(input_size + hidden_size, hidden_size)
def forward(self, x, h_prev):
combined = torch.cat([x, h_prev], dim=1)
r_t = torch.sigmoid(self.reset_gate(combined))
z_t = torch.sigmoid(self.update_gate(combined))
combined_reset = torch.cat([x, r_t * h_prev], dim=1)
h_candidate = torch.tanh(self.candidate_layer(combined_reset))
h_t = (1 - z_t) * h_prev + z_t * h_candidate
return h_t
# 输入维度为10,隐状态维度为20
input_size = 10
hidden_size = 20
# 创建GRU单元
gru_cell = GRUCell(input_size, hidden_size)
# 输入数据(批量大小为3)
x = torch.randn(3, input_size)
h_prev = torch.zeros(3, hidden_size)
# 前向传播
h_t = gru_cell(x, h_prev)
print(h_t)
GRU是一种改进的RNN,通过引入更新门和重置门来控制信息的流动,使得它在处理长序列数据时更加高效。它保留了RNN的优点,同时缓解了梯度消失和梯度爆炸的问题。由于其结构相对简单,GRU在很多序列数据处理任务中表现优异,是一种常用的循环神经网络结构。
更多推荐


所有评论(0)