1. 程式人生 > >【TensorFlow】LSTM(使用TFLearn預測正弦sin函式)

【TensorFlow】LSTM(使用TFLearn預測正弦sin函式)

專案已上傳至 GitHub —— sin_pre

資料生成

因為標準的迴圈神經網路模型預測的是離散的數值,所以需要將連續的 sin 函式曲線離散化

所謂離散化就是在一個給定的區間 [0,MAX] 內,通過有限個取樣點模擬一個連續的曲線,即間隔相同距離取點

取樣用的是 numpy.linspace() 函式,它可以建立一個等差序列,常用的引數有三個

  • start:起始值
  • stop:終止值,不包含在內
  • num:數列長度,預設為 50

然後使用一個 generate_data() 函式生成輸入和輸出,序列的第 i 項和後面的 TIMESTEPS-1 項合在一起作為輸入,第 i + TIMESTEPS 項作為輸出

TFLearn使用

TFlearn 對訓練模型進行了一些封裝,使 TensorFlow 更便於使用,如下示範了 TFLearn 的使用方法

from tensorflow.contrib.learn.python.learn.estimators.estimator import SKCompat

learn = tf.contrib.learn

# 建立深層迴圈網路模型
regressor = SKCompat(learn.Estimator(model_fn=lstm_model, model_dir='model/'))

# 呼叫fit函式訓練模型
regressor.fit(train_x, train_y, batch_size=BATCH_SIZE, steps=TRAINGING_STEPS)

# 使用訓練好的模型對測試集進行預測
predicted = [[pred] for pred in regressor.predict(test_x)]

完整程式碼

整個程式碼的結構如下

  • lstm_model() 類用於建立 LSTM 網路並返回一些結果
  • LstmCell() 函式用於建立單層 LSTM 結構,防止 LSTM 引數名稱一樣
  • generate_data() 函式用於建立資料集

由於原書中的程式碼是基於 1.0,而我用的是 1.5,所以出現了很多錯誤,我將所遇到的錯誤的解決方法都記錄在了文末

import numpy as np
import tensorflow as tf
import matplotlib as
mpl from matplotlib import pyplot as plt from tensorflow.contrib.learn.python.learn.estimators.estimator import SKCompat # TensorFlow的高層封裝TFLearn learn = tf.contrib.learn # 神經網路引數 HIDDEN_SIZE = 30 # LSTM隱藏節點個數 NUM_LAYERS = 2 # LSTM層數 TIMESTEPS = 10 # 迴圈神經網路截斷長度 BATCH_SIZE = 32 # batch大小 # 資料引數 TRAINING_STEPS = 3000 # 訓練輪數 TRAINING_EXAMPLES = 10000 # 訓練資料個數 TESTING_EXAMPLES = 1000 # 測試資料個數 SAMPLE_GAP = 0.01 # 取樣間隔 def generate_data(seq): # 序列的第i項和後面的TIMESTEPS-1項合在一起作為輸入,第i+TIMESTEPS項作為輸出 X = [] y = [] for i in range(len(seq) - TIMESTEPS - 1): X.append([seq[i:i + TIMESTEPS]]) y.append([seq[i + TIMESTEPS]]) return np.array(X, dtype=np.float32), np.array(y, dtype=np.float32) # LSTM結構單元 def LstmCell(): lstm_cell = tf.contrib.rnn.BasicLSTMCell(HIDDEN_SIZE) return lstm_cell def lstm_model(X, y): # 使用多層LSTM,不能用lstm_cell*NUM_LAYERS的方法,會導致LSTM的tensor名字都一樣 cell = tf.contrib.rnn.MultiRNNCell([LstmCell() for _ in range(NUM_LAYERS)]) # 將多層LSTM結構連線成RNN網路並計算前向傳播結果 output, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32) output = tf.reshape(output, [-1, HIDDEN_SIZE]) # 通過無啟用函式的全聯接層計算線性迴歸,並將資料壓縮成一維陣列的結構 predictions = tf.contrib.layers.fully_connected(output, 1, None) # 將predictions和labels調整為統一的shape y = tf.reshape(y, [-1]) predictions = tf.reshape(predictions, [-1]) # 計算損失值 loss = tf.losses.mean_squared_error(predictions, y) # 建立模型優化器並得到優化步驟 train_op = tf.contrib.layers.optimize_loss( loss, tf.train.get_global_step(), optimizer='Adagrad', learning_rate=0.1) return predictions, loss, train_op # 用sin生成訓練和測試資料集 test_start = TRAINING_EXAMPLES * SAMPLE_GAP test_end = (TRAINING_EXAMPLES + TESTING_EXAMPLES) * SAMPLE_GAP train_X, train_y = generate_data( np.sin(np.linspace(0, test_start, TRAINING_EXAMPLES, dtype=np.float32))) test_X, test_y = generate_data( np.sin( np.linspace(test_start, test_end, TESTING_EXAMPLES, dtype=np.float32))) # 建立深層迴圈網路模型 regressor = SKCompat(learn.Estimator(model_fn=lstm_model, model_dir='model/')) # 呼叫fit函式訓練模型 regressor.fit(train_X, train_y, batch_size=BATCH_SIZE, steps=TRAINING_STEPS) # 使用訓練好的模型對測試集進行預測 predicted = [[pred] for pred in regressor.predict(test_X)] # 計算rmse作為評價指標 rmse = np.sqrt(((predicted - test_y)**2).mean(axis=0)) print('Mean Square Error is: %f' % (rmse[0])) # 對預測曲線繪圖,並存儲到sin.jpg fig = plt.figure() plot_predicted, = plt.plot(predicted, label='predicted') plot_test, = plt.plot(test_y, label='real_sin') plt.legend([plot_predicted, plot_test], ['predicted', 'real_sin']) plt.show()

執行結果如下

$ python train.py

Mean Square Error is: 0.001638

sin

可以看到曲線重合得非常好,所以用 LSTM 預測具有時間序列的資料非常合適

錯誤總結

1. 沒有 unpack

出現如下錯誤

AttributeError: module 'tensorflow' has no attribute 'unpack'

原因是 tf.unpack 改為了 tf.unstack

# 原始碼
x_ = tf.unpack(x, axis=1)

# 修改為
x_ = tf.unstack(x, axis=1)

2. 沒有 rnn_cell

出現如下錯誤

AttributeError: module 'tensorflow.python.ops.nn' has no attribute 'rnn_cell'

原因是 tf.nn.rnn_cell 改為了 tf.contrib.rnn

# 原始碼
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE)
    cell = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * NUM_LAYERS)

# 修改為
lstm_cell = tf.contrib.rnn.BasicLSTMCell(HIDDEN_SIZE)
    cell = tf.contrib.rnn.MultiRNNCell([lstm_cell] * NUM_LAYERS)

3. rnn 不可呼叫

出現如下錯誤

TypeError: 'module' object is not callable

原因是 tf.nn.rnn 現在改為了幾個方法

tf.contrib.rnn.static_rnn
tf.contrib.rnn.static_state_saving_rnn
tf.contrib.rnn.static_bidirectional_rnn
tf.contrib.rnn.stack_bidirectional_dynamic_rnn

而我們需要的是 tf.nn.dynamic_rnn() 方法

# 原始碼
output, _ = tf.nn.rnn(cell, X, dtype=tf.float32)

# 修改為
output, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)

4. 不能呼叫 Estimator.fit

出現如下警告

WARNING:tensorflow:From train.py:71: calling BaseEstimator.fit (from tensorflow.contrib.learn.python.learn.estimators.estimator) with y is deprecated and will be removed after 2016-12-01.

該警告下面給出瞭解決方法

Instructions for updating:
Estimator is decoupled from Scikit Learn interface by moving into
separate class SKCompat. Arguments x, y and batch_size are only
available in the SKCompat class, Estimator will only accept input_fn.
Example conversion:
  est = Estimator(...) -> est = SKCompat(Estimator(...))

按照給出的方法修改程式碼

# 原始碼
regressor = learn.Estimator(model_fn=lstm_model)

# 修改為
from tensorflow.contrib.learn.python.learn.estimators.estimator import SKCompat

regressor = SKCompat(learn.Estimator(model_fn=lstm_model))

5. 臨時資料夾

出現如下警告

WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp01x9hws6

原因是現在的 Estimator 需要提供 model_dir

# 原始碼
regressor = SKCompat(learn.Estimator(model_fn=lstm_model))

# 修改為
regressor = SKCompat(
    learn.Estimator(model_fn=lstm_model, model_dir='model/'))

6. 尺寸必須一致

出現如下錯誤

ValueError: Dimensions must be equal, but are 60 and 40 
for 'rnn/rnn/multi_rnn_cell/cell_0/basic_lstm_cell/MatMul_1' 
(op: 'MatMul') with input shapes: [?,60], [40,120].

原因我不太清楚,可能是因為 TensorFlow 的調整導致生成的資料在形狀上與老版本不一致,也可能是因為使用 lstm_cell*NUM_LAYERS 的方法建立深層迴圈網路模型導致每層 LSTM 的 tensor 名稱都一樣

只能在網上搜了其他的類似的部落格後照著修改了程式碼,下面給出了修改的關鍵地方,詳細的部分在完整程式碼中

# LSTM結構單元
def LstmCell():
    lstm_cell = tf.contrib.rnn.BasicLSTMCell(HIDDEN_SIZE)
    return lstm_cell

def lstm_model(X, y):
    # 使用多層LSTM,不能用lstm_cell*NUM_LAYERS的方法,會導致LSTM的tensor名字都一樣
    cell = tf.contrib.rnn.MultiRNNCell([LstmCell() for _ in range(NUM_LAYERS)])
    # 將多層LSTM結構連線成RNN網路並計算前向傳播結果
    output, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)
    ......

7. Legend 不支援

出現如下錯誤

UserWarning: Legend does not support [<matplotlib.lines.Line2D object at 0x7feb52d58c18>] instances.
A proxy artist may be used instead.

原因是因為需要在呼叫 plt.plot 時引數解包

# 原始碼
plot_predicted = plt.plot(predicted, label='predicted')
plot_test = plt.plot(test_y, label='real_sin')

# 修改為(加逗號)
plot_predicted, = plt.plot(predicted, label='predicted')
plot_test, = plt.plot(test_y, label='real_sin')

8. 使用 plt.show() 不顯示圖片

在程式碼中使用 plt.show() 執行之後沒有圖片顯示,原因是原始碼中使用了 mpl.use(‘Agg’),而 Agg 是不會畫圖的,所以直接把這一行刪掉

9. get_global_step 不建議使用

出現如下警告

WARNING:tensorflow:From train.py:60: get_global_step 
(from tensorflow.contrib.framework.python.ops.variables) 
is deprecated and will be removed in a future version.

警告下面給出瞭解決方法

Instructions for updating:
Please switch to tf.train.get_global_step

按照解決方法修改程式碼

# 原始碼
train_op = tf.contrib.layers.optimize_loss(
        loss,
        tf.contrib.framework.get_global_step(),
        optimizer='Adagrad',
        learning_rate=0.1)

# 修改為
train_op = tf.contrib.layers.optimize_loss(
        loss,
        tf.train.get_global_step(),
        optimizer='Adagrad',
        learning_rate=0.1)

相關推薦

TensorFlowLSTM使用TFLearn預測正弦sin函式

專案已上傳至 GitHub —— sin_pre 資料生成 因為標準的迴圈神經網路模型預測的是離散的數值,所以需要將連續的 sin 函式曲線離散化 所謂離散化就是在一個給定的區間 [0,MAX] 內,通過有限個取樣點模擬一個連續的曲線,即間

tensorflow 學習筆記13 RNN LSTM結構預測正弦(sin)函式

import tensorflow as tf import numpy as np import matplotlib.pyplot as plt BATCH_START = 0 TIME_STEPS = 20 BATCH_SIZE = 50 INPUT_SIZE =

BZOJ1443遊戲二分圖匹配,博弈論

() ans evel getchar mes 最大匹配 開始 就會 明顯 【BZOJ1443】遊戲(二分圖匹配,博弈論) 題面 BZOJ 題解 很明顯的二分圖博弈問題。 發現每次移動一定是從一個黑點到達一個白點,或者反過來。 所以可以對於棋盤進行染色然後連邊。 考慮一下必

BZOJ3712Fiolki並查集重構樹

bzoj3 long std 不同 合並 ++i 卡爾 優先級 href 【BZOJ3712】Fiolki(並查集重構樹) 題面 BZOJ 題解 很神仙的題目。 我們發現所有的合並關系構成了一棵樹。 那麽兩種不同的東西如果產生反應,一定在兩個聯通塊恰好聯通的時候反應。 那麽

BZOJ4455小星星動態規劃,容斥

之間 lld algorithm std 還需要 tchar 一次 lin 還需 【BZOJ4455】小星星(動態規劃,容斥) 題面 BZOJ 洛谷 Uoj 題解 題意說簡單點就是給定一張\(n\)個點的圖和一棵\(n\)個點的樹,現在要讓圖和樹之間的點一一對應,並且如果樹

HDU2604Queuing矩陣快速冪+遞推

題目連結 Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(

POJ3169Layout差分約束系統+SPFA

題目連結 Layout Time Limit: 1000MS Memory Limit: 65536K Total Submissions:14919 Accepted: 7183 Description Like everyone

ZCMU1435盟國並查集刪除節點

題目連結 1435: 盟國 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 456  Solved: 104 [Submit][Status][Web Board] Description 世界上存在著N個國家,簡單起見

HDU4859 海岸線網路流-最小割

Problem Description 歡迎來到珠海!由於土地資源越來越緊張,使得許多海濱城市都只能依靠填海來擴充套件市區以求發展。作為Z市的決策人,在仔細觀察了Z市地圖之後,你準備通過填充某些海域來擴充套件Z市的海岸線到最長,來吸引更多的遊客前來旅遊度假。為了簡化問題,假設地圖為一個N*M的格子,

#290. ZJOI2017仙人掌數數+仙人掌+樹形dp

傳送門 模擬賽的時候打了個表發現為一條鏈的時候答案是\(2^{n-2}\)竟然順便過了第一個點 然後之後訂正的時候強聯通分量打錯了調了一個上午 首先不難發現我們可以去掉所有在環上的邊,那麼就變成了一個森林,不同的樹之間不可能有連邊,那麼只要所有樹的答案乘起來就好了,只要在每一棵樹內部樹形\(dp\)即可

BZOJ2330SDOI2012糖果差分約束,SPFA

【BZOJ2330】【SDOI2012】糖果 題面 題目描述 幼兒園裡有N個小朋友,lxhgww老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在

HDU4652Dice數學期望,動態規劃

題面 Vjudge 有一個m面骰子 詢問,連續出現n個相同的時候停止的期望 連續出現n個不同的時候停止的期望 題解 考慮兩種分開詢問來算。 第一種: 設f[i]表示已經有連續的i個相

OpenGLSOIL簡易的opengl影象庫

一、簡介 SOIL是簡易OpenGL影象庫(Simple OpenGL Image Library)的縮寫,它支援大多數流行的影象格式,並且使用簡單。可從官網下載其原始碼:http://www.lonesock.net/soil.html 二、配置 從他們的主頁可以

Unity3D Mathy常用數學運算,C#

在unity遊戲開發中,我們常常需要用到一些數學運算,比如攝像機的移動,人物移動,怪物ai的巡邏,技能特效的角度等等,下面是整理出一些常用(也可以說是比較簡單的)的數學運算公式。 Mathf.Lerp 插值 Math

Java集合List、Set、Map遍歷、刪除、比較元素時的小陷阱

主要說明List,其餘兩個都一樣 一、漏網之魚-for迴圈遞增下標方式遍歷集合,並刪除元素 如果你用for迴圈遞增下標方式遍歷集合,在遍歷過程中刪除元素,你可能會遺漏了某些元素。說那麼說可能也說不清楚,看以下示例: import ja

Csizeof空結構體/空類的大小

sizeof(空類/空結構體) = 1; #include <iostream> using namespace std; // 空類 class ClassA { }; // 繼承空類的空類 class ClassB

tensorflowTensorFlow入門多層 LSTM 通俗易懂版

前言: 根據我本人學習 TensorFlow 實現 LSTM 的經歷,發現網上雖然也有不少教程,其中很多都是根據官方給出的例子,用多層 LSTM 來實現 PTBModel 語言模型,比如: tensorflow筆記:多層LSTM程式碼分析  但是感覺這些例子還是太複雜了

TensorFlow01線性回歸

lob 超參數 教育版 ini src ont numpy mat font 特別說明 代碼地址:Github 環境說明 平臺:WIN10(教育版) 環境:Anaconda5.2(Python3.6.6) IDE:Pacharm2018.2.3(專業版) Tensor

TensorFlowWin10+TensorFlow-gpu1.9.0+CUDA9.0+cudnn7.1.42018/11/02

折騰了一天多,終於配置成功了orz 本篇文章是2018年11月2日寫的,Win10,顯示卡為960M 下載版本為:(請注意相容性) Anaconda3    5.3.0 TensorFlow-gpu   1.9.0 CUDA9.0 cu

tensorflow模型優化指數衰減學習率

指數衰減學習率是先使用較大的學習率來快速得到一個較優的解,然後隨著迭代的繼續,逐步減小學習率,使得模型在訓練後期更加穩定。在訓練神經網路時,需要設定學習率(learning rate)控制引數的更新速度,學習速率設定過小,會極大降低收斂速度,增加訓練時間;學習率太大,可能導致引數在最優解兩側來回振盪