我正在查看下面的代码:
class LstmParam:
def __init__(self, mem_cell_ct, x_dim):
self.mem_cell_ct = mem_cell_ct
self.x_dim = x_dim
concat_len = x_dim + mem_cell_ct
# weight matrices
self.wg = rand_arr(-0.1, 0.1, mem_cell_ct, concat_len)
self.wi = rand_arr(-0.1, 0.1, mem_cell_ct, concat_len)
self.wf = rand_arr(-0.1, 0.1, mem_cell_ct, concat_len)
self.wo = rand_arr(-0.1, 0.1, mem_cell_ct, concat_len)
# bias terms
self.bg = rand_arr(-0.1, 0.1, mem_cell_ct)
self.bi = rand_arr(-0.1, 0.1, mem_cell_ct)
self.bf = rand_arr(-0.1, 0.1, mem_cell_ct)
self.bo = rand_arr(-0.1, 0.1, mem_cell_ct)
# diffs (derivative of loss function w.r.t. all parameters)
self.wg_diff = np.zeros((mem_cell_ct, concat_len))
self.wi_diff = np.zeros((mem_cell_ct, concat_len))
self.wf_diff = np.zeros((mem_cell_ct, concat_len))
self.wo_diff = np.zeros((mem_cell_ct, concat_len))
self.bg_diff = np.zeros(mem_cell_ct)
self.bi_diff = np.zeros(mem_cell_ct)
self.bf_diff = np.zeros(mem_cell_ct)
self.bo_diff = np.zeros(mem_cell_ct)
def apply_diff(self, lr = 1):
self.wg -= lr * self.wg_diff
self.wi -= lr * self.wi_diff
self.wf -= lr * self.wf_diff
self.wo -= lr * self.wo_diff
self.bg -= lr * self.bg_diff
self.bi -= lr * self.bi_diff
self.bf -= lr * self.bf_diff
self.bo -= lr * self.bo_diff
# reset diffs to zero
self.wg_diff = np.zeros_like(self.wg)
self.wi_diff = np.zeros_like(self.wi)
self.wf_diff = np.zeros_like(self.wf)
self.wo_diff = np.zeros_like(self.wo)
self.bg_diff = np.zeros_like(self.bg)
self.bi_diff = np.zeros_like(self.bi)
self.bf_diff = np.zeros_like(self.bf)
self.bo_diff = np.zeros_like(self.bo)
我不明白为什么这么早就对 self.wg_diff = np.zeros((mem_cell_ct, concat_len)) 应用导数。我不确定这里发生了什么事。我也很困惑为什么它们设置为零。如果有人能解释为什么会这样。
最佳答案
一行例如
self.wg_diff = np.zeros((mem_cell_ct, concat_len))
不是应用导数,它只是初始化一个数组,该数组稍后将保存损失函数相对于wg
数组中的值的导数。
在apply_diff
中,在这里应用渐变:
self.wg -= lr * self.wg_diff
至关重要:在调用 __init__
函数创建 LstmParam
实例和调用 apply_diff
之间应用渐变,不同的代码(您没有显示)必须修改 self.wg_diff ,以便它实际上包含导数。
为了计算梯度,
- 前向传递需要使用一些数据作为输入并计算输出,其中计算涉及
wg
中的值。 - 然后使用损失函数将输出与所需的正确输出进行比较。
- 计算损失后,后向传递计算梯度(损失函数相对于计算输出所涉及的所有权重的导数)。向后传递用实际值填充
self.wg_diff
。
为了完整起见,下一行
self.wg_diff = np.zeros_like(self.wg)
正在重置下一次向后传递的梯度数组。
关于python - 为什么 LSTM 的导数设置为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59947408/