Keras Fine Tuning(微调)(2)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/github_39611196/article/details/86476284

目录

Keras Fine Tuning(微调)(1)

Keras Fine Tuning(微调)(2)

Keras Fine Tuning(微调)(3)

数据集下载:https://download.csdn.net/download/github_39611196/10940372


接上一篇博客: Keras Fine Tuning(微调)(1) ,本文主要介绍Keras中的fine tuning(微调),通过对西瓜、南瓜、番茄数据集进行分类来进行实例说明。

与上一篇博客冻结所有层不同,本片博客主要介绍对除最后四层外的VGG 16模型的网络层进行冻结,然后不做数据增强的数据集进行训练。

代码:

from keras.applications import VGG16

# 加载VGG模型
vgg_conv = VGG16(weights='imagenet', include_top=False, input_shape=(image_size, image_size, 3))

# 冻结除所有层
for layer in vgg_conv.layers[:-4]:
    layer.trainable = False
    
# 检查每一层trainable属性的状态
for layer in vgg_conv.layers:
    print(layer, layer.trainable)

from keras import models
from keras import layers
from keras import optimizers

# 创建模型
model = models.Sequential()

# 加入vgg的基础卷积网络
model.add(vgg_conv)

# 加入新的网络层
model.add(layers.Flatten())
model.add(layers.Dense(1024, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(3, activation='softmax')) # softmax 用于分类的激活函数

# 输出模型
model.summary()

# 训练模型
# 不做数据增强(Data Augmentation)
train_datagen = ImageDataGenerator(rescale=1./ 255)
validation_datagen = ImageDataGenerator(rescale=1./ 255)

# batch size
train_batchsize = 100
val_batch_size = 10

# 训练数据的数据生成器
train_generator = train_datagen.flow_from_directory(train_dir, target_size=(image_size, image_size), batch_size=train_batchsize, class_mode='categorical')  # categorical用于分类的时候使用

# 测试数据的数据生成器
validation_generator = validation_datagen.flow_from_directory(validation_dir, target_size=(image_size, image_size), batch_size=val_batchsize, class_mode='categorical', shuffle=False)

# 编译模型
model.compile(loss='categorical_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc'])

# 训练模型
history = model.fit_generator(train_generator, steps_per_epoch=train_generator.samples/ train_generator.batch_size, epochs=20, validation_data=validation_generator, validation_steps=validation_generator.samples/validation_generator.batch_size, verbose=1)

# 保存模型
model.save('last4_layers.h5')

# 显示正确率和损失曲线
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'b', label="Training acc")
plt.plot(epochs, val_acc, 'r', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'b', label='Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

# 显示错误分类的结果
validation_generator =validation_datagen.flow_from_directory(validation_dir, target_size=(image_size, image_size), batch_size=val_batchsize, class_mode='categorical', shuffle=False)

# 从生成器中获取文件名
fnames = validation_generator.filenames

# 从生成器中获取ground truth
ground_truth = validation_generator.classes

# 从生成器中获取类标签到类索引的映射
label2index = validation_generator.class_indices

# 从生成器中获取类索引到类标签的映射
idx2label = dict((v, k) for k, v in label2index.items())

# 通过生成器获取模型的预测值
predictions = model.predict_generator(validation_generator, steps=validation_generator.samples/ validation_generator.batch_size, verbose=1)
predicted_classes = np.argmax(predictions, axis=1)

errors =np.where(predicted_classes != ground_truth)[0]

print("No of errors = {}/{}".format(len(errors),validation_generator.samples))

# 显示分类错误的结果
for i in range(len(errors)):
    pred_class = np.argmax(predictions[errors[i]])
    pred_label = idx2label[pred_class]
    
    title = 'Original label:{}, Prediction :{}, confidence : {:.3f}'.format(
        fnames[errors[i]].split('/')[0],
        pred_label,
        predictions[errors[i]][pred_class])
    
    original = load_img('{}/{}'.format(validation_dir,fnames[errors[i]]))
    plt.figure(figsize=[7,7])
    plt.axis('off')
    plt.title(title)
    plt.imshow(original)
    plt.show()

准确率:

loss:

错误率:

分类错误的图片(部分):

猜你喜欢

转载自blog.csdn.net/github_39611196/article/details/86476284