Я должен сказать, что это может быть одной из самых странных проблем, с которыми я когда-либо сталкивался.
Я внедрял ResNet для выполнения 10-классификации по CIFR-10 с тензорным потоком. Казалось, что с фазой обучения все было в порядке - потери неуклонно снижались, а точность на тренировочной базе увеличивалась до более чем 90%, однако результаты были совершенно ненормальными во время логического вывода.
Я очень тщательно проанализировал свой код и исключил возможность ошибок при загрузке данных или сохранении / загрузке модели. Таким образом, единственное различие между фазой обучения и фазой тестирования заключается в уровнях нормализации партии.
Для слоев BN я использовал tf.layers.batch_normalization
напрямую и подумал, что я обращал внимание на каждую ловушку при использовании tf.layers.batch_normalization
.
В частности, я включил зависимость для train_op
следующим образом:
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
self.train_op = optimizer.minimize(self.losses)
Также для сохранения и загрузки модели я указал var_list
как tf.global_variables()
. Кроме того, я использовал training=True
для обучения и training=False
для теста.
Тем не менее, точность при выводе составляла всего около 10%, даже применительно к тем же данным, которые использовались для обучения. И когда я вывел последний слой сети (т. Е. 10-мерный вектор вводил в softmax), я обнаружил, что величина каждого элемента в 10-мерном векторе во время обучения всегда была 1e0 или 1e-1, а для вывода , это может быть 1e4 или даже 1e5. Самым странным было то, что я обнаружил, что величина вектора 10-размерности во время логического вывода коррелирует с размером партии, использованным при обучении, т. Е. Чем больше размер партии, тем меньше величина.
Кроме того, я также обнаружил, что величины moving_mean
и moving_variance
слоев BN также коррелируют с размером партии, но почему это вообще возможно? Я думал, что moving_mean
означает среднее значение для всего обучающегося населения, как и moving_variance
. Так почему же было что-то делать с размером партии?
Я думаю, что должно быть что-то, чего я не знаю об использовании BN с tenorflow. Эта проблема действительно сведет меня с ума! Я никогда не ожидал, что столкнусь с такой проблемой в tenorflow, учитывая, насколько удобно использовать BN с PyTorch!