Tensorflow與RNN、雙向LSTM等的踩坑記錄及解決
1、tensorflow(不定長)文本序列讀取與解析
tensorflow讀取csv時需要指定各列的數據類型。
但是對於RNN這種接受序列輸入的模型來說,一條序列的長度是不固定。這時如果使用csv存儲序列數據,應當首先將特征序列拼接成一列。
例如兩條數據序列,第一項是標簽,之後是特征序列
[0, 1.1, 1.2, 2.3] 轉換成 [0, ‘1.1_1.2_2.3’]
[1, 1.0, 2.5, 1.6, 3.2, 4.5] 轉換成 [1, ‘1.0_2.5_1.6_3.2_4.5’]
這樣每條數據都隻包含固定兩列瞭。
讀取方式是指定第二列為字符串類型,再將字符串按照’_’分割並轉換為數字。
關鍵的幾行代碼示例如下:
def readMyFileFormat(fileNameQueue): reader = tf.TextLineReader() key, value = reader.read(fileNameQueue) record_defaults = [["Null"], [-1], ["Null"], ["Null"], [-1]] phone1, seqlen, ts_diff_strseq, t_cod_strseq, userlabel = tf.decode_csv(value, record_defaults=record_defaults) ts_diff_str = tf.string_split([ts_diff_strseq], delimiter='_') t_cod_str = tf.string_split([t_cod_strseq], delimiter='_') # 每個字符串轉數字 Str2Float = lambda string: tf.string_to_number(string, tf.float32) Str2Int = lambda string: tf.string_to_number(string, tf.int32) ts_diff_seq = tf.map_fn(Str2Float, ts_diff_str.values, dtype = tf.float32) # 一定要加上dtype,且必須與fn的輸出類型一致 t_cod_seq = tf.map_fn(Str2Int, t_cod_str.values, dtype = tf.int32)
2、時序建模的序列預測、序列擬合、標簽預測,及輸入數據格式
序列預測、擬合的“標簽”都是序列本身,區別是未來時刻或者是當前時刻,當前時刻的擬合任務類似於antoencoder的reconstruction
標簽預測常見於語言學建模,有單詞級標簽的分詞與整句標簽的情感分析,前者需要對每一個單詞輸入都要輸出其分詞標識,後者是取最後若幹輸出級聯前饋神經網絡分類器
keras的輸入-輸出對:需要將序列拆分成多個片段
序列形式:
按時間列表:static_bidirectional_rnn
多維數組:bidirectional_dynamic_rnn與stack_bidirectional_dynamic_rnn 變長雙向rnn的正確使用姿勢
3、多任務設置及相應的輸出向量劃分
對於標簽預測任務,按需取輸出即可
對於序列預測、擬合:
雙向lstm:通常用於擬合。但如果需要捕捉動態信息,盡管需要序列完整輸入,則仍可以加上正向預測與反向預測
單向lstm:擬合與預測
4、zero padding
後一般需要通過tf.boolean_mask()隔離這些零的影響,函數輸入包括數據矩陣和補零位置的指示矩陣。
5、get_shape()方法
與 tf.shape() 類型區別,前者得到一個list,後者得到一個tensor
6、雙向LSTM的信息瓶頸的解決
如果在時間步的最後輸出,則可能會導致開始的一些字符被遺忘門給遺忘。
所以這裡就對每個時間步的輸出做出瞭處理,
主要處理有:
1、拼接:把所有的輸出拼接在一起。
2、Average
3、Pooling
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 變長雙向rnn的正確使用姿勢教學
- Tensorflow 2.4 搭建單層和多層 Bi-LSTM 模型
- pytorch lstm gru rnn 得到每個state輸出的操作
- python如何獲取tensor()數據類型中的值
- pytorch中使用LSTM詳解