Keras--基于VGG16卷积神经网络---猫狗分类

Cats vs. Dogs(猫狗大战)来源于 Kaggle 上的一个竞赛,内容非常简单, Kaggle 提供了一个猫和狗的数据集,我们需要建立一个算法进行训练,最后这个算法要能准确识别出猫和狗。Kaggle 提供的数据集分为训练集和测试集,训练集包含猫和狗各 12500 张图片 测试集包含 12500 张猫和狗的图片。
数据来源:Kaggle Cats vs. Dogs 的网址为 https://www.kaggle.com/c/dogs-vs-cats

这里主要选取了深度学习中VGG16模型,使用tensorflow-gpu2.6.0版本环境。

数据划分:选取了下载的数据集中train文件夹中的3000张图片作为本次实验的主要数据集。将猫狗各1000张图片放入其目录下用于训练的train文件夹中,即用于训练train文件夹中的数据集一共有2000张图片;将猫狗各500张图片放入其目录下用来验证的validation文件夹中,即用于验证的validation的文件夹中一共有1000张图片;将猫狗各500张图片放入test文件夹中,即用于测试的test文件中一共有1000张图片,划分情况如下:

 

(1)数据划分:

#从训练集中选取4000张图片,2000张用于训练,1000张用于验证,1000张用于测试
import os, shutil
original_dataset_dir = './DataSet/train'
base_dir ='./train_dataset/train'
os.mkdir(base_dir)

train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir,'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_dir, 'test')
os.mkdir(test_dir)
# 训练集文件
train_cats_dir = os.path.join(train_dir, 'cats')
os.mkdir(train_cats_dir)
train_dogs_dir = os.path.join(train_dir,'dogs')
os.mkdir(train_dogs_dir)
# 验证集文件
validation_cats_dir = os.path.join(validation_dir,'cats')
os.mkdir(validation_cats_dir)
validation_dogs_dir = os.path.join(validation_dir,'dogs')
os.mkdir(validation_dogs_dir)
#测试集文件
test_cats_dir = os.path.join(test_dir,'cats')
os.mkdir(test_cats_dir)
test_dogs_dir = os.path.join(test_dir,'dogs')
os.mkdir(test_dogs_dir)

#train--cats
fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(train_cats_dir, fname)
    shutil.copyfile(src, dst)

#validation---cats
fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(validation_cats_dir, fname)
    shutil.copyfile(src, dst)

#test---cats
fnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(test_cats_dir, fname)
    shutil.copyfile(src, dst)

fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(train_dogs_dir, fname)
    shutil.copyfile(src, dst)

fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(validation_dogs_dir, fname)
    shutil.copyfile(src, dst)

fnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir, fname)
    dst = os.path.join(test_dogs_dir, fname)
    shutil.copyfile(src, dst)

(2)基于VGG16构建模型:

from keras import models, layers
from tensorflow.keras.applications import VGG16
from tensorflow import optimizers
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
#训练样本的目录
train_dir='./train_dataset/train/train'
#验证样本的目录
validation_dir='./train_dataset/train/validation'
#测试样本目录
test_dir='./train_dataset/train/test'

#训练集生成器---训练集数据加强
train_datagen=ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest')

train_generator=train_datagen.flow_from_directory(
    directory=train_dir,
    target_size=(150,150),
    class_mode='binary',
    batch_size=20
)

#验证样本生成器
validation_datagen=ImageDataGenerator(rescale=1./255)
validation_generator=validation_datagen.flow_from_directory(
    directory=validation_dir,
    target_size=(150,150),
    class_mode='binary',
    batch_size=20
)

#测试样本生成器
test_datagen=ImageDataGenerator(rescale=1./255)
test_generator=test_datagen.flow_from_directory(
    directory=test_dir,
    target_size=(150,150),
    class_mode='binary',
    batch_size=20
)
print(train_generator.class_indices)
print(test_generator.class_indices)
print(validation_generator.class_indices)

#VGG 16实例化---使用imagenet数据集训练,不包含顶层(即全连接层)
conv_base = VGG16(weights='imagenet',
                  include_top=False,  #是否指定模型最后是否包含密集连接分类器
                  input_shape=(150, 150, 3))
#冻结卷积基----保证其权重在训练过程中不变--不训练这个,因为参数太多
conv_base.trainable = False

#构建网络模型----基于VGG16建立模型
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten(input_shape=conv_base.output_shape[1:]))  #图片输出四维,1代表数量
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))  #二分类

#定义优化器、代价函数、训练过程中计算准确率
model.compile(optimizer=optimizers.Adam(lr=0.0005/10),
              loss='binary_crossentropy',
              metrics=['acc'])
model.summary()

#拟合模型
history=model.fit_generator(
    train_generator,
    steps_per_epoch=100,
    epochs=20,
    validation_data=validation_generator,
    validation_steps=50
)
#保存模型
model.save('./model/data/model4_2_VGG 16_cats_vs_dogs_1.h5')

#评估测试集的准确率
test_eval=model.evaluate_generator(test_generator)
print("测试集准确率:",test_eval)
train_eval=model.evaluate_generator(train_generator)
print("训练集准确率:",train_eval)
val_eval=model.evaluate_generator(validation_generator)
print("验证集准确率:",val_eval)

#绘制训练过程中的损失曲线和精度曲线
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'bo')
plt.plot(epochs, acc, 'b', label='Training acc')
plt.plot(epochs,val_acc, 'ro')
plt.plot(epochs, val_acc, 'r', label='Validation acc')
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()
plt.plot(epochs, loss, 'bo')
plt.plot(epochs, loss,'b', label ='Training Loss')
plt.plot(epochs, val_loss,'ro')
plt.plot(epochs, val_loss,'r',label='Validation Loss')

plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.title("Training Loss and Validation Loss")
plt.legend()
plt.show()

模型训练20次的训练过程:

 模型训练后得到训练集验证集的准确率与损失率的效果:

 从test测试集中选取猫50张图片,狗50张图片组成新的一个test2进行模型的预测:

在test2文件夹中同样分cats、dogs两个分类,其中在cats有50张猫的图片,dogs中50张狗的图片

from keras.models import load_model
from keras.preprocessing.image import ImageDataGenerator, img_to_array,load_img
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
from sklearn.metrics import recall_score

#加载模型
model = load_model('./model/data/model4_2_VGG 16_cats_vs_dogs_1.h5')
model.summary()

test_datagen=ImageDataGenerator(rescale=1./255)
test_generator=test_datagen.flow_from_directory(
    directory="./train_dataset/test2",
    target_size=(150,150),
    shuffle=False,  #不打乱数据集
    class_mode='binary',
    batch_size=20
)
# print(test_datagen)
# print(test_generator.labels)
#预测
result=model.predict(test_generator)   #y_pred
result = [(int) ((result[i][0] + 0.5) / 1.0) for i in range(len(result))] #转为整数
print(result)
test_label=test_generator.classes    #y_test
print(test_label)


#分类报告
from sklearn.metrics import classification_report
print("分类报告:\n",classification_report(test_label, result))
print("混淆矩阵:\n",confusion_matrix(test_label, result))
print("召回率:",recall_score(test_label,result))

#绘制混淆矩阵
predict = ["cat","dog"]
fact = ["cat","dog"]
classes = list(set(fact))
r1 = confusion_matrix(test_label, result)
plt.figure(figsize=(12,10))
confusion = r1
plt.imshow(confusion, cmap=plt.cm.Blues)
indices = range(len(confusion))
indices2 = range(3)
plt.xticks(indices,classes,rotation=40,fontsize=18)
plt.yticks([0.00,1.00],classes,fontsize=18)
plt.ylim(1.5,-0.5)  #设置y的纵坐标的上下限
plt.title("Confusion matrix",fontdict={'weight':'normal','size':18})
#设置color bar的标签大小
cb = plt.colorbar()
cb.ax.tick_params(labelsize=18)
plt.xlabel('Predict label',fontsize=18)
plt.ylabel('True label',fontsize=18)
print("len(confusion",len(confusion))
for first_index in range(len(confusion)):
    for second_index in range(len(confusion[first_index])):
        if confusion[first_index][second_index]>200:
            color='black'
        else:
            color="black"
        plt.text(first_index,second_index,confusion[first_index][second_index],fontsize=18,color=color,verticalalignment='center',horizontalalignment='center')
# plt.show()

#绘画错分报告
#使用迭代器选取图片的x_test--遍历整个test2文件夹--test2中有100张图片
count=0
it=iter(test_generator)
x_test,_ = next(test_generator)
print(_)
for x in it:
    yy,_ = x
    x_test = np.concatenate((x_test,yy),axis=0)
    count+=1
    if count==100:
        break

#绘画错分报告
result = np.reshape(result, (-1, 1))
test_label = np.reshape(test_label, (-1, 1))

ins = test_label != result
diff_index = np.where(ins == True)[0]  # 查找不相同的下标
# print("diff_index:",diff_index)
numForPaint = 8  #只选取前8张错分图片
plt.figure()
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负

lables = ['猫','狗']
for i in range(numForPaint):    #只显示前8个
    j=diff_index[i]
    img = x_test[j]
    y_t = test_label[j][0]
    y_p = result[j][0]
    plt.subplot(2, 4, i + 1, xticks=[], yticks=[])  # 2*8子图显示
    plt.imshow(img)  # 黑白显示
    plt.title(f'{lables[y_t]}--> {lables[y_p]}')  # 显示标题
    plt.subplots_adjust(wspace=0.1, hspace=0.2)  # 调整子图间距
plt.show()


得到的分类报告结果:

 

 混淆矩阵:

 错分报告:

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程导语:    人工智能可谓是现阶段最火的行业,在资本和技术协同支持下正在进入高速发展期。当今全球市值前五大公司都指向同一发展目标:人工智能。近几年,人工智能逐渐从理论科学落地到现实中,与生活越来越息息相关,相关的各种职位炙手可热,而深度学习更是人工智能无法绕开的重要一环。 从AlphaGo打败李世石开始,深度学习技术越来越引起社会各界的广泛关注。不只学术界,甚至在工业界也取得了重大突破和广泛应用。其中应用最广的研究领域就是图像处理和自然语言处理。而要入门深度学习,CNN和RNN作为最常用的两种神经网络是必学的。网上关于深度学习的资料很多,但大多知识点分散、内容不系统,或者以理论为主、代码实操少,造成学员学习成本高。本门课程将从最基础的神经元出发,对深度学习的基础知识进行全面讲解,帮助大家迅速成为人工智能领域的入门者,是进阶人工智能深层领域的基石。 讲师简介:赵辛,人工智能算法科学家。2019年福布斯科技榜U30,深圳市海外高层次人才(孔雀人才)。澳大利亚新南威尔士大学全奖博士,SCI收录其发表过的10篇国际期刊学术文章。曾任深圳市微埃智能科技有限公司联合创始人。CSDN人工智能机器学习、深度学习方向满分级精英讲师。授课风格逻辑严谨、条理清晰、循序渐进、循循善诱,化枯燥为如沐春风,所教学生人数过万。 课程设计: 本课程分为5大模块,19小节,共计540时长(约9小时): 第一部分,课程介绍、目标与内容概览。主要学习人工智能深度学习应用场景;熟悉深度学习主流技术;掌握使用keras解决深度学习主要问题(神经网络、卷积神经网络、循环神经网络),以及深度学习主要内容:神经网络、卷积神经网络、循环神经网络;案例简介。 第二部分,深度学习之多层感知器(MLP)。主要学习多层感知器(MLP);MLP实现非线性分类深度学习实战准备;Python调用keras实现MLP。 MLP技术点实战案例:第三部分,深度学习卷积神经网络(CNN)。主要学习卷积神经网络 ; CNN模型分析;主流CNN模型; Python调用keras实现CNN; CNN技术点实战案例:第四部分,深度学习之循环神经网络(RNN)。主要学习循环神经网络;RNN模型分析;Python调用keras实现RNN。 RNN技术点实战案例: 第五部分,综合提升。主要进行迁移学习;混合模型;实战准备+综合实战,以及最后进行课程内容总结。 混合模型技术点实战案例
对于图像分类VGG16是一个常用的卷积神经网络模型。VGG16模型由16个卷积层和3个全连接层组成,其结构相对简单且易于理解。 首先,你需要准备一个包含图片的数据集,并将其分为训练集和测试集。然后,使用VGG16模型对图片进行特征提取和分类。 你可以使用Keras库来实现VGG16模型。首先,导入所需的库和模块: ```python from keras.applications.vgg16 import VGG16 from keras.models import Sequential from keras.layers import Dense, Flatten from keras.preprocessing.image import ImageDataGenerator ``` 接下来,加载预训练的VGG16模型: ```python vgg16 = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3)) ``` 然后,创建一个新的顺序模型,并添加VGG16模型作为其第一层: ```python model = Sequential() model.add(vgg16) ``` 在VGG16之后,添加一些全连接层来进行分类: ```python model.add(Flatten()) model.add(Dense(256, activation='relu')) model.add(Dense(1, activation='sigmoid')) ``` 接下来,编译模型并指定优化器、损失函数和评估指标: ```python model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) ``` 然后,使用ImageDataGenerator来生成批次的图像数据,并进行模型的训练: ```python 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('train_directory', target_size=(224, 224), batch_size=32, class_mode='binary') test_generator = test_datagen.flow_from_directory('test_directory', target_size=(224, 224), batch_size=32, class_mode='binary') model.fit(train_generator, steps_per_epoch=len(train_generator), epochs=10, validation_data=test_generator, validation_steps=len(test_generator)) ``` 最后,你可以使用训练好的模型对新的图像进行分类: ```python predictions = model.predict(test_images) ``` 这样,你就可以使用VGG16模型对图像进行分类了。希望这个回答能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值