vgg16微调狗猫失败的测试数据

问题描述 投票:0回答:2

所以,我一直在试图微调一个VGG16为了一个数据集我做它有4类进行分类,但同时在训练和验证集的准确性增加好,测试总是导致25%的准确率,无论我做什么。我决定通过微调第一次启动的猫一狗VGG16从数据集和Kaggle我也跟着,进行了良好的精度结果不同的教程。但是,这是我遇到的第一次同样的问题。现在,精度为50%(因为它是2类)。我开始认为这是一个Keras VGG16问题。我尝试了所有不同的建议,包括在线计算器中类似的那些类似的问题,但似乎没有任何工作。所有的预处理,增加和层冻结似乎是适当的进行,误差试验星期后,我觉得自己有责任把您的建议/咨询此事。

这是我使用的全部代码:

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,蟒蛇,硬GPU Tensorflow 2.1.1 1.4.0 3.6.4的Python

数据集用于: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和报告功能来分析。我仍然无法找到,虽然这个问题。

machine-learning keras neural-network computer-vision
2个回答
0
投票

到我做了一个数据集,其具有4类分类

对于初学者来说,你的网络配置似乎很奇怪的一个4级分类问题(至少可以这样说);第一个建议:

  1. 更改你的模型汇编loss='categorical_crossentropy'
  2. 改变你的最后一层
add_model.add(Dense(4, activation='softmax'))

因为,由于你的predictions = np.argmax(predictions, axis=1)行,我假设你已经在使用一个热经编码标签...


0
投票

模型=模型(输入= base_model.input,输出= add_model(base_model.output))你未能正确添加新层。只需使用功能的API。

out = base_model.output
out = Flatten()(out)
out = Dense(256, activation='relu')(out)
out = Dropout(0.5)(out)
out = Dense(2, activation='softmax')(out)
for layer in add_model.layers[:-3]:
    layer.trainable = False
model = Model(inputs=base_model.input, outputs=out)
© www.soinside.com 2019 - 2024. All rights reserved.