Tensorflow的基本使用
TensorFlow 的特點:
- 使用圖 (graph) 來表示計算任務.
- 在被稱之為
會話 (Session)
的上下文 (context) 中執行圖. - 使用 tensor 表示數據.
- 通過
變量 (Variable)
維護狀態. - 使用 feed 和 fetch 可以為任意的操作(arbitrary operation) 賦值或者從其中獲取數據.
TensorFlow 綜述
TensorFlow 是一個編程系統, 使用圖來表示計算任務。圖中的節點被稱之為 op (operation 的縮寫)。 一個 op 獲得 0 個或多個Tensor
, 執行計算, 產生 0 個或多個 Tensor
. 每個 Tensor 是一個類型化的多維數組. 例如, 你可以將一小組圖像集表示為一個四維浮點數數組, 這四個維度分別是 [batch, height, width, channels]
.
一個 TensorFlow 圖描述了計算的過程. 為了進行計算, 圖必須在 會話
里被啟動. 會話
將圖的 op 分發到諸如 CPU 或 GPU 之類的 設備
上, 同時提供執行 op 的方法. 這些方法執行后, 將產生的 tensor 返回. 在 Python 語言中, 返回的 tensor 是 numpy ndarray
對象; 在 C 和 C++ 語言中, 返回的 tensor 是tensorflow::Tensor
實例.
TensorFlow 計算圖
TensorFlow 程序通常被組織成一個構建階段和一個執行階段. 在構建階段, op 的執行步驟 被描述成一個圖. 在執行階段, 使用會話執行執行圖中的 op。
例如, 通常在構建階段創建一個圖來表示和訓練神經網絡,然后在執行階段反復執行圖中的訓練 op。
TensorFlow 支持 C, C++, Python 編程語言. 目前, TensorFlow 的 Python 庫更加易用, 它提供了大量的輔助函數來簡化構建圖的工作, 這些函數尚未被 C 和 C++ 庫支持.
三種語言的會話庫 (session libraries) 是一致的.
TensorFlow 構建圖
構建圖的第一步, 是創建源 op (source op)。源 op 不需要任何輸入, 例如 常量 (Constant)
. 源 op 的輸出被傳遞給其它 op 做運算.
Python 庫中, op 構造器的返回值代表被構造出的 op 的輸出, 這些返回值可以傳遞給其它 op 構造器作為輸入.
TensorFlow Python 庫有一個默認圖 (default graph), op 構造器可以為其增加節點. 這個默認圖對 許多程序來說已經足夠用了. 閱讀 Graph 類 文檔 來了解如何管理多個圖.
import tensorflow as tf # 創建一個常量 op, 產生一個 1x2 矩陣. 這個 op 被作為一個節點 # 加到默認圖中. # # 構造器的返回值代表該常量 op 的返回值. matrix1 = tf.constant([[3., 3.]]) # 創建另外一個常量 op, 產生一個 2x1 矩陣. matrix2 = tf.constant([[2.],[2.]]) # 創建一個矩陣乘法 matmul op , 把 'matrix1' 和 'matrix2' 作為輸入. # 返回值 'product' 代表矩陣乘法的結果. product = tf.matmul(matrix1, matrix2)
默認圖現在有三個節點, 兩個 constant()
op, 和一個matmul()
op. 為了真正進行矩陣相乘運算, 並得到矩陣乘法的 結果, 你必須在會話里啟動這個圖.
在一個會話中啟動圖
構造階段完成后, 才能啟動圖. 啟動圖的第一步是創建一個 Session
對象, 如果無任何創建參數, 會話構造器將啟動默認圖.
欲了解完整的會話 API, 請閱讀Session 類.
# 啟動默認圖. sess = tf.Session() # 調用 sess 的 'run()' 方法來執行矩陣乘法 op, 傳入 'product' 作為該方法的參數. # 上面提到, 'product' 代表了矩陣乘法 op 的輸出, 傳入它是向方法表明, 我們希望取回 # 矩陣乘法 op 的輸出. # # 整個執行過程是自動化的, 會話負責傳遞 op 所需的全部輸入. op 通常是並發執行的. # # 函數調用 'run(product)' 觸發了圖中三個 op (兩個常量 op 和一個矩陣乘法 op) 的執行. # # 返回值 'result' 是一個 numpy `ndarray` 對象. result = sess.run(product) print result # ==> [[ 12.]] # 任務完成, 關閉會話. sess.close()
Session
對象在使用完后需要關閉以釋放資源. 除了顯式調用 close 外, 也可以使用 "with" 代碼塊 來自動完成關閉動作.
with tf.Session() as sess: result = sess.run([product]) print result
在實現上, TensorFlow 將圖形定義轉換成分布式執行的操作, 以充分利用可用的計算資源(如 CPU 或 GPU). 一般你不需要顯式指定使用 CPU 還是 GPU, TensorFlow 能自動檢測. 如果檢測到 GPU, TensorFlow 會盡可能地利用找到的第一個 GPU 來執行操作.
如果機器上有超過一個可用的 GPU, 除第一個外的其它 GPU 默認是不參與計算的. 為了讓 TensorFlow 使用這些 GPU, 你必須將 op 明確指派給它們執行. with...Device
語句用來指派特定的 CPU 或 GPU 執行操作:
with tf.Session() as sess: with tf.device("/gpu:1"): matrix1 = tf.constant([[3., 3.]]) matrix2 = tf.constant([[2.],[2.]]) product = tf.matmul(matrix1, matrix2) ...
設備用字符串進行標識. 目前支持的設備包括:
"/cpu:0"
: 機器的 CPU."/gpu:0"
: 機器的第一個 GPU, 如果有的話."/gpu:1"
: 機器的第二個 GPU, 以此類推.
交互式使用
文檔中的 Python 示例使用一個會話 Session
來 啟動圖, 並調用 Session.run()
方法執行操作.
為了便於使用諸如 IPython 之類的 Python 交互環境, 可以使用 InteractiveSession
代替 Session
類, 使用 Tensor.eval()
和 Operation.run()
方法代替 Session.run()
. 這樣可以避免使用一個變量來持有會話.
# 進入一個交互式 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.]
Tensor
TensorFlow 程序使用 tensor 數據結構來代表所有的數據,計算圖中, 操作間傳遞的數據都是 tensor. 你可以把 TensorFlow tensor 看作是一個 n 維的數組或列表. 一個 tensor 包含一個靜態類型 rank, 和 一個 shape. 想了解 TensorFlow 是如何處理這些概念的, 參見 Rank, Shape, 和 Type.
變量
變量維護圖執行過程中的狀態信息。下面的例子演示了如何使用變量實現一個簡單的計數器。
# 創建一個變量, 初始化為標量 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 初始化, # 首先必須增加一個`初始化` op 到圖中. init_op = tf.initialize_all_variables() # 啟動圖, 運行 op with tf.Session() as sess: # 運行 'init' op sess.run(init_op) # 打印 'state' 的初始值 print sess.run(state) # 運行 op, 更新 'state', 並打印 'state' for _ in range(3): sess.run(update) print sess.run(state) # 輸出: # 0 # 1 # 2 # 3
代碼中 assign()
操作是圖所描繪的表達式的一部分, 正如 add()
操作一樣. 所以在調用 run()
執行表達式之前, 它並不會真正執行賦值操作.
通常會將一個統計模型中的參數表示為一組變量。例如, 你可以將一個神經網絡的權重作為某個變量存儲在一個 tensor 中。在訓練過程中, 通過重復運行訓練圖, 更新這個 tensor.
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)]
需要獲取的多個 tensor 值,在 op 的一次運行中一起獲得(而不是逐個去獲取 tensor)。
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()
操作將會產生錯誤。
接下來,將根據tf里的各個模塊來介紹函數,同時介紹一些相關函數背后的數學背景
TensorFlow app模塊
模塊:tf.app
定義在:tensorflow/python/platform/app.py
通用入口點腳本。
flags 模塊
flags 模塊:實現標志接口。
函數
run(...):使用可選的 “main” 函數和 “argv” 列表運行程序。
tf.app.run
run ( main = None , argv = None )定義在:tensorflow/python/platform/app.py
使用可選的 “main” 函數和 “argv” 列表運行程序。
會看到這么兩行代碼:
FLAGS, unparsed = parser.parse_known_args() tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)
第一行的含義是對運行命令行時傳進來的參數進行解析,如果傳進來的參數是之前被add到parser中的,則被傳給FLAGS,否則講傳給unpared。
如我們在運行程序時在后面加上了 --epoch 32 參數,如果這個參數之前被加入到parser中,則將parser中的epoch參數更改為32並傳誒FLAGS,否則 則將 --epoch 32寫入到unparsed中
為了了解第二行的含義,我們在/tensorflow/python/platform中找到app.py並打開。
# Copyright 2015 The TensorFlow Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== """Generic entry point script.""" from __future__ import absolute_import from __future__ import division from __future__ import print_function import sys as _sys from tensorflow.python.platform import flags from tensorflow.python.util.all_util import remove_undocumented def _benchmark_tests_can_log_memory(): return True def run(main=None, argv=None): """Runs the program with an optional 'main' function and 'argv' list.""" f = flags.FLAGS # Extract the args from the optional `argv` list. args = argv[1:] if argv else None # Parse the known flags from that list, or from the command # line otherwise. # pylint: disable=protected-access flags_passthrough = f._parse_flags(args=args) # pylint: enable=protected-access main = main or _sys.modules['__main__'].main # Call the main function, passing through any arguments # to the final program. _sys.exit(main(_sys.argv[:1] + flags_passthrough))
我們給這個方法傳遞了兩個參數,一個是要運行的主方法,另一個是:
argv=[sys.argv[0]] + unparsed
這個列表中儲存了我們要運行的程序的位置,以及沒有被parser匹配的參數。
help中寫道run()方法的用途是用argv列表運行一個可選的main方法。
下面的語句將沒有被parser匹配的參數放入argv中並且通過一個flags對象傳入要執行的函數中。
args = argv[1:] if argv else None flags_passthrough = f._parse_flags(args=args) main = main or _sys.modules['__main__'].main _sys.exit(main(_sys.argv[:1] + flags_passthrough))
如果我們傳入了一個函數名,則程序會去用沒有匹配的參數執行這個函數,否則,則會用沒有匹配的參數去執行__main__。
參考:http://blog.csdn.net/u013171318/article/details/73740818
tf.bitwise模塊
模塊:tf.bitwise
定義在:tensorflow/python/ops/bitwise_ops.py
用於操縱整數的二進制表示的操作。
函數
bitwise_and(...):元素計算 x 和 y 的按位與。
bitwise_or(...):元素計算 x 和 y 的按位或。
bitwise_xor(...):元素計算 x 和 y 的按位異或。
invert(...):翻轉所有位元素。
tf.bitwise.bitwise_and 元素按位與運算
bitwise_and ( x , y , name = None )元素計算 x 和 y 的按位與。
結果將設置那些在 x 和 y 中設置的位。對 x 和 y 的基礎表示進行計算。
ARGS:
- x:張量。必須是下列類型之一:int8,int16,int32,int64,uint8,uint16。
- y:張量。必須與 x 具有相同的類型。
- name:操作的名稱(可選)。
返回:
返回一個張量,與 x 具有相同的類型。
tf.bitwise.bitwise_or 元素按位或運算
bitwise_or ( x , y , name = None )元素計算 x 和 y 的按位或。
結果將設置那些在 x、y 或兩者中設置的位。對 x 和 y 的基礎表示進行計算。
ARGS:
- x:張量。必須是下列類型之一:int8,int16,int32,int64,uint8,uint16。
- y:張量。必須與 x 具有相同的類型。
- name:操作的名稱(可選)。
返回:
返回張量,與 x 具有相同的類型。
tf.bitwise.bitwise_xor 元素按位異或
bitwise_xor ( x , y , name = None )元素計算 x 和 y 的按位異或。
結果將設置位,在 x 和 y 中是不同的。對 x 和 y 的基礎表示進行計算。
ARGS:
- x:張量。必須是下列類型之一:int8,int16,int32,int64,uint8,uint16。
- y:張量。必須與 x 具有相同的類型。
- name:操作的名稱(可選)。
返回:
返回張量。與 x 具有相同的類型。
tf.bitwise.invert 所有位元素翻轉
invert ( x , name = None )翻轉所有位元素。
結果將准確地設置那些未在 x 中設置的位。計算是在 x 的基礎表示形式上執行的。
ARGS:
- x:張量。必須是下列類型之一:int8,int16,int32,int64,uint8,uint16。
- name:操作的名稱(可選)。
返回:
返回張量。與 x 具有相同的類型。
tf.compat模塊
TensorFlow Python / tf.compat
- 模塊:tf.compat
- tf.compat.as_bytes
- tf.compat.as_str_any
- tf.compat.as_text
tf.compat
定義在:tensorflow/python/util/compat.py
與 Python 2 和 3 具有兼容性的函數。
轉換例程
除了以下功能之外,as_str 將對象轉換為 str。
類型
兼容性模塊還提供以下類型:
- bytes_or_text_types
- complex_types
- integral_types
- real_types
功能
as_bytes(...):將字節或 unicode 轉換為 bytes,使用 UTF-8 編碼進行文本處理。
as_str(...):將字節或 unicode 轉換為 bytes,使用 UTF-8 編碼進行文本處理。
as_str_any(...):轉換 str 為 str(value),但 as_str 用於 bytes。
as_text(...):以 unicode 字符串的形式返回給定的參數。
其他成員
bytes_or_text_types
complex_types
integral_types
real_types
tf.compat.as_bytes
tf.compat.as_str
(字節和Unicode轉換)
tf.compat.as_str
as_bytes ( bytes_or_text , encoding = 'utf-8' )定義在:tensorflow/python/util/compat.py
將字節或 Unicode 轉換為 bytes,使用 UTF-8 編碼文本。
ARGS:
- bytes_or_text:bytes,str 或 unicode 對象。
- encoding:一個字符串,表示用於編碼 unicode 的字符集。
返回:
返回一個 bytes 對象。
注意:
- TypeError:當 bytes_or_text 不是二進制或 Unicode 字符串。
tf.compat.as_str_any 任何值轉化為str
as_str_any ( value )定義在:tensorflow/python/util/compat.py。
轉換 str 為 str(value),但 as_str 用於 bytes。
ARGS:
- value:可以轉換為 str 的對象。
返回:
返回一個 str 對象。
tf.compat.as_text 返回給定參數
as_text ( bytes_or_text , encoding = 'utf-8' )定義在:tensorflow/python/util/compat.py。
以 unicode 字符串形式返回給定的參數。
ARGS:
- bytes_or_text:一個 bytes,str 或 orunicode對象。
- encoding:一個字符串,表示用於解碼 unicode 的字符集。
返回:
A unicode(在 Python 2 中)或 str(在 Python 3 中)對象。
注意:
- TypeError:當 bytes_or_text 不是二進制或 unicode 字符串。
參考網站: https://www.w3cschool.cn/tensorflow_python/tensorflow_python-oaet2coo.html