CNN формирует одинаковый выход для всех входов - PullRequest
0 голосов
/ 29 апреля 2018

Я пытаюсь научить CNN классифицировать изображения из следующего набора данных: kaggle.com / nih-chest-xrays / data

Я решил начать с модели GoogLeNet , однако я заменил полностью подключенный слой на 14-мерный выход, используя функцию сигмоида (классы не являются взаимоисключающими). У меня возникли некоторые проблемы с получением модели для изучения, похоже, что, пытаясь минимизировать потери, она изучает среднее значение моих данных, так как через короткое время выводит одинаковый вывод e.g. [0,0,0,1,0,0,1,0,0,0,0,0,0,0] для всех входных данных. изображения.

Я немного обыскал, включая популярные вопросы, но, похоже, не могу найти решения где-либо еще, так как мой набор данных достаточно большой (112 тыс. Изображений), и я попробовал типичные рекомендации, которые я вижу в других вопросах .

Я пробовал:

  • Смена оптимизатора с Адама на Адаград
  • Замена невзвешенной кросс-энтропийной потери на взвешенную потерю, как описано здесь в 3.1
  • Гораздо меньшая двухслойная сеть (NaiveCNN.py связанный)
  • Изменение уровня обучения в регионе 0.1-0.00001
  • Проверка того, что мой входной конвейер на самом деле отправляет разные изображения в CNN, а не просто целую серию одного и того же изображения.
  • Использование явного инициализатора веса вместо стандартного тензорного потока. (Использовал tflearn по умолчанию tf.truncated_normal_initializer(stddev=0.001))
  • Использование встроенного тензорного потока tf.sigmoid_cross_entropy_with_logits вместо явно определенной перекрестной энтропии.
  • И мои прогнозы, и метки имеют форму [64,14], а tf.transpose ing выдает ошибку, как и ожидалось Incompatible shapes: [64,14] vs. [14,64], поэтому я не думаю, что либо

Я использую партию размером 64 на GTX1080ti, используя тензор потока 1.4.0, типичный вывод TensorBoard за 30 эпох обучения

Весь код, который я использую, здесь: https://gist.github.com/Kaapp/abdb54b232eb7f07b87955d9a18df57d

Я начинаю думать, что, возможно, это просто простая ошибка где-то в моем коде, но я смотрю на нее так долго, что не могу ее обнаружить или просто что-то неправильно понял. Извиняюсь за запутанные фрагменты кода, я добавил несколько переменных _x, _y и т. Д., Чтобы помочь при отладке того, что именно выводит сеть.

Пример небольшого набора данных (1000 изображений) из моего комментария

Редактирование / обновление: я обнаружил, что удаление выпадающего слоя в моей модели делает это полностью согласованным, выходные данные модели начинаются с 0,5 по всей плате и будут перемещаться вместе в каждом пакете, прогнозируя один и тот же выход для всего пакета. *

1 Ответ

0 голосов
/ 04 мая 2018

Использование предварительно обученной модели решило мою проблему. Я не мог изначально загрузить предварительно обученную модель из-за тонкости с тем, как работает средство сохранения тензорного потока.

Чтобы исправить это, мне нужно было повторно инициализировать Saver, когда построение моего графа было фактически завершено, чтобы он знал весь граф, а затем вручную инициализировал дополнительные переменные, а затем, наконец, восстановил контрольную точку следующим образом:

vars_to_init = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, "the_added_layer's_scope")
for var in vars_to_init:
    sess.run(var.initializer)
saver = tf.train.Saver()
saver.restore(sess, my_checkpoint_file_path)

После того, как я это сделал, я мог настроить существующую контрольную точку модели, обучив только последний слой, передав переменные функции минимизации:

trainable_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, "my_trainable_variables_scope")
self.train_step = tf.train.AdamOptimizer(
                        learning_rate=self.lr, 
                        beta1=0.9,
                        beta2=0.999).minimize(self.loss,var_list=trainable_vars)

Возможно, мой набор данных недостаточно разнообразен для правильного обучения сети с нуля, но точная настройка последнего слоя работает очень хорошо.

Надеюсь, это может помочь кому-то другому, если вы застряли так же, как я.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...