一個TFRecords 文件為一個字符串序列。這種格式並非隨機獲取,它比較適合大規模的數據流,而不太適合需要快速分區或其他非序列獲取方式。
操作組 |
操作 |
Training |
Optimizers,Gradient Computation,Gradient Clipping,Distributed execution |
Testing |
Unit tests,Utilities,Gradient checking |
1、優化器(optimizer)
Class tf.train.Optimizer
優化器(optimizers)類的基類。這個類定義了在訓練模型的時候添加一個操作的API。你基本上不會直接使用這個類,但是你會用到他的子類比如GradientDescentOptimizer, AdagradOptimizer, MomentumOptimizer.等等這些。
優化器的基類主要實現了兩個接口,一是計算損失函數的梯度,二是將梯度作用於變量。tf.train 主要提供了如下的優化函數:
- tf.train.Optimizer
- tf.train.GradientDescentOptimizer
- tf.train.AdadeltaOpzimizer
- Ada delta
- tf.train.AdagradDAOptimizer
- tf.train.MomentumOptimizer
- tf.train.AdamOptimizer
- tf.train.FtrlOptimizer
- tf.train.ProximalGradientDescentOptimizer
- tf.train.ProximalAdagradOptimizer
- tf.train.RMSPropOptimizer
2、梯度計算
TensorFlow 同時也提供了給定 TensorFlow 計算圖(computation graph)的導數。上節提到的優化器類會自動計算 computation graph 的導數,但用戶自定義優化器時,可以使用如下低級別的函數:
- tf.gradients
- tf.AggregationMethod
- tf.stop_gradient
- tf.hessians
3、梯度下降法
Class tf.train.GradientDescentOptimizer
__init__(learning_rate, use_locking=False,name=’GradientDescent’)
作用:創建一個梯度下降優化器對象
參數:
learning_rate: A Tensor or a floating point value. 要使用的學習率
use_locking: 要是True的話,就對於更新操作(update operations.)使用鎖
name: 名字,可選,默認是”GradientDescent”.
函數training()通過梯度下降法為最小化損失函數增加了相關的優化操作,在訓練過程中,先實例化一個優化函數,比如 tf.train.GradientDescentOptimizer,並基於一定的學習率進行梯度優化訓練:
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
然后,可以設置一個用於記錄全局訓練步驟的單值。以及使用minimize()操作,該操作不僅可以優化更新訓練的模型參數,也可以為全局步驟(global step)計數:
global_step = tf.Variable(0, name='global_step', trainable=False)
train_op = optimizer.minimize(loss, global_step=global_step)
4、移動平均(Moving Averages)
一些訓練優化算法,比如GradientDescent 和Momentum 在優化過程中便可以使用到移動平均方法。使用移動平均常常可以較明顯地改善結果。
tf.train.ExponentialMovingAverage(decay, steps)
tf.train.ExponentialMovingAverage這個函數用於更新參數,就是采用滑動平均的方法更新參數。這個函數初始化需要提供一個衰減速率(decay),用於控制模型的更新速度。這個函數還會維護一個影子變量(也就是更新參數后的參數值),這個影子變量的初始值就是這個變量的初始值,影子變量值的更新方式如下:
shadow_variable = decay * shadow_variable + (1-decay) * variable
shadow_variable是影子變量,variable表示待更新的變量,也就是變量被賦予的值,decay為衰減速率。decay一般設為接近於1的數(0.99,0.999)。decay越大模型越穩定,因為decay越大,參數更新的速度就越慢,趨於穩定。
tf.train.ExponentialMovingAverage這個函數還提供了自動更新decay的計算方式:
decay= min(decay,(1+steps)/(10+steps))
steps是迭代的次數,可以自己設定。
每次更新完以后,影子變量的值更新,varible的值就是你設定的值。如果在下一次運行這個函數的時候你不在指定新的值,那就不變,影子變量更新。如果指定,那就variable改變,影子變量也改變。
示例:
v1 = tf.Variable(0, dtype=tf.float32) step = tf.Variable(tf.constant(0)) ema = tf.train.ExponentialMovingAverage(0.99, step) maintain_average = ema.apply([v1]) variables_to_restore = ema.variables_to_restore() saver = tf.train.Saver(variables_to_restore)
5、交叉熵
交叉熵可在神經網絡(機器學習)中作為損失函數,p表示真實標記的分布,q則為訓練后的模型的預測標記分布,交叉熵損失函數可以衡量p與q的相似性。交叉熵作為損失函數還有一個好處是使用sigmoid函數在梯度下降時能避免均方誤差損失函數學習速率降低的問題,因為學習速率可以被輸出的誤差所控制。tensorflow中自帶的函數可以輕松的實現交叉熵的計算。
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)
注意:如果labels的每一行是one-hot表示,也就是只有一個地方為1,其他地方為0,可以使用tf.sparse_softmax_cross_entropy_with_logits()
警告:
1. 這個操作的輸入logits是未經縮放的,該操作內部會對logits使用softmax操作
2. 參數labels,logits必須有相同的形狀 [batch_size, num_classes] 和相同的類型(float16, float32, float64)中的一種
參數:_sentinel: 一般不使用
labels: labels的每一行labels[i]必須為一個概率分布
logits: 未縮放的對數概率,就是神經網絡最后一層的輸出,如果有batch的話,它的大小就是[batchsize,num_classes],單樣本的話,大小就是num_classes
dims: 類的維度,默認-1,也就是最后一維
name: 該操作的名稱
返回值:長度為batch_size的一維Tensor
示例:
labels = [[0.2, 0.3, 0.5], [0.1, 0.6, 0.3]] logits = [[2, 0.5, 1], [0.1, 1, 3]] logits_scaled = tf.nn.softmax(logits) result1 = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits) result2 = -tf.reduce_sum(labels * tf.log(logits_scaled), 1) result3 = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits_scaled) with tf.Session() as sess: print sess.run(result1) print sess.run(result2) print sess.run(result3) >> > [1.41436887 1.66425455] >> > [1.41436887 1.66425455] >> > [1.17185783 1.17571414]
labels的每一行是一個概率分布,而logits未經縮放(每行加起來不為1),我們用定義法計算得到交叉熵result2,和套用tf.nn.softmax_cross_entropy_with_logits()得到相同的結果, 但是將縮放后的logits_scaled輸tf.nn.softmax_cross_entropy_with_logits(), 卻得到錯誤的結果,所以一定要注意,這個操作的輸入logits是未經縮放的。
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None)
這個函數與上一個函數十分類似,唯一的區別在於labels.
注意:對於此操作,給定標簽的概率被認為是排他的。labels的每一行為真實類別的索引
警告:
1. 這個操作的輸入logits同樣是是未經縮放的,該操作內部會對logits使用softmax操作
2. 參數logits的形狀 [batch_size, num_classes] 和labels的形狀[batch_size]
返回值:長度為batch_size的一維Tensor, 和label的形狀相同,和logits的類型相同。
6、學習率衰減(decaying the learning rate)
tf.train.exponential_decay(learning_rate, global_step,
decay_steps, decay_rate, staircase=False, name=None)
對學習率進行指數衰退,學習率每decay_steps后乘以decay_rate。
在Tensorflow中,為解決設定學習率(learning rate)問題,提供了指數衰減法來解決。通過tf.train.exponential_decay函數實現指數衰減學習率。
步驟:1.首先使用較大學習率(目的:為快速得到一個比較優的解);
2.然后通過迭代逐步減小學習率(目的:為使模型在訓練后期更加穩定);
實現的是如下操作:
decayed_learning_rate=learining_rate*decay_rate^(global_step/decay_steps)
其中,decayed_learning_rate為每一輪優化時使用的學習率;
learning_rate為事先設定的初始學習率;
decay_rate為衰減系數;
decay_steps為衰減速度。
而tf.train.exponential_decay函數則可以通過staircase(默認值為False,當為True時,(global_step/decay_steps)則被轉化為整數) ,選擇不同的衰減方式。