从事图像处理或者计算机视觉的朋友可能会有使用tensorflow加载图像数据的需求,这些数据可以是公开数据集,也可以是自己制作的私有数据集。tensorflow提供了一些接口来导入图像数据,并使用Dataset方便地管理这些数据。如果是常用的公开数据集,可能已经有了比较好的数据载入相关的代码封装,这时就没有必要重复造轮子了。而对于一些不常用的公开数据集,往往需要自己编写代码载入数据,至于自己制作的或者数据组织形式罕见的那就更加需要自己动手了。本文就讨论一种载入图像数据的方法,对tensorflow在数据载入方面不太熟悉的朋友可能会有些收获。

1. 加载图片数据

我们首选需要将这些图片数据加载到内存中,当然并不是一定要一次性加载进内存,更常见的情况是使用生产者和消费者模型一边训练,一边加载。一般而言,分为两步,(1)加载图像文件的路径,(2)提供接口根据路径加载图像数据。下面就分步骤说明数据加载方面的操作详情。

(1) 获取图像文件路径

首先使用pathlib模块中提供的一些处理路径相关的操作提取指定根目录下所有图像文件的路径。在python中完成这种操作的方式很多,这里只是其中一种。




python BeautifulSoup 图片懒加载 python加载图像_数据管理

获取图像文件路径



(2) 查看图像及对应属性

获取图像路径之后,我们需要查看一下原始数据的具体形式,以对需要处理的数据有一个基本的认识。这一步对后续程序运行而言没有影响,但是在日常的工作和科研中间不可或缺。




python BeautifulSoup 图片懒加载 python加载图像_数据_02

查看图像及对应属性




python BeautifulSoup 图片懒加载 python加载图像_数据_03

原始图像数据展示



(3) 获取图像标签

原始的图像数据检查完毕,没有问题。接下来就需要处理图像标记相关的数据。这里演示的是一个分类问题的数据集,对于回归问题处理步骤也是一样的,只是在这一步载入的信息稍有差别。




python BeautifulSoup 图片懒加载 python加载图像_miniimagenet的图像预处理代码_04

获取图像标签



(4) 添加载入接口并测试

在实际使用这些图像数据时,并不是一次载入的,而是需要在使用过程中载入。这是就需要定义一个图像的载入和预处理函数作为钩子函数被数据管理器调用。不明白钩子函数作用的朋友可以先不用管。这里只需明白,编写一个数据载入和预处理的操作即可。下面的演示验证了这个接口的有效性,以及图像数据与标签数据之间的匹配是否正确。




python BeautifulSoup 图片懒加载 python加载图像_数据管理_05

添加载入接口并测试




python BeautifulSoup 图片懒加载 python加载图像_数据管理_06

载入之后的图像与标签展示



2. 创建Dataset

图像数据的路径和标签都准备好了之后,就需要创建数据管理器Dataset。很多的机器学习框架都提供了各自的数据管理器,原理大同小异,对于大量图像数据基本都是使用异步的方式按需要载入数据。下面就讨论一下tensorflow中管理器的用法。

(1) 构造图像-标签配对数据集

将图像文件路径和对应的载入操作绑定到Dataset之后,这个管理器就具备了提供图像数据的功能。将这样的图像数据管理器和对应的标签数据管理器匹配之后就可以得到一个完整的分类问题的数据集。




python BeautifulSoup 图片懒加载 python加载图像_数据_07

构造图像-标签配对数据集



(2) 设置数据集参数和操作

熟悉深度学习的朋友都知道,我们在使用训练数据集时常常需要对数据进行随机排列,这也算是一种数据增强的手段了,避免模型将数据点的排列方式当作一种特征而造成过拟合。此外,一个数据集往往需要训练很多遍,这是就需要进行一些repeat操作。不过shuffle与repeat以及batch操作的顺序会对随机排列的效果有影响。将随机排列放在最前面,就是保证我们通常所期望的epoch内部打散。最后还需要设置一个prefetch操作,这样有利于异步读取数据的时候充分发挥计算机的能力。




python BeautifulSoup 图片懒加载 python加载图像_数据集_08

设置数据集参数和操作



3. 训练模型

数据准备完成之后就可以训练数据了,这里演示的是以一个MobileNetV2的模型为基础进行finetune。finetune的意思是在一个已经训练好的模型的基础上,添加新的结构和参数而保持基础模型的参数不改变,训练时只需训练新加参数。在图像领域,比较常用的基础模型还有VGG16、VGG19、ResNet等等。

(1) 获取基准模型¶

keras提供了获取MobileNetV2模型参数和结构的方法,直接使用接口下载对应的模型文件即可。




python BeautifulSoup 图片懒加载 python加载图像_数据集_09

获取基准模型



(2) 适配输入数据数值范围

由于基础模型的输入要求数据的数值范围在[-1,1],而之前预处理函数中的归一化操作得到的数值范围是[0,1],所以需要进行一次变换。还可以使用一个batch的图像数据测试一下MobileNetV2的输出量的形状。




python BeautifulSoup 图片懒加载 python加载图像_数据管理_10

适配输入数据数值范围



(3) 构建模型并查看设置

基础模型准备完成之后就可以添加新的结构和参数,构建完整的模型了。这里的演示只是添加了两个简单的操作,增加了两个需要在训练中调整的张量参数。还可以将创建的模型的结构打印出来查看一下,符合预期。




python BeautifulSoup 图片懒加载 python加载图像_miniimagenet的图像预处理代码_11

构建模型并查看设置



(4) 训练模型

一切准备就绪,就可以开始训练模型。由于在数据管理器中使用了repeat操作,所以需要指定每一个epoch训楼的步数。一般而言,一个epoch就是将数据集遍历一遍。这里设置将数据集遍历10遍。从训楼安的损失函数来看,将数据集遍历到第7遍之后就已经收敛了。




python BeautifulSoup 图片懒加载 python加载图像_数据_12

训练模型



到此,在tensorflow2.0中载入图像数据和模型finetune操作就讨论完毕。本文是在学习官网教程之后编写的,基本流程与官网一致。喜欢阅读官网教程的朋友可以查看链接:https://www.tensorflow.org/tutorials/load_data/images 。本文的notebook版文件在github上的cnbluegeek/notebook仓库共享,欢迎感兴趣的朋友前往下载。