用实验证明深度学习中梯度消失的存在与LSTM的有效性

一直都听说传统RNN有个致命的缺陷,即梯度消失,导致其无法有效处理长序列

今天我们来用实验证明其存在,并且测试LSTM的有效性.


实验思路很简单,设置数据如下.

随机生成X 

X=[Ran0,Ran1,Ran2,Ran3,Ran4,Ran5,Ran6,Ran7,Ran8,Ran9]

Y=[Ran9] ,Y与X最后的数相同


实验猜想

如果梯度消失不存在,那使用传统RNN拟合Y时,无论X是正序还是逆序,拟合精度都应该一样


实验过程与结果分析

1.X使用正序

   Ran9在序列的最后输入,在反向传播训练时其权重首先被训练,预测精度良好,

   为什么达不到100%呢? 训练时间不够长,神经网络在0~8的权重还"舍不得"置为0.

   

2.X使用逆序

    Ran9在序列的最先输入,在反向传播训练时其权重最后被训练,预测精度完全没有!!!

    神经网络完全"忘了"最开始的输入才是最重要的.



3.使用LSTM

X使用正序

X使用逆序

可以看出,LSTM确实可以克服梯度消失的问题,不像SimpleRNN一样直接蒙了.

但同样需要更长的训练时间和更好的训练设置才可以取得理想精度.

有兴趣的同学试试加入批标准化层,或者Multi-LSTM试试.


    


完整代码,复制粘贴就能跑! 

欢迎留言指正!

#验证RNN的梯度消失
#LSTM确实有用

import numpy as np
import pandas as pd
import copy
import matplotlib.pyplot as plt

from sklearn.preprocessing import StandardScaler

from keras.models import Sequential,Model
from keras.layers import Dense,SimpleRNN,LSTM,Input


def create_RNN_data(data_in,timestep,label):#生成RNN形式的数据,label是因变量Y
    data_in=pd.DataFrame(data_in)
    data_=copy.deepcopy(data_in)
    
    for columns in data_.columns:
        if columns!=label:#不是因变量的label
            for i in range(1,timestep):
                data_[columns+'-'+str(i)]=data_[columns].shift(+i)
        
    data_.dropna(inplace=True)
    data_.index=np.arange(0,len(data_))
    return data_


time_step=10
data=pd.DataFrame({'X':np.random.randint(0,10,1000)}) #随机生成数据


data['Y']=data['X'].shift(time_step-1) 
#重要的一步,使得Y与前time_step步的X相同
#本文中,Y与[9]完全相同


data.dropna(inplace=True) #删除由于shift引入的空行
data.index=np.arange(0,len(data)) #重设index


rnn_data=create_RNN_data(data,time_step,'Y') #生成RNN形式的数据


#选择自变量
X_raw=rnn_data[['X','X-1','X-2','X-3','X-4','X-5','X-6','X-7','X-8','X-9']]
scaler = StandardScaler().fit(X_raw) #标准化能加速训练
X_raw1=scaler.transform(X_raw)


X_raw2=np.array(X_raw1)
X=np.reshape(X_raw2,(-1,time_step,1)) #reshape
Y=np.array(rnn_data['Y'])




#构建神经网络
input01=Input(shape=(time_step,1))
RNN01=LSTM(units=5,
                go_backwards=False)(input01) #返回的是一个数组,[output,state]
               #实验核心变量,go_backwards设置是否翻转输入的序列.
               #False,正序X,0,1,2,3,4,5,6,7,8,9
               #True,逆序X,9,8,7,6,5,4,3,2,1,0
               
               #[9]就是Y值,在使用True时,因此在反向传播训练时,[9]是最后一个,
               #梯度消失了无法得到有效训练
               
output01=Dense(1)(RNN01)


model=Model(inputs=input01,outputs=output01)
model.compile(optimizer='adam',loss='mse')


model.fit(X,
          Y,
          batch_size=20,
          validation_split=0.5,
          verbose=1,
          epochs=200,
          initial_epoch=0,
          shuffle=True)


pred=model.predict(X)


plt.scatter(Y,pred)
plt.xlabel('True')
plt.ylabel('Predict')

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值