復(fù)現(xiàn)論文 A Dual-Stage Attention-Based Recurrent Neural Network for Time Series Prediction 用于時間序列預(yù)測

星期二, 03. 十二月 2019 09:34下午

注:論文實現(xiàn)代碼和論文都在我的git賬號下惜犀,歡迎交流討論

論文題目:

論文基本框架

1.png

1校套、主要內(nèi)容

該論文主要通過在編碼層和解碼層都引入雙向注意力機制實現(xiàn)時間序列更好的預(yù)測

2碌识、輸入數(shù)據(jù)

輸入數(shù)據(jù)地址來自于:https://cseweb.ucsd.edu/~yaq007/NASDAQ100_stock_data.html
數(shù)據(jù)名稱為 nasdaq100/small/nasdaq100_padding.csv
直接下載該csv文件麸俘,會得到一個82列的df狰住,最后一列是標(biāo)簽厢蒜,訓(xùn)練集和驗證集通過如下代碼生成:

def get_data(data_path,T, n):
    input_X = []
    input_Y = []
    label_Y = []

    df = pd.read_csv(data_path)
    row_length = len(df)
    column_length = df.columns.size
    for i in range(row_length-T+1):
        X_data = df.iloc[i:i+T, 0:column_length-1]
        Y_data = df.iloc[i:i+T-1,column_length-1]
        label_data = df.iloc[i+T-1,column_length-1]
        input_X.append(np.array(X_data))
        input_Y.append(np.array(Y_data))
        label_Y.append(np.array(label_data))
    input_X = np.array(input_X).reshape(-1,T,n)
    input_Y = np.array(input_Y).reshape(-1,T-1,1)
    label_Y = np.array(label_Y).reshape(-1,1)
    return input_X,input_Y,label_Y

其中理疙,T為窗口長度晕城,n為傳感器數(shù)目,即81(82-1)窖贤,算法通過第k個窗口中前T個傳感器數(shù)據(jù)值和T-1個標(biāo)簽值砖顷,預(yù)測第T個標(biāo)簽值。

模型框架

模型一共分為兩層赃梧,即編碼階段Attention和解碼階段Attention滤蝠,兩者實現(xiàn)的思路是一致的,這里只說論文核心的兩部分

Attention程序?qū)崿F(xiàn)

    @staticmethod
    def _attention_layer(_h_t_1 = None,     # [-1, cell_dim]
                         _s_t_1 = None,     # [-1, cell_dim]
                         _x_k   = None,     # input attention layer   : [-1, input_dim, time_step]
                                            # temporal attention layer: [-1, time_step, input_dim];
                         _We    = None,     # [2*cell_dim, time_step]
                         _Ue    = None,     # [time_step, time_step]
                         _Ve    = None, ):  # [time_step, 1]
        _input = tf.concat([_h_t_1, _s_t_1], axis=1)  # [-1, 2*cell_dim]
        _output = tf.reshape(tf.transpose(tf.tensordot(_We, _input, axes=[0, 1])), [-1, _We.get_shape().as_list()[-1], 1]) + \
                  tf.transpose(tf.tensordot(_Ue, _x_k, axes=[0, 2]), perm=[1, 0, 2])   # [-1, time_step, input_dim]
        return tf.reshape(tf.tensordot(_Ve, tf.tanh(_output), axes=[0, 1]), \
                          [-1, _x_k.get_shape().as_list()[1]])    # input attention layer   : [-1, input_dim]
                                                                  # temporal attention layer: [-1, time_step]

Attention的實現(xiàn)是很簡單的授嘀,這里不詳細敘說物咳。

論文中主要解決的問題

  • 第一個問題:LSTM中如何實現(xiàn)Attention?
  • 第二個問題:如何將歷史標(biāo)簽用于解碼階段?

關(guān)于第一個問題,論文中用了如下公式:
論文中的公式(8):
e_t^k=V_e^Ttanh(W_e[h_{t-1};s_{t-1}]+U_ex^k)
論文中的公式(9):
\alpha_t^k=\frac{exp(e_t^k)}{\sum_{i=1}^nexp(e_t^i)}
式中蹄皱,x^k為第k個傳感器窗口為T的樣本览闰;h_{t-1}s_{t-1}分別為編碼器LSTM在t-1時刻的隱層狀態(tài)和細胞狀態(tài)芯肤,V_e, W_e, U_e為需要學(xué)習(xí)的參數(shù)。

關(guān)于第二個問題压鉴,論文中用了如下公式:
論文中的公式(15):
\breve{y}_{t-1}=\breve{w}^T[y_{t-1};c_{t-1}]+\breve纷妆
式中,y_{t-1}t-1時刻的歷史標(biāo)簽晴弃,c_{t-1}為解碼器LSTM在t-1時刻的細胞狀態(tài),得到的\breve{y}_{t-1}為解碼器LSTM在t-1時刻的輸入逊拍。

論文中的編碼階段實現(xiàn):

    def _Encode(self, encode_input=None):  # encode_input: [-1, time_step, input_dim]
        x_k = tf.transpose(encode_input, perm=[0, 2, 1], name='Series_of_length_TIME_STEP')#[-1,input_dim,time_step]
        encode_time_step_hidden = []
        for t in range(encode_input.get_shape()[1]):  # [t < time_step]
            e_t = self._attention_layer(_h_t_1 = self.encode_hidden,
                                        _s_t_1 = self.encode_cell,
                                        _x_k   = x_k,
                                        _We    = self._weights['Input_attention_layer_We'],
                                        _Ue    = self._weights['Input_attention_layer_Ue'],
                                        _Ve    = self._weights['Input_attention_layer_Ve'], )
            a_t = tf.nn.softmax(e_t)  # [-1, input_dim]
            tmp = tf.reshape(encode_input[:, t, :], shape=[-1, encode_input.get_shape().as_list()[-1]])
            x_t = tf.multiply(a_t, tmp)
            (self.encode_cell, self.encode_hidden) = self._LSTMCell(h_t_1 = self.encode_hidden,
                                                                    s_t_1 = self.encode_cell,
                                                                    x_t   = x_t,
                                                                    name  = 'Encode_LSTMCell')
            encode_time_step_hidden.append(self.encode_hidden)
        return tf.reshape(tf.stack(encode_time_step_hidden), [-1, self.TIME_STEP, self.DECODE_CELL])

注:程序用了for循環(huán)上鞠,因為每一個LSTM單元都用了Attention

論文中的解碼階段實現(xiàn):

    def _Decode(self, decode_input=None, y_t=None):
        for t in range(decode_input.get_shape()[1]-1):
            l_t = self._attention_layer(_h_t_1 = self.decode_hidden,
                                        _s_t_1 = self.decode_cell,
                                        _x_k   = decode_input,
                                        _We    = self._weights['Temporal_attention_layer_Wd'],
                                        _Ue    = self._weights['Temporal_attention_layer_Ud'],
                                        _Ve    = self._weights['Temporal_attention_layer_Vd'], )
            b_t = tf.reshape(tf.nn.softmax(l_t), shape=[-1, decode_input.get_shape().as_list()[1], 1])  # [-1, time_step, 1]
            c_t = tf.reduce_sum(tf.multiply(b_t, decode_input), axis=1)  # [-1, time_step, 1]*[-1, time_step, cell_dim]
                                                                         # ---> [-1, time_step, cell_dim]-->[-1, cell_dim]
            y_t_ = self._Dense(_input       = tf.concat([c_t, tf.reshape(y_t[:, t], [-1, 1])], axis=1),
                               _weights     = self._weights['Decode_layer_yt_weights'],
                               _bias        = self._weights['Decode_layer_yt_bias'],
                               _activation  = None,
                               _dtype       = tf.float32,
                               _is_bias     = True, )
            (self.decode_cell, self.decode_hidden) = self._LSTMCell(h_t_1 = self.decode_hidden,
                                                                    s_t_1 = self.decode_cell,
                                                                    x_t   = y_t_,
                                                                    name  = 'Decode_LSTMCell')
        pre_y_ = self._Dense(_input       = tf.concat([self.decode_hidden, self.decode_cell], axis=1),
                             _weights     = self._weights['Decode_layer_output_1_weights'],
                             _bias        = self._weights['Decode_layer_output_1_bias'],
                             _activation  = None,
                             _dtype       = tf.float32,
                             _is_bias     = True, )
        pre_y = self._Dense(_input       = pre_y_,
                            _weights     = self._weights['Decode_layer_output_2_weights'],
                            _bias        = self._weights['Decode_layer_output_2_bias'],
                            _activation  = None,
                            _dtype       = tf.float32,
                            _is_bias     = True, )
        return pre_y

注:編碼和解碼的程序是相似的,但是加入了歷史標(biāo)簽
簡而言之芯丧,論文就是在編碼階段對每一個LSTM單元引入了Attention芍阎,解碼階段也是這樣

程序?qū)崿F(xiàn)

程序的具體實現(xiàn)都在我的git賬戶上,對比其他git上的實現(xiàn)缨恒,親測我的實現(xiàn)mse是更好的谴咸,關(guān)于具體的程序請看git或者留言與我討論,關(guān)于程序中可能出現(xiàn)的問題歡迎打擾骗露。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岭佳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子萧锉,更是在濱河造成了極大的恐慌珊随,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柿隙,死亡現(xiàn)場離奇詭異叶洞,居然都是意外死亡,警方通過查閱死者的電腦和手機禀崖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門衩辟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人波附,你說我怎么就攤上這事艺晴。” “怎么了掸屡?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵财饥,是天一觀的道長。 經(jīng)常有香客問我折晦,道長钥星,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任满着,我火速辦了婚禮谦炒,結(jié)果婚禮上贯莺,老公的妹妹穿的比我還像新娘。我一直安慰自己宁改,他們只是感情好缕探,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著还蹲,像睡著了一般爹耗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谜喊,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天涯塔,我揣著相機與錄音汉匙,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛腹泌,可吹牛的內(nèi)容都是我干的拳芙。 我是一名探鬼主播薛夜,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼袱蚓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逾一?” 一聲冷哼從身側(cè)響起铸本,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遵堵,沒想到半個月后归敬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡鄙早,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年汪茧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片限番。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡舱污,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弥虐,到底是詐尸還是另有隱情扩灯,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布霜瘪,位于F島的核電站珠插,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颖对。R本人自食惡果不足惜捻撑,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顾患,春花似錦番捂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至犁河,卻和暖如春鳖枕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桨螺。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工宾符, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人彭谁。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像允扇,于是被迫代替她去往敵國和親缠局。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容