【项目07】数据准备(Data Preparation)

作者:欧新宇(Xinyu OU)

本文档所展示的测试结果,均运行于:Intel Core i7-7700K CPU 4.2GHz, nVidia GeForce GTX 1080 Ti 本教案所涉及的数据集仅用于教学和交流使用,请勿用作商用。

最后更新:2021年8月4日


数据准备是深度学习训练、测试等工作的前提,它是保证深度学习有效的必要工作。特别是对于自建数据集来说,数据清洗数据分类数据列表的生成都是必备可少的工作。数据准备是一项工程性非常强的工作,每一个数据集都需要针对性地撰写代码。

为了简化工作,本课程涉及的所有数据集都做好了前期的清洗和分类工作,只需要按照分类任务的特点生成数据列表即可。下面以两个不同的数据集为例,对进行数据集进行分割,并生成样本列表。具体包括:手势识别数据集、十二生肖分类数据集。本教案,将数据按照两种模式进行划分,第一种模式为简易模式,划分为训练集、测试集两部分;第二种模式按照工程习惯生成四个数据集,具体包括:

如下所示,分类任务的数据列表一般包含两个部分,

D:\Workspace\ExpDatasets\Gestures\Data\0\IMG_5991.JPG 0
D:\Workspace\ExpDatasets\Gestures\Data\1\IMG_1129.JPG 1
D:\Workspace\ExpDatasets\Gestures\Data\1\IMG_1139.JPG 1

其中,第一项为图片的保存路径,第二项为该图片的分类标签。中间使用一个Tab(或者1个空格)进行分隔。值得注意的是,数据(图片)保存的路径可以使用绝对路径也可以使用相对路径,但为了避免不必要的麻烦和错误,建议使用绝对路径进行索引。

【特别提示】

  1. 一般来说,训练集和验证集都是训练模型时的训练数据,其中训练集用于模型训练,验证集用于超参数评估。为了更好地完成超参数的选择,通常会将原始的训练集分割成训练集验证集,并进行模型训练;在完成超参数选择后,再将训练集验证集合并在一起后,进行统一训练。
  2. 测试集在很多情况下是没有标注的,并且测试集也不应该被用来参与模型参数的选择,只能在模型训练好,进行一次性的结果输出或性能评估。

一. 蝴蝶分类数据集Butterfly

蝴蝶分类数据集包含7个类,619张图片。所有数据都放在Data文件夹,并按照7个类别分别存入子文件夹;但该数据集没有官方的数据分割建议,因此需要手动进行分割。数据列表生成时将按照8:27:1:2两种比例进行分割。

1.1 程序说明

完整的Python代码,通常需要保存成.py文件,并且提供有意义的命名方式。同时,在.py文件的开头部分,应该添加该程序的说明,包括功能简介、函数说明、作者,版本等信息。

值得注意的是,这不是必要步骤,但是是一种良好的编程习惯。

1.2 导入必要库及参数的初始化

数据列表的生成包括样本数据的读取和样本列表及样本信息的输出两部分。为了不产生错误,一般需要对这些信息进行初始化,包括统计训练、验证、测试数量和类别数量的变量,还包括数据集信息的字典文件。

1.3 路径定义

路径定义一般包括设置图像的保存位置,标签文件及相关说明文件的输出路径,同时还会包含一些其他功能的设置,例如不需要加入列数据列表的排除文件及排除文件夹的设置。

1.4 数据划分

下面,我们按照两种模式来进行数据划分,两种模式只需要执行一种即可。

● 模式一:训练集+测试集

该模式按照 训练集:测试集 = 8:2 的比例进行划分。

● 模式二:训练集+验证集+测试集+训练验证集

该模式按照 训练集:验证集:测试集 = 7:1:2 的比例进行划分。

1.5 结果输出

两种模式下的样本数量输出统计结果如下:

二. 十二生肖分类数据集Zodiac

十二生肖分类数据集包含12个类,8508张图片。数据集已经事先实现了训练(train)、验证(valid)和测试(test)的分割。因此,在进行数据列表生成的时候,不需要手动进行分割,但要注意确保三种类型数据标签和类别的统一。在范例代码中,我们使用训练集生成标签列表,并将标签列表应用到验证集和测试集列表的生成过程中。

值得注意的是,有的数据集并非那么的干净,特别是手动收集的数据集,可能会存在损坏的样本或无法使用的样本。因此,在生成数据列表前,还需要对样本进行清洗。数据样本常见的问题包括:

  1. 样本无法读取。这类样本通常需要将其丢弃;
  2. 样本通道不一致。即同时存在彩色图像(depth=3)和灰度图像(depth=1),这类样本需要将图像的维度进行统一;
  3. 样本命名过长,部分程序无法很好执行。这类样本通常需要按类别进行重新命名。

1. 数据清洗

数据清洗一般有两种方法:

  1. 直接将非法文件或者坏文件删除。该方法比较简单,但是会对官方数据集造成改变;
  2. 清理出非法文件和坏文件的列表,然后在生成数据的过程中自动过滤,该方法稍微复杂一些,需要事先对数据进行筛选,但是可以保留原始数据集不变。

下面的代码,实现对图像坏样本进行索引,并保存到bad.txt中,扫描文件夹时,自动跳过文件夹.DS_Store.ipynb_checkpoints。在判断样本是否损坏时,使用OpenCV库的cv2.imread()函数尝试读取图片,如果能读取且输出图片矩阵,则认定图片为正常图片,否则为损坏的图片。该方法实现简单,通常也比较有效,但因为需要对所有图片进行IO操作,因此需要耗费一定的时间。有兴趣的朋友可以尝试调用CPU多线程并行来对下面的代码进行加速。

因为数据清洗速度较慢,因此只需要执行一次即可。(运行前先取消代码注释)

2. 数据标注列表生成