1. 程式人生 > >TensorFlow學習--入門之基本使用

TensorFlow學習--入門之基本使用

原文地址http://www.cnblogs.com/flyu6/p/5555161.html

整體介紹

使用 TensorFlow, 你必須明白 TensorFlow:

  • 使用圖 (graph) 來表示計算任務.
  • 在被稱之為 會話 (Session) 的上下文 (context) 中執行圖.
  • 使用 tensor 表示資料.
  • 通過 變數 (Variable) 維護狀態.
  • 使用 feed 和 fetch 可以為任意的操作(arbitrary operation)

賦值或者從其中獲取資料.

一個 TensorFlow 圖描述了計算的過程. 為了進行計算, 圖必須在 會話 裡被啟動. 會話 將圖的 op 分發到諸如 CPU 或 GPU 之類的 裝置 上, 同時提供執行 op 的方法. 這些方法執行後, 將產生的 tensor 返回. 在 Python 語言中, 返回的 tensor 是 numpy ndarray 物件; 在 C 和 C++ 語言中, 返回的 tensor 是tensorflow::Tensor 例項.

計算圖

TensorFlow 程式通常被組織成一個構建階段和一個執行階段. 在構建階段, op 的執行步驟 被描述成一個圖. 在執行階段, 使用會話執行執行圖中的 op.

其實這就是一個宣告式程式設計結構,就好比炒菜,我們都是把主材和佐料就準備好,才添油烹製。tensorflow的計算方式也是如此,我們先在構建階段將這個網路(如神經網路)構建出來,然後我們使用TensorFlow提供的Session方法開啟一個執行(run())將我們的網路放進去run一下,就可以得到我們想到的結果。這就是宣告式的程式設計方式。

Step 1: 構建圖

import tensorflow as tf
# 建立一個常量 op, 產生一個1x2 矩陣這個op被稱作是一個節點
# 加到預設圖中
#
#構造器的返回值代表常量 op的返回值
a = tf.constant([[3., 3.]])

b = tf.constant([[2.],[2.])

# 建立一個矩陣乘法操作, a, b作為輸入
# 返回 product 代表乘法的結果
product = tf.matmul(a,b)

現在已經建立好了一個 兩個矩陣相乘並返回product結果的圖。也就是說主材和佐料已經準備好了。接下來就是到了生火炒菜的時間了。為了得到product,我們就必須在一個會話(Session)中啟動這個一個圖了。

Step 2:啟動一個圖

#接著上面的程式碼
sess = tf.Session()

# 呼叫 sess 的 'run()' 方法來執行矩陣乘法 op, 傳入 'product' 作為該方法的引數. 
# 上面提到, 'product' 代表了矩陣乘法 op 的輸出, 傳入它是向方法表明, 我們希望取回
# 矩陣乘法 op 的輸出.
#
# 整個執行過程是自動化的, 會話負責傳遞 op 所需的全部輸入. op 通常是併發執行的.
# 
# 函式呼叫 'run(product)' 觸發了圖中三個 op (兩個常量 op 和一個矩陣乘法 op) 的執行.
#
# 返回值 'result' 是一個 numpy `ndarray` 物件.

sess.run(product)
print result

# ==> [[12.]]

# 任務完成後就需要關閉
sess.close()

當然,在我們寫程式碼的時候,有時候會忘記寫sess.close().這裡我們可以使用系統的帶的with來實現session的自動關閉。

with tf.Session() as sess:
      result = sess.run([product])
      print result

TensorFlow自從0.8版本開始支援分散式處理的機器學習,而且同時,TensorFlow會充分的利用計算機資源:cpu GPU 等。而且如果檢測到GPU,會盡可能的使用GPU來實現對程式的計算。而當計算機上有多個GPU的時候,我們可以通過tf.device()來指定哪個GPU來執行。具體示例如下:

with tf.Session() as sess:
with tf.device("/gpu:1"):
    a = tf.constant([[3., 3.]])
    b = tf.constant([[2.],[2.])
    product = tf.matmul(a,b)
    ...

裝置用字串進行標識. 目前支援的裝置包括:

  •  "/cpu:0": 機器的 CPU.
  •  "/gpu:0": 機器的第一個 GPU, 如果有的話.
  •  "/gpu:1": 機器的第二個 GPU, 以此類推.

互動式使用

文件中的 Python 示例使用一個會話 Session 來 啟動圖, 並呼叫 **Session.run()**方法執行操作.

為了便於使用諸如 IPython 之類的 Python 互動環境, 可以使用InteractiveSession 代替 Session 類, 使用 Tensor.eval() 和 Operation.run() 方法代替 Session.run(). 這樣可以避免使用一個變數來持有會話。

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

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

# 使用初始化來初始化 Variable
x.initializer.run()

# 增加一個減法操作 sub op 從x 減去a,然後輸出結果
sub = tf.sub(x,a)
print sub.eval()

# ==> [-2 -1]

Tensor

在TensorFlow中使用Tensor資料結構來表示所有的資料。Tensor可以看做是一個n維的陣列或列表。一個Tensor包含一個靜態型別Rank和一個shape.

變數 Variable

變數維護圖執行過程中的狀態資訊。下面的例子演示瞭如何使用變數實現一個簡單的計數器。

# 建立一個變數,  初始化為標量 0
state = tf.Variable(0, name="counter")

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

# 啟動圖後, 變數必須先經過`初始化` (init) op 初始化,
# 首先必須增加一個`初始化` op 到圖中.
init_op = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init_op) # 執行 init_op
    
    print sess.run(state) # 打印出事狀態
    
    for _ in range(3):
    sess.run(update)
    print sess.run(state)
    

# 輸出:
# 0
# 1
# 2
# 3

Fetch

為了取回操作的輸出內容, 可以在使用 Session 物件的 run() 呼叫 執行圖時, 傳入一些 tensor, 這些 tensor 會幫助你取回結果. 在之前的例子裡, 我們只取回了單個節點 state, 但是你也可以取回多個 tensor:

input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
intermed = tf.add(input2, input3)
mul = tf.mul(input1, intermed)

with tf.Session():
  result = sess.run([mul, intermed])
  print result

# 輸出:
# [array([ 21.], dtype=float32), array([ 7.], dtype=float32)]

Feed

上述示例在計算圖中引入了 tensor, 以常量或變數的形式儲存. TensorFlow 還提供了 feed 機制, 該機制 可以臨時替代圖中的任意操作中的 tensor 可以對圖中任何操作提交補丁, 直接插入一個 tensor.

feed 使用一個 tensor 值臨時替換一個操作的輸出結果. 你可以提供 feed 資料作為 run() 呼叫的引數. feed 只在呼叫它的方法內有效, 方法結束, feed 就會消失. 最常見的用例是將某些特殊的操作指定為 "feed" 操作, 標記的方法是使用 tf.placeholder() 為這些操作建立佔位符.

input1 = tf.placeholder(tf.types.float32)
input2 = tf.placeholder(tf.types.float32)
output = tf.mul(input1, input2)

with tf.Session() as sess:
  print sess.run([output], feed_dict={input1:[7.], input2:[2.]})

# 輸出:
# [array([ 14.], dtype=float32)]

如果沒有正確提供 feed, placeholder() 操作將會產生錯誤.