BPTT算法推导
随时间反向传播 (BackPropagation Through Time,BPTT)
符号注解:
- :词汇表的大小
- :句子的长度
- :隐藏层单元数
- :第t个时刻(第t个word)的损失函数,定义为交叉熵误差
- :一个句子的损失函数,由各个时刻(即每个word)的损失函数组成,。
注: 由于我们要推倒的是SGD算法, 更新梯度是相对于一个训练样例而言的, 因此我们一次只考虑一个句子的误差,而不是整个训练集的误差(对应BGD算法) - :第t个时刻RNN的输入,为one-hot vector,1表示一个单词的出现,0表示不出现
- :第t个时刻RNN隐藏层的输入
- :第t个时刻RNN隐藏层的输出
- :输出层的汇集输入
- :输出层的输出,激活函数为softmax
- :第t个时刻的监督信息,为一个one-hot vector
- :残差向量
- :从输入层到隐藏层的权值
- :隐藏层上一个时刻到当前时刻的权值
- :隐藏层到输出层的权值
他们之间的关系:
其中,是sigmoid函数。由于是one-hot向量,假设第个词出现,则相当于把的第列选出来,因此这一步是不用进行任何矩阵运算的,直接做下标操作即可,在matlab里就是。
BPTT与BP类似,是在时间上反传的梯度下降算法。RNN中,我们的目的是求得,根据这三个变化率来优化三个参数
注意到,因此我们只要对每个时刻的损失函数求偏导数再加起来即可。
1.计算
注:推导中用到了之前推导用到的结论。其中表示残差向量第i个分量,表示的第j个分量。
上述结果可以改写为:
其中表示向量外积。
2.计算
由于U是各个时刻共享的,所以t之前每个时刻U的变化都对有贡献,反过来求偏导时,也要考虑之前每个时刻U对E的影响。我们以为中间变量,应用链式法则:
但由于(分子向量,分母矩阵)以目前的数学发展水平是没办法求的,因此我们要求这个偏导,可以拆解为对的偏导数:
其中,,遵循
的传递关系,应用链式法则有:
其中,表示向量点乘。于是,我们得到了关于 的递推关系式。由出发,我们可以往前推出每一个,现在计算:
\begin{equation}\delta_t=\frac{\partial E_t}{\partial s_t}=\frac{\partial h_t}{\partial s_t}\frac{\partial z_t}{\partial h_t}\frac{\partial E_t}{\partial z_t}=diag(1-h_t\odot h_t)\cdot VT\cdot(\hat{y}_t-y_t)=(VT(\hat{y}t-y_t))\odot (1-h_t\odot h_t)\end{equation}
将代入$ \frac{\partial E_t}{\partial U{ij}} $有:
将上式写成矩阵形式:
不失严谨性,定义为全0的向量。
3.计算
按照上述思路,我们可以得到
由于是个one-hot vector,假设其第个位置为1,那么我们在更新时只需要更新的第列即可,计算的伪代码如下:
delta_t = V.T.dot(residual[T]) * (1-h[T]**2)
for t from T to 0
dEdW[ :,x[t] ] += delta_t
#delta_t = W.T.dot(delta_t) * (1 - h[t-1]**2)
delta_t = U.T.dot(delta_t) * (1 - h[t-1]**2)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术