网站建设流程的步骤,牡丹江建设银行网站,智慧旅游类网站开发商,通用网站建设需求分析1 RNN的缺陷——长期依赖的问题 #xff08;The Problem of Long-Term Dependencies#xff09;
前面一节我们学习了RNN神经网络#xff0c;它可以用来处理序列型的数据#xff0c;比如一段文字#xff0c;视频等等。RNN网络的基本单元如下图所示#xff0c;可以将前面的…
1 RNN的缺陷——长期依赖的问题 The Problem of Long-Term Dependencies
前面一节我们学习了RNN神经网络它可以用来处理序列型的数据比如一段文字视频等等。RNN网络的基本单元如下图所示可以将前面的状态作为当前状态的输入。 但也有一些情况我们需要更“长期”的上下文信息。比如预测最后一个单词“我在中国长大……我说一口流利的**。”“短期”的信息显示下一个单词很可能是一种语言的名字但如果我们想缩小范围我们需要更长期语境——“我在中国长大”但这个相关信息与需要它的点之间的距离完全有可能变得非常大。
不幸的是随着这种距离的扩大RNN无法学会连接这些信息。
从理论上讲RNN绝对有能力处理这种“长期依赖性”。人们可以为他们精心选择参数以解决这种形式的问题。遗憾的是在实践中RNN似乎无法学习它们。
幸运的是GRU也没有这个问题
2、GRU
什么是GRU
GRUGate Recurrent Unit是循环神经网络Recurrent Neural Network, RNN的一种。和LSTMLong-Short Term Memory一样也是为了解决长期记忆和反向传播中的梯度等问题而提出来的。
GRU和LSTM在很多情况下实际表现上相差无几那么为什么我们要使用新人GRU2014年提出而不是相对经受了更多考验的LSTM1997提出呢。
用论文中的话说相比LSTM使用GRU能够达到相当的效果并且相比之下更容易进行训练能够很大程度上提高训练效率因此很多时候会更倾向于使用GRU。
2.1总体结构框架
前面我们讲到神经网络的各种结构都是为了挖掘变换数据特征的所以下面我们也将结合数据特征的维度来对比介绍一下RNNLSTM的网络结构。 多层感知机线性连接层结构 从特征角度考虑
输入特征是n*1的单维向量这也是为什么卷积神经网络在linear层前要把所有特征层展平
隐藏层然后根据隐藏层神经元的数量m将前层输入的特征用m*1的单维向量进行表示对特征进行了提取变换隐藏层的数据特征单个隐藏层的神经元数量就代表网络参数可以设置多个隐藏层
输出特征最终根据输出层的神经元数量y输出y*1的单维向量。
卷积神经网络结构 从特征角度考虑
输入特征是(batch)*channel*width*height的张量
卷积层等然后根据输入通道channel的数量c_in和输出通道channel的数量c_out会有c_out*c_in*k*k个卷积核将前层输入的特征进行卷积对特征进行了提取变换k为卷积核尺寸卷积核的大小和数量c_out*c_in*k*k就代表网络参数可以设置多个卷积层每一个channel都代表提取某方面的一种特征该特征用width*height的二维张量表示不同特征层之间是相互独立的可以进行融合。
输出特征根据场景的需要设置后面的输出可以是多分类的单维向量等等。
循环神经网络RNN系列结构 从特征角度考虑
输入特征是(batch)*T_seq*feature_size的张量T_seq代表序列长度注意不是batch_size.
我们来详细对比一下卷积神经网络的输入特征
(batch)*T_seq*feature_size
(batch)*channel*width*height
逐个进行分析RNN系列的基础输入特征表示是feature_size*1的单维向量比如一个单词的词向量比如一个股票价格的影响因素向量而CNN系列的基础输入特征是width*height的二维张量
再来看一下序列T_seq和通道channelRNN系列的序列T_seq是指一个连续的输入比如一句话一周的股票信息而且这个序列是有时间先后顺序且互相关联的而CNN系列的通道channel则是指不同角度的特征比如彩色图像的RGB三色通道过程中每个通道代表提取了每个方面的特征不同通道之间是没有强相关性的不过也可以进行融合。
最后就是batch两者都有在RNN系列batch就是有多个句子在CNN系列就是有多张图片每个图片可以有多个通道
隐藏层明确了输入特征之后我们再来看看隐藏层代表着什么。隐藏层有T_seq个隐状态H_t和输入序列长度相同每个隐状态H_t类似于一个channel对应着T_seq中的t时刻的输入特征而每个隐状态H_t是用hidden_size*1的单维向量表示的所以一个隐含层是T_seq*hidden_size的张量对应时刻t的输入特征由feature_size*1变为hidden_size*1的向量。如图中所示同一个隐含层不同时刻的参数W_ih和W_hh是共享的隐藏层可以有num_layers个图中只有1个
以t时刻具体阐述一下
X_t是t时刻的输入是一个feature_size*1的向量
W_ih是输入层到隐藏层的权重矩阵
H_t是t时刻的隐藏层的值,是一个hidden_size*1的向量
W_hh是上一时刻的隐藏层的值传入到下一时刻的隐藏层时的权重矩阵
Ot是t时刻RNN网络的输出
从上右图中可以看出这个RNN网络在t时刻接受了输入Xt之后隐藏层的值是St输出的值是Ot。但是从结构图中我们可以发现St并不单单只是由Xt决定还与t-1时刻的隐藏层的值St-1有关。 2.2 GRU的输入输出结构
GRU的输入输出结构与普通的RNN是一样的。有一个当前的输入xt和上一个节点传递下来的隐状态hidden stateht-1 这个隐状态包含了之前节点的相关信息。结合xt和 ht-1GRU会得到当前隐藏节点的输出yt 和传递给下一个节点的隐状态 ht。 图 GRU的输入输出结构
那么GRU到底有什么特别之处呢下面来对它的内部结构进行分析
2.3 GRU的内部结构
不同于LSTM有3个门控GRU仅有2个门控
第一个是“重置门”reset gate其根据当前时刻的输入xt和上一时刻的隐状态ht-1变换后经sigmoid函数输出介于0和1之间的数字用于将上一时刻隐状态ht-1重置为ht-1’即ht-1’ht-1*r。 再将ht-1’与输入xt进行拼接再通过一个tanh激活函数来将数据放缩到-1~1的范围内。即得到如下图2-3所示的h’。 第一个是“更新门”update gate其根据当前时刻的输入xt和上一时刻的隐状态ht-1变换后经sigmoid函数输出介于0和1之间的数字 最终的隐状态ht的更新表达式即为 再次强调一下门控信号这里的z的范围为0~1。门控信号越接近1代表”记忆“下来的数据越多而越接近0则代表”遗忘“的越多。
2.4 小结
GRU很聪明的一点就在于使用了同一个门控z就同时可以进行遗忘和选择记忆LSTM则要使用多个门控。与LSTM相比GRU内部少了一个”门控“参数比LSTM少但是却也能够达到与LSTM相当的功能。考虑到硬件的计算能力和时间成本因而很多时候我们也就会选择更加”实用“的GRU。 3代码
import torch
import torch.nn as nndef my_gru(input,initial_states,w_ih,w_hh,b_ih,b_hh):h_previnitial_statesbatch_size,T_seq,feature_sizeinput.shapehidden_sizew_ih.shape[0]//3batch_w_ihw_ih.unsqueeze(0).tile(batch_size,1,1)batch_w_hhw_hh.unsqueeze(0).tile(batch_size,1,1)outputtorch.zeros(batch_size,T_seq,hidden_size)for t in range(T_seq):xinput[:,t,:]w_times_xtorch.bmm(batch_w_ih,x.unsqueeze(-1))w_times_xw_times_x.squeeze(-1)# print(batch_w_hh.shape,h_prev.shape)# 计算两个tensor的矩阵乘法torch.bmm(a,b),tensor a 的size为(b,h,w),tensor b的size为(b,w,m)# 也就是说两个tensor的第一维是相等的然后第一个数组的第三维和第二个数组的第二维度要求一样# 对于剩下的则不做要求输出维度 b,h,m# batch_w_hhbatch_size*(3*hidden_size)*hidden_size# h_prevbatch_size*hidden_size*1# w_times_xbatch_size*hidden_size*1##squeeze在给定维度维度值必须为1上压缩维度负数代表从后开始数w_times_h_prevtorch.bmm(batch_w_hh,h_prev.unsqueeze(-1))w_times_h_prevw_times_h_prev.squeeze(-1)r_ttorch.sigmoid(w_times_x[:,:hidden_size]w_times_h_prev[:,:hidden_size]b_ih[:hidden_size]b_hh[:hidden_size])z_ttorch.sigmoid(w_times_x[:,hidden_size:2*hidden_size]w_times_h_prev[:,hidden_size:2*hidden_size]b_ih[hidden_size:2*hidden_size]b_hh[hidden_size:2*hidden_size])n_ttorch.tanh(w_times_x[:,2*hidden_size:3*hidden_size]w_times_h_prev[:,2*hidden_size:3*hidden_size]b_ih[2*hidden_size:3*hidden_size]b_hh[2*hidden_size:3*hidden_size])h_prev(1-z_t)*n_tz_t*h_prevoutput[:,t,:]h_prevreturn output,h_previf __name____main__:fcnn.Linear(12,6)batch_size2T_seq5feature_size4hidden_size3# output_feature_size3inputtorch.randn(batch_size,T_seq,feature_size)h_prevtorch.randn(batch_size,hidden_size)gru_layernn.GRU(feature_size,hidden_size,batch_firstTrue)output,h_finalgru_layer(input,h_prev.unsqueeze(0))# for k,v in gru_layer.named_parameters():# print(k,v.shape)# print(output,h_final)my_output, my_h_finalmy_gru(input,h_prev,gru_layer.weight_ih_l0,gru_layer.weight_hh_l0,gru_layer.bias_ih_l0,gru_layer.bias_hh_l0)# print(my_output, my_h_final)# print(torch.allclose(output,my_output)) 参考资料
https://zhuanlan.zhihu.com/p/32481747
https://speech.ee.ntu.edu.tw/~tlkagk/courses/MLDS_2018/Lecture/Seq%20(v2).pdf
https://www.bilibili.com/video/BV1jm4y1Q7uh/?spm_id_from333.788vd_sourcecf7630d31a6ad93edecfb6c5d361c659