【深度学习】猫狗识别TensorFlow2实验报告

简介: 本文介绍了使用TensorFlow 2进行猫狗识别的实验报告,包括实验目的、采用卷积神经网络(CNN)进行训练的过程,以及如何使用交叉熵作为损失函数来识别猫狗图像数据集。

一、实验目的

利用深度学习实现猫狗动物识别,采用Kaggle提供的公开数据集,训练深度学习模型,对测试集猫狗中的图片准确分类。通过该实验掌握深度学习中基本的CV处理过程。

二、实验原理

(1)采用用卷积神经网络训练
卷积神经网络由一个或多个卷积层和顶端的全连通层(对应经典的神经网络)组成,同时也包括关联权重和池化层(pooling layer)。这一结构使得卷积神经网络能够利用输入数据的二维结构。与其他深度学习结构相比,卷积神经网络在图像和语音识别方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他深度、前馈神经网络,卷积神经网络需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。
(2)卷积层
设 f(x),g(x) 是 R 上的两个可积函数,则卷积定义为:

1.png

离散形式定义为:

2.png

下图展示了一步计算的具体过程

3.png

(3)非线性层
非线性层并不是 CNN 特有的网络层,一般情况下会使用 ReLU 作为模型的激活函数。
(4)池化层
池化层 是一个利用 池化函数 (pooling function) 对网络输出进行进一步调整的网络层。池化函数使用某一位置的相邻输出的总体统计特征来代替网络在该位置的输出。常用的池化函数包括最大池化 (max pooling) 函数 (即给出邻域内的最大值) 和平均池化 (average pooling) 函数 (即给出邻域内的平均值) 等。但无论选择何种池化函数,当对输入做出少量平移时,池化对输入的表示都近似 不变 (invariant)。局部平移不变性 是一个很重要的性质,尤其是当我们关心某个特征是否出现而不关心它出现的位置时。
池化层同卷积层类似,具有三个比较重要的参数:pool_size,strides 和 padding,分别表示池化窗口的大小,步长以及是否对图像的外侧进行补零操作。池化层同时也能够提高网络的计算效率
(5)全连接层
全链接层 (Fully-connected or Dense Layer) 的目的就是将我们最后一个池化层的输出连接到最终的输出节点上。例如,最后一个池化层的输出大小为 [5×5×16],也就是有 5×5×16=400 个节点,对于手写数字识别的问题,我们的输出为 0 至 9 共 10 个数字,采用 one-hot 编码的话,输出层共 10 个节点。例如在 LeNet 中有 2 个全连接层,每层的节点数分别为 120 和 84,在实际应用中,通常全连接层的节点数会逐层递减。需要注意的是,在进行编码的时候,第一个全连接层并不是直接与最后一个池化层相连,而是先对池化层进行 flatten 操作,使其变成一个一维向量后再与全连接层相连。
(6)输出层
输出层根据具体问题的不同会略有不同,例如对于手写数字识别问题,采用 one-hot 编码的话,输出层则包含 10 个节点。对于回归或二分类问题,输出层则仅包含 1 个节点。当然对于二分类问题,我们也可以像多分类问题一样将其利用 one-hot 进行编码,例如 [1,0] 表示类型 0,[0,1] 表示类型 1。

三、实验内容

【代码下载-实现不易,顺便star一下啦】https://github.com/823316627bandeng/TensorFlow2_keras_Demo-
(1)训练模型
数据集:采用kaggle公开的猫狗数据集,文件名称是cat..jpg或dog..jpg
神经网络:卷积神经网络
损失函数:分类交叉熵
优化器:Adam
评价准则:准确率
Epochs:100
(2)测试模型
测试集:采用kaggle公开的猫狗测试集,没有标签
(3)环境
python 3.8
Tensorflow 2.3
numpy
pandas
matplotlib
cv2

四、实验过程

(1)数据集的准备
猫狗识别的数据集依旧可以从Kaggle上下载,数据集下载链接:https://www.kaggle.com/c/dogs-vs-cats
用Python进行处理分类,文件夹train里面放着25000张图像,猫和狗的图像分别都是12500张,图像名称上都有标明类别。文件夹test里面放的是测试集,里面有12500张图像,都没有标签,要自己来预测分类。

import shutil
import os

def remove_file(old_path, new_path):
    print(old_path)
    print(new_path)
    filelist = os.listdir(old_path)  # 列出该目录下的所有文件,listdir返回的文件列表是不包含路径的。
    # print(filelist)
    cat_n =0
    dog_n = 0
    for file in filelist:
        src = os.path.join(old_path, file)
        if not os.path.isfile(src):
            continue
        animal_str = str(file).split('.')[0]
        if animal_str =='cat': 
            if cat_n < 2500:
                cat_path = os.path.join('./validation/cat/', file)
                shutil.move(src, cat_path)
                cat_n +=1
            elif cat_n < 12500:
                cat_path = os.path.join('./train/cat/', file)
                shutil.move(src, cat_path)
                cat_n += 1
            else:
                os.remove(src)
        elif animal_str == 'dog':
            if dog_n < 2500:
                dog_path = os.path.join('./validation/dog/', file)
                shutil.move(src, dog_path)
                dog_n += 1
            elif dog_n < 12500:
                dog_path = os.path.join('./train/dog/', file)
                dog_n += 1
                shutil.move(src, dog_path)
            else:
                os.remove(src)
        else:
            continue
if __name__ == '__main__':
    os.makedirs('./train/cat/')
    os.makedirs('./train/dog/')
    os.makedirs('./validation/cat/')
    os.makedirs('./validation/dog/')
    remove_file(r"./train/", r"./validation/")

把数据集目录整理成如下的形式

4.png

(2)数据集的导入
在训练前,先导入训练集和验证集。使用keras.preprocessing.image.ImageDataGenerator()做图像增强的数据预处理设置,再使用flow_from_directory()从文件路径中导入数据集,并设置图像大小、batch_size和是否shuffle等参数。

# import the data and make a augmentation
    train_datagen = keras.preprocessing.image.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_dir,
        target_size=(width, height),
        batch_size=batch_size,
        seed=7,
        shuffle=True,
        class_mode='categorical'
    )

    valid_datagen = keras.preprocessing.image.ImageDataGenerator(
        rescale=1. / 255,
    )

    valid_generator = valid_datagen.flow_from_directory(
        valid_dir,
        target_size=(width, height),
        batch_size=valid_batch_size,
        seed=7,
        shuffle=False,
        class_mode="categorical"
    )
``

(3)搭建神经网络结构
搭建一个非常基础的卷积神经网络
```python
model = keras.models.Sequential([
        keras.layers.Conv2D(filters=32, kernel_size=3,
                            padding='same', activation='relu',
                            input_shape=[width, height, channel]),
        keras.layers.Conv2D(filters=32, kernel_size=3,
                            padding='same', activation='relu'),
        keras.layers.MaxPool2D(pool_size=2),

        keras.layers.Conv2D(filters=64, kernel_size=3,
                            padding='same', activation='relu'),
        keras.layers.Conv2D(filters=64, kernel_size=3,
                            padding='same', activation='relu'),
        keras.layers.MaxPool2D(pool_size=2),

        keras.layers.Conv2D(filters=128, kernel_size=3,
                            padding='same', activation='relu'),
        keras.layers.Conv2D(filters=128, kernel_size=3,
                            padding='same', activation='relu'),
        keras.layers.MaxPool2D(pool_size=2),

        keras.layers.Flatten(),
        keras.layers.Dense(128, activation='relu'),
        keras.layers.Dense(num_classes, activation='softmax')
    ])

(4)模型训练
优化器使用adam,损失函数使用’categorical_crossentropy’ ,metrics参数填入accuracy,评估模型在训练和测试过程中的准确率。

model.compile(loss='categorical_crossentropy',
                  optimizer='adam', metrics=['accuracy'])
    model.summary()

    # set path of saving model
    logdir = './graph_def_and_weights'
    if not os.path.exists(logdir):
        os.mkdir(logdir)

    output_model_file = os.path.join(logdir,
                                     "catDog_weights.h5")

    print('Start training ...')
    # start training

    mode = input('Select mode: 1.Train 2.Predict\nInput number: ')
    if mode == '1':
        callbacks = [
            keras.callbacks.TensorBoard(logdir),
            keras.callbacks.ModelCheckpoint(output_model_file,
                                            save_best_only=True,
                                            save_weights_only=True),
            keras.callbacks.EarlyStopping(patience=5, min_delta=1e-3)
        ]
        history = trainModel(model, train_generator, valid_generator, callbacks)
        plot_learning_curves(history, 'accuracy', epochs, 0, 1)
        plot_learning_curves(history, 'loss', epochs, 0, 5)

(5)模型预测
先读取文件夹test中的图像,使用 model.predict() 进行预测,再根据预测结果把图像进行分类,分别存储到 猫 和 狗 的文件夹中。

def predictModel(model, output_model_file):

    # load the weights of model
    model.load_weights(output_model_file)

    os.makedirs('./save', exist_ok=True)
    os.makedirs('./save/cat', exist_ok=True)
    os.makedirs('./save/dog', exist_ok=True)

    test_dir = './test/'  # 1-12500.jpg
    for i in range(1, 12500):
        img_name = test_dir + '{}.jpg'.format(i)
        img = cv2.imread(img_name)
        img = cv2.resize(img, (width, height))
        img_arr = img / 255.0
        img_arr = img_arr.reshape((1, width, height, 3))
        pre = model.predict(img_arr)
        if pre[0][0] > pre[0][1]:
            cv2.imwrite('./save/cat/' + '{}.jpg'.format(i), img)
            print(img_name, ' is classified as Cat.')
        else:
            cv2.imwrite('./save/dog/' + '{}.jpg'.format(i), img)
            print(img_name, ' is classified as Dog.')

五、实验分析

(1)训练过程如下

Epoch 35/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2434 - accuracy: 0.8960 - val_loss: 0.2657 - val_accuracy: 0.8918
Epoch 36/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2385 - accuracy: 0.8995 - val_loss: 0.1975 - val_accuracy: 0.9184
Epoch 37/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2302 - accuracy: 0.9008 - val_loss: 0.2139 - val_accuracy: 0.9108
Epoch 38/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2297 - accuracy: 0.9038 - val_loss: 0.1968 - val_accuracy: 0.9206
Epoch 39/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2232 - accuracy: 0.9044 - val_loss: 0.1909 - val_accuracy: 0.9220
Epoch 40/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2234 - accuracy: 0.9049 - val_loss: 0.1916 - val_accuracy: 0.9228
Epoch 41/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2185 - accuracy: 0.9072 - val_loss: 0.2005 - val_accuracy: 0.9164
Epoch 42/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2167 - accuracy: 0.9104 - val_loss: 0.2019 - val_accuracy: 0.9162
Epoch 43/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2148 - accuracy: 0.9089 - val_loss: 0.2241 - val_accuracy: 0.9064
Epoch 44/100
313/313 [==============================] - 87s 279ms/step - loss: 0.2097 - accuracy: 0.9116 - val_loss: 0.1901 - val_accuracy: 0.9182

由于使用了EarlyStopping,当准确率在几个epochs内都没有提高超过一定幅度的话就会停止训练。由图可以看出,训练到40个epoch左右验证集的准确率达到91.16%多了。下面是训练过程的准确率和损失值变化曲线!

5.png


6.png

(2)模型测试
测试的数据会生成两个文件夹/save/cat和/save/dog,分别存储模型分类后的图片。因为并没有实际测试集的label,只能通过人工观察,还是有部分分类错误的图片。

7.png


8.png

六、实验体会与心得

通过该案例的运行和分析,掌握了基本的CV,学会了一些数据处理的基本操作,包括对文件的处理。对Python和TensorFlow2.X 的keras API的使用更加熟练。

目录
相关文章
|
11天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
146 55
|
2月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
深度学习之格式转换笔记(三):keras(.hdf5)模型转TensorFlow(.pb) 转TensorRT(.uff)格式
将Keras训练好的.hdf5模型转换为TensorFlow的.pb模型,然后再转换为TensorRT支持的.uff格式,并提供了转换代码和测试步骤。
106 3
深度学习之格式转换笔记(三):keras(.hdf5)模型转TensorFlow(.pb) 转TensorRT(.uff)格式
|
21天前
|
机器学习/深度学习 人工智能 算法
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
114 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
|
1月前
|
机器学习/深度学习 数据采集 数据可视化
TensorFlow,一款由谷歌开发的开源深度学习框架,详细讲解了使用 TensorFlow 构建深度学习模型的步骤
本文介绍了 TensorFlow,一款由谷歌开发的开源深度学习框架,详细讲解了使用 TensorFlow 构建深度学习模型的步骤,包括数据准备、模型定义、损失函数与优化器选择、模型训练与评估、模型保存与部署,并展示了构建全连接神经网络的具体示例。此外,还探讨了 TensorFlow 的高级特性,如自动微分、模型可视化和分布式训练,以及其在未来的发展前景。
74 5
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
84 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
1月前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
95 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
1月前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
95 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
1月前
|
机器学习/深度学习 人工智能 TensorFlow
基于TensorFlow的深度学习模型训练与优化实战
基于TensorFlow的深度学习模型训练与优化实战
93 0
|
1月前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
87 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
2月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
78 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练

热门文章

最新文章