Input 數據種類
tf.Variable
通常用在model 中需要不斷更新的變數,像是需要training 的weights 或是在LSTM中不用training 但需更新的memory。Creation :
宣告範例如下:w = tf.Variable(<value>, name=<optional-name>)
name是變數的名稱,可加可不加
value 為要輸入的數據,格式為tensor。
以上只是宣告,但數據還沒有初始化。
初始化:
開始run data 前,必須先初始variable 裡的data。初始的方法我用過兩個,其中一個就是呼tensorflow 內建的 function " tf.global_variables_initializer() " 直接初始化。ex:
with tf.Session() as session:
tf.global_variables_initializer().run()
........
另一個方法是讀取之前儲存的model 參數:
ex:
saver = tf.train.Saver()
saved_file_path = "...saved model path..."
with tf.Session() as sess:
# Restore variables from disk.
ckpt = tf.train.get_checkpoint_state(saved_file_path)
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess,ckpt.model_checkpoint_path)
tf.Placeholder:
這種型態數據,在run data 時,必須手動餵數據給他。通常用在model 裡的input data.
tf.placeholder(dtype, shape=None, name=None)
dtype :數據格式
shape: 數據維度
feed data:
在呼session run 時,必須給data 給他,範例如下:x = tf.placeholder(tf.float32, shape=(1024, 1024))
y = tf.matmul(x, x)
with tf.Session() as sess:
rand_array = np.random.rand(1024, 1024)
print(sess.run(y, feed_dict={x: rand_array}))
#or using eval()
print(y.eval(feed_dict={x: rand_array}))
數據輸入feed_dict 是以dict 的格式輸入,dict 的名子為placeholder 的變數名稱
print(y.eval(feed_dict={x: rand_array}))
tf.Constant
宣告的同時,就必須給輸入的數據,並且之後無法再做更動
tf.constant(value, dtype=None, shape=None, name='Const')
value : 輸入的數據,格式可以是scalar 或是tensor。也可以用numpy 的matrix 輸入
ex.
import numpy as np
import random
import tensorflow as tf
def twoD_array_random(dim0,dim1):
assert dim0 > 0, 'dim0 need > 0'
assert dim1 > 0, 'dim0 need > 0'
b = np.random.uniform(-0.1 , 0.1, size=[dim0, dim1])
return b
np_ix = twoD_array_random(5,5)
sess = tf.InteractiveSession()
ix = tf.constant(np_ix)
print (ix.eval())
sess.close()
DeBug 技巧
因為tensorflow 運作邏輯是先把所有data flow 路徑先定義好形成"graph"之後再呼session function 跑實際數據。所以寫graph 的當下想要確認某個data flow 節點跑出來的數據是否正確。必須呼叫session function,然後將節點加上.eval() tensorflow 才會跑出數據結果。 直接print 是映不出來的,以下為範例:
sess = tf.InteractiveSession() inp = tf.constant(np_input) xx = tf.constant(np_conca_x) mm = tf.constant(np_conca_m) bb = tf.constant(np_conca_b) saved_output = tf.constant(np_saved_output) saved_state = tf.constant(np_saved_state) temp = tf.matmul(inp, xx) + tf.matmul(saved_output, mm) + bb i_gate,f_gate,update,o_gate = tf.split(temp,num_or_size_splits=4,axis=1) saved_state = saved_state * tf.sigmoid(f_gate) + tf.sigmoid(i_gate) *tf.tanh(update) saved_output = tf.tanh(saved_state) * tf.sigmoid(o_gate) print (saved_state.eval()) print (saved_output.eval()) sess.close()
在debug 時,可以在最前面用"sess = tf.InteractiveSession()" 呼叫session,如範例中我想要知道最後save_state saved_output 的數據結果,在後面加上"eval",去跑數據再print 即可。如果data input 的形式是constant,eval function 不必加任何參數。但如果是placeholder,因為數據是你要餵給電腦,eval 內必須給feed_dict 來源( y.eval(feed_dict={x: rand_array}) 。
Gradient update for Optimizer
再tensorflow 中,loss function 的最佳化是call optimizer fuction。optimizer function 有很多種不同演算法,這邊用GradientDescent 當作範例:
ex1.
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)
這是比較簡單的方法,直接將gradient 直接對變數做更新。如果需要對gradient 做而外的處理
可以用下面的例子
ex2:
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
gradients, v = zip(*optimizer.compute_gradients(loss)) #split gradient and variable
gradients, _ = tf.clip_by_global_norm(gradients, 1.25) #control gradient to avoid gradients vanishing
optimizer = optimizer.apply_gradients(zip(gradients, v), global_step=global_step)
上面是LSTM的例子,因為怕gradient 太大,所以gradient 計算出來後不直接update,而是用f.clip_by_global_norm 處理,讓gradient 限制再一定大小之下,最後在update 到parameter 上。
其餘function 使用
split
將tensor 分割成多的tensor
split(value, num_or_size_splits, axis=0,num=None, name='split')
value : 要分割的tensor
num_or_size_splits: 如果為scalar,"num",表示平均分割出來的tensors 數量。如果為tensors,"size_splits",表示輸出 tensors 的size 大小
axis : 要執行分割的dimension
# 'value' is a tensor with shape [5, 30]
# Split 'value' into 3 tensors with sizes [4, 15, 11] along dimension 1
split0, split1, split2 = tf.split(value, [4, 15, 11], 1)
tf.shape(split0) ==> [5, 4]
tf.shape(split1) ==> [5, 15]
tf.shape(split2) ==> [5, 11]
# Split 'value' into 3 tensors along dimension 1
split0, split1, split2 = tf.split(value, num_or_size_splits=3, axis=1)
tf.shape(split0) ==> [5, 10]
concat
將tensors 結合成一個tensor
tf.concat(values,axis,name='concat')
values: list of tensors (以list 格式輸入多個tensors)
axis: 執行合併的dimension
example:
# tensor1, tensor2, tensor3 with shape [5, 4], [5, 15], [5, 11]
tensor = tf.concat([ tensor1 , tensor2, tensor3], axis=1)
tf.shape(tensor)==>[5, 30]