循环神经网络的反向传播
流程概述
循环神经网络(Recurrent Neural Network, RNN)是一种能够处理序列数据的神经网络模型。在训练过程中,我们需要通过反向传播算法来更新模型的参数,以实现模型的优化。本文将介绍循环神经网络的反向传播过程,并提供相应的代码示例。
反向传播步骤
下表展示了循环神经网络反向传播的步骤及每一步需要做的事情。
步骤 | 代码示例 | 说明 |
---|---|---|
步骤1:初始化 | dWxh, dWhh, dWhy = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why) |
初始化权重的梯度为零,用于累积梯度的更新 |
步骤2:反向传播 | dh_next = np.zeros_like(h[0]) |
初始化下一个时间步反向传播的梯度 |
for t in reversed(range(len(inputs))): |
从最后一个时间步开始,逐个时间步进行反向传播 | |
dy = np.copy(outputs[t]) |
计算当前时间步输出的误差(预测值和真实值之间的差异) | |
dy[targets[t]] -= 1 |
根据交叉熵损失函数计算输出层的梯度 | |
dWhy += np.dot(dy, hs[t].T) |
根据输出层的梯度更新输出层到隐藏层的权重梯度 | |
dh = np.dot(Why.T, dy) + dh_next |
计算当前时间步隐藏层的梯度(输出层梯度和下一时间步隐藏层梯度的总和) | |
dh_raw = (1 - hs[t] * hs[t]) * dh |
根据隐藏层的激活函数求导数,计算当前时间步隐藏层神经元的原始梯度 | |
dbh += dh_raw |
累积当前时间步隐藏层偏置的梯度 | |
dWxh += np.dot(dh_raw, xs[t].T) |
根据隐藏层的梯度更新隐藏层到输入层的权重梯度 | |
dWhh += np.dot(dh_raw, hs[t-1].T) |
根据隐藏层的梯度更新隐藏层到隐藏层的权重梯度 | |
dh_next = np.dot(Whh.T, dh_raw) |
更新下一个时间步反向传播的梯度 |
代码解释
下面是每一步所使用的代码及其解释:
# 步骤1:初始化
dWxh, dWhh, dWhy = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why)
# 初始化权重的梯度为零,用于累积梯度的更新
# 步骤2:反向传播
dh_next = np.zeros_like(h[0])
# 初始化下一个时间步反向传播的梯度
for t in reversed(range(len(inputs))):
# 从最后一个时间步开始,逐个时间步进行反向传播
dy = np.copy(outputs[t])
# 计算当前时间步输出的误差(预测值和真实值之间的差异)
dy[targets[t]] -= 1
# 根据交叉熵损失函数计算输出层的梯度
dWhy += np.dot(dy, hs[t].T)
# 根据输出层的梯度更新输出层到隐藏层的权重梯度
dh = np.dot(Why.T, dy) + dh_next
# 计算当前时间步隐藏层的梯度(输出层梯度和下一时间步隐藏层梯度的总和)
dh_raw = (1 - hs[t] * hs[t]) * dh