Tensorflow入門——Eager模式
眾所周知,Tensorflow入門之所以困難,與其採用的Graph 和 Session 模式有關,這與原生的 Python 程式碼簡單、直觀的印象格格不入。同時,由於計算僅僅發生在Session裡面,所以初始化引數和變數的時候沒辦法將結果打印出來,以至於除錯起來也十分困難。
當然Google官方也意識到了這點,於是引入了Eager模式,在這個模式下tensorflow的常量和變數可以直接計算並打印出來,甚至還可以和numpy陣列混合計算。本文程式碼參考官方教程(from github with Apache License 2.0)
同樣的,為了方便與讀者交流,所有的程式碼都放在了這裡:
https://github.com/zht007/tensorflow-practice
1. 啟用Eager模式
啟用Eager模式也非常簡單,僅幾行程式碼。
import tensorflow as tf
tf.enable_eager_execution()
tfe = tf.contrib.eager
注意,eager模式在程式開始就要啟用,且不能與普通模式混用。另外tfe在後面優化器(Optimizer)的時候需要用到,故先在這裡定義了。
2. Eger模式上手
Eger模式下,定義的變數或者常量可以直接打印出來
a = tf.constant([[1, 2],
[3, 4]])
print('a=',a)
b = tf.Variable(np.zeros((2,2)))
print('\n b=',b)
c = tf.Variable([[6, 7],
[8, 9]])
print('\n c=',c)
-------output-------
a= tf.Tensor(
[[1 2]
[3 4]], shape=(2, 2), dtype=int32)
b= <tf.Variable 'Variable:0' shape=(2, 2) dtype=float64, numpy=
array([[0., 0.],
[0., 0.]])>
c= <tf.Variable 'Variable:0' shape=(2, 2) dtype=int32, numpy=
array([[6, 7],
[8, 9]], dtype=int32)>
可以直接轉換成我們熟悉的numpy arrary
print(c.numpy())
---output---
[[6 7]
[8 9]]
當然也可以直接計算並輸出結果,甚至可以與numpy arrary 混合計算。
x = tf.Variable([[6, 7],
[8.0, 9.0]],dtype ="float32")
y = np.array([[1,2],
[3,4]],dtype ="float32")
print(tf.matmul(x,y))
----output----
tf.Tensor(
[[27. 40.]
[35. 52.]], shape=(2, 2), dtype=float32)
3. Eager 模式下訓練線性迴歸模型
最後我們用Tensor Flow 在Eager模式下訓練線性迴歸模型,該模型我們之前已經用Tensorflow和Keras訓練過了,感興趣的朋友可以參照之前的文章進行對比。
3.1 建立模擬資料
與之前的資料一樣,此處資料是100萬個帶噪音的線性資料,100萬個點用plt是畫不出來的,圖中隨機取樣了250個點
image我們定義一個幫助函式方便以batch的形式這100萬個資料點中隨機抽取batch size大小的資料進行訓練
def next_batch(x_data, batch_size):
batch_index = np.random.randint(len(x_data),size=(BATCH_SIZE))
x_train = x_data[batch_index]
y_train = y_true[batch_index]
return x_train, y_train
3.2 定義變數
此處與普通模式下的tensorflow變數沒有任何區別
w_tfe = tf.Variable(np.random.uniform())
b_tfe = tf.Variable(np.random.uniform(1,10)
3.3 線性函式
在普通模式下的tensorflow中我們需要定義計算圖譜,這裡我們直接以 python 函式的形式,定義要訓練的線性迴歸函式。
def linear_regression(inputs):
return inputs * w_tfe + b_tfe
3.4 損失函式
同樣的,MS(Mean Square)損失函式也要以python 函式的形式定義,而不是計算圖譜。
def mean_square_fn(model_fn, inputs, labels):
return tf.reduce_sum(tf.pow(model_fn(inputs) - labels, 2)) / (2 * BATCH_SIZE)
3.5 優化器
同樣使用Gradient Descent 的優化器,不同在於,普通模式下我們建立一個計算圖譜train = optimizer.minimize(error), 在Eager模式下,要用tfe.implicit_gradients()來返回一個函式。
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
grad = tfe.implicit_gradients(mean_square_fn)
3.6 模型訓練
由於沒有計算圖譜,所以也不需要初始化變數,也不需在Session下執行,而是類似於原生 Python 函式的形式將資料傳入"Optimizer模型"函式。訓練完成之後,w 和 b 的引數也自動儲存下來,不必在Session中提取。
for step in range(BATCHS):
x_train, y_train = next_batch(x_data, BATCH_SIZE)
optimizer.apply_gradients(grad(linear_regression, x_train, y_train))
3.7 驗證訓練結果
直接將最終的 w 和 b 帶入線性函式,訓練結果也非常符合預期。
image-201905021508088814. 總結
Eager 模式下的 Tensorflow 與原生的 Python 程式碼非常類似,可以直接計算並列印結果,建立和訓練模型的過程也類似於python函式的建立和呼叫。Eager 和Keras API 都是Tensorflow 2.0 官方主推的 Tensorflow使用方式,相信在不久的將來,獲取我們就再也看不到 init = tf.global_variables_initializer() 還有 with tf.Session() as sess:這樣的類似八股文一樣的關鍵詞啦。
轉載自:
作者:Hongtao洪滔
連結:https://www.jianshu.com/p/883addf4a1b2