Я работал над сетью Keras, чтобы классифицировать изображения в зависимости от того, содержат ли они светофоры или нет, но до сих пор у меня не было успеха. У меня есть набор данных из 11000+ изображений, и для моего первого теста я использовал 240 изображений (точнее, текстовые файлы для каждого изображения со значениями пикселей в градациях серого). Есть только один выход — 0 или 1, указывающий, есть ли на изображении светофоры.
Однако, когда я провел тест, он предсказал только один класс. Учитывая, что на 53/240 изображениях были светофоры, он достигал примерно 79% точности, потому что все время просто предсказывал 0. Я читал, что это может быть связано с несбалансированными данными, поэтому я уменьшил масштаб всего до 4 изображений — 2 со светофором, 2 без.
Даже с этим тестом он по-прежнему оставался с точностью 50% после 5 эпох; это просто предсказание одного класса! На подобные вопросы были даны ответы, но я не нашел ничего, что работает для меня :(
Вот код, который я использую:
from keras.datasets import mnist
from keras import models
from keras import layers
from keras.utils import to_categorical
import numpy as np
import os
train_images = []
train_labels = []
#The following is just admin tasks - extracting the grayscale pixel values
#from the text files, adding them to the input array. Same with the labels, which
#are extracted from text files and added to output array. Not important to performance.
for fileName in os.listdir('pixels1/'):
newRead = open(os.path.join('pixels1/', fileName))
currentList = []
for pixel in newRead:
rePixel = int(pixel.replace('\n', ''))/255
currentList.append(rePixel)
train_images.append(currentList)
for fileName in os.listdir('labels1/'):
newRead = open(os.path.join('labels1/', fileName))
line = newRead.readline()
train_labels.append(int(line))
train_images = np.array(train_images)
train_labels = np.array(train_labels)
train_images = train_images.reshape((4,13689))
#model
model = models.Sequential()
model.add(layers.Dense(13689, input_dim=13689, activation='relu'))
model.add(layers.Dense(13689, activation='relu'))
model.add(layers.Dense(1, activation='softmax'))
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=5, batch_size=1)
Я надеялся, что по крайней мере он сможет распознать изображения в конце. Я действительно хочу перейти к проведению тренировки на моих полных 11 000 примеров, но на данный момент я не могу заставить его работать с 4.
Грубые точки:
Кажется, вы считаете, что количество единиц в ваших плотных слоях должно быть равно размеру ваших данных (13869); это не вариант. Измените их оба на что-то меньшее (в диапазоне 100-200) - они даже не должны быть равными. Не рекомендуется использовать такую большую модель с относительно небольшим количеством выборок данных (изображений).
Поскольку вы находитесь в настройке двоичной классификации с одним узлом на последнем слое, вы должны использовать activation=sigmoid
для этого (последнего) слоя и скомпилировать свою модель с помощью loss='binary_crossentropy'
.
В приложениях для обработки изображений обычно первая пара слоев является сверточной.
@JoshuaPotts Что ж, точность 79% по сравнению с 50%, о которых вы сообщили изначально (т. Е. Случайное угадывание), звучит как большой прогресс, так что это не одно и то же. Я не уверен, что вы имеете в виду, когда «увеличили» свою модель, но в любом случае 240 изображений — это не так уж много. Следующий шаг — попытаться включить сверточные слои; но идея здесь заключалась не в том, чтобы дать полное руководство (что выходит за рамки SO), а только в том, чтобы указать на некоторые классические ошибки в вашем подходе.
Хорошо, понял. На самом деле он застрял на 79%, что и было бы, если бы вы только догадались (137 из 240 изображений не имеют светофоров). Однако, когда я увеличил эпохи до 400 и изменил размер пакета, он в конечном итоге достигает 1, поэтому я думаю, что мне это удалось. Спасибо за вашу помощь!
Интересно - спасибо за ответ. Я внес изменения 1 и 2 в свою модель без успеха. Однако, когда я запускаю его для 20+ эпох, он в конечном итоге достигает 1. Я подумал, что это победа, и снова увеличил его до 240 изображений, но с этим он делает то же самое - остается неизменным на 79%. Есть предположения?