国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

LSTNet--結(jié)合時(shí)間注意力機(jī)制的LSTM模型(附源碼)

這篇具有很好參考價(jià)值的文章主要介紹了LSTNet--結(jié)合時(shí)間注意力機(jī)制的LSTM模型(附源碼)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、引言

? ? ? ? LSTM出現(xiàn)以來,在捕獲時(shí)間序列依賴關(guān)系方面表現(xiàn)出了強(qiáng)大的潛力,直到Transformer的大殺四方。但是,就像我在上一篇博客《RNN與LSTM原理淺析》末尾提到的一樣,雖然Transformer在目標(biāo)檢測、目標(biāo)識別、時(shí)間序列預(yù)測等各領(lǐng)域都有著優(yōu)于傳統(tǒng)模型的表現(xiàn),甚至是壓倒性的優(yōu)勢。但Transformer所依賴的Multi-Head Attention機(jī)制給模型帶來了巨大的參數(shù)量與計(jì)算開銷,這使得模型難以滿足實(shí)時(shí)性要求高的任務(wù)需求。我也提到,LSTM想與Transformer抗衡,似乎應(yīng)該從注意力機(jī)制方面下手。事實(shí)上,已經(jīng)有研究這么做了,那就是LSTNet。

二、LSTNet

? ? ? ? 2018年,論文《Modeling Long- and Short-Term Temporal Patterns with Deep Neural Networks》正式提出了LSTNet。LSTNet的出現(xiàn)可以認(rèn)為是研究人員通過注意力機(jī)制提升LSTM模型時(shí)序預(yù)測能力的一次嘗試,文中共提出了LST-Skip與LST-Atten兩種模型。其中,LST-Skip需要手動設(shè)置序列的周期,比較適用于交通流預(yù)測等周期明確可知的時(shí)間序列,而LST-Atten模型則可以自動捕捉模型的周期。實(shí)驗(yàn)表明,上述兩種模型在周期序列預(yù)測中表現(xiàn)出了良好的性能。

? ? ? ? 然而,上述模型的性能受制于序列的周期與可用歷史狀態(tài)的長度。首先,模型的注意力機(jī)制為“時(shí)間注意力機(jī)制”,其本質(zhì)是利用了序列內(nèi)部的時(shí)間性周期,因此對于沒有明顯周期性的序列(如:車輛軌跡序列)則不能很好地發(fā)揮優(yōu)勢。其次,LST-Atten依賴于歷史狀態(tài)挖掘序列的周期,若可用的歷史狀態(tài)較短,無法反映一個(gè)完整的周期,則模型可自主挖掘周期性的優(yōu)勢仍無法體現(xiàn)。

三、方法? ? ? ??

? ? ? ? 本文以實(shí)現(xiàn)LST-Atten為例(在進(jìn)入FC層前的張量處理與原文稍有不同),描述LSTM中的時(shí)間注意力機(jī)制。由于在CSDN的編輯器中不方便使用各種專業(yè)符號,因此下文中使用的符號一切從簡,不以專業(yè)性為目的。

? ? ? ? 我們假設(shè)使用過去的A幀數(shù)據(jù)預(yù)測未來的B幀,且LSTM編碼器中A個(gè)LSTM單元的隱狀態(tài)為H,LSTM解碼器中第一個(gè)LSTM單元的隱狀態(tài)為h1。那么集成了時(shí)間注意力機(jī)制的LSTM編碼-解碼器工作原理可用如下表示:

LSTNet--結(jié)合時(shí)間注意力機(jī)制的LSTM模型(附源碼)

? ? ? ? ?其中,F(xiàn)為打分函數(shù),用于計(jì)算H與h1之間的余弦相關(guān)度。然后,通過softmax函數(shù),這些余弦相關(guān)度被轉(zhuǎn)換為各歷史隱狀態(tài)的相對權(quán)重。H中各時(shí)刻隱藏狀態(tài)的加權(quán)和與解碼器第一幀輸出的隱藏狀態(tài)h1相結(jié)合,最終通過全連接層得到第一幀的預(yù)測輸出。 其工作原理如圖1所示。

LSTNet--結(jié)合時(shí)間注意力機(jī)制的LSTM模型(附源碼)

四、結(jié)果?

? ? ? ? 該模型在公共交通流數(shù)據(jù)集 PeMS04 上進(jìn)行了測試。 我們選擇了測試點(diǎn)1測得的交通流數(shù)據(jù),其中70%的數(shù)據(jù)用于模型訓(xùn)練,30%的數(shù)據(jù)用于模型測試。使用 Adam 作為優(yōu)化器,MSE 作為模型測量指標(biāo),學(xué)習(xí)率為 0.0001,訓(xùn)練 800 輪。 訓(xùn)練損失如圖2所示,測試結(jié)果如表1所示。

LSTNet--結(jié)合時(shí)間注意力機(jī)制的LSTM模型(附源碼)

?

LSTNet--結(jié)合時(shí)間注意力機(jī)制的LSTM模型(附源碼)

?最后,我在測試集中選取了 4000 個(gè)樣本點(diǎn)進(jìn)行可視化,結(jié)果如圖 3 所示。

LSTNet--結(jié)合時(shí)間注意力機(jī)制的LSTM模型(附源碼)文章來源地址http://www.zghlxwxcb.cn/news/detail-502794.html

?五、源代碼

"模型訓(xùn)練"
import numpy as np
import torch
import torch.nn as nn
import os
import matplotlib.pyplot as plt
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
file=np.load('PeMS04.npz')
data=torch.from_numpy(file['data'])
device = torch.device('cuda:0')


'定義子函數(shù)與類模型'

def creat_dataset(data,look_back,pre_len):
    data_x = []
    data_y = []
    for i in range(len(data)-look_back-pre_len+1):  # 對選好的該輛車的數(shù)據(jù)劃分輸入(過去8點(diǎn))與輸出(未來12點(diǎn))
        data_x.append(data[i:i + look_back, :])
        data_y.append(data[i+look_back:i+look_back+pre_len, :])
    return np.asarray(data_x), np.asarray(data_y)  # 轉(zhuǎn)為ndarray數(shù)據(jù)

class LSTM_Atten(nn.Module):
    """搭建Decoder結(jié)構(gòu)"""
    def __init__(self,look_back,pre_len):
        super(LSTM_Atten, self).__init__()
        self.lstm = nn.LSTM(input_size=1, #1個(gè)輸入特征
                            hidden_size=128, #隱狀態(tài)h擴(kuò)展為為128維
                            num_layers=1, #1層LSTM
                            batch_first=True, # 輸入結(jié)構(gòu)為(batch_size, seq_len, feature_size). Default: False
                            )
        self.lstmcell=nn.LSTMCell(input_size=128, hidden_size=128)
        self.drop=nn.Dropout(0.2) #掉落率
        self.fc1=nn.Linear(256,128)
        self.fc2=nn.Linear(128,1)
        self.look_back=look_back
        self.pre_len=pre_len
        self.Softmax=nn.Softmax(dim=1)
    def forward(self, x):
        H,(h,c) = self.lstm(x.float(),None) #編碼
        h=h.squeeze(0)
        c=c.squeeze(0)
        H_pre=torch.empty((h.shape[0],self.pre_len,128*2)).to(device)
        for i in range(self.pre_len): #解碼
            h_t, c_t = self.lstmcell(h, (h, c))  # 預(yù)測
            H=torch.cat((H,h_t.unsqueeze(1)),1)
            h_atten=self.Atten(H) #獲取結(jié)合了注意力的隱狀態(tài)
            H_pre[:,i,:]=h_atten  #記錄解碼器每一步的隱狀態(tài)
            h, c = h_t, c_t  # 將當(dāng)前的隱狀態(tài)與細(xì)胞狀態(tài)記錄用于下一個(gè)時(shí)間步

        return self.fc2(self.fc1(H_pre)).squeeze(2)

    def Atten(self,H):
        h=H[:,-1,:].unsqueeze(1) #[batch_size,1,128]
        H=H[:,-1-self.look_back:-1,:] #[batch_size,look_back,128]
        atten=torch.matmul(h,H.transpose(1,2)).transpose(1,2) #注意力矩陣
        atten=self.Softmax(atten)
        atten_H=atten*H #帶有注意力的歷史隱狀態(tài)
        atten_H=torch.sum(atten_H,dim=1).unsqueeze(1) #按時(shí)間維度降維
        return torch.cat((atten_H,h),2).squeeze(1)







'數(shù)據(jù)預(yù)處理'
#data格式:[數(shù)據(jù)條數(shù);記錄點(diǎn)id;3個(gè)特征(0號特征是交通流)]
look_back=20
pre_len=30
data=data[0:11890,0,0].unsqueeze(1).numpy() #第0個(gè)記錄點(diǎn)記錄的前11890條交通流數(shù)據(jù)作為訓(xùn)練集[11890,1]
data=(data-data.min())/(data.max()-data.min()) #數(shù)據(jù)歸一化
X,Y=creat_dataset(data,look_back,pre_len) #[11871,5,1],[11871,1] 使用前5點(diǎn)預(yù)測后一點(diǎn)
X=torch.from_numpy(X).to(device)
Y=torch.from_numpy(Y).to(device)


'訓(xùn)練模型'
model=LSTM_Atten(look_back,pre_len).to(device)
loss_fun=nn.MSELoss()
optimizer=torch.optim.Adam(model.parameters(),0.0001)
epoch=800
batch_size=3947
cost=[]
for i in range(epoch):
    for t in range(int(11871/batch_size)):
        input=X[t*batch_size:(t+1)*batch_size,:,:] #按batch_size獲取輸入與標(biāo)簽
        label=Y[t*batch_size:(t+1)*batch_size,:].squeeze(2)

        output=model(input.float()) #預(yù)測值
        loss=loss_fun(label.float(),output.float()) #計(jì)算MSE損失
        optimizer.zero_grad() #梯度清零
        loss.backward() #反向傳播
        optimizer.step() #參數(shù)更新
    print(((i + 1) / epoch) * 100)
    cost.append(loss.item()) #記錄損失

torch.save(model.state_dict(),'lstm-atten.pth')

plt.figure()
plt.plot(cost)
plt.show()
"模型測試"
import numpy as np
import torch
import torch.nn as nn
import os
import matplotlib.pyplot as plt
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
file=np.load('PeMS04.npz')
data=torch.from_numpy(file['data'])


'定義子函數(shù)與類模型'
def creat_dataset(data,look_back,pre_len):
    data_x = []
    data_y = []
    for i in range(len(data)-look_back-pre_len+1):  # 對選好的該輛車的數(shù)據(jù)劃分輸入(過去8點(diǎn))與輸出(未來12點(diǎn))
        data_x.append(data[i:i + look_back, :])
        data_y.append(data[i+look_back:i+look_back+pre_len, :])
    return np.asarray(data_x), np.asarray(data_y)  # 轉(zhuǎn)為ndarray數(shù)據(jù)

class LSTM_Atten(nn.Module):
    """搭建Decoder結(jié)構(gòu)"""
    def __init__(self,look_back,pre_len):
        super(LSTM_Atten, self).__init__()
        self.lstm = nn.LSTM(input_size=1, #1個(gè)輸入特征
                            hidden_size=128, #隱狀態(tài)h擴(kuò)展為為128維
                            num_layers=1, #1層LSTM
                            batch_first=True, # 輸入結(jié)構(gòu)為(batch_size, seq_len, feature_size). Default: False
                            )
        self.lstmcell=nn.LSTMCell(input_size=128, hidden_size=128)
        self.drop=nn.Dropout(0.2) #掉落率
        self.fc1=nn.Linear(256,128)
        self.fc2=nn.Linear(128,1)
        self.look_back=look_back
        self.pre_len=pre_len
        self.Softmax=nn.Softmax(dim=1)
    def forward(self, x):
        H,(h,c) = self.lstm(x.float(),None) #編碼
        h=h.squeeze(0)
        c=c.squeeze(0)
        H_pre=torch.empty((h.shape[0],self.pre_len,128*2))
        for i in range(self.pre_len): #解碼
            h_t, c_t = self.lstmcell(h, (h, c))  # 預(yù)測
            H=torch.cat((H,h_t.unsqueeze(1)),1)
            h_atten=self.Atten(H) #獲取結(jié)合了注意力的隱狀態(tài)
            H_pre[:,i,:]=h_atten  #記錄解碼器每一步的隱狀態(tài)
            h, c = h_t, c_t  # 將當(dāng)前的隱狀態(tài)與細(xì)胞狀態(tài)記錄用于下一個(gè)時(shí)間步

        return self.fc2(self.fc1(H_pre)).squeeze(2)

    def Atten(self,H):
        h=H[:,-1,:].unsqueeze(1) #[batch_size,1,128]
        H=H[:,-1-self.look_back:-1,:] #[batch_size,look_back,128]
        atten=torch.matmul(h,H.transpose(1,2)).transpose(1,2) #注意力矩陣
        atten=self.Softmax(atten)
        atten_H=atten*H #帶有注意力的歷史隱狀態(tài)
        atten_H=torch.sum(atten_H,dim=1).unsqueeze(1) #按時(shí)間維度降維
        return torch.cat((atten_H,h),2).squeeze(1)




'數(shù)據(jù)預(yù)處理'
#data格式:[數(shù)據(jù)條數(shù);記錄點(diǎn)id;3個(gè)特征(0號特征是交通流)]
look_back=20
pre_len=30
data=data[11890:,0,0].unsqueeze(1).numpy() #第0個(gè)記錄點(diǎn)記錄的11890后的5102條交通流數(shù)據(jù)作為訓(xùn)練集[5102,1]
data=(data-data.min())/(data.max()-data.min()) #數(shù)據(jù)歸一化
X,Y=creat_dataset(data,look_back,pre_len) #[5083,10,1],[5083,10,1] 使用前5點(diǎn)預(yù)測后一點(diǎn)
X=torch.from_numpy(X)
Y=torch.from_numpy(Y).squeeze(2)


'測試模型'
model=LSTM_Atten(look_back,pre_len)
loss_fun=nn.MSELoss()
model.load_state_dict(torch.load('lstm-atten.pth'))
output=model(X.float()).squeeze(1)
loss=loss_fun(output.float(),Y.float())
print(loss)



plt.figure()
plt.plot(output[0:4000,0].detach(),'r')
plt.plot(Y[0:4000,0],'b')
plt.show()

到了這里,關(guān)于LSTNet--結(jié)合時(shí)間注意力機(jī)制的LSTM模型(附源碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包