深度学习之基于VGG16与ResNet50实现鸟类识别

鸟类识别在之前做过,但是效果特别差。而且ResNet50的效果直接差到爆炸,这次利用VGG16与ResNet50的官方模型进行鸟类识别。

1.导入库

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os,pathlib,PIL
from tensorflow.keras import layers,models,Sequential,Input,Model
from tensorflow.keras.layers import Conv2D,MaxPooling2D,Flatten,Dense,BatchNormalization,ZeroPadding2D,Activation,AveragePooling2D

# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

2.数据准备

数据所在文件夹

data_dir = "E:/tmp/.keras/datasets/Birds_photos"
data_dir = pathlib.Path(data_dir)
img_count = len(list(data_dir.glob('*/*')))
print(img_count)#共565张图片

labels:一共是4类

all_images_paths = list(data_dir.glob('*'))##”*”匹配0个或多个字符
all_images_paths = [str(path) for path in all_images_paths]
all_label_names = [path.split("\\")[5].split(".")[0] for path in all_images_paths]

超参数的设置

height = 227
width = 227
batch_size = 8
epochs = 20

按照8:2的比例划分训练集与测试集

train_data_gen = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1./255,
    validation_split=0.2
)
train_ds = train_data_gen.flow_from_directory(
    directory=data_dir,
    target_size=(height,width),
    batch_size=batch_size,
    shuffle=True,
    class_mode='categorical',
    subset='training'
)
test_ds = train_data_gen.flow_from_directory(
    directory=data_dir,
    target_size=(height,width),
    batch_size=batch_size,
    shuffle=True,
    class_mode='categorical',
    subset='validation'
)

查看数据

plt.figure(figsize=(15,10))

for images,labels in train_ds:
    for i in range(32):
        ax = plt.subplot(4,8,i+1)
        plt.imshow(images[i])
        plt.title(all_label_names[np.argmax(labels[i])])
        plt.axis("off")
    break
plt.show()

在这里插入图片描述

3.VGG16网络

迁移学习调用VGG16的官方模型

conv_base = tf.keras.applications.VGG16(weights='imagenet',include_top=False)
#设置为不可训练
conv_base.trainable = False
#模型搭建
model = tf.keras.Sequential()
model.add(conv_base)
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(512,activation='relu'))
model.add(tf.keras.layers.Dense(4,activation='sigmoid'))

模型编译&&训练

model.compile(
    optimizer="adam",
    loss='categorical_crossentropy',
    metrics=['accuracy']
)
history = model.fit(
    train_ds,
    validation_data=test_ds,
    epochs=epochs
)

在这里插入图片描述
模型的准确率很高,在博主实验的几个模型中,VGG16的模型准确率是最高的。

保存网络:

model.save("E:/Users/yqx/PycharmProjects/BirdsRec/model.h5")

利用网络模型进行预测:

new_model = tf.keras.models.load_model("E:/Users/yqx/PycharmProjects/BirdsRec/model.h5")
plt.figure(figsize=(18,18))
plt.suptitle("预测结果展示")
for images,labels in test_ds:
    for i in range(8):
        ax = plt.subplot(2,4,i+1)
        plt.imshow(images[i])
        img_array = tf.expand_dims(images[i],0)#增加一个维度
        pre = new_model.predict(img_array)
        plt.title(all_label_names[np.argmax(pre)])
        plt.axis("off")
    break
plt.show()

在这里插入图片描述
绘制混淆矩阵

from sklearn.metrics import confusion_matrix
import seaborn as sns
import pandas as pd

#绘制混淆矩阵
def plot_cm(labels,pre):
    conf_numpy = confusion_matrix(labels,pre)#根据实际值和预测值绘制混淆矩阵
    conf_df = pd.DataFrame(conf_numpy,index=all_label_names,columns=all_label_names)#将data和all_label_names制成DataFrame
    plt.figure(figsize=(8,8))

    sns.heatmap(conf_df,annot=True,fmt="d",cmap="BuPu")#将data绘制为混淆矩阵
    plt.title('混淆矩阵',fontsize = 15)
    plt.ylabel('真实值',fontsize = 14)
    plt.xlabel('预测值',fontsize = 14)
    plt.show()
test_pre = []
test_label = []
for images,labels in test_ds:
    for image,label in zip(images,labels):
        img_array = tf.expand_dims(image,0)#增加一个维度
        pre = model.predict(img_array)#预测结果
        test_pre.append(all_label_names[np.argmax(pre)])#将预测结果传入列表
        test_label.append(all_label_names[np.argmax(label)])#将真实结果传入列表
    break#由于硬件问题。这里我只用了一个batch,一共8张图片。
plot_cm(test_label,test_pre)#绘制混淆矩阵

在这里插入图片描述

4.ResNet50网络

与VGG16不同的是,ResNet50的网络参数设置的是可以训练,经过多次实验,这样ResNet50的实验效果是最好的。

conv_base = tf.keras.applications.ResNet50(weights='imagenet',include_top=False)
#设置为可以训练
conv_base.trainable = True
#模型搭建
model = tf.keras.Sequential()
model.add(conv_base)
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(512,activation='relu'))
model.add(tf.keras.layers.Dense(4,activation='sigmoid'))

在这里插入图片描述
虽然准确率在来回波动,但是整体的准确率是比较高的,比VGG16的准确率还是差一些的。博主关于ResNet50的了解还比较少,等到了解深刻了再回来更新。

  • 6
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
VGG16ResNet50都是经典的深度学习模型,用于图像分类和特征提取。它们在架构和性能上有一些显著的区别。 首先,VGG16是一个由16个卷积层和3个全连接层组成的深度卷积神经网络。它的特点是层次结构简单、层次较深,所有的卷积层都使用相同大小的卷积核(3x3),并且在每个卷积层之后都有一个池化层。VGG16的模型参数较多,训练时间较长,但在训练集上表现良好。 而ResNet50是Residual Network的一个变种,它引入了残差连接(residual connections)来解决深层网络训练中的梯度消失问题。ResNet5050个隐藏层组成,包括卷积层、批归一化层、全局平均池化层和全连接层。它的特点是使用了残差块(residual blocks),允许信息直接通过跳跃连接传递,从而有效地减少了梯度消失的影响。ResNet50的模型参数相对较少,训练时间相对较短,并且在训练集和测试集上都取得了很好的性能。 在性能方面,由于ResNet50的残差连接能够更好地捕捉图像的细节和特征,相比之下,ResNet50在更深的网络中具有更好的表现。因此,在许多图像分类和计算机视觉任务上,ResNet50通常比VGG16具有更高的准确率。 总结来说,VGG16ResNet50都是强大的深度学习模型,但在设计上有一些区别。VGG16简单而直观,适合用于小规模图像分类任务;而ResNet50引入了残差连接,能够处理更深的网络结构,适用于更复杂的图像分类和特征提取任务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值