Модель Keras предсказывает тот же класс - PullRequest
2 голосов
/ 21 февраля 2020

Я новичок в области глубокого обучения, и я попытался обучить модель для классификации изображений. Я использовал предварительно обученную модель (ResNet50) и добавил собственные слои. Набор данных, который я использую для обучения, содержит около 1000 изображений для каждого класса, и я разделил его на обучающие и тестовые наборы. Моя проблема в том, что если я оцениваю модель с model.evaluate(test_set_generator), я получаю точность около 90%

Если я загружаю изображение и прогнозирую с помощью model.predict(img), результат всегда будет одного и того же класса

Мои генераторы:

img_height = 128
img_width = 128

train_datagen = ImageDataGenerator(
    rescale=1./255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)


train_generator = train_datagen.flow_from_directory(
    data_dir_path,
    target_size=(img_height, img_width),
    batch_size=16,
    shuffle=True,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    test_dir_path,
    target_size=(img_height, img_width),
    batch_size=16,
    class_mode='categorical')

моя модель:

    base_model = tf.keras.applications.ResNet50(input_shape=(img_height,img_width,3),
                                                   include_top=False,
                                                   weights='imagenet')
    prediction_layer = tf.keras.layers.Dense(5)

    model = models.Sequential()
    model.add(base_model)
    model.add(tf.keras.layers.GlobalAveragePooling2D())
    model.add(prediction_layer)

    base_learning_rate = 0.0005
    model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=base_learning_rate),
                  loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
                  metrics=['accuracy'])

Как я загружаю изображение:

test_image = image.load_img(path_to_image, target_size=(128, 128))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis=0)

Я пытался загрузить и предсказать каждое изображение из моего набора тестов, и я всегда получал один и тот же результат (это небольшой результат, но более или менее каждый вывод выглядит одинаково):

 [[ -38774.88  -228962.86    20932.826 -169404.3   -265980.06 ]]
 [[ -54851.016 -320424.4     31585.99  -236997.28  -374307.2  ]]
 [[ -36518.344 -212326.48    18832.361 -156810.19  -244721.2  ]]
 [[ -31010.965 -196458.73    19816.562 -146228.39  -230922.06 ]]
 [[ -37712.95  -222710.1     19780.334 -164643.36  -256392.48 ]] 

Я не могу понять, почему оценка дает правильные результаты и прогноз не делает. Я предсказал test_set_generator с model.predict(test_set_generator), и я получил результаты, которые выглядели хорошо для меня. Результаты не всегда были одинаковыми.

Я пытался изменить скорость обучения, больше слоев, выпадающий слой, разное количество эпох и шагов для каждой эпохи, другую предварительно обученную модель и разные размеры партий.

Я благодарен за любые предложения

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

Ваша модель ожидает, что значения изображения находятся в диапазоне (0, 1).

Попробуйте с:

test_image = image.load_img(path_to_image, target_size=(128, 128))
test_image = image.img_to_array(test_image) / 255  # < - division by 255
test_image = np.expand_dims(test_image, axis=0)
0 голосов
/ 21 февраля 2020

В вашем коде есть две ошибки:

  • Во-первых, когда вы вызываете слой Dense без параметров активации, это будет активация linear по умолчанию, в мультиклассовой задаче. нам нужна softmax активация
prediction_layer = tf.keras.layers.Dense(5, activation = "softmax")
  • Во-вторых, потеря, которую вы используете binary_crossentropy, потеря, используемая для двоичной классификации, но здесь мы, опять же, имеем мультиклассовая задача, поэтому вам нужно использовать categorical_crossentropy loss
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=base_learning_rate),
                  loss=tf.keras.losses.CategoricalCrossentropy(),
                  metrics=['accuracy'])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...