#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_collection") 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, тогда все работает нормально, мой исходный код находится здесь: