Skip to content

05. 图片怎样变成数字数组 ​

运费模型一次只读一个重量。如果一次处理多条包裹,或者识别一张由许多像素组成的图片,程序需要把数字按明确形状组织起来。本篇从单个数走向向量、矩阵和张量,重点是读懂每个轴代表什么。

从一个数到一张表 ​

先只看数字的摆放方式。程序里按一定形状组织起来的一组数字,称为数组。单个重量 2.5 是一个数,称为标量。三个重量按顺序排成 [1,2,3],就得到一个向量;在这里,可以先把它理解成一排有顺序的数字。如果每件包裹同时记录重量和体积,就需要一张有行、有列的数字表,称为矩阵:每一行是一件包裹,每一列是一种特征。

样本重量 / 千克体积 / 升
A12
B23
C36

只看重量和体积两列数字,这张矩阵有 3 行、2 列,它的形状记作 [3,2]。形状像收纳盒的规格,告诉程序有几行、每行放几个数。沿着行号选择包裹、沿着列号选择特征,是两个不同方向,称为两个轴。轴的数量也常叫数组的维数;注意“64 维向量”中的 64 指有 64 个分量,这种向量的数组形状仍只有一个轴 [64]。

体积这里只帮助观察一行怎样容纳多个特征。前面的运费模型仍只接收重量,后面会另用一条算式演示两个特征怎样相加。

图片的轴有具体含义 ​

灰度图片可以看作一张明暗数值表:每个像素占一格,格中的数记录这个位置的明暗。8×8 图片就是 8 行、每行 8 格,共 64 个数。把这 64 个数的顺序打乱,数量虽然没变,图案却会变,因此程序既要知道数值,也要知道排列。

八乘八教学像素展开为64维向量,再将两张图片组成二乘64的批次

先读第一行,再读第二行,直到第八行,把小方阵排成一长行,这就是第 03 篇提到的展平,结果形状为 [64]。如果把两张图片各自展平,再放成两行,就得到 [2,64]:两条样本,每条 64 个像素数。

把一组样本放在一起计算,叫一个批次(Batch),像一次把几张作业放到同一个托盘里。第一个轴是托盘中第几张图,第二个轴是图中第几个像素。选择这两个位置的编号叫索引;Python 从 0 开始编号,因此索引 0 指第一项。

有些模型需要保留像素的相邻关系,就不会先排成一长行。例如后面的卷积网络,可以先理解为用小窗口在图上观察局部形状。它接收的同一批图片可能写成 [2,1,8,8]:2 张图、每张 1 层明暗、每层 8 行 8 列。

这里“一层明暗”叫一个通道。彩色图像常用红、绿、蓝三层数值合成颜色,也就是 RGB 三通道;某些程序按蓝、绿、红的 BGR 顺序保存,传错顺序就会改变颜色。在模型工具中,标量、向量、矩阵以及更多轴的数组,都可以用张量表示。画成一摞图片只是帮助理解:四个轴分别用于编号,不是在说图片真的存在于四维空间。

矩阵乘法在组合什么 ​

如果每条样本有两个特征,模型要把两个输入分别乘自己的权重,再相加:ŷ=w1×x1+w2×x2+b。x1,x2 是这一条样本的两个特征值,w1,w2 是分别与它们配对的权重,数字 1、2 用来区分位置。例如输入一行 [1,2],权重一列 [2,3],先算 1×2+2×3=8,再加偏置 b。

矩阵乘法把这样的“对应相乘,再相加”同时应用到多行输入上。把每条样本放成一行,输入矩阵 X 的形状为 [B,2],权重列为 [2,1],相乘后得到 [B,1],即每条样本有一个计算结果;再给每条结果加上 b,得到预测。

内侧的维度 2 必须一致,因为每条样本的两个特征分别与两个系数配对后相加。B 是当前批次的样本数,并不是模型参数。下一批可以有不同的 B,但每条样本的特征含义仍要保持不变。

reshape 不能替代检查轴 ​

reshape 意为重塑形状,像把同一串数字从“2 行、每行 3 个”重新装成“3 行、每行 2 个”。它保持元素总数,却不会理解哪一列是重量、哪一轴是颜色。把原图的行和列互换,需要的是转置,也就是交换两个轴;两种操作的目的不同。

Python 列表的嵌套也可以帮助理解索引:

python
images = [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]
print(images[1][0][1])  # 第二张图、第一行、第二列,结果为5

这段代码可在第 02 篇准备的解释器直接运行。这里用 2×2 教学图片展示索引,没有训练或识别过程。若把样本轴当成行轴,得到的值可能仍然是数字,错误却已经进入整个计算链路。

张量是多维数值数组的统称;每个轴都应对应明确对象。后续看模型时,先写出输入、权重与输出形状,再检查数值。下一篇回到同一批运费样本:06. 怎样衡量预测好坏。

别急,先让缓存热一下。