Получение низкой точности тестирования с помощью функции Tensorflow batch_norm

#python #tensorflow

#python #tensorflow

Вопрос:

Я использую официальную функцию пакетной нормализации (BN) (tf.contrib.layers.batch_norm()) Tensorflow для данных MNIST. Я использую следующий код для добавления BN:

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

Во время тестирования я меняю «is_training = False» в приведенной выше строке кода и соблюдаю точность только 20%. Однако это дает точность ~ 99%, если я использую приведенный выше код также для тестирования (т. Е. Сохраняя is_training= True) с размером пакета 100 изображений. Это наблюдение указывает на то, что экспоненциальное скользящее среднее и дисперсия, вычисленные с помощью batch_norm(), вероятно, неверны или я что-то упускаю в своем коде.

Может кто-нибудь, пожалуйста, ответить о решении вышеуказанной проблемы.

Ответ №1:

Вы получаете точность ~ 99% при тестировании модели is_training=True только из-за размера пакета 100. Если вы измените размер пакета на 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)
 

В зависимости, поскольку пакетное нормирование может ограничить выразительную способность слоя, к которому применяется (поскольку оно ограничивает диапазон значений), вы должны разрешить сети изучать параметры gamma и beta (коэффициенты аффинного преобразования, описанные в документе), что позволяет сети изучать, таким образом, аффинныйпреобразования, которые увеличивают мощность представления слоя.

Вы можете включить изучение этих параметров True , задав параметр batch_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"])
 

Комментарии:

1. большое спасибо. Я сохраняю файл с помощью команды: saver.save(sess, checkpoint_path, global_step=step) Я не вижу никакой возможности сохранить необучаемые параметры с помощью save(). Не могли бы вы, пожалуйста, сообщить мне, как сохранить и восстановить необучаемые параметры?

2. Когда вы создаете заставку, вы можете указать переменную для сохранения. saver = tf.train. Saver(tf.get_trainable_variables() tf.get_collection_ref(«batch_norm_non_trainable_variables_collection») другой список переменных)

3. Я последовал решению (добавил variable_collection и сохранил не поддающиеся обучению параметры), но все же наблюдаю ту же проблему. Тем не менее, я использовал функцию batch_norm_wrapper() для этого , и она отлично работала как в обучении, так и в тестировании, хотя я явно не сохранял необучаемые параметры.

4. Я не знаю. здесь я определил слой batch_norm, обертывающий метод tf.contrib.layers.batch_norm, и я использовал его (в train.py файл в родительском каталоге), как я вам уже говорил, и это сработало. Может быть, вы можете взглянуть на мой исходный код, чтобы найти разницу между вашей и моей реализацией

5. Спасибо @nessuno за то, что поделился своим кодом, который в конечном итоге помог мне найти недостающий элемент. scale=True Для решения проблемы необходимо было добавить. В вашем коде по умолчанию для scale равно True , тогда как в исходном коде для него установлено значение false . Кроме того, я думаю, что я должен установить updates_collections=None для обновления параметров на месте. Что касается проблемы сохранения, я думаю, что заставка tf.train.Saver() по умолчанию сохраняет все (обучаемые и необучаемые) переменные.

Ответ №2:

Я столкнулся с тем же вопросом при обработке MNIST. Мой счет в поезде нормальный, в то время как тестовый счет в начале очень низкий, а затем он постепенно растет.

введите описание изображения здесь

Я изменил значение momentum= 0.99 по умолчанию на momentum = 0.9, тогда все работает нормально, мой исходный код находится здесь:

mnist_bn_fixed.py