1. 程式人生 > >tensorflow學習筆記(2)張量與計算圖

tensorflow學習筆記(2)張量與計算圖

TensorFlow簡介:

官網上對TensorFlow的介紹是,一個使用資料流圖(data flow graphs)技術來進行數值計算的開源軟體庫。資料流圖中的節點,代表數值運算;節點節點之間的邊,代表多維資料(tensors)之間的某種聯絡。我們可以在多種裝置(含有CPU或GPU)上通過簡單的API呼叫來使用該系統的功能。

TensorFlow包含構建資料流圖與計算資料流圖等基本步驟,圖中的節點表示數學操作,圖中連結各節點的邊表示多維陣列,即:tensors(張量) 張量是TensorFlow最核心的元件,所有運算和優化都是基於張量進行的。張量是基於向量和矩陣的推廣,可以將標量看為零階張量,向量看做一階張量,矩陣看做二階張量(後面詳細介紹)。

資料流圖是描述有向圖中的數值計算過程。有向圖中的節點通常代表數學運算,但也可以表示資料的輸入、輸出和讀寫等操作;有向圖中的邊表示節點之間的某種聯絡,它負責傳輸多維資料(Tensors)。圖中這些tensors的flow也就是TensorFlow的命名來源。

基本使用:

  • 將計算流程表示成圖;

  • 通過Sessions來執行圖計算;

  • 將資料表示為tensors;

  • 使用Variables來保持狀態資訊;

  • 分別使用feeds和fetches來填充資料和抓取任意的操作結果;

TensorFlow初識,簡單例項   

import tensorflow as tf
a =tf.placeholder("float")
b =tf.placeholder("float")
y = tf.multiply(a,b)
sess = tf.Session()
print(sess.run(y, feed_dict={a: 3, b: 3}))
上面程式碼中,首先匯入TensorFlow,然後tf.placeholder("float")定義a和b兩個浮點型別的變數,tf.multiply(a,b)表示兩個變數相乘操作,常用的算術還有:
Operation Description
tf.add sum
tf.subtract substraction
tf.multiply multiplication
tf.div division
tf.mod module
tf.abs return the absolute value
tf.neg return negative value
tf.sign return the sign
tf.inv returns the inverse
tf.square calculates the square
tf.round returns the nearest integer
tf.sqrt calculates the square root
tf.pow calculates the power
tf.exp calculates the exponential
tf.log calculates the logarithm
tf.maximum returns the maximum
tf.minimum returns the minimum
tf.cos calculates the cosine
tf.sin calculates the sine
如果兩種不同型別計算時會報錯,需要tf.cast()轉換型別,例如:
tf.subtract(tf.constant(3.0),tf.constant(1)) 
"""
TypeError: Input 'y' of 'Sub' Op has type int32 that does not 
match type float32 of argument 'x'.
"""

上面程式碼需改為:

tf.subtract(tf.cast(tf.constant(3.0), tf.int32), tf.constant(1))

另外,還會用到的矩陣計算方法:

Operation Description
tf.diag returns a diagonal tensor with a given diagonal values
tf.transpose returns the transposes of the argument
tf.matmul returns a tensor product of multiplying two tensors listed as arguments
tf.matrix_determinant returns the determinant of the square matrix specified as an argument
tf.matrix_inverse returns the inverse of the square matrix specified as an argument
接下來 tf.Session()語句表示建立一個session,這是最重要的一步,它用來計算生成的符號表達式。到這一步TensorFlow程式碼還沒有真正被執行, 而呼叫run()方法後演算法才真正被執行。可以看出,TensorFlow既是一個表示機器學習演算法的介面,又是對機器學習演算法的實現。

為了抓取輸出結果,在執行session的run函式後,通過print函式列印狀態資訊。

填充(Feeds):
TensorFlow提供的機制:先建立特定資料型別的佔位符(placeholder),之後再進行資料的填充("feed_dict=  ");如果不對placeholder()的變數進行資料填充,將會引發錯誤。

基本資料型別:

資料型別 Python 型別 描述
DT_FLOAT tf.float32 32 位浮點數.
DT_DOUBLE tf.float64 64 位浮點數.
DT_INT64 tf.int64 64 位有符號整型.
DT_INT32 tf.int32 32 位有符號整型.
DT_INT16 tf.int16 16 位有符號整型.
DT_INT8 tf.int8 8 位有符號整型.
DT_UINT8 tf.uint8 8 位無符號整型.
DT_STRING tf.string 可變長度的位元組陣列.每一個張量元素都是一個位元組陣列.
DT_BOOL tf.bool 布林型.
DT_COMPLEX64 tf.complex64 由兩個32位浮點陣列成的複數:實數和虛數.
DT_QINT32 tf.qint32 用於量化Ops的32位有符號整型.
DT_QINT8 tf.qint8 用於量化Ops的8位有符號整型.
DT_QUINT8 tf.quint8 用於量化Ops的8位無符號整型.

張量的階

TensorFlow用張量表示所有的資料,張量可看成一個n維的陣列或列表,在圖中的節點之間流通。張量的維數稱為,注:張量的階和矩陣的階不是同一個概念。下面的張量(使用Python的list定義)是2階:

  t = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
數學例項 Python 例子
0 純量 (只有大小) s = 1
1 向量(大小和方向) v = [1, 2, 3]
2 矩陣(資料表) m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
3 3階張量 (資料立體) t = [[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]]
n n階  ....

張量的形狀

TensorFlow使用三種記號描述張量的維度:階,形狀及維數,它們之間的關係:
形狀 維數 例項
0 [ ] 0-D 一個 0維張量. 一個純量.
1 [D0] 1-D 一個1維張量的形式[5].
2 [D0, D1] 2-D 一個2維張量的形式[3, 4].
3 [D0, D1, D2] 3-D 一個3維張量的形式 [1, 4, 3].
n [D0, D1, ... Dn] n-D 一個n維張量的形式 [D0, D1, ... Dn].

張量的一些常用操作:

Operation Description
tf.shape To find a shape of a tensor
tf.size To find the size of a tensor
tf.rank To find a rank of a tensor
tf.reshape To change the shape of a tensor keeping the same elements contained
tf.squeeze To delete in a tensor dimensions of size 1
tf.expand_dims To insert a dimension to a tensor 
tf.slice To remove a portions of a tensor
tf.split To divide a tensor into several tensors along one dimension
tf.tile To create a new tensor replicating a tensor multiple times
tf.concat To concatenate tensors in one dimension
tf.reverse To reverse a specific dimension of a tensor
tf.transpose To transpose dimensions in a tensor
tf.gather To collect portions according to an index
例如,將一個2維張量擴充套件為3維:
vectors = tf.constant(conjunto_puntos)
extended_vectors = tf.expand_dims(vectors, 0)
print (expanded_vectors.get_shape())
執行上面這句,可以得到擴充套件後張量的維度。

TensorFlow計算圖:

有了張量和基於張量的各種操作,之後需要將各種操作整合起來,輸出結果。但不幸的是,隨著操作種類和數量的增多,有可能引發各種意想不到的問題,包括多個操作之間應該並行還是順次執行,如何協同各種不同的底層裝置,以及如何避免各種型別的冗餘操作等等。這些問題有可能拉低整個深度學習網路的執行效率或者引入不必要的Bug,計算圖正是為解決這一問題產生的。

論文《Learning Deep Architectures for AI》作者用不同的佔位符(*,+,sin)構成操作結點,以字母x、a、b構成變數結點,以有向線段將這些結點連線起來,組成一個表徵運算邏輯關係的清晰明瞭的“圖”型資料結構,這就是最初的計算圖。


計算圖的引入可以讓開發者從巨集觀上俯瞰整個神經網路的內部結構,就好像編譯器可以從整個程式碼的角度決定如何分配暫存器那樣,計算圖也可以從巨集觀上決定程式碼執行時的GPU記憶體分配,以及分散式環境中不同底層裝置間的相互協作方式。除此之外,現在也有許多深度學習框架將計算圖應用於模型除錯,可以實時輸出當前某一操作型別的文字描述。

例項1:

node1 = tf.constant(3.0, dtype=tf.float32)
node2 = tf.constant(4.0) # also tf.float32 implicitly
print(node1, node2)
node1和node2是constant,常量不可改變,其輸出結果:
Tensor("Const_2:0", shape=(), dtype=float32) Tensor("Const_3:0", shape=(), dtype=float32)
上面並沒有直接輸出3.0和4.0,而是輸出可以生成3.0和4.0的兩個張量,如果想要得到3.0和4.0,需要上面介紹的session和run操作:
sess = tf.Session()
print(sess.run([node1, node2]))
計算圖是將節點列到一個圖中的一系列操作,其輸入是節點(nodes),輸出也是node。或者更復雜一點,操作也是node:

例項2:

node3 = tf.add(node1, node2)
print("node3:", node3)
print("sess.run(node3):", sess.run(node3))
輸出結果為:
node3: Tensor("Add_1:0", shape=(), dtype=float32)
sess.run(node3): 7.0

為了使演算法容易理解,TensorFlow中的視覺化工具Tensorboard包含了一些debug函式與優化程式,可以察看不同型別的引數統計結果與圖中的計算細節(這部分以後參照例項學習一下)。

例項3:

輸入可以是任意量,例如構建模型:y=w*x+b,w和b一定時,x是可變數:

W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
x = tf.placeholder(tf.float32)
linear_model = W*x + b
W和b是Variable,執行上面的語句,W和b並沒有被初始化,如果執行程式,需要下面的初始化語句:
init = tf.global_variables_initializer()
完整例項如下:
import tensorflow as tf
W = tf.Variable([.5], dtype=tf.float32)
b = tf.Variable([-.5], dtype=tf.float32)
x = tf.placeholder(tf.float32)
linear_model = W*x + b
#print("linear_model:",linear_model)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print(sess.run(linear_model, {x: [1, 2, 3, 4]}))
輸出結果為:[ 0.   0.5  1.   1.5]

例項4:

import tensorflow as tf

W = tf.Variable(1)
assign_W = W.assign(10)#修改變數方法,assign
with tf.Session() as sess:
    sess.run(W.initializer)
    print(W.eval())
    sess.run(assign_W)
    print(W.eval())
assign只是一個函式,並且不需要初始化,但是assign_add()和assign_sub()需要初始化。
import tensorflow as tf

W = tf.Variable(10)
sess1 = tf.Session()
sess2 = tf.Session()
sess1.run(W.initializer)
sess2.run(W.initializer)
print('W add 1=',sess1.run(W.assign_add(1)))
print('W sun 2=',sess2.run(W.assign_sub(2)))
sess1.close()
sess2.close()

參考:

https://www.tensorflow.org/get_started/get_started

http://jorditorres.org/research-teaching/tensorflow/first-contact-with-tensorflow-book/first-contact-with-tensorflow/#cap1

http://blog.csdn.net/liyuqian199695/article/details/61647946

http://wiki.jikexueyuan.com/project/tensorflow-zh/resources/dims_types.html