TensorFlow官方教程學習筆記(一)——起步
阿新 • • 發佈:2019-01-30
TensorFlow可以拆成兩個詞:Tensor(張量)和Flow(流),Tensor代表最底層的資料結構,每一個Tensor可以簡易的理解為一個多維陣列,類似於Caffe中的Blob,不過與Blob不同的是,對於一張圖片,Tensor的四個維度分別是[batch, height, width, channel](Blob的為[batch, channel, height, width])。Tensor存在於節點op(operation)中,op執行計算功能,值得注意的是,Tensor並不真正具有op的輸出值(it does not hold the values of that operation's output),它只是代表了這個op操作的返回值,它也可以作為另外一個op的輸入。一個Tensor可以在多個op中流動(Flow),這樣就組成了一個圖(Graph),當圖構建好之後,上下文(context)就會啟動一個會話(session)來執行圖中的op,這時Tensor的值才被計算出來。
建立一個預設圖(default graph):
g = tf.Gragh()
with = g.as_default():
它與以下程式碼是等效的:
with tf.Graph().as_default() as g:
這樣context就建立了一個預設圖。
建立好一個預設圖後,就可以通過插入op來構建圖:
這裡插入了兩種型別的op:constant和matmul(常量和矩陣相乘),matrix1、matrix2和product代表op返回值的Tensor。g = tf.Gragh() with = g.as_default(): matrix1 = tf.constant([[3., 3.]]) matrix2 = tf.constant([[2.],[2.]]) product = tf.matmul(matrix1, matrix2)
插入op的方式有很多種,如:
tf.Operation.name #The full name of this operation. tf.Operation.type #The type of the op (e.g. "MatMul"). tf.Operation.inputs #The list of Tensor objects representing the data inputs of this op.
建立好圖後,需要建立一個session來啟動這個圖,例如上面程式碼中,只有在session中啟動這個圖才能真正的進行矩陣相乘的運算,並得到結果:
g = tf.Gragh()
with = g.as_default():
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
product = tf.matmul(matrix1, matrix2)
sess = tf.Session() #Construct a `Session` to execut the graph.
result = sess.run(product) #Execute the graph and store the value that `product` represents in `result`.
print result
sess.close() #Close the Session.
sess.run(product)觸發了三個op的執行,返回值 'result' 是一個 numpy `ndarray` 物件。也可以使用以下程式碼來啟動圖:
with tf.Session() as sess:
result = sess.run(product)
print result
這樣就可以在會話結束後自動的關閉會話而不需要呼叫close()。
除了sess.run(product)來執行op操作以外,用Tensor的操作product.eval()也可以表達同樣的效果。對於Tensor的操作有很多種,如:
tf.Tensor.dtype #The DType of elements in this tensor.
tf.Tensor.name #The string name of this tensor.
tf.Tensor.eval(feed_dict=None, session=None) #Evaluates this tensor in a Session.
tf.Tensor.get_shape() #Returns the TensorShape that represents the shape of this tensor.
tf.Tensor.set_shape(shape) #Updates the shape of this tensor.
在計算圖時,還可以使用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)
...
這麼多個with,可以把它們合到一起,表達一個完整的計算圖的過程:
g = tf.Graph()
with g.as_default(), g.device('/gpu:1'), tf.Session() as sess:
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
product = tf.matmul(matrix1, matrix2)
result = sess.run(product)
print result
在TensorFlow中還有一個重要的成員:變數(Variable)在官方文件中,對變數的說明很簡單:變數維護圖執行過程中的狀態資訊。這可能不太好理解,我的個人理解是,變數實際上就是通過不斷的迭代來更新它的值,最終來滿足模型的條件。一個簡單的例子:
# 建立一個變數, 初始化為標量 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
變數存在於記憶體的快取區,它與Tensor是包含的關係,變數在建立之後,必須被顯式的初始化。tf.initialize_all_variables()就是將所有變數初始化的op操作。在session建立之後,需要執行這個op操作。
在整個session執行完之後,可以將變數save,在這之前你需要使用tf.train.Saver()建立一個saver。
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add an op to initialize the variables.
init_op = tf.initialize_all_variables()
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, initialize the variables, do some work, save the
# variables to disk.
with tf.Session() as sess:
sess.run(init_op)
# Do some work with the model.
..
# Save the variables to disk.
save_path = saver.save(sess, "/tmp/model.ckpt")
print "Model saved in file: ", save_path
你也可以對一個已存有的變數進行restore,這裡不需要再進行初始化:
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, use the saver to restore variables from disk, and
# do some work with the model.
with tf.Session() as sess:
# Restore variables from disk.
saver.restore(sess, "/tmp/model.ckpt")
print "Model restored."
# Do some work with the model
...
當然你也可以選擇某一個變數進行儲存:
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add ops to save and restore only 'v2' using the name "my_v2"
saver = tf.train.Saver({"my_v2": v2})
# Use the saver object normally after that.
...
在Tensor的操作中有一個很重要的機制:feed,它實際上起著替換的作用,常常用來為run()、eval()中的Tensor提供資料,不過前提是這個需要為這些Tensor建立佔位符:tf.placeholder()。具體的使用方法如下:
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.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_dict的作用就是將[7.]傳遞給input1,將[2.]傳遞給input2,從而來進行run()的操作。
值得注意的是,如果你使用tf.placeholder()建立了佔位符,而並沒有正確的為它提供feed,將會產生很嚴重的錯誤。