本文首發於我的個人博客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
表示a
是const_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程序有兩個階段:
- 定義計算
- 執行計算
也就是說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