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,_ = xx_test = np.concatenate((x_test,yy),axis=0)count+=1if 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()

得到的分类报告结果:

 

 混淆矩阵:

 错分报告:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1379722.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

软件欺诈的骗局揭露:“替罪羊”究竟是如何构建的?

创建一个能工作的软件产品是很困难的,卖欺诈性的软件产品要容易得多。 声明:本文已获作者Matt Stancliff翻译授权。 作者 | Matt Stancliff 译者 | 苏本如,责编 | 郭芮 头图 | CSDN 下载自东方 IC 出品 | CSDN(ID:CSDN…

什么?我要对AI礼貌?人机交互面临的道德漏洞

作者 | 库珀 来源 | 数据实战派 头图 | 付费下载于 IC Photo 如果你在一条道路上行驶,突然前面拐弯处出现一辆无人驾驶汽车,你会继续坚持你的道路优先权,还是让位使它先过去? 目前,我们大多数人在涉及其他人的情况下能…

Docker安装 elasticsearch-head

目录 前言安装elasticsearch-head步骤1:准备1. 安装docker2. 搜索可以使用的镜像。3. 也可从docker hub上搜索镜像。4. 选择合适的redis镜像。 步骤2:拉取elasticsearch-head镜像拉取镜像查看已拉取的镜像 步骤3:创建容器创建容器方式1&#…

猿创征文|瑞吉外卖——管理端_菜品管理_1

个人名片: 博主:酒徒ᝰ. 专栏:瑞吉外卖 个人简介:沉醉在酒中,借着一股酒劲,去拼搏一个未来。 本篇励志:真正的程序员不看参考手册,新手和胆小鬼才会看。 本项目基于B站黑马程序员Jav…

【CSS】CSS 布局——常规流布局

<h1>基础文档流</h1><p>我是一个基本的块级元素。我的相邻块级元素在我的下方另起一行。</p><p>默认情况下&#xff0c;我们会占据父元素 100%的宽度&#xff0c;并且我们的高度与我们的子元素内容一样高。我们的总宽度和高度是我们的内容 内边距…

SpringBoot整合、SpringBoot与异步任务

目录 一、背景描述二、简单使用方法三、原理五、使用自定义线程池六、Async失效情况 一、背景描述 java 的代码是同步顺序执行&#xff0c;当我们需要执行异步操作时我们通常会去创建一个新线程去执行。比如new Thread()。start()&#xff0c;或者使用线程池线程池 new Thread…

stm工程文件夹

STM32工程文件构成 从下图可以看出我们的工程目录是由CORE、OBJ、STM32F10x_FWLib、USER、SYSTEM以及HARDWARE文件夹组成的。此外还有一个文本文档README.TXT、以及一个Windows 批处理文件 (.bat)keilkilll.bat。 1、CORE文件夹 CORE文件夹下一共有三个文件&#xff0c;它们分…

STL文件及其读取

1引言 STL(Stereo lithographic)文件格式是美国3D SYSTEMS公司提出的三维实体造型系统的一个接口标准&#xff0c;其接口格式规范。采用三角形面片离散地近似表示三维模型&#xff0c;目前已被工业界认为是快速成形(rapid prototypi ng)领域的标准描述文件格式。在逆向工程、有…

Python-OpenCV中的图像处理-直方图

Python-OpenCV中的图像处理-直方图 直方图统计直方图绘制直方图Matplotlib绘制灰度直方图Matplotlib绘制RGB直方图 使用掩膜统计直方图直方图均衡化Numpy图像直方图均衡化OpenCV中的直方图均衡化CLAHE 有限对比适应性直方图均衡化 2D直方图OpenCV中的2D直方图Numpy中2D直方图 直…

基于frida检测demo来学习frida检测及anti

原文地址:https://www.zhuoyue360.com/crack/108.html 前言 随着逆向的攻防强度不断的提升,目前主流的移动安全厂商的加固服务基本上都已包含了常见Hook框架的反调试,我们最常见的hook工具如下: fridaxposed 为了更好的提升自己相关的经验,我们可以拿这类demo来进行原理的学…

腾讯云轻量应用服务器镜像应用模板清单大全

腾讯云轻量应用服务器支持多种应用模板镜像&#xff0c;Windows和Linux镜像模板都有&#xff0c;如&#xff1a;宝塔Linux面板腾讯云专享版、WordPress、WooCommerce、LAMP、Node.js、Docker CE、K3s、宝塔Windows面板和ASP.NET等应用模板镜像&#xff0c;腾讯云服务器网分享腾…

聊一下互联网开源变现

(点击即可收听) 互联网开源变现其实是指通过开源软件或者开放源代码的方式&#xff0c;实现收益或盈利。这种方式越来越被广泛应用于互联网行业 在互联网开源变现的模式中&#xff0c;最常见的方式是通过捐款、广告、付费支持或者授权等方式获利。 例如&#xff0c;有些开源软件…

Linux 基础(五)常用命令-文件属性

文件属性 文件权限文件属性修改文件权限属性 文件所有者 文件权限 文件属性 Linux中文件权限 可以通过文件属性体现&#xff1b; 使用 ll 查看文件列表 最前面的 l d 表示文件类型 1 5 表示硬链接数 或者 子文件夹个数 所属用户 所属用户组 文件大小 创建/更新时间 文件&…

首个女性向3A手游要来了?获IGN认可,《以闪亮之名》能否突出重围

最近的手游市场可以说是热度十足&#xff0c;各大厂商都发布了旗下新作的消息&#xff0c;3A高自由度似乎成了所有新游的主基调&#xff0c;但说起与众不同&#xff0c;那便不得不说这款《以闪亮之名》&#xff0c;这是本季度新游中唯一一个女性向3A作品。 这款手游主打超自由时…

2009年“五一”假期市民旅游指南

信息来源于&#xff1a;上海旅游官网 为使广大市民更好地领略上海的都市风情&#xff0c;满足 市民的旅游消费需求&#xff0c;丰富节日生活 &#xff0c;本市部分景点 、旅游企业 精心策划&#xff0c;积极准备&#xff0c;推出一系列适合市民市内旅游的节目&#xff0c;在…

常州嬉戏谷游玩全攻略

攻略导读&#xff1a;常州环球动漫嬉戏谷&#xff0c;一座国际动漫游戏体验博览园&#xff0c;颠覆传统&#xff0c;突破创新&#xff0c;定位鲜明&#xff0c;以满足逾4亿中国互联网用户的庞大娱乐需求为目标&#xff0c;以更适合未来前往的体验型公园为前瞻。假面文化的“梦幻…

第四十八周周报

学习目标&#xff1a; 修改ViTGAN 学习内容&#xff1a; 位置编码和多尺度 学习时间&#xff1a; 8.5-8。12 学习产出&#xff1a; 这两周主要工作在修改ViTGAN的结构和代码&#xff0c;将相对位置编码加入ViTGAN并将生成器变为多尺度&#xff0c;由于匹配维度很困难&am…

Jpa与Druid线程池及Spring Boot整合(二): spring-boot-starter-data-jpa 踏坑异常处理方案

Jpa与Druid线程池及Spring Boot整合(一) Jpa与Druid线程池及Spring Boot整合(二)&#xff1a;几个坑 附录官网文档&#xff1a;core.domain-events域事件 从聚合根发布事件 存储库管理的实体是聚合根。在领域驱动设计应用程序中&#xff0c;这些聚合根通常会发布领域事件。Sp…

pass 软件_PASS软件非劣效Logrank检验的h1参数如何设置?

前言 近日&#xff0c;有朋友在《统计咨询》公众号咨询&#xff1a;在使用PASS中的Non-Inferiority Logrank Tests程序计算样本量时&#xff0c;h1(Hazard Rate of Reference Group) 这个参数不懂得如何设置&#xff1f;见下图红色矩形标注的参数。相信这个也是其他很多朋友碰…

简单聊聊什么是Sass、Pass和Iass?

Iass&#xff0c;Pass和Saas都是什么意思&#xff1f;想必大家都听过也查阅过资料。但现在网上很多文章都会把一些比较简单的概念包装得非常牛气&#xff0c;逼格很高&#xff0c;各种高大上就是不说大白话&#xff0c;本文正好通过搭建网校平台为例和小伙伴简单分享一下它们之…