這是一套香港科技大學釋出的極簡 TensorFlow 入門教程,三天全套幻燈片教程已被分享到 Google Drive。機器之心將簡要介紹該教程並藉此梳理 TensorFlow 的入門概念與實現。
該教程第一天先介紹了深度學習和機器學習的潛力與基本概念,而後便開始探討深度學習框架 TensorFlow。首先我們將學到如何安裝 TensorFlow,其實我們感覺 TensorFlow 環境配置還是相當便捷的,基本上按照官網的教程就能完成安裝。隨後就從「Hello TensorFlow」開始依次講解計算圖、佔位符、張量等基本概念。
當然我們真正地理解 TensorFlow 還需要從實戰出發一點點學習那些最基本的概念,因此第一天重點講解了線性迴歸、Logistic 迴歸、Softmax 分類和神經網路。每一個模型都從最基本的概念出發先推導執行過程,然後再結合 TensorFlow 講解張量、計算圖等真正的意義。神經網路這一部分講解得十分詳細,我們將從最基本的感知機原理開始進而使用多層感知機解決異或問題(XOR),重點是該課程詳細推導了前向傳播與反向傳播的數學過程並配以 TensorFlow 實現。
教程第二天詳細地討論了卷積神經網路,它從 TensorFlow 的訓練與構建技巧開始,解釋了應用於神經網路的各種權重初始化方法、啟用函式、損失函式、正則化和各種最佳化方法等。在教程隨後論述 CNN 原理的部分,我們可以看到大多是根據史丹佛 CS231n 課程來解釋的。第二天最後一部分就是使用 TensorFlow 實現前面的理論,該教程使用單獨的程式碼塊解釋了 CNN 各個部分的概念,比如說 2 維卷積層和最大池化層等。
教程第三天詳解了迴圈神經網路,其從時序資料開始先講解了 RNN 的基本概念與原理,包括編碼器-解碼器模式、注意力機制和門控迴圈單元等非常先進與高效的機制。該教程後一部分使用了大量的實現程式碼來解釋前面我們所瞭解的迴圈神經網路基本概念,包括 TensorFlow 中單個迴圈單元的構建、批次輸入與迴圈層的構建、RNN 序列損失函式的構建、訓練計算圖等。
下面機器之心將根據該教程資料簡要介紹 TensorFlow 基本概念和 TensorFlow 機器學習入門實現。更詳細的內容請檢視香港科技大學三日 TensorFlow 速成課程資料
三日速成課程 Google Drive 資料地址:https://drive.google.com/drive/folders/0B41Zbb4c8HVyY1F5Ml94Z2hodkE
三日速成課程百度雲盤資料地址:http://pan.baidu.com/s/1boGGzeR
TensorFlow 基礎
本小節將從張量與圖、常數與變數還有佔位符等基本概念出發簡要介紹 TensorFlow。需要進一步瞭解 TensorFlow 的讀者可以閱讀谷歌 TensorFlow 的文件,當然也可以閱讀其他中文教程或書籍,例如《TensorFlow:實戰 Google 深度學習框架》和《TensorFlow 實戰》等。
TensorFlow 文件地址:https://www.tensorflow.org/get_started/
1. 圖
TensorFlow 是一種採用資料流圖(data flow graphs),用於數值計算的開源軟體庫。其中 Tensor 代表傳遞的資料為張量(多維陣列),Flow 代表使用計算圖進行運算。資料流圖用「結點」(nodes)和「邊」(edges)組成的有向圖來描述數學運算。「結點」一般用來表示施加的數學操作,但也可以表示資料輸入的起點和輸出的終點,或者是讀取/寫入持久變數(persistent variable)的終點。邊表示結點之間的輸入/輸出關係。這些資料邊可以傳送維度可動態調整的多維資料陣列,即張量(tensor)。
在 Tensorflow 中,所有不同的變數和運算都是儲存在計算圖。所以在我們構建完模型所需要的圖之後,還需要開啟一個會話(Session)來執行整個計算圖。在會話中,我們可以將所有計算分配到可用的 CPU 和 GPU 資源中。
如上所示我們構建了一個加法運算的計算圖,第二個程式碼塊並不會輸出計算結果,因為我們只是定義了一張圖,而沒有執行它。第三個程式碼塊才會輸出計算結果,因為我們需要建立一個會話(Session)才能管理 TensorFlow 執行時的所有資源。但計算完畢後需要關閉會話來幫助系統回收資源,不然就會出現資源洩漏的問題。
TensorFlow 中最基本的單位是常量(Constant)、變數(Variable)和佔位符(Placeholder)。常量定義後值和維度不可變,變數定義後值可變而維度不可變。在神經網路中,變數一般可作為儲存權重和其他資訊的矩陣,而常量可作為儲存超引數或其他結構資訊的變數。在上面的計算圖中,結點 1 和結點 2 都是定義的常量 tf.constant()。我們可以分別宣告不同的常量(tf.constant())和變數(tf.Variable()),其中 tf.float 和 tf.int 分別宣告瞭不同的浮點型和整數型資料。
2. 佔位符和 feed_dict
TensorFlow 同樣還支援佔位符,佔位符並沒有初始值,它只會分配必要的記憶體。在會話中,佔位符可以使用 feed_dict 饋送資料。
feed_dict 是一個字典,在字典中需要給出每一個用到的佔位符的取值。在訓練神經網路時需要每次提供一個批次的訓練樣本,如果每次迭代選取的資料要透過常量表示,那麼 TensorFlow 的計算圖會非常大。因為每增加一個常量,TensorFlow 都會在計算圖中增加一個結點。所以說擁有幾百萬次迭代的神經網路會擁有極其龐大的計算圖,而佔位符卻可以解決這一點,它只會擁有佔位符這一個結點。
3. 張量
在 TensorFlow 中,張量是計算圖執行運算的基本載體,我們需要計算的資料都以張量的形式儲存或宣告。如下所示,該教程給出了各階張量的意義。
零階張量就是我們熟悉的標量數字,它僅僅只表達了量的大小或性質而沒有其它的描述。一階張量即我們熟悉的向量,它不僅表達了線段量的大小,同時還表達了方向。一般來說二維向量可以表示平面中線段的量和方向,三維向量和表示空間中線段的量和方向。二階張量即矩陣,我們可以看作是填滿數字的一個表格,矩陣運算即一個表格和另外一個表格進行運算。當然理論上我們可以產生任意階的張量,但在實際的機器學習演算法運算中,我們使用得最多的還是一階張量(向量)和二階張量(矩陣)。
一般來說,張量中每個元素的資料型別有以上幾種,即浮點型和整數型,一般在神經網路中比較常用的是 32 位浮點型。
4. TensorFlow 機器
在整個教程中,下面一張示意圖將反覆出現,這基本上是所有 TensorFlow 機器學習模型所遵循的構建流程,即構建計算圖、饋送輸入張量、更新權重並返回輸出值。
在第一步使用 TensorFlow 構建計算圖中,我們需要構建整個模型的架構。例如在神經網路模型中,我們需要從輸入層開始構建整個神經網路的架構,包括隱藏層的數量、每一層神經元的數量、層級之間連線的情況與權重、整個網路每個神經元使用的啟用函式等內容。此外,我們還需要配置整個訓練、驗證與測試的過程。例如在神經網路中,定義整個正向傳播的過程與引數並設定學習率、正則化率和批次大小等各類訓練超引數。第二步需要將訓練資料或測試資料等饋送到模型中,TensorFlow 在這一步中一般需要開啟一個會話(Session)來執行引數初始化和饋送資料等任務。例如在計算機視覺中,我們需要隨機初始化整個模型引數數值,並將影像成批(影像數等於批次大小)地饋送到定義好的卷積神經網路中。第三步即更新權重並獲取返回值,這個一般是控制訓練過程與獲得最終的預測結果。
TensorFlow 模型實戰
TensorFlow 線性迴歸
該教程前面介紹了很多線性迴歸的基本概念,包括直線擬合、損失函式、梯度下降等基礎內容。我們一直認為線性迴歸是理解機器學習最好的入門模型,因為他的原理和概念十分簡單,但又基本涉及到了機器學習的各個過程。總的來說,線性迴歸模型可以用下圖概括:
其中「×」為資料點,我們需要找到一條直線以最好地擬合這些資料點。該直線和這些資料點之間的距離即損失函式,所以我們希望找到一條能令損失函式最小的直線。以下是使用 TensorFlow 構建線性迴歸的簡單案例。
1. 構建目標函式(即「直線」)
目標函式即 H(x)=Wx+b,其中 x 為特徵向量、W 為特徵向量中每個元素對應的權重、b 為偏置項。
# X and Y data
x_train = [1, 2, 3]
y_train = [1, 2, 3]
W = tf.Variable(tf.random_normal([1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')
# Our hypothesis XW+b
hypothesis = x_train * W + b
如上所示,我們定義了 y=wx+b 的運算,即我們需要擬合的一條直線。
2. 構建損失函式
下面我們需要構建整個模型的損失函式,即各資料點到該直線的距離,這裡我們構建的損失函式為均方誤差函式:
該函式表明根據資料點預測的值和該資料點真實值之間的距離,我們可以使用以下程式碼實現:
# cost/loss function
cost = tf.reduce_mean(tf.square(hypothesis - y_train))
其中 tf.square() 為取某個數的平方,而 tf.reduce_mean() 為取均值。
3. 採用梯度下降更新權重
# Minimize
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)
為了尋找能擬合資料的最好直線,我們需要最小化損失函式,即資料與直線之間的距離,因此我們可以採用梯度下降演算法:
4. 執行計算圖執行訓練
# Launch the graph in a session.
sess = tf.Session()
# Initializes global variables in the graph.
sess.run(tf.global_variables_initializer())
# Fit the line
for step in range(2001):
sess.run(train)
if step % 20 == 0:
print(step, sess.run(cost), sess.run(W), sess.run(b))
上面的程式碼開啟了一個會話並執行變數初始化和饋送資料。
最後,該課程給出了完整的實現程式碼,剛入門的讀者可以嘗試實現這一簡單的線性迴歸模型:
import tensorflow as tf
W = tf.Variable(tf.random_normal([1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')
X = tf.placeholder(tf.float32, shape=[None])
Y = tf.placeholder(tf.float32, shape=[None])
# Our hypothesis XW+b
hypothesis = X * W + b
# cost/loss function
cost = tf.reduce_mean(tf.square(hypothesis - Y))
# Minimize
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)
# Launch the graph in a session.
sess = tf.Session()
# Initializes global variables in the graph.
sess.run(tf.global_variables_initializer())
# Fit the line
for step in range(2001):
cost_val, W_val, b_val, _ = sess.run([cost, W, b, train],
feed_dict={X: [1, 2, 3], Y: [1, 2, 3]})
if step % 20 == 0:
print(step, cost_val, W_val, b_val)
下面讓我們概覽該課程更多的內容:
Logistic 迴歸
該課程照例先簡介了 Logistic 迴歸的基本概念,如下展示了目標函式、損失函式和權重更新過程。
後面展示了 Logistic 迴歸的實現程式碼:
xy = np.loadtxt('data-03-diabetes.csv', delimiter=',', dtype=np.float32)
x_data = xy[:, 0:-1]
y_data = xy[:, [-1]]
# placeholders for a tensor that will be always fed.
X = tf.placeholder(tf.float32, shape=[None, 8])
Y = tf.placeholder(tf.float32, shape=[None, 1])
W = tf.Variable(tf.random_normal([8, 1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')
# Hypothesis using sigmoid: tf.div(1., 1. + tf.exp(tf.matmul(X, W)))
hypothesis = tf.sigmoid(tf.matmul(X, W) + b)
# cost/loss function
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis))
train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)
# Accuracy computation
# True if hypothesis>0.5 else False
predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))
# Launch graph
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
feed = {X: x_data, Y: y_data}
for step in range(10001):
sess.run(train, feed_dict=feed)
if step % 200 == 0:
print(step, sess.run(cost, feed_dict=feed))
# Accuracy report
h, c, a = sess.run([hypothesis, predicted, accuracy], feed_dict=feed)
print("\nHypothesis: ", h, "\nCorrect (Y): ", c, "\nAccuracy: ", a)
Softmax 分類
下圖展示了 Softmax 的基本方法,它可以產生和為 1 的類別機率。
以下程式碼為 Softmax 分類器處理 MNIST 資料集:
# weights & bias for nn layers
W = tf.Variable(tf.random_normal([784, 10]))
b = tf.Variable(tf.random_normal([10]))
hypothesis = tf.matmul(X, W) + b
# define cost/loss & optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
# initialize
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# train my model
for epoch in range(training_epochs):
avg_cost = 0
total_batch = int(mnist.train.num_examples / batch_size)
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
feed_dict = {X: batch_xs, Y: batch_ys}
c, _ = sess.run([cost, optimizer], feed_dict=feed_dict)
avg_cost += c / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print('Learning Finished!')
# Test model and check accuracy
correct_prediction = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('Accuracy:', sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
神經網路
下圖簡要介紹了神經網路的運算過程,這一部分十分詳細,對於初學者來說是難得的資料:
下面是該教程採用神經網路解決異或問題的程式碼,異或問題是十分經典的任務,我們可以從該問題中理解神經網路的強大之處:
x_data = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=np.float32)
y_data = np.array([[0], [1], [1], [0]], dtype=np.float32)
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)
W1 = tf.Variable(tf.random_normal([2, 2]), name='weight1')
b1 = tf.Variable(tf.random_normal([2]), name='bias1')
layer1 = tf.sigmoid(tf.matmul(X, W1) + b1)
W2 = tf.Variable(tf.random_normal([2, 1]), name='weight2')
b2 = tf.Variable(tf.random_normal([1]), name='bias2')
hypothesis = tf.sigmoid(tf.matmul(layer1, W2) + b2)
# cost/loss function
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis))
train = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
# Accuracy computation
# True if hypothesis>0.5 else False
predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))
# Launch graph
with tf.Session() as sess:
# Initialize TensorFlow variables
sess.run(tf.global_variables_initializer())
for step in range(10001):
sess.run(train, feed_dict={X: x_data, Y: y_data})
if step % 100 == 0:
print(step, sess.run(cost, feed_dict={X: x_data, Y: y_data}), sess.run([W1, W2]))
# Accuracy report
h, c, a = sess.run([hypothesis, predicted, accuracy],
feed_dict={X: x_data, Y: y_data})
print("\nHypothesis: ", h, "\nCorrect: ", c, "\nAccuracy: ", a)
卷積神經網路
第二天教程就正式進入卷積神經網路,我們只能用下圖展示卷積神經網路大概的架構,更多資料請檢視原課程課件:
該教程同樣提供了很多卷積網路的實現程式碼,下面我們簡要介紹一個簡單的卷積神經網路實現過程,該卷積神經網路的架構如下:
下面的程式碼穿件了第一個卷積層,即上圖卷積層 1 和池化層 1:
# input placeholders
X = tf.placeholder(tf.float32, [None, 784])
X_img = tf.reshape(X, [-1, 28, 28, 1]) # img 28x28x1 (black/white)
Y = tf.placeholder(tf.float32, [None, 10])
# L1 ImgIn shape=(?, 28, 28, 1)
W1 = tf.Variable(tf.random_normal([3, 3, 1, 32], stddev=0.01))
# Conv -> (?, 28, 28, 32)
# Pool -> (?, 14, 14, 32)
L1 = tf.nn.conv2d(X_img, W1, strides=[1, 1, 1, 1], padding='SAME')
L1 = tf.nn.relu(L1)
L1 = tf.nn.max_pool(L1, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
'''
Tensor("Conv2D:0", shape=(?, 28, 28, 32), dtype=float32)
Tensor("Relu:0", shape=(?, 28, 28, 32), dtype=float32)
Tensor("MaxPool:0", shape=(?, 14, 14, 32), dtype=float32)
'''
後面的程式碼構建了第二個卷積層,即上圖中的卷積層 2 和池化層 2:
'''
Tensor("Conv2D:0", shape=(?, 28, 28, 32), dtype=float32)
Tensor("Relu:0", shape=(?, 28, 28, 32), dtype=float32)
Tensor("MaxPool:0", shape=(?, 14, 14, 32), dtype=float32)
'''
# L2 ImgIn shape=(?, 14, 14, 32)
W2 = tf.Variable(tf.random_normal([3, 3, 32, 64], stddev=0.01))
# Conv ->(?, 14, 14, 64)
# Pool ->(?, 7, 7, 64)
L2 = tf.nn.conv2d(L1, W2, strides=[1, 1, 1, 1], padding='SAME')
L2 = tf.nn.relu(L2)
L2 = tf.nn.max_pool(L2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
L2 = tf.reshape(L2, [-1, 7 * 7 * 64])
'''
Tensor("Conv2D_1:0", shape=(?, 14, 14, 64), dtype=float32)
Tensor("Relu_1:0", shape=(?, 14, 14, 64), dtype=float32)
Tensor("MaxPool_1:0", shape=(?, 7, 7, 64), dtype=float32)
Tensor("Reshape_1:0", shape=(?, 3136), dtype=float32)
最後我們只需要構建一個全連線層就完成了整個 CNN 架構的搭建,即用以下程式碼構建上圖最後紫色的全連線層:
'''
Tensor("Conv2D_1:0", shape=(?, 14, 14, 64), dtype=float32)
Tensor("Relu_1:0", shape=(?, 14, 14, 64), dtype=float32)
Tensor("MaxPool_1:0", shape=(?, 7, 7, 64), dtype=float32)
Tensor("Reshape_1:0", shape=(?, 3136), dtype=float32)
'''
L2 = tf.reshape(L2, [-1, 7 * 7 * 64])
# Final FC 7x7x64 inputs -> 10 outputs
W3 = tf.get_variable("W3", shape=[7 * 7 * 64, 10], initializer=tf.contrib.layers.xavier_initializer())
b = tf.Variable(tf.random_normal([10]))
hypothesis = tf.matmul(L2, W3) + b
# define cost/loss & optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
最後我們只需要訓練該 CNN 就完成了整個模型:
# initialize
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# train my model
print('Learning stared. It takes sometime.')
for epoch in range(training_epochs):
avg_cost = 0
total_batch = int(mnist.train.num_examples / batch_size)
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
feed_dict = {X: batch_xs, Y: batch_ys}
c, _, = sess.run([cost, optimizer], feed_dict=feed_dict)
avg_cost += c / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print('Learning Finished!')
# Test model and check accuracy
correct_prediction = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('Accuracy:', sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
迴圈神經網路
該教程第三天講述了迴圈神經網路,下圖展示了迴圈單元的展開,迴圈單元是處理時序資料的核心。更詳細的資料請檢視該課程課件。
以下 TensorFlow 程式碼定義了簡單的迴圈單元:
# One cell RNN input_dim (4) -> output_dim (2)
hidden_size = 2
cell = tf.contrib.rnn.BasicRNNCell(num_units=hidden_size)
x_data = np.array([[[1,0,0,0]]], dtype=np.float32)
outputs, _states = tf.nn.dynamic_rnn(cell, x_data, dtype=tf.float32)
sess.run(tf.global_variables_initializer())
pp.pprint(outputs.eval())
下面該課程展示了一個簡單的卷積神經網路案例,如下所示,該案例訓練一個 RNN 以輸出「hihello」。
1. 建立 RNN 單元
如下可知 TensorFlow 中一般可以建立 3 種 RNN 單元,即 RNN 單元、LSTM 單元和 GRU 單元
# RNN model
rnn_cell = rnn_cell.BasicRNNCell(rnn_size)
rnn_cell = rnn_cell. BasicLSTMCell(rnn_size)
rnn_cell = rnn_cell. GRUCell(rnn_size)
2. 執行 RNN
# RNN model
rnn_cell = rnn_cell.BasicRNNCell(rnn_size)
outputs, _states = tf.nn.dynamic_rnn(
rnn_cell,
X,
initial_state=initial_state,
dtype=tf.float32)
3. 設定 RNN 的引數
hidden_size = 5 # output from the LSTM
input_dim = 5 # one-hot size
batch_size = 1 # one sentence
sequence_length = 6 # |ihello| == 6
4. 建立資料
idx2char = ['h', 'i', 'e', 'l', 'o'] # h=0, i=1, e=2, l=3, o=4
x_data = [[0, 1, 0, 2, 3, 3]] # hihell
x_one_hot = [[[1, 0, 0, 0, 0], # h 0
[0, 1, 0, 0, 0], # i 1
[1, 0, 0, 0, 0], # h 0
[0, 0, 1, 0, 0], # e 2
[0, 0, 0, 1, 0], # l 3
[0, 0, 0, 1, 0]]] # l 3
y_data = [[1, 0, 2, 3, 3, 4]] # ihello
X = tf.placeholder(tf.float32,
[None, sequence_length, input_dim]) # X one-hot
Y = tf.placeholder(tf.int32, [None, sequence_length]) # Y label
5. 將資料饋送到 RNN 中
X = tf.placeholder(
tf.float32, [None, sequence_length, hidden_size]) # X one-hot
Y = tf.placeholder(tf.int32, [None, sequence_length]) # Y label
cell = tf.contrib.rnn.BasicLSTMCell(num_units=hidden_size, state_is_tuple=True)
initial_state = cell.zero_state(batch_size, tf.float32)
outputs, _states = tf.nn.dynamic_rnn(
cell, X, initial_state=initial_state, dtype=tf.float32)
6. 建立序列損失函式
outputs, _states = tf.nn.dynamic_rnn(
cell, X, initial_state=initial_state, dtype=tf.float32)
weights = tf.ones([batch_size, sequence_length])
sequence_loss = tf.contrib.seq2seq.sequence_loss(
logits=outputs, targets=Y, weights=weights)
loss = tf.reduce_mean(sequence_loss)
train = tf.train.AdamOptimizer(learning_rate=0.1).minimize(loss)
7. 訓練 RNN
這是最後一步,我們將開啟一個 TensorFlow 會話完成模型的訓練。
prediction = tf.argmax(outputs, axis=2)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(2000):
l, _ = sess.run([loss, train], feed_dict={X: x_one_hot, Y: y_data})
result = sess.run(prediction, feed_dict={X: x_one_hot})
print(i, "loss:", l, "prediction: ", result, "true Y: ", y_data)
# print char using dic
result_str = [idx2char[c] for c in np.squeeze(result)]
print("\tPrediction str: ", ''.join(result_str))