PyTorch 深度学习实战 | 基于 ResNet 的花卉图片分类

简介: 本期将提供一个利用深度学习进行花卉图片分类的案例,并使用迁移学习的方法解决训练数据较少的问题。图片分类是根据图像的语义信息对不同的图片进行区分,是计算机视觉中的基本问题,也是图像检测、图像分割、物体跟踪等高阶视觉任务的基础。在深度学习领域,图片分类的任务一般基于卷积神经网络来完成,如常见的卷积神经网络有 VGG、GoogleNet、ResNet 等。而在图像分类领域,数据标记是最基础和烦琐的工作。有时由于条件限制,往往得不到很多经过标记的、用于训练的图片,其中一个解决办法就是对已经预训练好的模型进行迁移学习。本文是以 ResNet 为基础,对花卉图片进行迁移学习,从而完成对花卉图片的分类任

“工欲善其事,必先利其器”。如果直接使用 Python 完成模型的构建、导出等工作,势必会耗费相当多的时间,而且大部分工作都是深度学习中共同拥有的部分,即重复工作。所以本案例为了快速实现效果,就直接使用将这些共有部分整理成框架的 TensorFlow 和 Keras 来完成开发工作。TensorFlow 是 Google 公司开源的基于数据流图的科学计算库,适合用于机器学习、深度学习等人工智能领域。Keras 是一个用 Python 编写的高级神经网络 API,它能够以 TensorFlow、CNTK 或 Theano 作为后端运行。Keras 的开发重点是支持快速的实验,所以,本案例中,大部分与模型有关的工作都是基于 Keras API 来完成的。而现在版本的 TensorFlow 已经将 Keras 集成了进来,所以只需要安装 TensorFlow 即可。注意,由于本案例采用的 ResNet 网络较深,所以模型训练需要消耗的资源较多,需要 GPU 来加速训练过程。

1、环境安装

安装 TensorFlow 的 GPU 版本是相对比较繁杂的事情,需要找对应的驱动,安装合适版本的 CUDA 和 cuDNN。而一种比较方便的办法就是使用 Anaconda 来进行 tensorflow-gpu 的安装。具体的安装过程可以参考本书的附录 A.2 部分。其他需要安装的依赖包的名称及版本号如下:

其他依赖包可以在 Anaconda 界面上进行选择安装,也可以将其添加到 requirements.txt 文件,然后使用 conda install -yes -file requirements.txt 命令进行安装。另外,Conda 可以创建不同的环境来支持不同的开发要求。例如,有些工程需要 TensorFlow 1.15.0 环境来进行开发,而另外一些工程需要 TensorFlow 2.1.0 来进行开发,替换整个工作环境或者重新安装 TensorFlow 都不是很好的选择。所以,本案例使用 Conda 创建虚拟环境来解决。

2、数据集简介

在进行模型构建和训练之前,需要进行数据收集。为了简化收集工作,本案例采用已标记好的花卉数据集 Oxford 102 Flowers。数据集可以从 VGG 官方网站上进行下载。单击如图 1 所示的 Downloads 区域的 1、4 和 5 对应的超链接就可以下载所需要的文件。

image.png


■ 图 1 Oxford 102 Flowers 数据集下载网站

该数据集由牛津大学工程科学系于 2008 年发布,是一个英国本土常见花卉的图片数据集,包含 102 个类别,每类包含 40 ~ 258 张图片。在基于深度学习的图像分类任务中,这样较为少量的图片还是比较有挑战性的。Oxford 102 Flowers 的分类细节和部分类别的图片及对应的数量如图 2 所示。

image.png


■ 图 2 Oxford 102 Flowers 的分类细节和部分类别的图片及对应的数量

除了图片文件(dataset images),数据集中还包含图片分割标记文件(image segmentations)、分类标记文件(the image iabels)和数据集划分文件(the data splits)。由于本案例中不涉及图片分割,所以使用的是图片、分类标记和数据集划分文件。

3、数据集的下载与处理

Python urllib 库提供了 urlretrieve()函数可以直接将远程数据下载到本地。可以使用 urlretrieve()函数下载所需文件;然后把压缩的图片文件进行解压,并解析分类标记文件和数据集划分文件;再根据数据集划分文件并分成训练集、验证集和测试集;最后,向不同类别的数据集中按图片所标识的花的种类分类存放图片文件。代码及详细注释如代码清单 1 所示。

代码清单 1

import os
from urllib.request import urlretrieve
import tarfile
from scipy. io import loadmat2
from shutil import copyfile
import glob
import numpy as np

"""
函数说明:按照分类(labels)复制未分组的图片到指定的位置10
Parameters:
    data path - 数据存放目录
    labels - 数据对应的标签,需要按标签放到不同的目录
"""

def copy_data_files(data path, labels) :
if not os. path, exists( data path) :
  os.mkdir(data path)
  
  # 创建分类目录
for i in range(0,102) :
os.mkdir(os.path.join( data path, str(i)))

for label in labels:
src path = str(label[0])
dst path = os.path. join(data path, label[1], src path. split(os. sep)[ - 1])
copyfile(src path, dst path)

if_name_ _== '_main_':
  # 检查本地数据集目录是否存在,若不存在,则需创建 
  data set path = "./data'
  if not os. path. exists( data set path) :
    os.mkdir(data set path)
    
#下载 102 Category Elower 数据集并解压 
flowers archive file = "102flowers.tgz'
flowers_url frefix = "https://www,robots.ox.ac.uk/~vgg/data/flowers/102/'
flowers archive path = os.path, join(data set path, flowers archive file)
if not os path.exists(flowers archive path) :
print("正在下载图片文件...")
urlretrieve(flowers url frefix + flowers archive file, flowers archive path)
print("图片文件下载完成.")
print("正在解压图片文件...")
tarfile. open(flowers archive path)..extractall(path = data set_path)
print("图片文件解压完成,")

# 下载标识文件,标识不同文件的类别
flowers labels file = "imagelabels.mat'
flowers labels path = os.path. join(data set path, flowers labels file)
   if not os.path.exists(flowers labels path) :
    print("正在下载标识文件...")
urlretrieve(flowers url frefix + flowers labels file, flowers labels path)
print("标识文件下载完成")
flower_labels = loadmat(flowers_labels_path)['labels'][0] - 1

#下载数据集分类文件,包含训练集、验证集和测试集
sets splits file = "setid.mat"
sets splits_path = os.path. join(data set path, sets splits file)
if not os.path,exists( sets splits path) :
print("正在下载数据集分类文件...")
urlretrieve(flowers url frefix + sets splits file, sets splits path)
print("数据集分类文件下载完成")
sets_splits = loadmat( sets splits path)

# 由于数据集分类文件中测试集数量比训练集多,所以进行了对调
train set = sets splits['tstid'][0] - 1
valid set = sets splits[ 'valid'][0] - 1
test_set = sets splits['trnid'][0] - 1

# 获取图片文件名并找到图片对应的分类标识
image files = sorted(glob.glob(os.path. join(data set path, 'jpg', ' x .jpg')))
image labels = np.array([i for i in zip(image files, flower labels)])

# 将训练集、验证集和测试集分别放在不同的目录下
print("正在进行训练集的复制...")
copy_data files(os.path. join(data set path, 'train'), image labels[train set, :]
  print("已完成训练集的复制,开始复制验证集...")
copy_data files(os.path. join(data_set_path, 'valid'), image labels[valid set, :]
  print("已完成验证集的复制,开始复制测试集...")
copy_data files(os.path, join(data set_path, 'test'), image labels[test set, :] 
  print("已完成测试集的复制,所有的图片下载和预处理工作已完成.")

下载的图片数据有 330MB 左右。国外的网站有时候下载比较慢,可以用下载工具下载,或者使用参考书前言中提供的二维码进行下载。

需要说明的是,分类标记文件 imagelabels.mat 和数据集划分文件 setid.mat 是 MATLAB 的数据存储的标准格式,可以用 MATLAB 程序打开进行查看。本案例中使用 scipy 库的 loadmat()函数对 .mat 文件进行读取。图片分类后的目录结构如图 3 所示。

image.png


■ 图 3 图片分类后的目录结构

目录
相关文章
|
23天前
|
机器学习/深度学习 监控 PyTorch
深度学习工程实践:PyTorch Lightning与Ignite框架的技术特性对比分析
在深度学习框架的选择上,PyTorch Lightning和Ignite代表了两种不同的技术路线。本文将从技术实现的角度,深入分析这两个框架在实际应用中的差异,为开发者提供客观的技术参考。
39 7
|
2月前
|
机器学习/深度学习 算法 PyTorch
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
这篇文章详细介绍了多种用于目标检测任务中的边界框回归损失函数,包括IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU和WIOU,并提供了它们的Pytorch实现代码。
199 1
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
|
2月前
|
机器学习/深度学习 PyTorch 算法框架/工具
揭秘深度学习中的微调难题:如何运用弹性权重巩固(EWC)策略巧妙应对灾难性遗忘,附带实战代码详解助你轻松掌握技巧
【10月更文挑战第1天】深度学习中,模型微调虽能提升性能,但常导致“灾难性遗忘”,即模型在新任务上训练后遗忘旧知识。本文介绍弹性权重巩固(EWC)方法,通过在损失函数中加入正则项来惩罚对重要参数的更改,从而缓解此问题。提供了一个基于PyTorch的实现示例,展示如何在训练过程中引入EWC损失,适用于终身学习和在线学习等场景。
88 4
揭秘深度学习中的微调难题:如何运用弹性权重巩固(EWC)策略巧妙应对灾难性遗忘,附带实战代码详解助你轻松掌握技巧
|
2月前
|
机器学习/深度学习 人工智能 算法
揭开深度学习与传统机器学习的神秘面纱:从理论差异到实战代码详解两者间的选择与应用策略全面解析
【10月更文挑战第10天】本文探讨了深度学习与传统机器学习的区别,通过图像识别和语音处理等领域的应用案例,展示了深度学习在自动特征学习和处理大规模数据方面的优势。文中还提供了一个Python代码示例,使用TensorFlow构建多层感知器(MLP)并与Scikit-learn中的逻辑回归模型进行对比,进一步说明了两者的不同特点。
73 2
|
2月前
|
机器学习/深度学习 算法 数据可视化
如果你的PyTorch优化器效果欠佳,试试这4种深度学习中的高级优化技术吧
在深度学习领域,优化器的选择对模型性能至关重要。尽管PyTorch中的标准优化器如SGD、Adam和AdamW被广泛应用,但在某些复杂优化问题中,这些方法未必是最优选择。本文介绍了四种高级优化技术:序列最小二乘规划(SLSQP)、粒子群优化(PSO)、协方差矩阵自适应进化策略(CMA-ES)和模拟退火(SA)。这些方法具备无梯度优化、仅需前向传播及全局优化能力等优点,尤其适合非可微操作和参数数量较少的情况。通过实验对比发现,对于特定问题,非传统优化方法可能比标准梯度下降算法表现更好。文章详细描述了这些优化技术的实现过程及结果分析,并提出了未来的研究方向。
28 1
|
2月前
|
机器学习/深度学习 API 算法框架/工具
残差网络(ResNet) -深度学习(Residual Networks (ResNet) – Deep Learning)
残差网络(ResNet) -深度学习(Residual Networks (ResNet) – Deep Learning)
42 0
|
2月前
|
机器学习/深度学习 数据采集 自然语言处理
【NLP自然语言处理】基于PyTorch深度学习框架构建RNN经典案例:构建人名分类器
【NLP自然语言处理】基于PyTorch深度学习框架构建RNN经典案例:构建人名分类器
|
2天前
|
机器学习/深度学习 数据采集 传感器
基于深度学习的图像识别技术在自动驾驶中的应用研究####
本文旨在探讨深度学习技术,特别是卷积神经网络(CNN)在自动驾驶车辆图像识别领域的应用与进展。通过分析当前自动驾驶技术面临的挑战,详细介绍了深度学习模型如何提升环境感知能力,重点阐述了数据预处理、网络架构设计、训练策略及优化方法,并展望了未来发展趋势。 ####
24 6
|
6天前
|
机器学习/深度学习 自然语言处理 语音技术
Python在深度学习领域的应用,重点讲解了神经网络的基础概念、基本结构、训练过程及优化技巧
本文介绍了Python在深度学习领域的应用,重点讲解了神经网络的基础概念、基本结构、训练过程及优化技巧,并通过TensorFlow和PyTorch等库展示了实现神经网络的具体示例,涵盖图像识别、语音识别等多个应用场景。
22 8
|
10天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的卷积神经网络(CNN)及其在图像识别中的应用
本文旨在通过深入浅出的方式,为读者揭示卷积神经网络(CNN)的神秘面纱,并展示其在图像识别领域的实际应用。我们将从CNN的基本概念出发,逐步深入到网络结构、工作原理以及训练过程,最后通过一个实际的代码示例,带领读者体验CNN的强大功能。无论你是深度学习的初学者,还是希望进一步了解CNN的专业人士,这篇文章都将为你提供有价值的信息和启发。