Точность Keras CNN либо статична, либо слишком высока для классификации изображений

#python #tensorflow #keras #deep-learning #conv-neural-network

#python #тензорный поток #keras #глубокое обучение #conv-нейронная сеть

Вопрос:

Я пытаюсь реализовать сверточную нейронную сеть, которая может определять, носит ли человек очки или нет. К сожалению, я продолжаю получать очень странные результаты, независимо от того, какие точные настройки я использую для скорости обучения, конкретного оптимизатора и т. Д. При большинстве настроек я замечаю, что точность моей модели не меняется после второй эпохи и застревает на отметке 0,56 (что близко к соотношению одной метки, 2700 изображений, по сравнению с другой меткой, 2200 изображений). В других прогонах с немного другими настройками точность внезапно возрастает примерно до 0,9 и продолжает увеличиваться. Однако в обоих случаях модель каждый раз предсказывает одну и ту же классификацию («в очках») (даже для изображений, которые были в наборе обучения / проверки), всегда с уровнем достоверности 100% (метка каждый раз равна ровно 1).

Я не очень разбираюсь в нейронных сетях для классификации изображений, поэтому я не совсем уверен, как разобраться в проблеме. Я попытался распечатать некоторые значения из моего набора данных и их соответствующие метки, и метки содержат обе метки (0 и 1). Поэтому я предполагаю, что это, вероятно, проблема с моей моделью, но я сам не могу разобраться. Я пробовал разные оптимизаторы (в основном Adam, SGD), меньшую и большую скорость обучения, разные значения импульса, меньше / больше сверточных слоев и разные параметры для заполнения и kernel_initializer, разные размеры пакетов… Он по-прежнему зависит либо от очень быстрого повышения точности, либо от статической.

Мой код выглядит следующим образом:

 #parameters
batch_size = 16
img_height = 180
img_width = 180
num_classes = 2
epochs = 10

#training data
train_db = tf.keras.preprocessing.image_dataset_from_directory(
  `D:archivefaces`,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width), color_mode = "grayscale",
  batch_size=batch_size)

#validation data
val_db = tf.keras.preprocessing.image_dataset_from_directory(
  `D:archivefaces`,
  validation_split=0.2,
  subset="validation",
  seed=123,
  image_size=(img_height, img_width), color_mode = "grayscale",
  batch_size=batch_size)

#speeds up the model training
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_db = train_db.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_db = val_db.cache().prefetch(buffer_size=AUTOTUNE)

#establishing the model
model = Sequential([
layers.experimental.preprocessing.Rescaling(1./255),
layers.Conv2D(16, (3,3), activation='relu', input_shape=(img_width, img_height, 1), kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2, 2),
layers.Conv2D(32, (3,3), activation='relu', kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2,2),
layers.Conv2D(64, (3,3), activation='relu', kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2,2),
layers.Conv2D(64, (3,3), activation='relu', kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2,2),
layers.Conv2D(64, (3,3), activation='relu', kernel_initializer='he_uniform', padding='same'),
layers.MaxPooling2D(2,2),
layers.Flatten(),
layers.Dense(512, activation='relu', kernel_initializer='he_uniform'),
layers.Dense(1, activation='sigmoid')
])

#different optimizer options
opt = tf.keras.optimizers.SGD(learning_rate=0.001, momentum=0.9)
opt2 = tf.keras.optimizers.Adam(learning_rate=0.001)

#compiling the model
model.compile(
  optimizer=opt,
  loss=tf.losses.BinaryCrossentropy(),
  metrics='accuracy')

#training the model
model.fit(train_db,validation_data=val_db,epochs=epochs)
  

Ответ №1:

поскольку вы используете loss=tf.losses .BinaryCrossentropy() затем в image_dataset_from_directory вам нужно добавить label_mode=’binary’ как для train_db, так и для val_db. Для val_db добавьте shuffle=False

Комментарии:

1. Я пытался добавить это, к сожалению, безрезультатно. Что, казалось, имело значение, так это использование гораздо меньшего объема данных (10% от фактического набора данных), теперь он фактически предсказывает значения от 0 до 1.

2. попробуйте добавить batch_size=batch_size в model.fit