星期二, 03. 十二月 2019 09:34下午
注:論文實現(xiàn)代碼和論文都在我的git賬號下惜犀,歡迎交流討論
論文題目:
論文基本框架
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
其中理疙,為窗口長度晕城,
為傳感器數(shù)目,即81(82-1)窖贤,算法通過第
個窗口中前
個傳感器數(shù)據(jù)值和
個標(biāo)簽值砖顷,預(yù)測第
個標(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):
論文中的公式(9):
式中蹄皱,為第
個傳感器窗口為T的樣本览闰;
和
分別為編碼器LSTM在
時刻的隱層狀態(tài)和細胞狀態(tài)芯肤,
為需要學(xué)習(xí)的參數(shù)。
關(guān)于第二個問題压鉴,論文中用了如下公式:
論文中的公式(15):
式中,為
時刻的歷史標(biāo)簽晴弃,
為解碼器LSTM在
時刻的細胞狀態(tài),得到的
為解碼器LSTM在
時刻的輸入逊拍。
論文中的編碼階段實現(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)的問題歡迎打擾骗露。