猫狗识别与分类

猫狗识别与分类

文章目录

一、前言

在实现猫狗识别的时候,我看到csdn上检索的猫狗识别有一些博客比较繁杂,可是作为正式进入AL世界的Hello world,这是不合理的,代码本来就不复杂。
繁杂的操作和图片有点让人生畏,所以我决定有必要重写一下程序、记录一下过程。

下面是一些国内的pip源,有需要可自取

阿里云 http://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣(douban) http://pypi.douban.com/simple/
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/

二、环境配置

软件:ANACONDA3+Pycharm2019

keras>=2.7;
tensorflow>=2.7
注:一定关掉科学上网

三、源码以及数据集

链接:https://pan.baidu.com/s/1gvFfpK64Z16rkW81jWVZdw
提取码:f1ff

四、基础猫狗识别程序如下

1、train.py

基于卷积池化构架的猫狗识别训练程序

train.py程序结构:

  • 第一步:导入包
  • 第二步:指定一些超参数
  • 第三步:准备训练集和验证集
  • 第四步:建立神经网络模型
  • 第五步:训练模型
  • *第六步:根据训练过程中的信息绘制图表

import numpy as np
import os,random,shutil
np.random.seed(7)

FOLDER=".\\dataset_default"
train_data_dir=os.path.join(FOLDER,'train')
val_data_dir=os.path.join(FOLDER,'validate')

train_samples_num=4916
val_samples_num=1439
IMG_W,IMG_H,IMG_CH=150,150,3
batch_size=32
epochs=20
class_num=2

from keras.preprocessing.image import ImageDataGenerator
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(
    train_data_dir,
    target_size=(IMG_W, IMG_H),
    batch_size=batch_size,
    color_mode='rgb',
    class_mode='categorical')

val_datagen = ImageDataGenerator(rescale=1. / 255)

val_generator = val_datagen.flow_from_directory(
        val_data_dir,
        target_size=(IMG_W, IMG_H),
        batch_size=batch_size,
        color_mode='rgb',
        class_mode='categorical')

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense

def build_model(input_shape):

    model = Sequential()
    model.add(Conv2D(32, (3, 3), input_shape=input_shape))
    model.add(Activation("relu"))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Conv2D(32, (3, 3)))
    model.add(Activation("relu"))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Flatten())
    model.add(Dense(64))
    model.add(Activation("relu"))
    model.add(Dropout(0.5))
    model.add(Dense(class_num))
    model.add(Activation("softmax"))

    from tensorflow import optimizers
    model.compile(
        loss="categorical_crossentropy",
        optimizer='adam',
        metrics=["accuracy"],
    )

    return model

model=build_model(input_shape=(IMG_W,IMG_H,IMG_CH))

history_ft = model.fit(train_generator,
                       steps_per_epoch=train_samples_num // batch_size,
                       epochs=epochs,
                       validation_data=val_generator,
                       validation_steps=val_samples_num // batch_size
                       )

model.save("./model.h5")
print(history_ft.history.keys())

import matplotlib.pyplot as plt
acc = history_ft.history['accuracy']
val_acc = history_ft.history['val_accuracy']
loss = history_ft.history['loss']
val_loss = history_ft.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='validate acc')
plt.title('Training and validation acc')
plt.legend()

plt.show()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='validate Loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

2、detect.py

detect.py程序结构:

  • 第一步:导入库以及定义一些参数
  • 第二步:定义一个函数,从测试文件夹内读取任意一张图片
  • 第三步:定义一个预测函数
  • *第四步:载入模型并预测

import os, random
from matplotlib.pyplot import imshow
import numpy as np
import matplotlib.pyplot as plt
IMG_W,IMG_H,IMG_CH=150,150,3

def read_random_image():
    folder=r"./Imgs/"
    file_path = folder + random.choice(os.listdir(folder))
    pil_im = Image.open(file_path, 'r')
    return pil_im

from PIL import Image
from keras.preprocessing import image

def predict(model, img, target_size):
    name = ["猫", "狗"]
    if img.size != target_size:
        img = img.resize(target_size)

    x = image.img_to_array(img)
    x *= 1. / 255
    x = np.expand_dims(x, axis=0)
    preds = model.predict(x)

    imshow(np.asarray(img))

    print(preds)
    for i in range(2):
        if preds[0][i]>0.5:
            print(name[i])
            break

from keras.models import load_model
model_path = './model.h5'
model = load_model(model_path)

print("下面将抽五张图并预测如下:")
for i in range(5):
    print("该图片的猫狗概率如下:")
    predict(model,read_random_image(),(IMG_W,IMG_H))
    plt.show()

'''
test_datagen = ImageDataGenerator(rescale=1. / 255) # 只需要和trainset同样的scale即可,不需增强

test_data_dir="./data_oppo/train"
val_generator = test_datagen.flow_from_directory(
        test_data_dir,
        target_size=(IMG_W, IMG_H),
        batch_size=32,
        color_mode='rgb',
        class_mode='categorical')
test_loss,test_acc=model.evaluate(val_generator)
print("test_acc={}  test_loss={}".format(test_acc,test_loss))
'''

以下是跑通这个程序的过程。如果清楚这些步骤的过程可以略过下面

五、配置环境过程

1、打开Anaconda Prompt

a、创建一个叫MNIST4的环境

conda create -n MNIST4 python=3.8

注:记得python=3.8,大了就下载不了tensorflow包了
注:名字不重要,你之后想起什么名字都可以

猫狗识别与分类

b、创建成功后激活环境并下载keras包:

conda activate MNIST4

猫狗识别与分类

为了提高下载速度,在国内清华源中下载keras包

pip install keras -i https://pypi.tuna.tsinghua.edu.cn/simple/

猫狗识别与分类

c、下载matplotlib包

pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple/

猫狗识别与分类

d、下载tensorflow包

pip install tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple/

猫狗识别与分类

e、下载SciPy包

pip install SciPy -i https://pypi.tuna.tsinghua.edu.cn/simple/

猫狗识别与分类

2、打开Pycharm配置

配置代码运行环境

猫狗识别与分类
猫狗识别与分类
猫狗识别与分类
猫狗识别与分类
猫狗识别与分类
注:这里刷新出来的时候比较长,需要等等
之后一路点击确认下去

; 六、运行基础程序

这个程序是最基础的程序,有训练模型,部署模型的能力,数据集6000简单训练20轮,验证集精度大概有0.7的精度,
当然这只是用来玩的基础版本,一定要理解, 之后的VGG–>Res–>DenseNet–>EffectionNet
也都只是时间问题了。

1、运行train程序

a、将开头的程序copy进pycharm的程序中

猫狗识别与分类

; b、运行结果:

猫狗识别与分类
这样就训练成功了。

训练数据画图如下:

猫狗识别与分类
猫狗识别与分类

1、运行detect程序

a、将开头的detect程序进pycharm的程序中

猫狗识别与分类

; b、运行结果

猫狗识别与分类

七、基于DenseNet神经网络构架的猫狗识别训练程序

DenseNet神经网络架构是2017年比较活的架构
到2020年虽然干不过谷歌的EffectionNet不过在很多方面已经很优秀了
所以特意举这个例子

数据集:6000
验证集精度大概在0.97左右。

1、在之前的基础上导入sklearn包

pip install sklearn -i https://pypi.tuna.tsinghua.edu.cn/simple/

猫狗识别与分类

2、将程序copy到pycharm

train.py程序结构

  • 第一步:导入相应的库和指定超参数
  • 第二步:学习率修改函数
  • 第三步:准备训练集
  • 第四步:建立Keras模型:模型的建立主要包括模型的搭建,模型的编译
  • 第五步:回调函数
  • 第六步:模型的训练
  • 第七步:绘制训练过程图像
from idlelib import history

from tensorflow.keras.callbacks import ReduceLROnPlateau,ModelCheckpoint
import tensorflow as tf
import os

FOLDER=".\\dataset_default"
train_data_dir=os.path.join(FOLDER,'train')
val_data_dir=os.path.join(FOLDER,'validate')
train_samples_num=4916
val_samples_num=1439

IMG_W,IMG_H,IMG_CH=150,150,3
batch_size=32
epochs=10
class_num=2

if not os.path.exists("save_weights"):
    os.makedirs("save_weights")

def lr_schedule(epoch):
    """Learning Rate Schedule
        Learning rate is scheduled to be reduced after 80, 120, 160, 180 epochs.

        Called automatically every epoch as part of callbacks during training.

        # Arguments
        epoch (int): The number of epochs
        # Returns
        lr (float32): learning rate
"""
    lr = 1e-4
    if epoch > 40:
        lr *= 0.5e-3
    elif epoch > 30:
        lr *= 0.5
    elif epoch > 20:
        lr *= 0.5
    elif epoch > 10:
        lr *= 0.5
    print('Learning rate: ', lr)
    return lr

from keras.preprocessing.image import ImageDataGenerator
'''
在深度学习中,一般要求样本的数量要充足,样本数量越多,训练出来的模型效果越好,模型的泛化能力越强。但是实际中,样本数量不足或者样本质量不够好,这就要对样本做数据增强,来提高样本质量。
关于数据增强的作用总结如下:
1,增加训练的数据量,提高模型的泛化能力
2,增加噪声数据,提升模型的鲁棒性
讲解数据增强的文章:#https://zhuanlan.zhihu.com/p/41679153
'''
train_datagen = ImageDataGenerator(rescale=1.0 / 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')
'''
  ImageDataGenerator类的简单介绍
(1)图片生成器,负责生成一个批次一个批次的图片,以生成器的形式给模型训练;

(2)对每一个批次的训练图片,适时地进行数据增强处理(data augmentation);
'''

train_generator = train_datagen.flow_from_directory(
                                    train_data_dir,
                                    target_size=(IMG_W, IMG_H),
                                    batch_size=batch_size,
                                    shuffle=True,
                                    color_mode='rgb',
                                    class_mode='categorical')

val_datagen = ImageDataGenerator(rescale=1.0 / 255)

val_generator = val_datagen.flow_from_directory(
        val_data_dir,
        target_size=(IMG_W, IMG_H),
        batch_size=batch_size,
        shuffle=False,
        color_mode='rgb',
        class_mode='categorical')

from keras.models import Sequential
from keras.initializers import TruncatedNormal

def build_model(input_shape):

    covn_base = tf.keras.applications.DenseNet121(weights='imagenet', include_top=False, input_shape=(150, 150, 3))
    covn_base.trainable = True

    for layers in covn_base.layers[:-5]:
        layers.trainable = False

    model = tf.keras.Sequential()
    model.add(covn_base)
    model.add(tf.keras.layers.GlobalAveragePooling2D())
    model.add(tf.keras.layers.Dense(512, activation='relu'))
    model.add(tf.keras.layers.Dropout(rate=0.5))
    model.add(tf.keras.layers.Dense(2, activation='softmax'))
    model.summary()

    model.compile(optimizer=tf.optimizers.RMSprop(lr_schedule(0)),
                  loss='binary_crossentropy',
                  metrics=["accuracy"])
    return model

model=build_model(input_shape=(IMG_W,IMG_H,IMG_CH))

reduce_lr = ReduceLROnPlateau(
                                monitor='val_loss',
                                factor=0.1,
                                patience=2,
                                mode='auto',
                                verbose=1
                             )

checkpoint = ModelCheckpoint(
                                filepath='./save_weights/myDenseNet121.h5',
                                monitor='val_accuracy',
                                save_weights_only=False,
                                save_best_only=True,
                                mode='auto',
                                period=1
                            )

history_ft = model.fit(train_generator,
                       steps_per_epoch=train_samples_num // batch_size,
                       epochs=epochs,
                       validation_data=val_generator,
                       validation_steps=val_samples_num // batch_size,
                        callbacks=[checkpoint, reduce_lr]
                       )

model.save("./model2.h5")
print(history_ft.history.keys())

import matplotlib.pyplot as plt
acc = history_ft.history['accuracy']
val_acc = history_ft.history['val_accuracy']
loss = history_ft.history['loss']
val_loss = history_ft.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='validate acc')
plt.title('Training and validation acc')
plt.legend()

plt.show()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='validate Loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

3、运行结果

猫狗识别与分类
猫狗识别与分类
可以看到算比较理想,验证集精度0.97。毕竟数据集那么小,才6000张图片。
kaggle正式比赛时候训练的模型数据集可是25000张图片
至于为什么验证集精度比训练集精度高可以看这篇博客:https://blog.csdn.net/qq_51116518/article/details/122227731

Original: https://blog.csdn.net/qq_51116518/article/details/122225124
Author: 风吹落叶花飘荡
Title: 猫狗识别与分类

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/663072/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球