2016-10-17 25 views
2

我使用Tensorflow正式批標準化(BN)函數(tf.contrib.layers.batch_norm())在MNIST數據低測試精度。我使用用於添加BN以下代碼:獲取使用Tensorflow batch_norm功能

local4_bn = tf.contrib.layers.batch_norm(local4, is_training=True) 

在測試過程中,我改變「is_training =假」在上面的代碼行,並觀察只有20%的準確度。但是,如果我使用上述代碼進行測試(即,保持is_training = True),則批量大小爲100個圖像時,它的準確率爲〜99%。此觀察結果表明,由batch_norm()計算出的指數移動平均值和方差可能不正確,或者我在代碼中丟失了某些內容。

任何人都可以請回答有關上述問題的解決方案。

回答

2

僅當批量大小爲100時測試模型is_training=True時,您的準確性會達到〜99%。 如果將批量更改爲1,則精度會降低。

這是由於,你計算指數移動平均和方差爲輸入料和比你(分批)歸一化使用這些值的各層輸出這一事實。

batch_norm函數具有參數variables_collections,它可以幫助您在列車階段存儲計算出的移動平均值和方差,並在測試階段重新使用它們。

如果您定義這些變量的集合,那麼batch_norm層將在測試階段使用它們,而不是計算新值。

因此,如果您批標準化層定義改變你

local4_bn = tf.contrib.layers.batch_norm(local4, is_training=True, variables_collections=["batch_norm_non_trainable_variables_collection"]) 

層將計算的變量存儲到"batch_norm_non_trainable_variables_collection"集合。

在測試階段,當你通過is_training=False參數,該層將重新使用的計算值,它集合中找到。

請注意,移動平均值和方差不是可訓練參數,因此,如果您只在檢查點文件中保存模型可訓練參數,則必須手動添加存儲到先前定義的集合中的不可訓練變量。

在創建Saver對象可以做到這一點:

saver = tf.train.Saver(tf.get_trainable_variables() + tf.get_collection_ref("batch_norm_non_trainable_variables_co‌​llection") + otherlistofvariables) 

在成癮,因爲批標準化可以限制施加到所述層的表現力(因爲它限制了的值的範圍) ,應啓用網絡學習參數gammabeta(在paper描述的仿射變換系數),其允許網絡學習,因此,仿射變換增加該層的代表性的功率。

您可以啓用這些參數設置爲Truebatch_norm函數的參數,這樣的學習:

local4_bn = tf.contrib.layers.batch_norm(
    local4, 
    is_training=True, 
    center=True, # beta 
    scale=True, # gamma 
    variables_collections=["batch_norm_non_trainable_variables_collection"]) 
+0

非常感謝。我正在使用以下命令保存文件: saver.save(sess,checkpoint_path,global_step = step) 我沒有看到使用save()保存不可訓練參數的任何選項。你能告訴我如何保存和恢復不可訓練的參數嗎? – Hasnat

+1

創建保存程序時,您可以指定要保存的變量。保存= tf.train.Saver(tf.get_trainable_variables()+ tf.get_collection_ref(「batch_norm_non_trainable_variables_collection」)+ otherlistofvariables) – nessuno

+0

我已經遵循解決方案(添加variable_collection並保存不可訓練參數),但仍然觀察同樣的問題。然而,我已經使用了[this]的batch_norm_wrapper()函數(http://r2rt.com/implementing-batch-normalization-in-tensorflow.html),並且它在列車和測試中都能很好地工作,儘管我沒有明確地保存不可訓練的參數。 – Hasnat