Точность обучения при подгонке модели не отражена в матрице путаницы - PullRequest
0 голосов
/ 26 сентября 2019

Я тренирую модель классификации изображений, чтобы классифицировать определенные изображения, содержащие классы гор, водопадов и людей.В настоящее время я использую Vgg-Net (трансферное обучение) для обучения этим данным.Во время обучения я получаю почти 93% точности данных обучения и 90% точности данных валидации.Тем не менее, когда я хочу проверить классы, ошибочно классифицированные во время обучения, используя путаницу с данными обучения, точность, по-видимому, намного меньше.Только около 30% данных классифицированы правильно.

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

Код для создания объектов ImageDataGenerator для обучения и проверки

from keras.applications.inception_v3 import preprocess_input, decode_predictions
#Train DataSet Generator with Augmentation
print("\nTraining Data Set")
train_generator = ImageDataGenerator(preprocessing_function=preprocess_input)
train_flow = train_generator.flow(
    train_images, train_labels,
    batch_size = BATCH_SIZE
)

#Validation DataSet Generator with Augmentation
print("\nValidation Data Set")
val_generator = ImageDataGenerator(preprocessing_function=preprocess_input)
val_flow = val_generator.flow(
    validation_images,validation_labels,
    batch_size = BATCH_SIZE
)

Код для построения модели и ее компиляции

# Initialize InceptionV3 with transfer learning
base_model = applications.vgg16.VGG16(weights='imagenet', 
                                include_top=False, 
                                input_shape=(WIDTH, HEIGHT,3))

# add a global spatial average pooling layer
x = base_model.output

x = GlobalAveragePooling2D()(x)
# and a dense layer
x = Dense(1024, activation='relu')(x)
predictions = Dense(len(categories), activation='softmax')(x)

# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
    layer.trainable = False


# this is the model we will train
model = Model(inputs=base_model.input, outputs=predictions)

# compile the model (should be done *after* setting layers to non-trainable)
model.compile(optimizer=optimizers.RMSprop(lr=1e-4), metrics=['accuracy'], loss='categorical_crossentropy')
model.summary()

Код для подгонки модели к набору данных обученияи подтвердите, используя набор данных проверки

import math
top_layers_file_path=r"/content/drive/My Drive/intel-image-classification/intel-image-classification/top_layers.iv3.hdf5"

checkpoint = ModelCheckpoint(top_layers_file_path, monitor='loss', verbose=1, save_best_only=True, mode='min')
tb = TensorBoard(log_dir=r'/content/drive/My Drive/intel-image-classification/intel-image-classification/logs', batch_size=BATCH_SIZE, write_graph=True, update_freq='batch')
early = EarlyStopping(monitor="loss", mode="min", patience=5)
csv_logger = CSVLogger(r'/content/drive/My Drive/intel-image-classification/intel-image-classification/logs/iv3-log.csv', append=True)

history = model.fit_generator(train_flow, 
                              epochs=30, 
                              verbose=1,
                              validation_data=val_flow, 
                              validation_steps=math.ceil(validation_images.shape[0]/BATCH_SIZE),                              
                              steps_per_epoch=math.ceil(train_images.shape[0]/BATCH_SIZE),
                              callbacks=[checkpoint, early, tb, csv_logger])

шаги обучения показывают следующую точность:

Epoch 1/30

91/91 [==============================] - 44s 488ms/step - loss: 0.6757 - acc: 0.7709 - val_loss: 0.4982 - val_acc: 0.8513

Epoch 2/30

91/91 [==============================] - 32s 349ms/step - loss: 0.4454 - acc: 0.8395 - val_loss: 0.3980 - val_acc: 0.8557

.
.

Epoch 20/30

91/91 [==============================] - 32s 349ms/step - loss: 0.2026 - acc: 0.9238 - val_loss: 0.2684 - val_acc: 0.8940

.
.

Epoch 30/30

91/91 [==============================] - 32s 349ms/step - loss: 0.1739 - acc: 0.9364 - val_loss: 0.2616 - val_acc: 0.8984

Прогнозы прогона на самом наборе данных обучения:

import math
import numpy as np
predictions = model.predict_generator(
    train_flow,
    verbose=1,
    steps=math.ceil(train_images.shape[0]/BATCH_SIZE))
predicted_classes = [x[0] for x in enc.inverse_transform(predictions)]
true_classes = [x[0] for x in enc.inverse_transform(train_labels)]

enc - OneHotEncoder

Тем не менее, матрица путаницы выглядит следующим образом:

import sklearn

sklearn.metrics.confusion_matrix(
    true_classes, 
    predicted_classes,
    labels=['mountain','people','waterfall'])

Матрица путаницы (не удалось загрузить более привлекательную картинку)

  ([[315, 314, 283],

   [334, 309, 273],

   [337, 280, 263]])

Полнаякод загружен на https://nbviewer.jupyter.org/github/paridhichoudhary/scene-image-classification/blob/master/Classification_v7.ipynb

1 Ответ

0 голосов
/ 26 сентября 2019

Я полагаю, это из-за train_generator.flow имеет shuffle=True по по умолчанию .Этот результат в predicted_classes не соответствует train_labels.

Может быть, установка shuffle=False на train_generator.flow должна помочь в этом, или вместо этого использовать что-то подобное, что может быть проще для понимания.

predicted_classes = []
true_classes = []
for i in range(len(train_flow)):  # you can just use `len(train_flow)` instead of `math.ceil(train_images.shape[0]/BATCH_SIZE))`
    x, y = train_flow[i]  # you can use `train_flow[i]` like this
    z = model.predict(x)
    for j in range(x.shape[0]):
        predicted_classes.append(z[j])
        true_classes.append(y[j])

Я еще не пробовал, но это должно сработать.

...