RNN循环神经网络中的权重更新算法 |
您所在的位置:网站首页 › 神经网络参数更新公式 › RNN循环神经网络中的权重更新算法 |
参考: 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为各传递权重,则权重的更新算法为:
二、我们所用于分析权重梯度变化的无非用到里面的一个具体环节,现在把它形式化展现:
此处的表示t-1时刻的隐含层输出作为t时刻隐含层的输入,表示t时刻的输入。,代表前一时刻和本时刻输入的融合。设激活函数,则有;设输出层函数为,则输出是输出标签。 若我们以表示第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 |