TensorFlow使用圖 (graph) 來表示計算任務.
在被稱之為 會話 (Session) 的上下文 (context) 中執行圖.
使用張量(tensor) 表示數據.
通過變量 (Variable) 維護狀態.
使用feed和fetch可以為任意的操作(arbitrary operation) 賦值或者從其中獲取數據.
TensorFlow 是一個編程系統, 使用圖來表示計算任務. 圖中的節點被稱之為 op (operation 的縮寫). 一個 op 獲得 0 個或多個 Tensor, 執行計算, 產生 0 個或多個 Tensor
一個 TensorFlow 圖描述了計算的過程. 為了進行計算, 圖必須在 會話 里被啟動. 會話 將圖的 op 分發到諸如 CPU 或 GPU 之類的 設備 上, 同時提供執行 op 的方法. 這些方法執行后, 將產生的 tensor 返回. 在 Python 語言中, 返回的 tensor 是 numpy ndarray 對象; 在 C 和 C++ 語言中, 返回的 tensor 是 tensorflow::Tensor 實例.
計算圖
TensorFlow 程序通常被組織成一個構建階段和一個執行階段. 在構建階段, op 的執行步驟 被描述成一個圖. 在執行階段, 使用會話執行執行圖中的 op.
例如, 通常在構建階段創建一個圖來表示和訓練神經網絡, 然后在執行階段反復執行圖中的訓練 op.
TensorFlow 支持 C, C++, Python 編程語言. 目前, TensorFlow 的 Python 庫更加易用
構建圖
構建圖的第一步, 是創建源 op (source op). 源 op 不需要任何輸入, 例如 常量 (Constant). 源 op 的輸出被傳遞給其它 op 做運算.
Python 庫中, op 構造器的返回值代表被構造出的 op 的輸出, 這些返回值可以傳遞給其它 op 構造器作為輸入.
TensorFlow Python 庫有一個默認圖 (default graph), op 構造器可以為其增加節點. 這個默認圖對 許多程序來說已經足夠用了.
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 對象, 如果無任何創建參數, 會話構造器將啟動默認圖.
# 啟動默認圖.
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.]
生成constant(常量)
生成全0數組
# 語法:
tf.zeros(shape, dtype, name)
# 樣例:
tf.zeros([2, 3], int32) # ==> [[0, 0, 0], [0, 0, 0]]
生成一個與給定tensor類型、形狀一致的常量,其所有元素為0
# 語法:
tf.zeros_like(tensor, dtype, name)
# 樣例
a = tf.constant([[1, 2, 3], [4, 5, 6]] )
tf.zeros_like(a) # ==> [[0, 0, 0], [0, 0, 0]]
生成全1數組
# 語法:
tf.ones(shape, dtype, name)
# 樣例:
tf.ones([2, 3], int32) # ==> [[1, 1, 1], [1, 1, 1]]
生成一個與給定tensor類型、形狀一致的常量,其所有元素為1
# 語法:
tf.ones_like(tensor, dtype, name)
# 樣例:
a = tf.constant([[1, 2, 3], [4, 5, 6]])
tf.ones_like(a) # ==> [[1, 1, 1], [1, 1, 1]]
生成一個給定值的常量
# 語法:
tf.constant(value, dtype, shape, name)
# 樣例:
a = tf.constant([[1, 2, 3], [4, 5, 6]], int32)
# ==> [[1, 2, 3], [4, 5, 6]]
生成一個全部為給定數字的數組
# 語法:
tf.fill(dims, value, name)
# 樣例:
a = tf.fill([2, 3], 9) # ==> [[9, 9, 9], [9, 9, 9]]
變量
在TensorFlow中,變量(tf.Variable)用於保存,更新神經網絡的參數張量。
2.1 變量常見的屬性與方法
tf.constant是一個op(算子),而tf.Variable是一個類,用於實例化對象,然后用對象初始化多個op。變量常見的屬性與方法:
x = tf.Variable()
x.initializer # 初始化單個變量
x.value() # 讀取op
x.assign() # 寫入op
x.assign_add() # 更多op
x.eval() # 輸出變量內容
變量初始化
雖然在定義變量時,我們給出了變量初始化的方法,但這個方法並沒有被真正運行。一個變量的值在被使用之前,這個變量的初始化過程需要被明確地調用。
初始化全部變量
這個方法最簡單。通過tf.global_variables_initializer函數,我們就不需要將變量一個一個初始化了。
init = tf.global_variables_initializer()
# -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([1.0, 2.0, 3.0], shape=[3], name='a') b = tf.constant([1.0, 2.0, 3.0], shape=[3], name='b') c = a + b sess = tf.Session() print(sess.run(c)) hello = tf.constant("Hello, TensorFlow!") sess = tf.Session() print(sess.run(hello)) a = tf.constant(10) b = tf.constant(32) print(sess.run(a+b)) # 創建一個常量 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) with tf.Session() as sess: result2 = sess.run(product) print(result2) # 創建一個變量, 初始化為標量 0. state = tf.Variable(0, name='counter') # 創建一個 op, 其作用是使 state 增加 1 one = tf.constant(1) # 定義加法步驟 (注: 此步並沒有直接計算) new_value = tf.add(state, one) # 將 State 更新成 new_value update = tf.assign(state, new_value) # 變量Variable需要初始化並激活,並且打印的話只能通過sess.run(): # 啟動圖后, 變量必須先經過`初始化` (init) op 初始化, # 首先必須增加一個`初始化` op 到圖中. init = tf.global_variables_initializer() # 啟動圖, 運行 op, 使用 Session 計算 with tf.Session() as sess: # 運行 'init' op sess.run(init) # fetch打印 'state' 的初始值 print(sess.run(state)) # 運行 op, 更新 'state', 並打印 'state' for _ in range(3): sess.run(update) print(sess.run(state)) input1 = tf.constant(3.0) input2 = tf.constant(2.0) input3 = tf.constant(5.0) intermed = tf.add(input2, input3) mul = tf.multiply(input1, intermed) with tf.Session() as sess: # fetch獲取多個 tensor 值,在 op 的一次運行中一起獲得(而不是逐個去獲取 tensor) result = sess.run([mul, intermed]) print("result:", result) #result: [21.0, 7.0] #Feed #feed 使用一個 tensor 值臨時替換一個操作的輸出結果. 你可以提供 feed 數據作為 run() 調用的參數. #feed 只在調用它的方法內有效, 方法結束, feed 就會消失. 最常見的用例是將某些特殊的操作指定為 # "feed" 操作, 標記的方法是使用 tf.placeholder() 為這些操作創建占位符. # 如果要傳入值,用tensorflow的占位符,暫時存儲變量, # 以這種形式feed數據:sess.run(***, feed_dict={input: **}) #在 Tensorflow 中需要定義 placeholder 的 type ,一般為 float32 形式 input1 = tf.placeholder(tf.float32) input2 = tf.placeholder(tf.float32) # mul = multiply 是將input1和input2 做乘法運算,並輸出為 output ouput = tf.multiply(input1, input2) with tf.Session() as sess: print(sess.run(ouput, feed_dict={input1: [7], input2: [2]})) # 輸出[ 14.] #用Tensorflow計算a=(b+c)*(c+2) # 首先,創建一個TensorFlow常量=>2 const = tf.constant(2.0, name='const') # 創建TensorFlow變量b和c b = tf.Variable(2.0, name='b') #Tensorflow可以自動進行數據類型檢測,比如:賦值2.0就默認為tf.float32,但最好還是顯式地定義。 c = tf.Variable(1.0, dtype=tf.float32, name='c') # 創建operation #在TensorFlow中,+−×÷都有其特殊的函數表示。實際上,TensorFlow定義了足夠多的函數來表示所有的數學運算, #當然也對部分數學運算進行了運算符重載,但保險起見,我還是建議你使用函數代替運算符。 d = tf.add(b, c, name='d') e = tf.add(c, const, name='e') a = tf.multiply(d, e, name='a') init_op = tf.global_variables_initializer() #運行graph需要先調用tf.Session()函數創建一個會話(session)。session就是我們與graph交互的handle。 # session with tf.Session() as sess: # 2. 運行init operation sess.run(init_op) # 計算 a_out = sess.run(a) print("Variable a is {}".format(a_out))
D:\python>python tt.py
[2. 4. 6.]
b'Hello, TensorFlow!'
42
[[12]]
0
1
2
3
result: [21.0, 7.0]
[14.]
Variable a is 9.0
import numpy as np import pandas as pd import tensorflow as tf def main(): testNormal() testPlaceholder() testPlaceholder1() def testNormal(): mylist = [2, 4, 6, 8] sq = tf.square(mylist) sess = tf.Session() result = sess.run(sq) print(result) # [ 4 16 36 64] def testPlaceholder1(): input1 = tf.placeholder(tf.float32) input2 = tf.placeholder(tf.float32) output = tf.multiply(input1, input2) with tf.Session() as sess: print(sess.run([output], feed_dict={input1:7., input2:2.})) print(sess.run([output], feed_dict={input1:[7.], input2:[2.]})) #A Simple TensorFlow example #用Tensorflow計算a=(b+c)∗(c+2) def testPlaceholder(): #1. 定義數據: # 首先,創建一個TensorFlow常量=>2 const = tf.constant(2.0, name='const') # 創建TensorFlow變量b和c #b = tf.Variable(2.0, name='b') # 創建placeholder b = tf.placeholder(tf.float32, [None, 1], name='b') c = tf.Variable(1.0, dtype=tf.float32, name='c') #2. 定義運算(也稱TensorFlow operation): d = tf.add(b, c, name='d') e = tf.add(c, const, name='e') a = tf.multiply(d, e, name='a') #TensorFlow中所有的變量必須經過初始化才能使用,初始化方式分兩步: #<1. 定義初始化operation init_op = tf.global_variables_initializer() # session with tf.Session() as sess: #<2. 運行init operation sess.run(init_op) # 計算 #a_out = sess.run(a) a_out = sess.run(a, feed_dict={b: np.arange(0, 10)[:, np.newaxis]}) print("Variable a is {}".format(a_out)) if __name__ == '__main__': main()
[ 4 16 36 64]
Variable a is [[ 3.]
[ 6.]
[ 9.]
[12.]
[15.]
[18.]
[21.]
[24.]
[27.]
[30.]]
[14.0]
[array([14.], dtype=float32)]
# 算術操作符:+ - * / %
tf.add(x, y, name=None) # 加法(支持 broadcasting)
tf.subtract(x, y, name=None) # 減法
tf.multiply(x, y, name=None) # 乘法
tf.divide(x, y, name=None) # 浮點除法, 返回浮點數(python3 除法)
tf.mod(x, y, name=None) # 取余
# 冪指對數操作符:^ ^2 ^0.5 e^ ln
tf.pow(x, y, name=None) # 冪次方
tf.square(x, name=None) # 平方
tf.sqrt(x, name=None) # 開根號,必須傳入浮點數或復數
tf.exp(x, name=None) # 計算 e 的次方
tf.log(x, name=None) # 以 e 為底,必須傳入浮點數或復數
# 取符號、負、倒數、絕對值、近似、兩數中較大/小的
tf.negative(x, name=None) # 取負(y = -x).
tf.sign(x, name=None) # 返回 x 的符號
tf.reciprocal(x, name=None) # 取倒數
tf.abs(x, name=None) # 求絕對值
tf.round(x, name=None) # 四舍五入
tf.ceil(x, name=None) # 向上取整
tf.floor(x, name=None) # 向下取整
tf.rint(x, name=None) # 取最接近的整數
tf.maximum(x, y, name=None) # 返回兩tensor中的最大值 (x > y ? x : y)
tf.minimum(x, y, name=None) # 返回兩tensor中的最小值 (x < y ? x : y)
# 三角函數和反三角函數
tf.cos(x, name=None)
tf.sin(x, name=None)
tf.tan(x, name=None)
tf.acos(x, name=None)
tf.asin(x, name=None)
tf.atan(x, name=None)
# 其它
tf.div(x, y, name=None) # python 2.7 除法, x/y-->int or x/float(y)-->float
tf.truediv(x, y, name=None) # python 3 除法, x/y-->float
tf.floordiv(x, y, name=None) # python 3 除法, x//y-->int
tf.realdiv(x, y, name=None)
tf.truncatediv(x, y, name=None)
tf.floor_div(x, y, name=None)
tf.truncatemod(x, y, name=None)
tf.floormod(x, y, name=None)
tf.cross(x, y, name=None)
tf.add_n(inputs, name=None) # inputs: A list of Tensor objects, each with same shape and type
tf.squared_difference(x, y, name=None)
