Вопрос или проблема
Я завершил обучение модели с точностью 1.000 и валидационной точностью 0.9565. К сожалению, каждый раз, когда я ввожу изображение в свою модель, я получаю один и тот же результат независимо от изображения. Я делаю что-то не так при прогнозировании или во время обучения? W и A — это метки моих классов.
Моя структура папок для генераторов изображений выглядит следующим образом:
images/
a/
a001.jpg.png..
w/
w002.jpg.png..
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2)
test_datagen = ImageDataGenerator(rescale=1./255)
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(150, 150,3),padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
model.add(Conv2D(32, (3, 3),padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
model.add(Conv2D(64, (3, 3),padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
model.add(Flatten()) # это преобразует наши 3D карты признаков в 1D векторы признаков
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss="binary_crossentropy",
optimizer="rmsprop",
metrics=['accuracy'])
batch_size = 64
# это генератор, который будет считывать изображения, найденные в
# подпапках 'data/train' и бесконечно создавать
# партии увеличенных данных изображений
train_generator = train_datagen.flow_from_directory(
'C:\\Users\\Zahid\\Desktop\\Dataset\\train', # это целевая директория
target_size=(150, 150), # все изображения будут изменены на 150x150
batch_size=batch_size,
color_mode="rgb",
class_mode="binary") # поскольку мы используем потерю binary_crossentropy, нам нужны бинарные метки
# это аналогичный генератор для валидационных данных
validation_generator = test_datagen.flow_from_directory(
'C:\\Users\\Zahid\\Desktop\\Dataset\\val',
target_size=(150, 150),
batch_size=batch_size,
color_mode="rgb",
class_mode="binary")
model.fit_generator(
train_generator,
steps_per_epoch=2000 // batch_size,
epochs=50,
validation_data=validation_generator,
validation_steps=800 // batch_size)
model.save_weights('first_try.h5')
img = cv2.imread("C:\\Users\\Zahid\\Desktop\\Data\\TrainingData\\images\\a\\img_0201.jpg.png")
resized_image = cv2.resize(image, (150, 150))
x = img_to_array(resized_image)
x = x.reshape((1,) + x.shape)
x = x/255
print(x.shape)
scores_train = model.predict(x)
print(scores_train)
Поскольку вы используете сигмоид в качестве функции активации в последнем слое, он будет генерировать вывод на основе вероятности; если вероятность выше 50%, то это принадлежит классу “W”, а если ниже 50% — классу “A”. Если вы сможете распечатать вероятность вывода для различных изображений и поделиться ею, это немного поможет нам понять проблему.
Проблема была устранена изменением слоя Dense на 2, тем самым указав два класса, а также заменив функцию активации Sigmoid на Softmax.
Когда вы делите на 255 в прогнозировании, убедитесь, что тип данных является float, а не int или unsigned int. Убедитесь, что вы неявно конвертируете изображение x в float и делите на 255.0 перед прогнозированием. Другими словами, убедитесь, что ваш массив не состоит только из 0. Вы все равно можете использовать Sigmoid для бинарной классификации с 1 слоем Dense. Это должно сработать.
Ответ или решение
Причины похожего вывода от классификатора Keras и их решения
При работе с нейронными сетями и классификаторами, такими как Keras, может возникнуть ситуация, когда модель выдает идентичный или очень похожий результат для различных входных данных. Это может быть связано с несколькими факторами. Рассмотрим основные причины и предложим решения этой проблемы.
1. Переобучение модели
Ваши данные показывают, что модель достигла точности в 1.000 на обучающем наборе и 0.9565 на валидационном наборе. Очень высокая точность на обучающем наборе может указывать на переобучение. В этом случае модель слишком сильно заучивает конкретные примеры из тренировочного набора, что приводит к плохой обобщающей способности на новых данных.
Решение:
- Используйте регуляризацию, например, Dropout, чтобы избежать переобучения. Проверьте результаты при изменении вышеупомянутого уровня Dropout.
- Увеличьте объем данных для обучения, возможно, с помощью аугментации данных (например, изменения яркости, вращений и т.д.).
- Совместите обе модели обучения (обучающую и валидационную), чтобы лучше понять, как они реагируют на разные классы.
2. Неправильная настройка выходного слоя
Изначально в вашем коде был один выходной нейрон с sigmoid активацией. Это также могло привести к проблеме, когда модель не могла различать два класса. В бинарной классификации, если вы используете один выходной нейрон с активацией sigmoid, модель выдает вероятности, которые могут не различать классы, что ведет к схожим выводам.
Решение:
- Измените последний слой на два нейрона с функцией активации softmax. Это позволит модель более точно различать два класса (например, «A» и «W»):
model.add(Dense(2)) # Изменить на 2 нейрона
model.add(Activation('softmax')) # Использовать softmax для многоклассовой классификации
3. Неправильное нормирование входных данных
Важно правильно нормировать входные данные перед тем, как вводить их в модель. Если входное изображение не правильно нормализовано, оно может не предаваться должным образом, приводя к неправильным предсказаниям.
Решение:
- Убедитесь, что перед актуальным предсказанием входное изображение преобразуется в формат float и что правильная нормализация выполняется:
x = x.astype('float32') # Явное приведение к float
x /= 255.0 # Нормализация
4. Проблемы с данными и их структурой
Структура папок должна быть корректной, а всех изображения — качественными и соответствующими классу. Если в папках с классами содержатся несоответствующие данные или много шумов, это может также приводить к тому, что модель не сможет восстановить схему.
Решение:
- Проверьте целостность и ясность классов в данных. Если в каком-либо классе много помех (нетипичных данных), то это может уменьшить качество вашего обучения.
5. Проверка на новых данных
Как только вы внесли изменения в архитектуру модели и подготовили данные, протестируйте модель на новых, ранее не виденных изображениях, чтобы убедиться, что она действительно научилась различать классы.
Решение:
- Загрузите несколько новых изображений и проведите тесты, чтобы убедиться в общей эффективности модели.
Заключение
Если вы столкнулись с проблемой одинакового вывода на разные изображения в Keras, обязательно проверьте все вышеупомянутые аспекты. Убедитесь, что ваша модель не переобучена, выходной слой правильно настроен, и входные данные корректно нормализованы. Внесите необходимые изменения и протестируйте модель снова, чтобы достичь стабильных и точных результатов.