1. 程式人生 > 實用技巧 >Tensorflow入門——Eager模式

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-20190502150808881

4. 總結

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