Как осуществить поиск объекта на изображении с помощью полносверточной нейронной сети
📁 python, вопрос, помощь, пример, боты, ии
Здравствуйте, стоит задача поиска объекта с помощью полносверточной нейронной сети, используя Keras, theano, на языке python. На данный момент используется вот такая конфигурация сети:
def create_encoding_layers(): keel = 3 filter_size = 64 pad = 1 pool_size = 2 retu [ ZeroPadding2D(padding=(pad,pad)), Convolution2D(filter_size, keel, keel, border_mode='valid'), BatchNormalization(), Activation('relu'), MaxPooling2D(pool_size=(pool_size, pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(32, keel, keel, border_mode='valid'), BatchNormalization(), Activation('relu'), MaxPooling2D(pool_size=(pool_size, pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(32, keel, keel, border_mode='valid'), BatchNormalization(), Activation('relu'), MaxPooling2D(pool_size=(pool_size, pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(64, keel, keel, border_mode='valid'), BatchNormalization(), Activation('relu'), ] def create_decoding_layers(): keel = 3 filter_size = 64 pad = 1 pool_size = 2 retu[ ZeroPadding2D(padding=(pad,pad)), Convolution2D(64, keel, keel, border_mode='valid'), BatchNormalization(), UpSampling2D(size=(pool_size,pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(32, keel, keel, border_mode='valid'), BatchNormalization(), UpSampling2D(size=(pool_size,pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(32, keel, keel, border_mode='valid'), BatchNormalization(), UpSampling2D(size=(pool_size,pool_size)), ZeroPadding2D(padding=(pad,pad)), Convolution2D(filter_size, keel, keel, border_mode='valid'), BatchNormalization(), ZeroPadding2D(padding=(0,pad+1)), ] segnet_basic = models.Sequential() segnet_basic.add(Layer(input_shape=(120, 420, 1))) segnet_basic.encoding_layers = create_encoding_layers() for l in segnet_basic.encoding_layers: segnet_basic.add(l) segnet_basic.decoding_layers = create_decoding_layers() for l in segnet_basic.decoding_layers: segnet_basic.add(l) segnet_basic.add(Convolution2D(1, 1, 1, border_mode='valid',)) segnet_basic.summary() segnet_basic.add(Reshape((120,420,1)))На вход подается фотография и маска(область, где находится объект заполнена единицами, а остальная область нулями). Как я понимаю, на выходе мы должны получить такую же маску. Пробовал разные функции потерь. На выходе получается ерунда. Собственно вопрос: что нужно исправить, чтобы получить на выходе аналогичную маску ? Какую функцию потерь и optimizer использовать? На картинке пример работы уже обученной сети. image - изображение, которое подается сети, label - ожидаемый результат, который я для вывода умно��ил на 255, result - то, что выдает сеть.Так же умножил на 255 для вывода
Исходя из того, что указано в вопросе, можно сделать выводы:
- Ваша НС, вероятно, переобучается. Это следует из того, что на train множестве Вы имеете хорошие результаты, а на тестовом -- никакие. Один из возможных вариантом -- это использование регуляризации. Кроме того, попробуйте использовать метод
dropOut. Данная техника способствует уменьшению переобучения путём случайного исключения связей в НС. - Вам необходимо делать cross-validation (cv). Данная процедура проводится для оценки модели и подбора параметров. Нас интересут оценка. В scikit-lea есть замечательные механизмы, позволяющие это делать. Один из вариантов cv (вам он подходит больше, так как ваша выборка маленькая) заключается в том, что исходное множество разбивается на 2 части (например): 0.3 - 0.7. Та часть, которая больше 0.7 является обучающим множеством. Та часть, которая меньше -- валидационном. Мы производим обучение на обучающем множестве. После чего проверяем наш результат на валидационном. Проделаем так много раз. Возьмите, для простоты 10. Всё зависит от дисперсии ответов и размера множества. Если cv не делать, то судить о модели никак нельзя.
- Ещё одной вероятной причиной переобучения является наличие большого количества слоёв в НС при необльшом количестве примеров.
- Для того, чтобы повысить число примеров, можно воспользоваться нарезкой изображений. Берём и режем каждое изображение на необшие области, сопостовимые с объектом интереса (желательно, чтобы области были больше объекта). Лучше резать картинку так, чтобы зоны ложились в нахлёст. Например, пусть исходная картика имеет размер 400х400. Порежем её на семплы 20х20. Будем передвигать окно 20х20 с шагом 10. Тогда получится, что каждое окно будет ложиться на предыдущее. Для каждого окна можно осуществлять предсказание, которое Вы хотели делать.
- Ещё одним возможным вариантом является вращение картинок на небольшие углы. Но данный вид трансформации может быть пагубным (в зависимости от задачи).
Дальнейшие советы давать сложно, поскольку не видно всего множества, а также непонятна конечная цель задачи.
Войдите чтобы оставить ответ