tensorflow學習筆記(2)張量與計算圖
TensorFlow簡介:
官網上對TensorFlow的介紹是,一個使用資料流圖(data flow graphs)技術來進行數值計算的開源軟體庫。資料流圖中的節點,代表數值運算;節點節點之間的邊,代表多維資料(tensors)之間的某種聯絡。我們可以在多種裝置(含有CPU或GPU)上通過簡單的API呼叫來使用該系統的功能。
TensorFlow包含構建資料流圖與計算資料流圖等基本步驟,圖中的節點表示數學操作,圖中連結各節點的邊表示多維陣列,即:tensors(張量)。 張量是TensorFlow最核心的元件,所有運算和優化都是基於張量進行的。張量是基於向量和矩陣的推廣,可以將標量看為零階張量,向量看做一階張量,矩陣看做二階張量(後面詳細介紹)。
資料流圖是描述有向圖中的數值計算過程。有向圖中的節點通常代表數學運算,但也可以表示資料的輸入、輸出和讀寫等操作;有向圖中的邊表示節點之間的某種聯絡,它負責傳輸多維資料(Tensors)。圖中這些tensors的flow也就是TensorFlow的命名來源。
基本使用:
-
將計算流程表示成圖;
-
通過Sessions來執行圖計算;
-
將資料表示為tensors;
-
使用Variables來保持狀態資訊;
-
分別使用feeds和fetches來填充資料和抓取任意的操作結果;
TensorFlow初識,簡單例項
上面程式碼中,首先匯入TensorFlow,然後tf.placeholder("float")定義a和b兩個浮點型別的變數,tf.multiply(a,b)表示兩個變數相乘操作,常用的算術還有: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}))
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.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 |
為了抓取輸出結果,在執行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 |
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