學習網址:Tensorflow中文社區 http://www.tensorfly.cn/
一、tensorflow框架筆記
1.Variable
一個Variable
代表一個可修改的張量,存在在TensorFlow的用於描述交互性操作的圖中。它們可以用於計算輸入值,也可以在計算中被修改。對於各種機器學習應用,一般都會有模型參數,如w、b,可以用Variable
表示。
2. session
Tensorflow依賴於一個高效的C++後端來進行計算。與後端的這個連接叫做session。
3.InteractiveSession
InteractiveSession
類,它能讓你在運行圖的時候,插入一些計算圖,這些計算圖是由某些操作(operations)構成的。
爲了便於使用諸如 IPython 之類的 Python 交互環境, 可以使用 InteractiveSession
代替 Session
類,用Tensor.eval()
和 Operation.run()
方法代替 Session.run()
. 這樣可以避免使用一個變量來持有會話.
4. RNN
- BasicRNNCell - 香草RNN細胞。
- GRUCell- 門控復發單元。
- BasicLSTMCell- 基於遞歸神經網絡正則化的LSTM單元。沒有窺視孔連接或細胞剪切。
- LSTMCell - 一個更復雜的LSTM細胞,允許可選的窺視孔連接和細胞剪切。
- MultiRNNCell - 將多個單元格組合成多層單元格的包裝器。
- DropoutWrapper - 一個包裝添加到單元格的輸入和/或輸出連接丟失。
- CoupledInputForgetGateLSTMCell- LSTMCell基於LSTM:搜索空間奧德賽的輸入和忘記門的擴展。
- TimeFreqLSTMCell - 基於建模時頻模式的時頻LSTM單元與LSTM與卷積結構的LVCSR任務
- GridLSTMCell - 來自網格長期短期記憶的單元格。
- AttentionCellWrapper- 將注意力集中在基於長期短期記憶網絡的機器閱讀的現有RNN小區上。
- LSTMBlockCell- 一個更快的基本LSTM單元版本(注意:這個是在lstm_ops.py)
5. tf.nn.xw_plus_b()函數
相當於:tf.matmul(x, weights) + biases
tf.nn.xw_plus_b(
x,
weights,
biases,
name=None
)
- x:2D Tensor。維度通常爲:batch,in_units
- weights:2D Tensor。維度通常爲:in_units,out_units
- biases:1D Tensor。維度爲:out_units
- name:操作的名稱(可選)。如果未指定,則使用“xw_plus_b”。
6. 常用CNN
(1)tf.nn.atrous_conv2d()空洞卷積或者擴張卷積
如何理解空洞卷積(dilated convolution)?
其實用一句話概括就是:在不用pooling的情況下擴大感受野(pooling層會導致信息損失)
7. 區別
普通會話:
sess = tf.Session()
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
交互式會話:
sess = tf.InteractiveSession()
# Operation.run()
train_step.run(feed_dict={x: batch[0], y_: batch[1]})
# Tensor.eval()
accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels})
8. dropout--tf.placeholder()
用一個placeholder
來代表一個神經元的輸出在dropout中保持不變的概率。這樣我們可以在訓練過程中啓用dropout,在測試過程中關閉dropout。
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
9.feed_dict
中加入額外的參數keep_prob
來控制dropout比例
for i in range(20000):
batch = mnist.train.next_batch(50)
# 每100輪,檢測下精度:測試過程中關閉dropout
if i%100 == 0:
train_accuracy = accuracy.eval(feed_dict={
x:batch[0], y_: batch[1], keep_prob: 1.0})
print("step %d, training accuracy %g"%(i, train_accuracy))
train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5}) # 訓練過程中啓用dropout
# 訓練過程中關閉dropout
print("test accuracy %g"%accuracy.eval(feed_dict={
x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
10.tensorflow.compat.v1
TensorFlow 2.0中提供了tensorflow.compat.v1代碼包來兼容原有1.x的代碼,可以做到幾乎不加修改的運行。 TensorFlow 2.0中提供了命令行遷移工具,來自動的把1.x的代碼轉換爲2.0的代碼。
參考:https://cloud.tencent.com/developer/article/1414830
11. 保存檢查點(checkpoint):加載、恢復模型
爲了得到可以用來後續恢復模型以進一步訓練或評估的檢查點文件(checkpoint file),我們實例化一個tf.train.Saver
。
saver = tf.train.Saver()
在訓練循環中,將定期調用saver.save()
方法,向訓練文件夾中寫入包含了當前所有可訓練變量值得檢查點文件。
saver.save(sess, FLAGS.train_dir, global_step=step)
這樣,我們以後就可以使用saver.restore()
方法,重載模型的參數,繼續訓練。
saver.restore(sess, FLAGS.train_dir)
tf.train.Saver類
功能:保存和恢復變量
有關變量,保存和恢復的概述,請參見變量
將Saver類添加ops 從而在checkpointes裏save和restore變量 。它還提供了運行這些操作的便捷方法。
Checkpoints是專有格式的二進制文件,它將變量名稱映射到張量值。測試Checkpoints內容的最佳方式是使用Saver來加載。
Savers可以使用提供的計數器自動爲Checkpoint文件名編號,這使您可以在訓練模型時在不同的步驟中保留多個Checkpoints。例如,您可以使用訓練步驟編號對Checkpoint文件名進行編號。爲避免填滿磁盤,儲存器會自動管理Checkpoint文件。例如,他們只能保留N個最新文件,或每N小時訓練一個Checkpoint。
- max_to_keep:表示要保留的最近文件的最大數量。創建新文件時,將刪除舊文件。如果爲None或0,則不會從文件系統中刪除任何Checkpoint,但只有最後一個Checkpoint保留在checkpoint文件中。默認爲5(即保留最近的5個Checkpoint文件。)
- keep_checkpoint_every_n_hours:除了保留最新的 max_to_keep檢查點文件之外,您可能還希望每N小時的訓練保留一個Checkpoint文件。如果您想稍後分析模型在長時間訓練期間的進展情況,這將非常有用。例如,傳遞keep_checkpoint_every_n_hours=2確保每2小時訓練保留一個檢查點文件。默認值10,000小時可有效禁用該功能。
12. tf.contrib.crf
(1)tf.contrib.crf.crf_log_likelihood()
在一個條件隨機場裏面計算標籤序列的log-likelihood
函數的目的:使用crf 來計算損失,裏面用到的優化方法是:最大似然估計
參數:max_seq_len = 一個句子的字數
- inputs: 一個形狀爲 [batch_size, max_seq_len, num_tags] 的tensor,也就是每個標籤的預測概率值,這個值根據實際情況選擇計算方法,CNN,RNN...都可以,一般使用BILSTM處理之後輸出轉換爲他要求的形狀作爲CRF層的輸入。
- tag_indices: 一個形狀爲[batch_size, max_seq_len] 的矩陣,其實就是真實標籤序列。
- sequence_lengths:一個形狀爲[batch_size] 的向量,表示batch中每個序列的長度。這是一個樣本真實的序列長度,因爲爲了對齊長度會做些padding,但是可以把真實的長度放到這個參數裏
- transition_params: 形狀爲[num_tags, num_tags] 的轉移矩陣,可以沒有,沒有的話這個函數也會算出來。
返回:
- log_likelihood: 標量,log-likelihood
- transition_params: 形狀爲[num_tags, num_tags] 的轉移矩陣,轉移概率,如果輸入沒輸,它就自己算個給返回。
示例代碼:https://www.cnblogs.com/lovychen/p/8490397.html
(2)tf.contrib.crf.viterbi_decode
viterbi_decode(score,transition_params)
通俗一點,作用就是返回最好的標籤序列,這個函數只能夠在測試時使用,在tensorflow外部解碼。
參數:
-
score: 一個形狀爲[seq_len, num_tags] matrix of unary potentials. transition_params: 形狀爲[num_tags, num_tags] 的轉移矩陣
返回:
-
viterbi: 一個形狀爲[seq_len] 顯示了最高分的標籤索引的列表. viterbi_score: A float containing the score for the Viterbi sequence.
(3)tf.contrib.crf.crf_decode
crf_decode(potentials,transition_params,sequence_length)
在tensorflow內解碼
參數:
- potentials: 一個形狀爲[batch_size, max_seq_len, num_tags] 的tensor,
- transition_params: 一個形狀爲[num_tags, num_tags] 的轉移矩陣
- sequence_length: 一個形狀爲[batch_size] 的 ,表示batch中每個序列的長度
返回:
- decode_tags:一個形狀爲[batch_size, max_seq_len] 的tensor,類型是tf.int32,表示最好的序列標記。
- best_score: 一個形狀爲[batch_size] 的tensor,包含每個序列解碼標籤的分數。
13. Early stopping早停止
tf.contrib.estimator.stop_if_no_decrease_hook()
tf.contrib.estimator.stop_if_no_decrease_hook(
estimator,
metric_name,
max_steps_without_decrease,
eval_dir=None,
min_steps=0,
run_every_secs=60,
run_every_steps=None
)
其中metric_name用來指明監控的變量(比如loss或者accuracy)
二. tf 常用函數
1.tf.argmax
()
tf.argmax
是一個非常有用的函數,它能給出某個tensor對象在某一維上的其數據最大值所在的索引值。
2. tf.cast()
把布爾值轉換成浮點數,如
tf.cast(correct_prediction, "float")
[True, False, True, True]
會變成 [1,0,1,1]
3.tf.truncated_normal()
tf.truncated_normal
初始函數將根據所得到的均值和標準差,生成一個隨機分佈,從截斷的正態分佈中輸出隨機值。
tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
從截斷的正態分佈中輸出隨機值。 shape表示生成張量的維度,mean是均值,stddev是標準差。這個函數產生正太分佈,均值和標準差自己設定。這是一個截斷的產生正太分佈的函數,就是說產生正太分佈的值如果與均值的差值大於兩倍的標準差,那就重新生成。和一般的正太分佈的產生隨機數據比起來,這個函數產生的隨機數與均值的差距不會超過兩倍的標準差,但是一般的別的函數是可能的。
4. tf.reverse反序
import tensorflow as tf
import numpy as np
t=[[1,2,3],[4,5,6]]
t0=tf.reverse(t,[0])
t1=tf.reverse(t,[1])
t21=tf.reverse(t,[0,1])
t22=tf.reverse(t,[1,0])
sess=tf.Session()
print(sess.run(t0))
print(sess.run(t1))
print(sess.run(t21))
print(sess.run(t22))
運行結果如下:
按行(axis=0)變換,上下行交換位置
[[4 5 6]
[1 2 3]]
axis=1按照橫軸變換,前後列交換位置
[[3 2 1]
[6 5 4]]
先縱軸變換,後橫軸變換
[[6 5 4]
[3 2 1]]
先橫軸後縱軸變換
[[6 5 4]
[3 2 1]]
5. tf.concat()
tensorflow中用來拼接張量的函數tf.concat(),用法:
tf.concat([tensor1, tensor2, tensor3,...], axis)
先給出tf源代碼中的解釋:
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 0) # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 1) # [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]
# tensor t3 with shape [2, 3]
# tensor t4 with shape [2, 3]
tf.shape(tf.concat([t3, t4], 0)) # [4, 3]
tf.shape(tf.concat([t3, t4], 1)) # [2, 6]
這裏解釋了當axis=0和axis=1的情況,怎麼理解這個axis呢?其實這和numpy中的np.concatenate()用法是一樣的。
- axis=0 代表在第0個維度拼接
- axis=1 代表在第1個維度拼接
對於一個二維矩陣,第0個維度代表最外層方括號所框下的子集,第1個維度代表內部方括號所框下的子集。維度越高,括號越小。
對於這種情況,我可以再解釋清楚一點:
對於[ [ ], [ ]]和[[ ], [ ]],低維拼接等於拿掉最外面括號,高維拼接是拿掉裏面的括號(保證其他維度不變)。注意:tf.concat()拼接的張量只會改變一個維度,其他維度是保存不變的。比如兩個shape爲[2,3]的矩陣拼接,要麼通過axis=0變成[4,3],要麼通過axis=1變成[2,6]。改變的維度索引對應axis的值。
這樣就可以理解多維矩陣的拼接了,可以用axis的設置來從不同維度進行拼接。
對於三維矩陣的拼接,自然axis取值範圍是[0, 1, 2]。
對於axis等於負數的情況:
負數在數組索引裏面表示倒數(countdown)。比如,對於列表ls = [1,2,3]而言,ls[-1] = 3,表示讀取倒數第一個索引對應值。
axis=-1表示倒數第一個維度,對於三維矩陣拼接來說,axis=-1等價於axis=2。同理,axis=-2代表倒數第二個維度,對於三維矩陣拼接來說,axis=-2等價於axis=1。
一般在維度非常高的情況下,我們想在最'高'的維度進行拼接,一般就直接用countdown機制,直接axis=-1就搞定了。
6. tf.app.run()
解析命令行參數,調用main 函數 main(sys.argv)
7. tf.ConfigProto()
主要的作用是配置tf.Session的運算方式,比如gpu運算或者cpu運算
https://blog.csdn.net/u012436149/article/details/53837651
https://blog.csdn.net/qq_31261509/article/details/79746114
8. tf.train.get_checkpoint_state
函數功能:找出訓練時保存的模型,其中有model_checkpoint_path和all_model_checkpoint_paths兩個屬性
ckpt.model_checkpoint_path:可以找出所有模型中最新的模型
ckpt.all_model_checkpoint_paths:可以找出所有模型
tf.train.checkpoint_exists(...)
: 檢查是否存在具有指定前綴的V1或V2檢查點(棄用)。
9. tensorflow之計算梯度minimize和梯度修剪:compute_gradients與apply_gradients
9.1 minimize的使用
opt = tf.tf.train.GradientDescentOptimizer(learning_rate=0.1)
train_op = opt.minimize(loss)
minimize的內部存在兩個操作:(1)計算各個變量的梯度 (2)用梯度更新這些變量的值
def minimize(self, loss, global_step=None, var_list=None, name=None):
grads_and_vars = self.compute_gradients(loss, var_list=var_list)
vars_with_grad = [v for g, v in grads_and_vars if g is not None]
if not vars_with_grad:
raise ValueError(
"No gradients provided for any variable, check your graph for ops"
" that do not support gradients, between variables %s and loss %s." %
([str(v) for _, v in grads_and_vars], loss))
return self.apply_gradients(grads_and_vars, global_step=global_step, name=name)
9.2 梯度修剪:主要避免訓練梯度爆炸和消失問題
tf.train.XXXOptimizer
apply_gradients
和compute_gradients
是所有的優化器都有的方法。
(1)computer_gradients(loss, val_list)
計算出各個變量的偏導數(梯度),是爲了防止梯度爆炸和梯度消失。通過對gradient的修正,來進行避免。
val_list:進行求偏導的變量的列表,默認爲graph中收集的變量列表
compute_gradients(
loss,
var_list=None,
gate_gradients=GATE_OP,
aggregation_method=None,
colocate_gradients_with_ops=False,
grad_loss=None
)
計算loss
中可訓練的var_list
中的梯度,相當於minimize()
的第一步,返回(gradient, variable)
對的list。
(2)apply_gradients(grads_and_vars, global_step=None, name=None)
該函數的作用是將compute_gradients()
返回的值作爲輸入參數對variable進行更新。
apply_gradients(
grads_and_vars,
global_step=None,
name=None
)
minimize()
的第二部分,返回一個執行梯度更新的ops。
(3)tf.clip_by_value
輸入一個張量t,把t中的每一個元素的值都壓縮在clip_value_min和clip_value_max之間。小於min的讓它等於min,大於max的元素的值等於max。
tf.clip_by_value(
t, # grad
clip_value_min,
clip_value_max,
name=None # val
)
例子:
#Now we apply gradient clipping. For this, we need to get the gradients,
#use the `clip_by_value()` function to clip them, then apply them:
threshold = 1.0
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
grads_and_vars = optimizer.compute_gradients(loss)
#list包括的是:梯度和更新變量的元組對
capped_gvs = [(tf.clip_by_value(grad, -threshold, threshold), var)
for grad, var in grads_and_vars]
#執行對應變量的更新梯度操作
training_op = optimizer.apply_gradients(capped_gvs)
(4)tf.clip_by_norm
指對梯度進行裁剪,通過控制梯度的最大範式,防止梯度爆炸的問題,是一種比較常用的梯度規約的方式。
tf.clip_by_norm(
t,
clip_norm, # 裁剪率
axes=None,
name=None
)
其作用在於將傳入的梯度張量t
的L2範數進行了上限約束,約束值即爲clip_norm
,如果t
的L2範數超過了clip_norm
,則變換爲t * clip_norm / l2norm(t)
,如此一來,變換後的t
的L2範數便小於等於clip_norm
了。
10. tf.reduce_sum()之類函數
(1)tf.reduce_sum() 求和函數,在 tensorflow 裏面,計算的都是 tensor,可以通過調整 axis =0,1 的維度來控制求和維度
reduce_sum (
input_tensor ,
axis = None ,
keep_dims = False ,
name = None ,
reduction_indices = None
)
- input_tensor:要減少的張量,應該有數字類型。
- axis:表示在那個維度進行sum操作。
- keep_dims:如果爲true,則保留長度爲1的縮小尺寸。表示是否保留原始數據的維度,False相當於執行完後原始數據就會少一個維度
- name:操作的名稱(可選)。
- reduction_indices:axis的廢棄的名稱。爲了跟舊版本的兼容,現在已經不使用了。
tf.reduce_sum函數中reduction_indices參數表示函數的處理維度。
reduction_indices參數的值默認的時候爲None,默認把所有的數據求和,即結果是一維的。
reduction_indices參數的值爲0,是第0維對應位置相加。
reduction_indices參數的值爲1,是第1維對應位置相加。
返回值及注意:
此函數計算一個張量的各個維度上元素的總和。v
函數中的input_tensor是按照axis中已經給定的維度來減少的;除非 keep_dims 是true,否則張量的秩將在axis的每個條目中減少1;如果keep_dims爲true,則減小的維度將保留爲長度1。
如果axis沒有條目,則縮小所有維度,並返回具有單個元素的張量.
11. tf.assign()
tf.assign(A, new_number): 這個函數的功能主要是把A的值變爲new_number
12.logging模塊
參考:https://www.cnblogs.com/liujiacai/p/7804848.html
logging模塊是Python內置的標準模塊,主要用於輸出運行日誌,可以設置輸出日誌的等級、日誌保存路徑、日誌文件回滾等;相比print,具備如下優點:
- 可以通過設置不同的日誌等級,在release版本中只輸出重要信息,而不必顯示大量的調試信息;
- print將所有信息都輸出到標準輸出中,嚴重影響開發者從標準輸出中查看其它數據;logging則可以由開發者決定將信息輸出到什麼地方,以及怎麼輸出。
13. model.char_lookup.read_value()、model.char_lookup.assign(emb_weights)
read_value()、assign()是tf.Variable的函數
參考:變量常量類型 https://blog.csdn.net/xierhacker/article/details/53103979
assign(value, use_locking=False)
作用:爲變量指定一個新的值
read_value()
作用:返回這個變量的值,在當前的上下文中讀取。返回的是一個含有這個值的Tensor
14. tf.train.import_meta_graph
import_meta_graph(
meta_graph_or_file,
clear_devices=False,
import_scope=None,
**kwargs
)
從文件中將保存的graph的所有節點加載到當前的default graph中,並返回一個saver。也就是說,我們在保存的時候,除了將變量的值保存下來,其實還有將對應graph中的各種節點保存下來,所以模型的結構也同樣被保存下來了。