「PyTorch深度学习入门」4. 使用张量表示真实世界的数据(上)

来源 | Deep Learning with PyTorch

作者 |  Stevens, et al.

译者 | 杜小瑞

校对 | gongyouliu

编辑 | auroral-L

全文共3914字,预计阅读时间20分钟。

第四章  使用张量表示真实世界的数据(上)

 

1. 使用图像

    1.1  添加颜色通道

    1.2  加载一个图片文件

    1.3  改变布局

    1.4  数据标准化

2.  三维图像:体积数据

    2.1  加载专用格式

3.  表示表格数据

    3.1  使用真实数据集

    3.2  加载葡萄酒数据张量

    3.3  表示分数

    3.4  one-hot 编码

    3.5  何时进行分类

    3.6  找到阈值

4.  使用时间序列

    4.1  添加一个时间维度

    4.2  按时间段构造数据

    4.3  准备训练

5.  表示文本

    5.1  将文本转化为数字

    5.2  one-hot 编码字符

    5.3  one-hot 编码整个单词

    5.4  文本嵌入

    5.5  作为蓝图的文本嵌入

6.  结论

7.  练习

8.  总结

本章内容包括:

 用PyTorch张量表示真实数据

 使用一系列数据类型

 从文件加载数据

 将数据转换为张量

对张量进行变换,以便将其用作神经网络模型的输入

 

在上一章中,我们了解到张量是PyTorch中数据的构建块。神经网络以张量作为输入,产生张量作为输出。实际上,神经网络内部和优化过程中的所有操作都是张量之间的操作,神经网络中的所有参数(例如权重和偏差)都是张量。知道如何对张量执行操作并有效地对其进行索引对于成功地使用PyTorch之类的工具至关重要。既然你已经知道了张量的基本知识,那么当你读完这本书的时候,你对张量的熟练程度就会提高。

这里有一个我们已经可以解决的问题:我们如何获取一段数据、一段视频或一行文本,并以一种适合于训练深度学习模型的方式用一个张量来表示它?这是我们将在本章学习的内容。我们将介绍不同类型的数据,重点介绍与本书相关的类型,并展示如何将这些数据表示为张量。然后我们将学习如何从最常见的磁盘格式加载数据,并了解这些数据类型的结构,以便了解如何为训练神经网络做好准备。通常情况下,我们的原始数据对于我们想要解决的问题来说并不是完美的,因此我们将有机会通过一些更有趣的张量操作来练习我们的张量操作技巧。

本章中的每一节都将描述一种数据类型,每一节都有自己的数据集。虽然我们已经构建了这一章,使每种数据类型都建立在前一种数据类型的基础上,但如果你愿意的话,可以随意跳过一点。

在本书的其余部分中,我们将使用大量的图像和立体数据,因为这些是常见的数据类型,它们以书籍格式重现得很好。我们还将介绍表格数据、时间序列和文本,因为我们的许多读者也会对这些内容感兴趣。既然一张图片胜过千言万语,我们就从图像数据开始。接下来,我们将使用关于葡萄酒的表格数据,就像我们在电子表格中找到的一样。之后,我们将转向有序表格数据,使用自行车共享程序中的时间序列数据集。最后,我们将深入研究Jane Austen的文本数据。文本数据保留了它的有序特性,但引入了将单词表示为数字数组的问题。

在每一节中,我们都会从深度学习研究者的出发点开始:在将数据输入模型之前。我们鼓励你保留这些数据集;当我们在下一章开始学习如何训练神经网络模型时,它们将成为极好的材料。

1. 使用图像

卷积神经网络的引入彻底改变了计算机视觉(参见http://mng.bz/zjMa)之后,基于图像的系统获得了一套全新的功能。现在,通过使用成对的输入和期望输出示例来训练端到端网络,可以以前所未有的性能水平解决需要高度优化的算法构建块的复杂管道的问题。为了参与这场革命,我们需要能够从常见的图像格式加载一幅图像,然后将数据转换成张量表示,该表示将图像的各个部分按PyTorch期望的方式排列。

图像被表示为一组标量,这些标量排列在具有高度和宽度(以像素为单位)的规则网格中。每个网格点(像素)可能只有一个标量,将被表示为灰度图像;或每个网格点有多个标量,它们通常代表不同的颜色(如上一章所述),或不同的特征(如深度相机的深度)。

表示单个像素处的值的标量通常使用8位整数进行编码,如在消费相机中。在医学、科学和工业应用中,发现使用的是更高的数值精度并不罕见,例如12位或16位。这允许在像素编码有关物理特性(如骨密度、温度或深度)的信息的情况下具有更宽的范围或更高的灵敏度。

1.1 添加颜色通道

我们之前提到过颜色。有几种方法可以将颜色编码成数字。最常见的是RGB,其中颜色由代表红、绿和蓝强度的三个数字定义。我们可以把一个颜色通道看作是一个灰度强度图,它只反映了所讨论的颜色,类似于你用一副纯红色太阳镜观察所讨论的场景时所看到的情况。图4.1显示了彩虹,其中每个RGB通道捕获光谱的某一部分(该图被简化了,因为它省略了橙色和黄色波段等由红色和绿色的组合表示的部分)。

 

「PyTorch深度学习入门」4. 使用张量表示真实世界的数据(上)_第1张图片

图 4.1 一道彩虹,分为红、绿、蓝三种颜色

 

图中红色通道中彩虹的红色波段最亮,蓝色通道的彩虹蓝带和天空的蓝色带都是高强度的,同时注意,白云在三个通道中都是高强度的。

1.2 加载一个图片文件

图像有几种不同的文件格式,但幸运的是有很多方法可以在Python中加载图像。让我们首先使用imageio模块(code/p1ch4/1_image_dog.ipynb)加载一个PNG图像。

 

「PyTorch深度学习入门」4. 使用张量表示真实世界的数据(上)_第2张图片

注意

我们将在本章中使用imageio,因为它使用统一的API处理不同的数据类型。出于许多目的,使用TorchVision是处理图像和视频数据的最佳默认选择。我们在这里使用imageio进行更轻松的探索。

在这里,img是一个三维的NumPy数组对象:两个空间维度,宽度和高度;以及对应于红色、绿色和蓝色通道的第三维度。任何输出NumPy数组的库都能够获得PyTorch张量。唯一要注意的是维度的布局。处理图像数据的PyTorch模块需要将张量设置为C× H× W:通道、高度和宽度。

1.3 改变布局

我们可以使用张量的置换方法,对每一个新的维度使用旧的维度来得到一个合适的布局。给定一个如前所述的输入张量H× W× C,我们通过先设置通道2,然后设置通道0和通道1来获得适当的布局。

我们在前面已经看到过,但是请注意,这个操作不会复制张量数据。相反,out使用与img相同的底层存储,只在张量级别处理大小和步长信息。这很方便,因为操作非常便宜;但正如一个提示:在img中改变一个像素将导致在out中的改变。

还要注意,其他深度学习框架使用不同的布局。例如,最初TensorFlow将通道维度放在最后,也就是H× W× C的布局(现在支持多种布局)。从低层的性能角度来看,这种策略有优点也有缺点,但是对于我们来说,只要我们正确地reshape我们的张量,这并没有什么区别。

到目前为止,我们只描述了一个图像。按照我们在早期数据类型中使用的相同策略,为了创建一个包含多个图像的数据集作为神经网络的输入,我们沿着第一维度成批存储图像以获得一个N× C× H× W张量。

作为使用堆栈构建张量的一种稍微有效的替代方法,我们可以预先分配适当大小的张量,并用从目录加载的图像填充它,如下所示:

这表示我们的批处理将由三个RGB图像组成,高度为256像素,宽度为256像素。注意张量的类型:我们期望每种颜色都表示为8位整数,就像标准消费相机的大多数摄影格式一样。我们现在可以从输入目录加载所有PNG图像并将它们存储在tensor中:

 

「PyTorch深度学习入门」4. 使用张量表示真实世界的数据(上)_第3张图片


1.4 数据标准化

我们前面提到过,神经网络通常使用浮点张量作为输入。当输入数据大致在0到1或-1到1之间时,神经网络表现出最佳的训练性能(这是其构建块定义方式的影响)。

所以我们要做的一件典型的事情就是将一个张量转换成浮点值,并对像素值进行规一化。转换为浮点很容易,但标准化更为棘手,因为它取决于我们决定的输入范围应该在0和1(或-1和1)之间。一种可能是将像素值除以255(8位无符号中的最大可表示数): 

另一种可能性是计算输入数据的平均值和标准偏差,并对其进行缩放,以便输出在每个通道上具有零平均值和单位标准偏差:

注意

在这里,我们只对一批图像进行标准化,因为我们还不知道如何对整个数据集进行操作。在处理图像时,最好先计算所有训练数据的平均值和标准差,然后用这些固定的、预先计算的量进行减除。我们在第2.1.4节的图像分类器预处理中看到了这一点。

我们可以对输入执行其他一些操作,如旋转、缩放和裁剪等几何变换,这些可能有助于训练。或者可能需要使任意输入符合网络的输入要求,例如图像的大小。我们将在第12.6节中发现其中一些策略。现在,只需记住你有可用的图像处理选项。

2. 三维图像:体积数据

就像我们用相机拍摄图像一样,我们已经学会了如何加载和表示2D图像。在某些情况下,例如涉及CT(计算机断层扫描)扫描的医学成像应用程序中,我们通常处理沿头到脚轴堆叠的图像序列,每个序列对应于人体的一个切片。在CT扫描中,强度代表身体不同部位的密度,如肺、脂肪、水、肌肉和骨骼,当CT扫描显示在临床工作站上时,密度从暗到亮依次增加。每个点的密度是根据穿过人体后到达探测器的X射线数量计算出来的,用一些复杂的数学将原始传感器数据解卷积到整个体积中。

CT只有一个强度通道,类似于灰度图像。这意味着,在本地数据格式中,通道维度常常被忽略;因此,与上一节类似,原始数据通常有三个维度。通过将单独的二维切片叠加到三维张量中,这样就可以建立表示物体三维解剖结构的体积数据。与我们在图4.1中看到的不同,图4.2中的额外维度表示物理空间中的偏移,而不是可见光谱的特定波段。

 

「PyTorch深度学习入门」4. 使用张量表示真实世界的数据(上)_第4张图片

图 4.2 从头顶到下颚的CT扫描切片

本书的第2部分将致力于解决现实世界中的医学成像问题,因此我们将不深入讨论医学成像数据格式的细节。现在,可以说存储立体数据的张量和存储图像数据的张量之间没有根本的区别。在通道维之后,我们增加一个额外的维度深度,就形成一个N× C× D× H× W的5维张量。

2.1 加载专用格式

让我们使用imageio模块中的volread函数加载一个CT扫描的示例,该函数的参数是一个目录,将所有医学数字成像和通信(DICOM)文件以一个NumPy 3维数组(code/p1ch4/2_volumatile_CT.ipynb)的形式串联起来。

 

「PyTorch深度学习入门」4. 使用张量表示真实世界的数据(上)_第5张图片

正如第1.3节所述,由于没有通道信息,布局与PyTorch预期的不同。因此,我们必须使用unsqueze为通道维度腾出空间:

 

「PyTorch深度学习入门」4. 使用张量表示真实世界的数据(上)_第6张图片

此时,我们可以通过沿批处理方向堆叠多个卷(volumes)来组装5维数据集,就像我们在上一节中所做的那样。我们将在第2部分看到更多的CT数据。

「PyTorch深度学习入门」4. 使用张量表示真实世界的数据(上)_第7张图片

你可能感兴趣的:(python,计算机视觉,机器学习,人工智能,深度学习)