Обучение нейронной сети для регрессии всегда предсказывает среднее

9

Я тренирую простую сверточную нейронную сеть для регрессии, где задача состоит в том, чтобы предсказать (x, y) расположение блока на изображении, например:

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

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

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

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

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

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

Проблема, с которой я сталкиваюсь, заключается в том, что даже после значительных тренировок потери действительно не уменьшаются. Наблюдая за выходом сети, я замечаю, что сеть имеет тенденцию выводить значения, близкие к нулю, для обоих выходных узлов. Таким образом, предсказание местоположения прямоугольника всегда является центром изображения. Есть некоторые отклонения в прогнозах, но всегда около нуля. Ниже показаны потери:

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

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

Таким образом, кажется, что сеть просто прогнозирует среднее значение обучающих данных, а не усваивает подходящие данные. Любые идеи о том, почему это может быть? Я использую Адама в качестве оптимизатора, с начальной скоростью обучения 0,01, а Релус в качестве активаций


Если вас интересует какой-то мой код (Keras), он ниже:

# Create the model
model = Sequential()
model.add(Convolution2D(32, 5, 5, border_mode='same', subsample=(2, 2), activation='relu', input_shape=(3, image_width, image_height)))
model.add(Convolution2D(64, 5, 5, border_mode='same', subsample=(2, 2), activation='relu'))
model.add(Convolution2D(128, 5, 5, border_mode='same', subsample=(2, 2), activation='relu'))
model.add(Flatten())
model.add(Dense(100, activation='relu'))
model.add(Dense(2, activation='linear'))


# Compile the model
adam = Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss='mean_squared_error', optimizer=adam)


# Fit the model
model.fit(images, targets, batch_size=128, nb_epoch=1000, verbose=1, callbacks=[plot_callback], validation_split=0.2, shuffle=True)
Karnivaurus
источник
Изображения на лучших примерах ваших реальных образцов? Это 5 отдельных образцов? Похоже, на изображениях нет информации, которая могла бы помочь обобщить. Я имею в виду, что вам не нужна нейронная сеть, чтобы найти местоположение белого квадрата по x, y, вы можете просто разобрать изображение и найти белый пиксель. Объясните немного больше о своем видении этой модели. Есть ли какая-то временная схема, посредством которой вы предсказываете следующее местоположение?
photox
Привет и да, изображения 5 отдельных образцов. Я не уверен, как они отображаются для вас, но они должны быть 5 отдельных квадратных изображений (я немного изменил макет, чтобы помочь ...). Да, я понимаю, что вам не нужна нейронная сеть для этой задачи, но это всего лишь тестовый эксперимент, который поможет мне научиться делать регрессию с нейронной сетью. Я не понимаю, что вы подразумеваете под отсутствием информации, которая могла бы помочь в обобщении ... Каждая обучающая пара состоит из квадратного изображения и двумерного вектора расположения квадрата (x, y). Спасибо :)
Karnivaurus
1
1) Ваша входная форма на первом слое конвоя использует 3 (rbg) канала, но ваши данные представлены в оттенках серого (1 канал) 2) Вам не нужно так много конфорных слоев и фильтров, на самом деле я думаю, что один слой, и горстка маленьких ядер будет в порядке.
photox
Вы уверены, что изображения действительно соответствуют целям?
user31264
1
Как говорит @photox, вам не нужны слои конвона. Добавление их затрудняет поиск оптимального решения оптимизатором. Если вы удалите 3 слоя конв, я подозреваю, что ваша «модель» будет работать.
Питер

Ответы:

9

Оптимизатор не может сходиться к (суб) оптимальному решению. Почему? Ваша проблема слишком проста и / или ваша модель слишком сложна.

Слишком легкая проблема

Как уже сказал @photox, эту проблему можно решить только с одним скрытым слоем. Я даже подозреваю, что это можно сделать без скрытого слоя. Это потому, что эта проблема линейно отделима .

1/высота/ширина2/высоташиринаNN/высоташиринавысота*ширинапиксели отличны от нуля (например, смещение равно значению серого цвета), активация x-выхода равна центру квадрата. Следовательно, линейная функция может вычислить местоположение квадрата.

Есть несколько решений:

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

Слишком сложная модель

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

5×5

Другой пример - оптимизатор Adam с множеством дополнительных параметров. Оптимизатор Adam может хорошо работать с этими параметрами, но почему бы вам не начать с простого SGDоптимизатора со значениями по умолчанию.

Таким образом, вы можете сделать несколько оптимизаций:

  • использовать LinearRegressionот scikit-Learn. Хорошо, это не то, что вы хотите, но я просто хочу показать, насколько сложна эта модель.
  • Удалить слои конвоя
  • Уменьшить размер скрытых Denseслоев
  • Используйте SGDоптимизатор по умолчанию
  • Если вы используете скрытый слой, вы должны попробовать sigmoidактивацию. Вы можете думать о каждом из узлов скрытого слоя как об обнаружении, если квадрат находится в определенном месте.
  • Если все это не работает, поэкспериментируйте с частотой обучения, чтобы определить, слишком ли она высокая или слишком низкая.

Ps

Я думаю, вам понравится этот пост от Adit Deshpande.

Pieter
источник
Дайте мне знать, если эти решения изменили поведение оптимизаторов.
Питер
Спасибо, это очень полезно. Я работаю над вашими предложениями. Тем не менее, я не понимаю вашу первую мысль. Я не понимаю, почему, если проблема слишком проста, то ее сложнее оптимизировать, чем более сложную проблему. Для данной сети, почему более простую проблему сложнее оптимизировать, чем более сложную проблему? В простой задаче я бы подумал, что будут очень сильные градиенты и сильный глобальный оптимум. Но ваше первое замечание говорит о том, что простота проблемы затрудняет оптимизацию, предполагая, что более сложная проблема поможет оптимизации ...
Karnivaurus
0

Это похоже на типичную проблему переоснащения. Ваши данные не предоставляют достаточно информации, чтобы получить лучший результат. Вы выбираете комплекс NN с вашим поездом, чтобы запомнить все нюансы данных поезда . Потеря никогда не может быть нулем, как на вашем графике. Кстати, кажется, что ваша проверка имеет ошибку или набор проверки не подходит для проверки, потому что потеря проверки также становится равной нулю.

Леонид Ганелайн
источник
4
Вопрос говорит, что сеть почти всегда выдает ноль. Это было бы в случае серьезного переоснащения , а не переоснащения. Также нет разрыва между тренировкой и ошибкой проверки на кривой обучения, что указывает на то, что переоснащение не является проблемой (ошибка не равна нулю, шкала логарифмическая)
user20160
0

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

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

Рави Шанкар
источник
-1

Я на самом деле работал над очень похожей проблемой. По сути, у меня было множество точек на белом фоне, и я обучал NN распознавать точку, которая была помещена на заднем плане первой. Способ, который я нашел для работы, состоял в том, чтобы просто использовать один полностью связанный слой нейронов (таким образом, 1-слойный NN). Например, для изображения размером 100x100 у меня будет 10000 входных нейронов (пикселей), напрямую соединенных с 2 выходными нейронами (координатами). В PyTorch, когда я преобразовывал значения пикселей в тензор, он автоматически нормализовал мои данные, вычитая среднее значение и деля его на стандартное отклонение. В обычных задачах машинного обучения это хорошо, но не для изображения, где может быть несоответствие в количестве цветных пикселей в изображении (т. Е. У вас, где только несколько белых пикселей). Так, Я вручную нормализовал, разделив все значения интенсивности пикселей на 255 (так что теперь они находятся в диапазоне 0-1 без типичного метода нормализации, который пытается подогнать все значения интенсивности к нормальному распределению). Тогда у меня все еще были проблемы, потому что он предсказывал среднюю координату пикселей в обучающем наборе. Таким образом, мое решение состояло в том, чтобы установить очень высокую скорость обучения, что противоречит практически всем преподавателям и учебным пособиям по ML. Вместо того чтобы использовать 1e-3, 1e-4, 1e-5, как говорят большинство людей, я использовал скорость обучения 1 или 0,1 со стохастическим градиентным спуском. Это решило мои проблемы, и моя сеть, наконец, научилась запоминать мой тренировочный набор. Он не слишком хорошо подходит для тестирования, но, по крайней мере, он работает, что является лучшим решением, чем большинство других предложили по вашему вопросу. в настоящее время находится в диапазоне 0-1 без типичного метода нормализации, который пытается подогнать все значения интенсивности к нормальному распределению). Тогда у меня все еще были проблемы, потому что он предсказывал среднюю координату пикселей в обучающем наборе. Таким образом, мое решение состояло в том, чтобы установить очень высокую скорость обучения, что противоречит практически всем преподавателям и учебным пособиям по ML. Вместо того чтобы использовать 1e-3, 1e-4, 1e-5, как говорят большинство людей, я использовал скорость обучения 1 или 0,1 со стохастическим градиентным спуском. Это решило мои проблемы, и моя сеть, наконец, научилась запоминать мой тренировочный набор. Он не слишком хорошо подходит для тестирования, но, по крайней мере, он работает, что является лучшим решением, чем большинство других предложили по вашему вопросу. в настоящее время находится в диапазоне 0-1 без типичного метода нормализации, который пытается подогнать все значения интенсивности к нормальному распределению). Тогда у меня все еще были проблемы, потому что он предсказывал среднюю координату пикселей в обучающем наборе. Таким образом, мое решение состояло в том, чтобы установить очень высокую скорость обучения, что противоречит практически всем преподавателям и учебным пособиям по ML. Вместо того чтобы использовать 1e-3, 1e-4, 1e-5, как говорят большинство людей, я использовал скорость обучения 1 или 0,1 со стохастическим градиентным спуском. Это решило мои проблемы, и моя сеть, наконец, научилась запоминать мой тренировочный набор. Он не слишком хорошо подходит для тестирования, но, по крайней мере, он работает, что является лучшим решением, чем большинство других предложили по вашему вопросу.

боб
источник