TensorFlow 入門


CS224d-Day 2:

在 Day 1 里,先了解了一下 NLP 和 DP 的主要概念,對它們有了一個大體的印象,用向量去表示研究對象,用神經網絡去學習,用 TensorFlow 去訓練模型,基本的模型和算法包括 word2vec,softmax,RNN,LSTM,GRU,CNN,大型數據的 seq2seq,還有未來比較火熱的研究方向 DMN,還有模型的調優。

今天先不直接進入理論學習,而是先學習一下 TensorFlow,在原課程里,這部分在第7講,但是我覺得最高效地學習算法的方式,就是一邊學理論,一邊寫代碼,實踐中才能理解更深刻。

Day 2 先認識 TensorFlow,了解一下基本用法,下一次就寫代碼來訓練模型算法,以問題為導向,以項目為驅動。


本文結構:

  • 1. TensorFlow 是什么
  • 2. 為什么需要 TensorFlow
  • 3. TensorFlow 的優點
  • 4. TensorFlow 的工作原理
  • 5. 安裝
  • 6. TensorFlow 基本用法
    • 要點
    • 例子
    • 概念
      • 張量
      • 會話

1. TensorFlow 是什么

是一個深度學習庫,由 Google 開源,可以對定義在 Tensor(張量)上的函數自動求導。

Tensor(張量)意味著 N 維數組,Flow(流)意味著基于數據流圖的計算,TensorFlow即為張量從圖的一端流動到另一端。

它的一大亮點是支持異構設備分布式計算,它能夠在各個平臺上自動運行模型,從電話、單個CPU / GPU到成百上千GPU卡組成的分布式系統。

支持CNN、RNN和LSTM算法,是目前在 Image,NLP 最流行的深度神經網絡模型。


2. 為什么需要 TensorFlow 等庫

深度學習通常意味著建立具有很多層的大規模的神經網絡。

除了輸入X,函數還使用一系列參數,其中包括標量值、向量以及最昂貴的矩陣和高階張量。

在訓練網絡之前,需要定義一個代價函數,常見的代價函數包括回歸問題的方差以及分類時候的交叉熵。

訓練時,需要連續的將多批新輸入投入網絡,對所有的參數求導后,代入代價函數,從而更新整個網絡模型。

這個過程中有兩個主要的問題:1. 較大的數字或者張量在一起相乘百萬次的處理,使得整個模型代價非常大。2. 手動求導耗時非常久。

所以 TensorFlow 的對函數自動求導以及分布式計算,可以幫我們節省很多時間來訓練模型。


3. TensorFlow 的優點

第一,基于Python,寫的很快并且具有可讀性。

第二,在多GPU系統上的運行更為順暢。

第三,代碼編譯效率較高。

第四,社區發展的非常迅速并且活躍。

第五,能夠生成顯示網絡拓撲結構和性能的可視化圖。


4. TensorFlow 的工作原理

TensorFlow是用數據流圖(data flow graphs)技術來進行數值計算的。

數據流圖是描述有向圖中的數值計算過程。

有向圖中,節點通常代表數學運算,邊表示節點之間的某種聯系,它負責傳輸多維數據(Tensors)。

節點可以被分配到多個計算設備上,可以異步和并行地執行操作。因為是有向圖,所以只有等到之前的入度節點們的計算狀態完成后,當前節點才能執行操作。


5. 安裝

極客學院有官方文檔翻譯版,講的很清楚,有各種安裝方式的講解。

我選擇基于 Anaconda 的安裝,因為這個很方便。

Anaconda 是一個集成許多第三方科學計算庫的 Python 科學計算環境,用 conda 作為自己的包管理工具,同時具有自己的計算環境,類似 Virtualenv。

  • 安裝 Anaconda
    我之前已經安裝過 Anaconda 了,直接從下面進行:

  • 建立一個 conda 計算環境

# 計算環境名字叫 tensorflow:
# Python 2.7
$ conda create -n tensorflow python=2.7

  • 激活環境,使用 conda 安裝 TensorFlow
$ source activate tensorflow
(tensorflow)$  # Your prompt should change

# Mac OS X, CPU only:
(tensorflow)$ pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0rc0-py2-none-any.whl

  • 安裝成功后,每次使用 TensorFlow 的時候需要激活 conda 環境

  • conda 環境激活后,你可以測試是否成功,在終端進入 python,輸入下面代碼,沒有提示錯誤,說明安裝 TensorFlow 成功:

$ python
...
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
Hello, TensorFlow!
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print(sess.run(a + b))
42
>>>

  • 當你不用 TensorFlow 的時候,關閉環境:
(tensorflow)$ source deactivate

$  # Your prompt should change back
  • 再次使用的時候再激活:
$ source activate tensorflow
(tensorflow)$  # Run Python programs that use TensorFlow.
...

(tensorflow)$ source deactivate

在 Jupyter notebook 里用 TensorFlow
我在 (tensorflow)$ 直接輸入 jupyter notebook 后,輸入 import tensorflow as tf 是有錯誤的,可以參考這里


6. TensorFlow 基本用法

接下來按照官方文檔中的具體代碼,來看一下基本用法。

你需要理解在TensorFlow中,是如何:

  • 將計算流程表示成圖;
  • 通過Sessions來執行圖計算;
  • 將數據表示為tensors;
  • 使用Variables來保持狀態信息;
  • 分別使用feeds和fetches來填充數據和抓取任意的操作結果;

先看個栗子:
例1,生成三維數據,然后用一個平面擬合它:

# (tensorflow)$ python   用 Python API 寫 TensorFlow 示例代碼

import tensorflow as tf
import numpy as np

# 用 NumPy 隨機生成 100 個數據
x_data = np.float32(np.random.rand(2, 100)) 
y_data = np.dot([0.100, 0.200], x_data) + 0.300

# 構造一個線性模型
b = tf.Variable(tf.zeros([1]))
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0))
y = tf.matmul(W, x_data) + b

# 最小化方差
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

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

# 啟動圖 (graph)
sess = tf.Session()
sess.run(init)

# 擬合平面
for step in xrange(0, 201):
    sess.run(train)
    if step % 20 == 0:
        print step, sess.run(W), sess.run(b)

# 輸出結果為:
0 [[-0.14751725  0.75113136]] [ 0.2857058]
20 [[ 0.06342752  0.32736415]] [ 0.24482927]
40 [[ 0.10146417  0.23744738]] [ 0.27712563]
60 [[ 0.10354312  0.21220125]] [ 0.290878]
80 [[ 0.10193551  0.20427427]] [ 0.2964265]
100 [[ 0.10085492  0.201565  ]] [ 0.298612]
120 [[ 0.10035028  0.20058727]] [ 0.29946309]
140 [[ 0.10013894  0.20022322]] [ 0.29979277]
160 [[ 0.1000543   0.20008542]] [ 0.29992008]
180 [[ 0.10002106  0.20003279]] [ 0.29996923]
200 [[ 0.10000814  0.20001261]] [ 0.29998815]

注意這幾條代碼:

W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0))

y = tf.matmul(W, x_data) + b

init = tf.initialize_all_variables()

sess = tf.Session()
sess.run(init)

sess.run(train) 
print step, sess.run(W), sess.run(b)

接下來看具體概念:

  • TensorFlow 用圖來表示計算任務,圖中的節點被稱之為operation,縮寫成op。
  • 一個節點獲得 0 個或者多個張量 tensor,執行計算,產生0個或多個張量。
  • 圖必須在會話(Session)里被啟動,會話(Session)將圖的op分發到CPU或GPU之類的設備上,同時提供執行op的方法,這些方法執行后,將產生的張量(tensor)返回。

1. 構建圖
例2,計算矩陣相乘:

import tensorflow as tf

# 創建一個 常量 op, 返回值 'matrix1' 代表這個 1x2 矩陣.
matrix1 = tf.constant([[3., 3.]])

# 創建另外一個 常量 op, 返回值 'matrix2' 代表這個 2x1 矩陣.
matrix2 = tf.constant([[2.],[2.]])

# 創建一個矩陣乘法 matmul op , 把 'matrix1' 和 'matrix2' 作為輸入.
# 返回值 'product' 代表矩陣乘法的結果.
product = tf.matmul(matrix1, matrix2)

默認圖有三個節點, 兩個 constant() op, 和一個 matmul() op. 為了真正進行矩陣相乘運算, 并得到矩陣乘法的結果, 你必須在會話里啟動這個圖.

2. 張量 Tensor
從向量空間到實數域的多重線性映射(multilinear maps)(v是向量空間,v*是對偶空間)
例如代碼中的 [[3., 3.]],Tensor 可以看作是一個 n 維的數組或列表。在 TensorFlow 中用 tensor 數據結構來代表所有的數據, 計算圖中, 操作間傳遞的數據都是 tensor。

3. 在一個會話中啟動圖
創建一個 Session 對象, 如果無任何創建參數, 會話構造器將啟動默認圖。
會話負責傳遞 op 所需的全部輸入,op 通常是并發執行的。

# 啟動默認圖.
sess = tf.Session()

# 調用 sess 的 'run()' 方法, 傳入 'product' 作為該方法的參數,
# 觸發了圖中三個 op (兩個常量 op 和一個矩陣乘法 op),
# 向方法表明, 我們希望取回矩陣乘法 op 的輸出.
result = sess.run(product)

# 返回值 'result' 是一個 numpy `ndarray` 對象.
print result
# ==> [[ 12.]]

# 任務完成, 需要關閉會話以釋放資源。
sess.close()

交互式使用
在 Python API 中,使用一個會話 Session 來 啟動圖, 并調用 Session.run() 方法執行操作.

為了便于在 IPython 等交互環境使用 TensorFlow,需要用 InteractiveSession 代替 Session 類, 使用 Tensor.eval() 和 Operation.run() 方法代替 Session.run()。

例3,計算 'x' 減去 'a':

# 進入一個交互式 TensorFlow 會話.
import tensorflow as tf
sess = tf.InteractiveSession()

x = tf.Variable([1.0, 2.0])
a = tf.constant([3.0, 3.0])

# 使用初始化器 initializer op 的 run() 方法初始化 'x' 
x.initializer.run()

# 增加一個減法 sub op, 從 'x' 減去 'a'. 運行減法 op, 輸出結果 
sub = tf.sub(x, a)
print sub.eval()
# ==> [-2. -1.]

變量 Variable

上面用到的張量是常值張量(constant)。

變量 Variable,是維護圖執行過程中的狀態信息的. 需要它來保持和更新參數值,是需要動態調整的。

下面代碼中有 tf.initialize_all_variables,是預先對變量初始化,
Tensorflow 的變量必須先初始化,然后才有值!而常值張量是不需要的。

下面的 assign() 操作和 add() 操作,在調用 run() 之前, 它并不會真正執行賦值和加和操作。

例4,使用變量實現一個簡單的計數器:

# -創建一個變量, 初始化為標量 0.  初始化定義初值
state = tf.Variable(0, name="counter")

# 創建一個 op, 其作用是使 state 增加 1
one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)

# 啟動圖后, 變量必須先經過`初始化` (init) op 初始化,
# 才真正通過Tensorflow的initialize_all_variables對這些變量賦初值
init_op = tf.initialize_all_variables()

# 啟動默認圖, 運行 op
with tf.Session() as sess:

  # 運行 'init' op
  sess.run(init_op)
  
  # 打印 'state' 的初始值
  # 取回操作的輸出內容, 可以在使用 Session 對象的 run() 調用 執行圖時, 
  # 傳入一些 tensor, 這些 tensor 會幫助你取回結果. 
  # 此處只取回了單個節點 state,
  # 也可以在運行一次 op 時一起取回多個 tensor: 
  # result = sess.run([mul, intermed])
  print sess.run(state)
  
  # 運行 op, 更新 'state', 并打印 'state'
  for _ in range(3):
    sess.run(update)
    print sess.run(state)

# 輸出:

# 0
# 1
# 2
# 3

上面的代碼定義了一個如下的計算圖:


Ok,總結一下,來一個清晰的代碼:
過程就是:建圖->啟動圖->運行取值

計算矩陣相乘:

import tensorflow as tf

# 建圖
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])

product = tf.matmul(matrix1, matrix2)

# 啟動圖
sess = tf.Session()

# 取值
result = sess.run(product)
print result

sess.close()

上面的幾個代碼介紹了基本用法,通過觀察,有沒有覺得 tf 和 numpy 有點像呢。

TensorFlow和普通的Numpy的對比
cs224d的課件中有下面這個代碼,來看一下二者之間的區別:

eval()

在 Python 中定義完 a 后,直接打印就可以看到 a。

In [37]: a = np.zeros((2,2))

In [39]: print(a)
[[ 0.  0.]
 [ 0.  0.]]

但是在 Tensorflow 中需要顯式地輸出(evaluation,也就是說借助eval()函數)!

In [38]: ta = tf.zeros((2,2))

In [40]: print(ta)
Tensor("zeros_1:0", shape=(2, 2), dtype=float32)

In [41]: print(ta.eval())
[[ 0.  0.]
[ 0. 0.]]

**通過幾個例子了解了基本的用法,feed 在上面的例子中還沒有寫到,下一次就能用到了,其他的可以查詢這里。 **


Day 1 宏觀了解了 NLP,Day 2 搞定了工具,下次要直接先進入實戰,訓練模型,先從 Logistic 和 NN 開始,一邊看模型一邊寫代碼一邊思考模型原理,這樣理解才會更深刻!

[cs224d]

Day 1. 深度學習與自然語言處理 主要概念一覽
Day 2. TensorFlow 入門
Day 3. word2vec 模型思想和代碼實現
Day 4. 怎樣做情感分析
Day 5. CS224d-Day 5: RNN快速入門
Day 6. 一文學會用 Tensorflow 搭建神經網絡
Day 7. 用深度神經網絡處理NER命名實體識別問題
Day 8. 用 RNN 訓練語言模型生成文本
Day 9. RNN與機器翻譯
Day 10. 用 Recursive Neural Networks 得到分析樹
Day 11. RNN的高級應用

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,250評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,923評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,041評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,475評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,253評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,801評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,882評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,023評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,530評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,494評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,639評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,177評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,890評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,289評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,552評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,242評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,626評論 2 370

推薦閱讀更多精彩內容