TensorFlow快速上手

本文首發於我的個人博客QIMING.INFO,轉載請帶上鍊接及署名。

TensorFlow是目前很火的一款深度學習框架,其源碼是用C++寫的,保證了運行速度,其又提供了Python的接口,大大降低了程序猿們學習新語言的成本,所以在深度學習領域廣爲流行。

但是很多人在初學TensorFlow時會覺得有些難以入手,霎時間接觸諸如張量、圖、會話等概念會有點吃力,所以本文將介紹如何快速入門TensorFlow並上手寫代碼,一邊實踐一邊理解概念,提升學習速度。

1 安裝

安裝TensorFlow有多種方式,爲了快速上手寫代碼,這裏介紹一種最爲簡單的方法,像安裝其他Python庫一樣,直接用pip就好,即在命令行中輸入:

pip install tensorflow

注1:還可以通過Docker安裝或從源碼安裝。

注2:此處安裝的是僅支持CPU版本的,支持GPU版本的將在後續文章中說明。

2 使用

在使用的第一步,慣例我們先引入tensorflow庫,爲方便起見,將其用tf簡寫,如下:

import tensorflow as tf

2.1 張量

張量即tensor,是TensorFlow中所有數據的基本表現形式,TensorFlow中的常量、變量都屬於張量。

2.1.1 常量

a = tf.constant([[1.,2.],[3.,4.]],name='const_a')
print(a)

這段代碼創建了一個常量a,直接輸出後的結果如下:

Tensor("const_a:0", shape=(2,2), dtype=float32)

可以看到直接輸出的結果並不是我們給定的值,而是一個張量的結構。(輸出值需要在會話中進行,下文會進行介紹)

其中const_a:0表示aconst_a的第一個值(也是唯一一個),shape代表維度,(2,2)表示此張量是個2x2的矩陣,第三個屬性爲數據類型。

常用的常數生成函數還有:

# 產生全是0的2x3矩陣
tf.zeros([2,3],int32)
# 產生全是1的2x3矩陣
tf.ones([2,3],int32)
# 產生全是9的2x3矩陣
tf.fill([2,3],9)

2.1.2 變量

變量在TensorFlow中十分重要,因其可以在計算中修改,所以神經網絡的模型參數一般使用變量。

創建變量可以直接調用Variable函數,將值傳入即可。

# 創建一個全1的2x2矩陣
x = tf.Variable(tf.ones([2,2]),name='var_x')

需要注意的是,使用變量時,需要對其進行初始化:

init = tf.global_variables_initializer()

2.2 會話

TensorFlow中,所有操作都只能在會話(Session)中進行。

假如我們想求上文中創建的常量a和變量x的和,完整代碼如下:

import tensorflow as tf

# 創建一個2x2的矩陣常量a,值爲[[1.0,2.0],[3.0,4.0]]
a = tf.constant([[1.,2.],[3.,4.]],name='const_a')
# 創建一個全1的2x2矩陣
x = tf.Variable(tf.ones([2,2]),name='var_x')
# 定義一個加法操作
add = tf.add(a,x) # 或 add = a + x
# 初始化所有變量
init = tf.global_variables_initializer()
# 利用Python上下文管理器創建Session,並在其中執行有關操作
with tf.Session() as sess:
    # 執行初始化變量
    sess.run(init)
    # 執行加法運算並輸出結果
    print(sess.run(add))

注1:創建常量、變量時的name參數可省略

注2:創建Session的另一種方法:

# 創建會話
sess = tf.Session()
# 調用會話來執行節點的計算,假如是上例中的add
sess.run(add)
# 執行結束後關閉會話
sess.close()

這種方式不好的地方在於當程序因爲異常而退出時,Session.close()可能不會執行從而導致資源泄露。

運行後輸出如下:

[[2. 3.]
 [4. 5.]]

2.3 圖

至此,你是否隱約感受到了TensorFlow在運行時的一點不同?

不同於一般的程序,TensorFlow程序有兩個階段:

  1. 定義計算
  2. 執行計算

也就是說TensorFlow會將所有運算都定義好後再在Session中執行,不像一般程序,可以一邊定義一邊執行。

事實上,TensorFlow在進行第一個階段時就是將計算定義在了一個圖(Graph)裏,在上文中,是將操作放到了TensorFlow默認提供的一張計算圖中了,當然,我們也可以自己新建一張圖,如下:

# 創建一張圖g
g = tf.Graph()
with g.as_default():
    # 在圖中定義常量c爲5.0
    c = tf.constant(5.0)

# 創建一個Session,將圖g作爲參數傳給它
with tf.Session(graph=g) as sess:
    # 輸出c
    print(sess.run(c))
    
# 執行後,輸出結果爲:5.0

2.4 擬合線性迴歸

瞭解了上述基本概念和操作,接下來,我們來動手實踐來擬合y=0.1x+0.2這個函數吧。

import tensorflow as tf
import numpy as np

# 使用numpy生成100個隨機點
x_data = np.random.rand(100)
y_data = x_data*0.1 + 0.2

# 給k隨機賦初值2.2
k = tf.Variable(2.2)
# 給b隨機賦初值1.1
b = tf.Variable(1.1)
# 構造一個線性模型
y = k*x_data + b

# 二次代價函數的損失值
loss = tf.reduce_mean(tf.square(y_data-y))
# 定義一個梯度下降法來進行訓練的優化器
optimizer = tf.train.GradientDescentOptimizer(0.2)
# 最小化代價函數
train = optimizer.minimize(loss)

# 初始化變量
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    # 訓練201次
    for step in range(201):
        sess.run(train)
        # 每訓練20次 輸出一下結果
        if step%20 == 0:
            print(step,sess.run([k,b]))

訓練結果如下:

0 [1.7758392, 0.34141564]
20 [0.87541753, -0.19211102]
40 [0.57061648, -0.03798072]
60 [0.38562673, 0.055564649]
80 [0.27335268, 0.11233925]
100 [0.20521127, 0.14679691]
120 [0.16385485, 0.16770996]
140 [0.13875481, 0.18040252]
160 [0.12352109, 0.18810588]
180 [0.11427544, 0.19278121]
200 [0.10866406, 0.19561876]

可以看出,在訓練了201次後,k值和b值都分別非常接近0.1和0.2了。

3 參考資料

[1]TensorFlow中文社區.基本用法 | TensorFlow 官方文檔中文版
[2]鄭澤宇,樑博文,顧思宇.TensorFlow:實戰Goole深度學習框架(第2版)[M].北京:電子工業出版社.2018-02
[3]視頻《深度學習框架Tensorflow學習與應用》@Youtube

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章