上一篇:《数据工程师,转型人工智能岗位的理想时空通道》

序言:本节将带您深入探索 TensorFlow 提供的关键工具和方法,涵盖数据集管理和神经网络模型的构建与训练。在现代人工智能框架中,TensorFlow 的数据集接口 (TensorFlow Datasets, 简称 TFDS) 与 Keras 模型库为深度学习任务提供了极大的便利。本章将具体展示如何使用 TFDS 和 Keras 配合构建神经网络架构,以实现高效的数据处理和模型训练。通过本节的实践操作,您将掌握从数据加载、预处理到模型搭建的核心流程,为进一步的人工智能模型研发奠定坚实的基础。

使用TFDS与Keras模型

在上一节中,我们学到了如何使用TensorFlow和Keras创建一个简单的计算机视觉模型,使用Keras内置的数据集(包括Fashion MNIST),代码如下所示:

mnist = tf.keras.datasets.fashion_mnist

(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

使用TFDS时,代码非常相似,但有一些小的变化。Keras的数据集直接给我们返回了可以在model.fit中原生使用的ndarray类型,但使用TFDS时,我们需要进行一些转换:

(training_images, training_labels), (test_images, test_labels) = tfds.as_numpy(tfds.load('fashion_mnist', split=['train', 'test'], batch_size=-1, as_supervised=True))

在这里,我们使用了tfds.load,将fashion_mnist作为所需的数据集传递给它。我们知道这个数据集有训练集和测试集的划分,所以在数组中传入这些划分项将返回包含图像和标签的适配器数组。使用tfds.as_numpy在调用tfds.load时会将数据返回为Numpy数组。指定batch_size=-1会让我们获取所有数据,而as_supervised=True则确保返回的格式为(输入,标签)元组。

完成这些操作后,我们基本上获得了与Keras数据集相同的数据格式,但有一个区别——在TFDS中,数据的形状是(28, 28, 1),而在Keras数据集中是(28, 28)。

这意味着代码需要做一些小的改动来指定输入数据的形状为(28, 28, 1),而不是(28, 28):

import tensorflow as tf

import tensorflow_datasets as tfds

(training_images, training_labels), (test_images, test_labels) = tfds.as_numpy(tfds.load('fashion_mnist', split=['train', 'test'], batch_size=-1, as_supervised=True))

training_images = training_images / 255.0

test_images = test_images / 255.0

model = tf.keras.models.Sequential([

tf.keras.layers.Flatten(input_shape=(28, 28, 1)),

tf.keras.layers.Dense(128, activation=tf.nn.relu),

tf.keras.layers.Dropout(0.2),

tf.keras.layers.Dense(10, activation=tf.nn.softmax)

])

model.compile(optimizer='adam',

loss='sparse_categorical_crossentropy',

metrics=['accuracy'])

model.fit(training_images, training_labels, epochs=5)

对于更复杂的示例,可以参考第3章中使用的“马或人”数据集,这个数据集在TFDS中也可以使用。以下是使用它来训练模型的完整代码:

import tensorflow as tf

import tensorflow_datasets as tfds

data = tfds.load('horses_or_humans', split='train', as_supervised=True)

train_batches = data.shuffle(100).batch(10)

model = tf.keras.models.Sequential([

tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(300, 300, 3)),

tf.keras.layers.MaxPooling2D(2, 2),

tf.keras.layers.Conv2D(32, (3,3), activation='relu'),

tf.keras.layers.MaxPooling2D(2,2),

tf.keras.layers.Conv2D(64, (3,3), activation='relu'),

tf.keras.layers.MaxPooling2D(2,2),

tf.keras.layers.Conv2D(64, (3,3), activation='relu'),

tf.keras.layers.MaxPooling2D(2,2),

tf.keras.layers.Conv2D(64, (3,3), activation='relu'),

tf.keras.layers.MaxPooling2D(2,2),

tf.keras.layers.Flatten(),

tf.keras.layers.Dense(512, activation='relu'),

tf.keras.layers.Dense(1, activation='sigmoid')

])

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

history = model.fit(train_batches, epochs=10)

正如你所见,这相当直接:只需调用 tfds.load,传入你想要的分割(在本例中是训练集),然后在模型中使用它。数据被批处理并打乱顺序,以便更有效地进行训练。

“Horses or Humans”数据集被划分为训练集和测试集,因此如果你想在训练时验证模型,可以通过TFDS加载单独的验证集,方法如下:

val_data = tfds.load('horses_or_humans', split='test', as_supervised=True)

你需要像处理训练集一样批处理它。例如:

validation_batches = val_data.batch(32)

然后在训练时,指定这些批次作为验证数据。你还需要显式设置每个周期要使用的验证步数,否则TensorFlow会报错。如果不确定,设置为1即可,如下:

history = model.fit(train_batches, epochs=10, validation_data=validation_batches, validation_steps=1)

加载特定版本

所有在TFDS中存储的数据集都使用MAJOR.MINOR.PATCH编号系统。其保证如下:如果仅PATCH更新,则调用返回的数据相同,但底层组织可能发生变化。这种变化对开发者应是无感知的。如果MINOR更新,则数据保持不变,但可能会在每条记录中增加新的特性(非破坏性更改)。此外,对特定切片(参见第74页的“使用自定义切片”)的数据不会重新排序。如果MAJOR更新,则记录格式及其位置可能会发生变化,因此特定切片可能会返回不同的值。

在检查数据集时,你会看到何时有不同版本可用——例如,cnn_dailymail数据集就是这样。如果你不想要默认版本(本文撰写时是3.0.0),而是希望使用早期版本,例如1.0.0,可以按以下方式加载:

data, info = tfds.load("cnn_dailymail:1.0.0", with_info=True)

请注意,如果你在Colab上使用TFDS,建议检查Colab使用的TFDS版本。本文撰写时,Colab预装的TFDS是2.0版,但其中存在一些加载数据集的bug(包括cnn_dailymail数据集),这些问题在TFDS 2.1及之后的版本中已修复,因此建议使用这些版本,或者至少在Colab中安装它们,而不是依赖内置的默认版本。

使用映射函数进行数据增强

在前面的章节中,你见到了使用ImageDataGenerator为模型提供训练数据时的一些有用增强工具。你可能想知道如何在使用TFDS时实现同样的功能,因为这时你不是从子目录流式读取图像。实现此功能的最佳方法(或任何其他形式的转换)是对数据适配器使用映射函数。让我们看看如何实现这一点。

之前,我们对Horses or Humans数据集的处理只是从TFDS中加载数据并为其创建批次,如下所示:

data = tfds.load('horses_or_humans', split='train', as_supervised=True)

train_batches = data.shuffle(100).batch(10)

要对数据进行变换并将其映射到数据集,你可以创建一个映射函数。这只是标准的Python代码。例如,假设你创建了一个名为augmentimages的函数,并让它进行一些图像增强,如下所示:

def augmentimages(image, label):

image = tf.cast(image, tf.float32)

image = (image/255)

image = tf.image.random_flip_left_right(image)

return image, label

然后你可以将其映射到数据上,创建一个名为train的新数据集:

train = data.map(augmentimages)

之后,在创建批次时,使用train而不是data,如下:

train_batches = train.shuffle(100).batch(32)

在augmentimages函数中,你可以看到使用tf.image.random_flip_left_right(image)对图像进行左右随机翻转。tf.image库中有很多可用于增强的函数;详细内容请参阅文档。

使用TensorFlow Addons

TensorFlow Addons库包含更多可用函数。ImageDataGenerator增强中的一些功能(如旋转)仅在此库中可用,因此建议查看它。

使用TensorFlow Addons非常简单——只需安装库即可:

pip install tensorflow-addons

安装完成后,可以将Addons混入到你的映射函数中。以下是将旋转Addons用于前面映射函数的示例:

import tensorflow_addons as tfa

def augmentimages(image, label):

image = tf.cast(image, tf.float32)

image = (image/255)

image = tf.image.random_flip_left_right(image)

image = tfa.image.rotate(image, 40, interpolation='NEAREST')

return image, label

使用自定义分割

到目前为止,你一直使用的是预先分割为训练集和测试集的数据集。例如,Fashion MNIST有60,000和10,000条记录,分别用于训练和测试。但如果你不想使用这些分割呢?如果你想根据自己的需求分割数据呢?TFDS的一个强大之处就在于——它提供了一个API,允许你精细地控制数据的分割方式。

实际上你已经见过这种方式了,例如像这样加载数据时:

data = tfds.load('cats_vs_dogs', split='train', as_supervised=True)

注意split参数是一个字符串,这里你请求了train分割,它恰好是整个数据集。如果你熟悉Python的切片符号,也可以使用它。这种符号可以总结为在方括号内定义你想要的切片,如下所示:[: : ]。它是一种相当复杂的语法,赋予了很大的灵活性。

例如,如果你希望train的前10,000条记录作为训练数据,可以省略,直接调用train[:10000](一个有用的记忆技巧是将前导冒号读作“前”,所以这将读作“train前10,000条记录”):

data = tfds.load('cats_vs_dogs', split='train[:10000]', as_supervised=True)

你还可以使用%来指定分割。例如,如果你希望前20%的记录用于训练,可以像这样使用:20%:

data = tfds.load('cats_vs_dogs', split='train[:20%]', as_supervised=True)

你甚至可以更进一步,组合多个分割。也就是说,如果你希望训练数据是前1000条记录和最后1000条记录的组合,可以这样做(-1000:表示“最后1000条记录”,“:1000”表示“前1000条记录”):

data = tfds.load('cats_vs_dogs', split='train[-1000:]+train[:1000]', as_supervised=True)

Dogs vs. Cats数据集没有固定的训练、测试和验证分割,但使用TFDS,创建自定义分割非常简单。假设你希望分割为80%、10%、10%。可以这样创建三个数据集:

train_data = tfds.load('cats_vs_dogs', split='train[:80%]', as_supervised=True)

validation_data = tfds.load('cats_vs_dogs', split='train[80%:90%]', as_supervised=True)

test_data = tfds.load('cats_vs_dogs', split='train[-10%:]', as_supervised=True)

一旦你有了它们,就可以像使用任何命名分割一样使用它们。

需要注意的是,由于返回的数据集无法被探测其长度,因此通常很难确认你是否正确地分割了原始数据集。要查看你在某个分割中的记录数量,你必须遍历整个数据集并一条条计数。以下是对你刚创建的训练集进行计数的代码:

train_length = [i for i, _ in enumerate(train_data)][-1] + 1

print(train_length)

这可能是一个较慢的过程,因此请确保仅在调试时使用它。

本节总结: 本章介绍了如何使用 TensorFlow Datasets(TFDS)和 Keras 搭建神经网络模型,并探索了数据增强、分割和预处理等关键操作。通过将 TFDS 数据集与 Keras 模型结合,您学会了如何高效加载和转换数据,为神经网络模型的构建和训练做好准备。此外,我们还介绍了如何灵活地自定义数据分割和应用数据增强,为模型提供更加多样化的训练数据。掌握了这些技能后,您将能够更自如地应用 TensorFlow 和 Keras 进行各种深度学习项目的开发,为复杂模型的搭建奠定坚实的基础。下一节我们将会为大家介绍从TFDS中下载出来的数据集是以什么形式保存下来的—TFRecord!

构建人工智能模型基础:TFDS和Keras的完美搭配的更多相关文章

  1. 我的Keras使用总结(2)——构建图像分类模型(针对小数据集)

    Keras基本的使用都已经清楚了,那么这篇主要学习如何使用Keras进行训练模型,训练训练,主要就是“练”,所以多做几个案例就知道怎么做了. 在本文中,我们将提供一些面向小数据集(几百张到几千张图片) ...

  2. 使用 keras 和 tfjs 构建血细胞分类模型

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识!

  3. Unity3D游戏开发初探—2.初步了解3D模型基础

    一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...

  4. Spring Boot 构建电商基础秒杀项目 (二) 使用 Spring MVC 方式获取用户信息

    SpringBoot构建电商基础秒杀项目 学习笔记 修改 DOMapper 在 UserPasswordDOMapper.xml 添加: <select id="selectByUse ...

  5. 使用Flask构建机器学习模型API

    1. Python环境设置和Flask基础 使用"Anaconda"创建一个虚拟环境.如果你需要在Python中创建你的工作流程,并将依赖项分离出来,或者共享环境设置," ...

  6. python基础-并发编程之I/O模型基础

    1. I/O模型介绍 1.1 I/O模型基础 更好的理解I/O模型,需要先回顾:同步.异步.阻塞.非阻塞 同步:执行完代码后,原地等待,直至出现结果 异步:执行完代码后,不等待,继续执行其他事务(常与 ...

  7. PLUTO平台是由美林数据技术股份有限公司下属西安交大美林数据挖掘研究中心自主研发的一款基于云计算技术架构的数据挖掘产品,产品设计严格遵循国际数据挖掘标准CRISP-DM(跨行业数据挖掘过程标准),具备完备的数据准备、模型构建、模型评估、模型管理、海量数据处理和高纬数据可视化分析能力。

    http://www.meritdata.com.cn/article/90 PLUTO平台是由美林数据技术股份有限公司下属西安交大美林数据挖掘研究中心自主研发的一款基于云计算技术架构的数据挖掘产品, ...

  8. 硬货 | 手把手带你构建视频分类模型(附Python演练))

    译者 | VK 来源 | Analytics Vidhya 概述 了解如何使用计算机视觉和深度学习技术处理视频数据 我们将在Python中构建自己的视频分类模型 这是一个非常实用的视频分类教程,所以准 ...

  9. 二手车价格预测 | 构建AI模型并部署Web应用 ⛵

    作者:韩信子@ShowMeAI 数据分析实战系列:https://www.showmeai.tech/tutorials/40 机器学习实战系列:https://www.showmeai.tech/t ...

  10. OSI七层模型基础知识及各层常见应用

       OSI Open Source Initiative(简称OSI,有译作开放源代码促进会.开放原始码组织)是一个旨在推动开源软件发展的非盈利组织.OSI参考模型(OSI/RM)的全称是开放系统互 ...

随机推荐

  1. ElementUI.Dialog.props怎么设置全局变量

    在main.js中为啥?这个可以 ElementUI.Dialog.props.closeOnClickModal.default = false // 全局关闭点遮罩关闭弹框 为啥这个不可以? El ...

  2. 平衡树 -- Splay & Treap

    Treap & Splay学习笔记 前置知识 -- BST 二叉搜索树,一种比较好玩的数据结构,其实现原理是运用每个点的权值构建,其中满足这样的构造方式: 若 \(value > t[x ...

  3. linux 操作系统下安装可视化界面

    一.安装背景 1.小白一只,英文不熟.还很菜,面了几个实施,打击的体无完肤!so,人丑多读书吧. 2.安装环境: VMware + centos7 3.本着不懂就问的原则 开始了--- 二.安装前准备 ...

  4. 虚拟机中创建的centos网络ping不通 - ping unkown host

    一.查看虚拟机设置 二.su 进入超级管理员账户  ls /etc/sysconfig/network-scripts 查看虚拟机网络信息 第一个,每一个机器的配置文件名不同 进入到  network ...

  5. redis 基准性能测试与变慢优化

    redis 参考目录: 生产级Redis 高并发分布式锁实战1:高并发分布式锁如何实现 https://www.cnblogs.com/yizhiamumu/p/16556153.html 生产级Re ...

  6. ZEGO 最后一公里网络传输的容灾及优化方案

    作为运维,你是否遇到过一些用户域名解析异常,你是否又遇到过某些区域云商加速节点异常导致业务不可用,此时的你一脸茫然,不知所措?作为运维,你是否被最后一公里问题搞得焦头烂额? 那么今天我们就来探讨一下最 ...

  7. ES6之常用开发知识点:字符串的扩展与正则表达式的扩展(三)

    字符串的扩展 codePointAt JavaScript 内部,字符以 UTF-16 的格式储存,每个字符固定为2个字节.对于那些需要4个字节储存的字符(Unicode 码点大于0xFFFF的字符) ...

  8. 小tips:CSS3中的background-clip属性(背景的裁剪区域)

    CSS3中的background-clip属性,其主要是用来确定背景的裁剪区域,换句话说,就是如何控制元素背景显示区域. 语法如下: background-clip : border-box || p ...

  9. ArgoWorkflow教程(四)---Workflow & 日志归档

    上一篇我们分析了argo-workflow 中的 artifact,包括 artifact-repository 配置以及 Workflow 中如何使用 artifact.本篇主要分析流水线 GC 以 ...

  10. UWP 通过 .NET 9 和Native AOT 的支持实现 UWP 应用的现代化

    微软(9 月 11 日)发布博文,微软正在预览对 .NET 9 的 UWP(通用 Windows 平台)支持,为现有 UWP 开发人员提供一条使用最新的 .NET 和本机 AOT 实现其应用程序现代化 ...