草庐IT

PyTorch深度学习实战 | 猫狗分类

TiAmo zhang 2023-05-16 原文

本文内容使用TensorFlow和Keras建立一个猫狗图片分类器。

图1 猫狗图片

01、安装TensorFlow和Keras库

TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。

节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。它灵活的架构让你可以在多种平台上展开计算,例如台式计算机中的一个或多个CPU(或GPU),服务器,移动设备等等。

TensorFlow最初由Google大脑小组(隶属于Google机器智能研究机构)的研究员和工程师们开发出来,用于机器学习和深度神经网络方面的研究,但这个系统的通用性使其也可广泛用于其他计算领域。如图2所示。

图2 TensorFlow数据流图

运行Anaconda Prompt工具,在该工具命令窗口下安装数值计算开源库(tensorflow),如图3和图4所示,输入以下pip命令:

pip install tensorflow

图3 安装tensorflow库

图4 tensorflow库安装成功

Keras是一个由Python编写的开源人工神经网络库,可以作为Tensorflow、Microsoft-CNTK和Theano的高阶应用程序接口,进行深度学习模型的设计、调试、评估、应用和可视化,即高层神经网络API。

Keras的命名来自古希腊语“κέρας(牛角)”或“κραίνω(实现)”,意为将梦境化为现实的“牛角之门”。Keras的最初版本以Theano为后台,设计理念参考了Torch但完全由Python编写,自2017年起,Keras得到了Tensorflow团队的支持,其大部分组件被整合至Tensorflow的Python API中。在2018年Tensorflow 2.0.0公开后,Keras被正式确立为Tensorflow高阶API,即tf.keras。此外自2017年7月开始,Keras也得到了CNTK 2.0的后台支持。

Keras在代码结构上由面向对象方法编写,完全模块化并具有可扩展性,其运行机制和说明文档有将用户体验和使用难度纳入考虑,并试图简化复杂算法的实现难度。Keras支持现代人工智能领域的主流算法,包括前馈结构和递归结构的神经网络,也可以通过封装参与构建统计学习模型。在硬件和开发环境方面,Keras支持多操作系统下的多GPU并行计算,可以根据后台设置转化为Tensorflow、Microsoft-CNTK等系统下的组件。Keras为支持快速实验而生,能够把你的 idea 迅速转换为结果。

运行Anaconda Prompt工具,在该工具命令窗口下安装开源人工神经网络库(keras),输入以下pip命令:

pip install keras

如图5、图6所示。

图5 安装keras库

图6 keras库安装成功

环境配置好后,开始着手建立一个可以将猫狗图片分类的卷积神经网络,并使用到深度学习框架TensorFlow和Keras,配置网络以便远程访问Jupyter Notebook。

02、案例实现

【目的】

面向小数据集,使用keras进行数据增强;

使用keras构建两层卷积神经网络,实现猫狗分类;

对学习模型进行性能评估。

【原理】

基于keras框架,构建顺序神经网络,包含3层卷积,使用relu激活函数,同时使用max池化,后接2个全连接层,中间使用dropout进行降采样。

【训练时长】

50个epoch,每个epoch大概需要50秒,在it1080下训练过程共需要40分钟左右。

【数据资源】

cat_dog数据集,从kaggle猫狗数据集中随机抽取3000个样本,其中训练集包含猫狗各1000,测试集包含猫狗各500。

【步骤1】数据预处理

使用小数据集(几百张到几千张图片)构造高效、实用的图像分类器的方法,需要通过一系列随机变换进行数据增强,可以抑制过拟合,使得模型的泛化能力更好。

在Keras中,这个步骤可以通过keras.preprocessing.image.ImageGenerator来实现:

(1) 在训练过程中,设置要施行的随机变换

(2) 通过.flow或.flow_from_directory(directory)方法实例化一个针对图像batch的生成器,这些生成器可以被用作keras模型相关方法的输入,如fit_generator,evaluate_generator和predict_generator

导入相关资源的代码如下所示。

import numpy as np
from keras.preprocessing.image import ImageDataGenerator #图像预处理
import keras.backend as K
K.set_image_dim_ordering('tf')
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
加载数据的代码如下:
使用.flow_from_directory()来从jpgs图片中直接产生数据和标签
# 用于生成训练数据的对象
train_gen= ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

# 用于生成测试数据的对象
test_datagen = ImageDataGenerator(rescale=1./255)

参数解释如下:

  • rotation_range是一个0~180的度数,用来指定随机选择图片的角度。

  • width_shift和height_shift用来指定水平和竖直方向随机移动的程度,这是两个0~1之间的比例。

  • rescale值将在执行其他处理前乘到整个图像上,图像在RGB通道都是0~255的整数,这样的操作可能使图像的值过高或过低,所以将这个值定为0~1之间的数。

  • shear_range是用来进行剪切变换的程度。

  • zoom_range用来进行随机的放大

  • horizontal_flip随机地对图片进行水平翻转,这个参数适用于水平翻转不影响图片语义的时候

  • fill_mode用来指定当需要进行像素填充,如旋转,水平和竖直位移时,如何填充新出现的像素

# 从指定路径小批量读取数据
train_data = train_gen.flow_from_directory(
        '../datas/min_data/train', # t路径
        target_size=(150, 150), # 图片大小
        batch_size=32, # 每次读取的数量
        class_mode='binary') # 标签编码风格

# 从测试集中分批读取验证数据
val_data= test_gen.flow_from_directory(
        '../datas/min_data/test',
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

使用小数据集(几百张到几千张图片)构造高效、实用的图像分类器的方法,需要通过一系列随机变换进行数据增强,可以抑制过拟合,使得模型的泛化能力更好。

【步骤2】构建神经网络

模型包含3层卷积加上ReLU激活函数,再接max-pooling层,代码如下所示

model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(3, 150, 150)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

两个全连接网络,并以单个神经元和sigmoid激活结束模型。这种选择会产生二分类的结果,与这种配置相适应使用binary_crossentropy作为损失函数,每个卷积层的滤波器数目并不多。

为了防止过拟合,需要添加Dropout层,代码如下所示。

model.add(Flatten()) # 展平
model.add(Dense(64)) # 全连接
model.add(Activation('relu')) # 激活
model.add(Dropout(0.5)) # 降采样
model.add(Dense(1)) # 全连接
model.add(Activation('sigmoid')) # 激活

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

投入数据,训练网络,代码如下所示。

model.fit_generator(
        train_data, # 训练集
        samples_per_epoch=2000, # 训练样本数量
        nb_epoch=50, # 训练次数
        validation_data=val_data, #验证数据
        nb_val_samples=800 # 验证集大小
    )
model.save_weights('../model/cat_dog.h5') # 保存模型文件

完整代码如下所示。

【案例1】Conv_3.ipynb

from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K


# 图片大小
img_width, img_height = 150, 150

train_data_dir = '../datas/min_data/train'
validation_data_dir = '../datas/min_data/test'
nb_train_samples = 2000
nb_val_samples =1000
epochs = 50
batch_size = 16

if K.image_data_format() == 'channels_first':
    input_shape = (3, img_width, img_height)
else:
    input_shape = (img_width, img_height, 3)
    
# 数据读取、数据增强
train_gen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)
val_gen = ImageDataGenerator(rescale=1. / 255)

train_data= train_gen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

val_data=val_gen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')

# 构建3层卷积神经网络
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(Conv2D(64, (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(1))
model.add(Activation('sigmoid'))

# 定义损失函数和优化策略
model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# 开始训练
model.fit_generator(
    train_data,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=val_data,
    validation_steps=nb_val_samples // batch_size)
# 保存
yaml_string = model.to_yaml()
with open('cat_dog.yaml', 'w') as outfile:
    outfile.write(yaml_string)
model.save_weights('cat_dog.h5')

运行结果如下:

Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
WARNING:tensorflow:From /home/yangrh/anaconda3/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py:1208: calling reduce_prod (from tensorflow.python.ops.math_ops) with keep_dims is deprecated and will be removed in a future version.
Instructions for updating:
keep_dims is deprecated, use keepdims instead
WARNING:tensorflow:From /home/yangrh/anaconda3/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py:1297: calling reduce_mean (from tensorflow.python.ops.math_ops) with keep_dims is deprecated and will be removed in a future version.
Instructions for updating:
keep_dims is deprecated, use keepdims instead
Epoch 1/50
125/125 [==============================] - 40s - loss: 0.7057 - acc: 0.5140 - val_loss: 0.6797 - val_acc: 0.5363
Epoch 2/50
125/125 [==============================] - 40s - loss: 0.6851 - acc: 0.5865 - val_loss: 0.6391 - val_acc: 0.6839
......
Epoch 50/50
125/125 [==============================] - 40s - loss: 0.3996 - acc: 0.8370 - val_loss: 0.5988 - val_acc: 0.7947

【性能评估】

50个epoch,每个epoch大概需要50秒,在it1080下训练过程共需要40分钟左右,在验证集上的准确率达到80%,训练准确率与错误率如图7所示。

图7 准确率与错误率

下面案例代码使用训练好的模型对猫狗图片进行分类。

【案例2】Predict_Model.ipynb

import os
import keras
import keras.backend as K
from tables.tests.test_tables import LargeRowSize
K.set_image_dim_ordering('tf')
import numpy as np
from keras import callbacks
from keras.models import Sequential, model_from_yaml, load_model
from keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPool2D
from keras.optimizers import Adam, SGD
from keras.preprocessing import image
from keras.utils import np_utils, plot_model
from sklearn.model_selection import train_test_split
from keras.applications.resnet50 import preprocess_input, decode_predictions

img_h, img_w = 150, 150
image_size = (150, 150)
nbatch_size = 256
nepochs = 48
nb_classes = 2

def pred_data():

    with open('cat_dog.yaml') as yamlfile:
        loaded_model_yaml = yamlfile.read()
    model = model_from_yaml(loaded_model_yaml)
    model.load_weights('cat_dog.h5')

    sgd = Adam(lr=0.0003)
    model.compile(loss='categorical_crossentropy',optimizer=sgd, metrics=['accuracy'])

    images = []
    path='../datas/pred/'
    for f in os.listdir(path):
        img = image.load_img(path + f, target_size=image_size)
        img_array = image.img_to_array(img)

        x = np.expand_dims(img_array, axis=0)
        x = preprocess_input(x)
        result = model.predict_classes(x,verbose=0)

        print(f,result[0])

# 0表示猫,1表示狗
pred_data()

运行结果如下:

c7.jpg [0]
dog.33.jpg [0]
dog.34.jpg [1]
dog.41.jpg [0]
c3.jpg [0]
c1.jpg [1]
dog.36.jpg [0]
c4.jpg [0]
dog.35.jpg [0]
dog.39.jpg [0]
c5.jpg [0]
dog.38.jpg [0]
c2.jpg [0]
dog.40.jpg [0]
c6.jpg [1]
c0.jpg [0]
dog.37.jpg [0]

有关PyTorch深度学习实战 | 猫狗分类的更多相关文章

  1. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  2. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  3. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  4. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  5. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  6. ruby - 我如何学习 ruby​​ 的正则表达式? - 2

    如何学习ruby​​的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby​​的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/

  7. 深度学习12. CNN经典网络 VGG16 - 2

    深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG

  8. 机器学习——时间序列ARIMA模型(四):自相关函数ACF和偏自相关函数PACF用于判断ARIMA模型中p、q参数取值 - 2

    文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk​=Var(yt​)Cov(yt​,yt−k​)​其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞

  9. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

  10. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

随机推荐