Я тренирую простую сверточную нейронную сеть для регрессии, где задача состоит в том, чтобы предсказать (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)
Ответы:
Оптимизатор не может сходиться к (суб) оптимальному решению. Почему? Ваша проблема слишком проста и / или ваша модель слишком сложна.
Слишком легкая проблема
Как уже сказал @photox, эту проблему можно решить только с одним скрытым слоем. Я даже подозреваю, что это можно сделать без скрытого слоя. Это потому, что эта проблема линейно отделима .
Есть несколько решений:
Слишком сложная модель
Ваша модель состоит из нескольких частей, которые увеличивают сложность, но не помогают оптимизатору найти оптимальный оптимум.
Другой пример - оптимизатор Adam с множеством дополнительных параметров. Оптимизатор Adam может хорошо работать с этими параметрами, но почему бы вам не начать с простого
SGD
оптимизатора со значениями по умолчанию.Таким образом, вы можете сделать несколько оптимизаций:
LinearRegression
от scikit-Learn. Хорошо, это не то, что вы хотите, но я просто хочу показать, насколько сложна эта модель.Dense
слоевSGD
оптимизатор по умолчаниюsigmoid
активацию. Вы можете думать о каждом из узлов скрытого слоя как об обнаружении, если квадрат находится в определенном месте.Ps
Я думаю, вам понравится этот пост от Adit Deshpande.
источник
Это похоже на типичную проблему переоснащения. Ваши данные не предоставляют достаточно информации, чтобы получить лучший результат. Вы выбираете комплекс NN с вашим поездом, чтобы запомнить все нюансы данных поезда . Потеря никогда не может быть нулем, как на вашем графике. Кстати, кажется, что ваша проверка имеет ошибку или набор проверки не подходит для проверки, потому что потеря проверки также становится равной нулю.
источник
Я столкнулся с той же проблемой с моим набором данных. Оказывается, в моем случае предикторы сильно сконцентрированы с очень малой дисперсией. Вы должны проверить дисперсию ваших предсказательных переменных и посмотреть, как она распределяется.
Тем не менее, некоторые преобразования выходной переменной могут быть выполнены для изменения или изменения ее масштаба. Это может привести к более равномерному распределению типов. Например, в задачах распознавания изображений выравнивание гистограммы или усиление контрастности иногда работают в пользу правильного принятия решения.
источник
Я на самом деле работал над очень похожей проблемой. По сути, у меня было множество точек на белом фоне, и я обучал 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 со стохастическим градиентным спуском. Это решило мои проблемы, и моя сеть, наконец, научилась запоминать мой тренировочный набор. Он не слишком хорошо подходит для тестирования, но, по крайней мере, он работает, что является лучшим решением, чем большинство других предложили по вашему вопросу.
источник