Таким образом, я пытался настроить VGG16, чтобы классифицировать созданный мной набор данных, который имеет 4 класса, но хотя точность как в обучающих, так и в проверочных наборах хорошо увеличилась, тестирование всегда приводило к точности 25%, независимо от того,что я сделал.Я решил начать с тонкой настройки VGG16 с набора данных о кошках и собаках из Kaggle, и я следовал различным урокам, которые давали хорошие результаты точности.Тем не менее, это та же проблема, с которой я столкнулся в первый раз.Теперь точность составляет 50% (так как это 2 класса).Я начинаю думать, что это проблема Keras VGG16.Я перепробовал различные предложения онлайн, в том числе похожие в похожих вопросах в stackoverflow, но, похоже, ничего не работает.Кажется, что вся предварительная обработка, добавление и замораживание слоев выполняются надлежащим образом, и после нескольких недель пробных ошибок я вынужден обратиться к вашим предложениям / советам по этому вопросу.
Это весь код, который я использую:
from keras.models import Sequential, Model, load_model
from keras import applications
from keras import optimizers
from keras.layers import Dropout, Flatten, Dense
from keras.preprocessing.image import ImageDataGenerator
from sklearn.metrics import classification_report,confusion_matrix
from keras.callbacks import ModelCheckpoint
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
Далее я использую реализацию функции матрицы смешения.
def plot_confusion_matrix_two(cm,
target_names,
title='Confusion matrix',
cmap=None,
normalize=True):
import matplotlib.pyplot as plt
import numpy as np
import itertools
accuracy = np.trace(cm) / float(np.sum(cm))
misclass = 1 - accuracy
if cmap is None:
cmap = plt.get_cmap('Blues')
plt.figure(figsize=(8, 6))
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(title)
plt.colorbar()
if target_names is not None:
tick_marks = np.arange(len(target_names))
plt.xticks(tick_marks, target_names, rotation=45)
plt.yticks(tick_marks, target_names)
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
thresh = cm.max() / 1.5 if normalize else cm.max() / 2
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
if normalize:
plt.text(j, i, "{:0.4f}".format(cm[i, j]),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
else:
plt.text(j, i, "{:,}".format(cm[i, j]),
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))
plt.show()
Вызов VGG16 с весами imagenet и без верхнего слоя + заморозить нижние слои
img_rows, img_cols, img_channel = 224, 224, 3
base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(img_rows, img_cols, img_channel))
for layer in base_model.layers[:-4]:
layer.trainable = False
# check the trainable status of the individual layers
for layer in base_model.layers:
print(layer, layer.trainable)
Добавление последних слоев для классификации наших данных и компиляции модели:
add_model = Sequential()
add_model.add(Flatten(input_shape=base_model.output_shape[1:]))
add_model.add(Dense(256, activation='relu'))
add_model.add(Dropout(0.5))
add_model.add(Dense(2, activation='softmax'))
for layer in add_model.layers[:-3]:
layer.trainable = False
model = Model(inputs=base_model.input, outputs=add_model(base_model.output))
model.compile(loss='categorical_crossentropy', optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
model.summary()
Параметры обучения, пути и т.д ...
image_size = 224
epochs = 500
train_batch = 50
valid_batch = 30
test_batch = 20
train_dir = 'D:/PetImages/train'
valid_dir = 'D:/PetImages/valid'
test_dir = 'D:/PetImages/test'
Генераторы данных для чтения из разных наборов.Наборы находятся в отдельных папках, поэтому в моем случае нет необходимости разбивать поезд и действительны.
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
#vertical_flip=True,
fill_mode='nearest')
validation_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(image_size, image_size),
batch_size=train_batch,
class_mode='categorical',
shuffle=True)
validation_generator = validation_datagen.flow_from_directory(
valid_dir,
target_size=(image_size, image_size),
batch_size=valid_batch,
class_mode='categorical',
shuffle=True)
test_generator = test_datagen.flow_from_directory(
test_dir,
target_size=(image_size, image_size),
batch_size=test_batch,
class_mode='categorical',
shuffle=True)
Обучение модели:
history = model.fit_generator(
train_generator,
steps_per_epoch=train_generator.samples // train_generator.batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=validation_generator.samples // validation_generator.batch_size,
#callbacks=[ModelCheckpoint('VGG16-transferlearning.model', monitor='val_acc', save_best_only=True)]
verbose=1
)
А затем прогнозирование на тестовом наборе для сравнения справдивость и точность и т. д .:
predictions = model.predict_generator(test_generator, steps=test_generator.samples//test_generator.batch_size,
verbose=0)
#Confution Matrix and Classification Report
predictions = np.argmax(predictions, axis=1)
print('Confusion Matrix')
cm = confusion_matrix(test_generator.classes, predictions)
#print(cm)
target_names =['cats', 'dogs']
#target_names =['Bark', 'Jump','Stand', 'Walk']
plot_confusion_matrix_two(cm, target_names, title='Confusion Matrix',cmap=None,normalize=False)
print('Classification Report')
print(classification_report(test_generator.classes, predictions, target_names=target_names))
print('Confusion Matrix')
print(cm)
Я действительно перепробовал все разные трюки, чтобы проверить.Я даже пытался проверить, как модель работает на самих тренировочных данных, а не на тестовых, и все равно дает 50% (что очень странно, учитывая, что точность обучения достигает почти 99%).Я пытался настроить гиперпараметры, разные алгоритмы, но ничего не изменилось.
Система: Windows 10, Anaconda, Keras 2.1.1 Tensorflow-gpu 1.4.0 Python 3.6.4
Используемый набор данных: https://files.fm/u/t6zdskc7
Я застрял уже несколько недель, и это действительно расстраивает.Если кто-нибудь может мне помочь, я буду вечно благодарен !!
Редактировать:
Так что, спросив вокруг, мне сказали, что модель на самом деле учится иЯ могу проверить точность прогноза, используя следующий фрагмент кода:
x, y = zip(*(test_generator[i] for i in range(len(test_generator))))
x_test, y_test = np.vstack(x), np.vstack(y)
loss, acc = model.evaluate(x_test, y_test, batch_size=64)
print("Accuracy: ", acc)
print("Loss: ",loss)
Оказывается, я получаю реальное значение, которое имеет смысл (около 70% в зависимости от настройки гиперпараметров).Так что теперь я предполагаю, что что-то идет не так, когда я пытаюсь проанализировать, используя confusion_matrix и функции отчета.Я все еще не могу найти проблему, хотя.