RNN循环神经网络中的权重更新算法

您所在的位置:网站首页 神经网络参数更新公式 RNN循环神经网络中的权重更新算法

RNN循环神经网络中的权重更新算法

#RNN循环神经网络中的权重更新算法| 来源: 网络整理| 查看: 265

参考:

http://ir.hit.edu.cn/~jguo/docs/notes/bptt.pdf

http://www.cnblogs.com/wacc/p/5341670.html

https://zybuluo.com/hanbingtao/note/541458

http://www.wildml.com/2015/10/recurrent-neural-networks-tutorial-part-3-backpropagation-through-time-and-vanishing-gradients/

一段时间学习了ML的基础算法,但是对与DL没怎么接触,这次算首次触电吧。写的不足之处,请大家指正。

一、下图是对RNN的整体解析,大家应该比较熟悉了:

                                  

若我们以E表示交叉熵误差,V、W、U为各传递权重,则权重的更新算法为:

                                            V=V-lr \cdot \frac{\partial E}{\partial V}, W=W-lr \cdot \frac{\partial E}{\partial W},U=U-lr \cdot \frac{\partial E}{\partial U}

二、我们所用于分析权重梯度变化的无非用到里面的一个具体环节,现在把它形式化展现:

                                                  

此处的S_{t-1}表示t-1时刻的隐含层输出作为t时刻隐含层的输入,X_{t}表示t时刻的输入。net_t=S_{t-1} \cdot W+X_t \cdot U,代表前一时刻和本时刻输入的融合。设激活函数act=f(x),则有S_t=f(net_t);设输出层函数为g(x),则输出\hat{y_t} = g(VS_t)是输出标签。

若我们以E_t表示第t时刻的损失函数,并将其定义为交叉熵误差E_t=-y_{t}^Tlog(\hat{y_t})。那么整个序列的误差,就是所有时刻误差的总和。

三、下面,我们来展现权值更新的计算细节:

self.calc_delta(sensitivity_array, activator) self.calc_gradient() def calc_delta(self, sensitivity_array, activator): self.delta_list = [] # 用来保存各个时刻的误差项 for i in range(self.times): self.delta_list.append(np.zeros( (self.state_width, 1))) #对每一时刻的误差项进行初始化 self.delta_list.append(sensitivity_array) #将sensitivity_array作为最后的误差项;就是t时刻的误差项delta for k in range(self.times - 1, 0, -1): self.calc_delta_k(k, activator) # 迭代计算每个k时刻的误差项 def calc_delta_k(self, k, activator): ''' 根据k+1时刻的delta计算k时刻的delta ''' state = self.state_list[k+1].copy() element_wise_op(self.state_list[k+1], activator.backward) #对于k+1时刻的s状态,每个隐层中的s执行反向backward()操作,实际上得到上一时刻k对应的s状态state_list[k]; self.delta_list[k] = np.dot( np.dot(self.delta_list[k+1].T, self.W), np.diag(state[:,0])).T # .T代表矩阵的转置

计算每个时刻t权重的梯度 ''' gradient = np.dot(self.delta_list[t], self.state_list[t-1].T) self.gradient_list[t] = gradient def calc_gradient(self): self.gradient_list = [] # 保存各个时刻的权重梯度 for t in range(self.times + 1): self.gradient_list.append(np.zeros( (self.state_width, self.state_width))) for t in range(self.times, 0, -1): self.calc_gradient_t(t) # 实际的梯度是各个时刻梯度之和 self.gradient = reduce( lambda a, b: a + b, self.gradient_list, self.gradient_list[0]) # [0]被初始化为0且没有被修改过

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3