
这几天看了一些利用图像 DCT 系数作为空间特征训练卷积神经网络的论文,感觉挺好玩的,这里这里做一下整理总结。
Warning: 还没写完!好多内容还没看!
编写记录
- 2021 年 5 月 26 日 09 点 编写目录;
- 2021 年 5 月 26 日 10 点 看完博客,写了点;
- 2021 年 5 月 26 日 17 点 看了会儿论文,写了点;
- 2021 年 5 月 29 日 加了 DCT 公式和代码实现。
JPEG 算法
本节主要参考维基百科 和该系列博客。
联合图像专家小组(英语:Joint Photographic Experts Group,缩写:JPEG)是一种针对照片影像而广泛使用的有损压缩标准方法。使用 JPEG 格式压缩的图片文件一般也被称为 JPEG Files,最普遍被使用的扩展名格式为
.jpg
,其他常用的扩展名还包括.jpeg
、.jpe
、.jfif
以及.jif
。JPEG/JFIF 是互联网上最普遍的被用来存储和传输彩色照片的格式。
JPEG 编码的主要流程如下图所示,从图中可以看出,在 JPEG 编码中, RGB
格式的图像首先会被转换成 YCbCR
色彩空间,随后,图像的每个通道会分别进行不同的下采样。采样完成后接着进行量化的 DCT 计算得到量化的 DCT 系数,最终使用霍夫曼编码对数据进行无损压缩。

以 24bits/pixel 的彩色图片为例,具体来说,一个常见的 JPEG 算法过程分为 7 过程:色彩空间转换(Color space transformation、降采样(Downsampling)、区块分割(Block splitting)、离散余弦变换(Discrete cosine transform)、量化(Quantization)、熵编码(Entropy coding)和解码(Decoding)。
色彩空间转换(Color space transformation) - 无损
这一步的主要目的是把原始图像的色彩空间从 RGB
转换为 YCbCr
。
所谓
颜色空间
,是指表达颜色的数学模型。YCbCr
模型广泛应用在图片和视频的压缩传输中,Y
表示亮度 (Luminance),Cb
和Cr
分别表示绿色和红色的色度成分 chroma components
。对于人眼来说,图像中明暗的变化更容易被感知到,这是由于人眼的构造引起的。视网膜上有两种感光细胞,能够感知亮度变化的视杆细胞,以及能够感知颜色的视锥细胞,由于视杆细胞在数量上远大于视锥细胞,所以我们更容易感知到明暗细节。
这两种色彩空间的示意图如下:
RGB
色彩空间:

YCbCr
色彩空间:

可以明显看到,亮度图的细节更加丰富。而 JPEG 算法的主要思想,就是在尽可能保留 Y 通道的前提下,大幅度压缩色度通道,即 JPEG 把图像转换为 YCbCr
之后,就可以针对数据的重要程度的不同做不同的处理。这也是为什么 JPEG 使用这种颜色空间的原因。
从 RGB
到 YCbCr
的一个转换计算公式如下:

降采样(Downsampling) - 有损
这一步又称为
色度抽样
。简单来说也是根据人类视觉系统(HVS)
的特性,对亮度和色度进行不同策略的采样,一般来说,会对亮度不采样而对色度大幅采样。

如上图,抽样系统中通常用一个三分比值 J:a:b
来表示某个方案。JPEG 中最常用的是 4:2:0
:
- J:水平抽样总数,通常为 4。
- a:第一行中的抽样数目。
- b:第二行中的额外抽样数目。
区块分割(Block splitting) - 无损
完成色度抽样后,随后将每个通道分割成 8×8
块。根据不同大小色度抽样产生不同大小的最小编码单元块(MCU)。其中 8×8
的选取是依据经验,在计算复杂度和算法效果中均衡得出的。
至于边界处理,有一些边界填充技术。
离散余弦变换(Discrete cosine transform) - 无损
完成区块分割后,接着把分割出来的每一个 8×8
的子区域,使用二维的离散余弦变换(DCT)转换到频率空间。离散余弦变换 类似于离散傅里叶变换,但是只使用实数,相当于一个长度大概是它两倍的离散傅里叶变换。
DCT
是 JPEG 算法的核心。1807 年,39 岁的傅里叶在他的一篇论文里提出了一个想法,他认为 任何周期性的函数,都可以分解为为一系列的三角函数的组合。而对于离散的数据而言,如果离散的输入数据是对称的话,那么傅里叶变化出来的函数只含有余弦项,这种变换称为离散余弦变换。也就是说,经过 DCT
变换,可以把一个数组分解成数个数组的和,如果我们数组视为一个一维矩阵,那么可以把结果看做是一系列矩阵的和。
对于彩色图像而言,每一个 8×8×3
的输入矩阵,经过一个二维 DCT 变换后,得到 8×8×3
的输出,也就是 DCT 系数。
下图是 64 个基本余弦波,这 64 个余弦波,可以组合成任意 8*8 的图形。我们只要用系数(系数表示每个单独的余弦波对整体图像所做的贡献)对这 64 个余弦波进行加权,就可以表示出任何的图形。

以最常用的 DCT-II 公式为例,其计算公式如下:
对于一个二维的图像输入 i, j
的 DCT 系数计算公式如下:
DCT 逆的公式如下:
根据公式,可以轻松地用 Numpy 实现,代码如下:
1 | # 系数矩阵 |
这里给出两个计算例子:
全为 100 的矩阵:
更通常的例子(取自维基百科):
可以看到,数据经过 DCT 变化后,被明显分成了直流分量和交流分量两部分。图中,左上部分低频区的系数比较大,右下高频区的系数较小。鉴于人眼对高频区的识别不敏感,所以在下面量化部分可以舍弃一些高频区的数据。这里的 DCT 变化还没开始压缩。
量化(Quantization) - 有损
在 DCT 变化后,舍弃高频区数据的过程称为量化。JPEG 算法提供了两张标准的量化系数矩阵,分别用于处理亮度数据 Y 和色差数据 Cr 以及 Cb 。

上表分别为亮度量化表和色彩量化表,表示 50% 的图像质量。这两张表中的数据基于人眼对不同频率的敏感程度制定的。
量化表是控制 JPEG 压缩比的关键,可以根据输出图片的质量来自定义量化表,通常自定义量化表与标准量化表呈比例关系,表中数字越大则质量越低,压缩率越高。Photoshop 有 12 张量化表。
量化时,用前面的量化矩阵与 DCT 矩阵逐项相除并取整。
量化是有损的,在解码时,反量化会乘回量化表的相应值。由于存在取整,低频段会有所损失,高频段的 0 字段则会被舍弃,最终导致图像质量降低。
熵编码(Entropy coding) - 无损
得到量化后的矩阵就要开始编码压缩过程了,首先要把二维矩阵变为一维数组,这里采用了 zigzag 排列,将相似频率组在一起:

这么做的目的只有一个,就是尽可能把 0 放在一起,由于 0 大部分集中在右下角,所以才去这种由左上角到右下角的顺序。
最后对得到的整数数组进行哈夫曼压缩,得到最终的压缩数据,压缩详细过程略,注意哈夫曼压缩本身是无损的。
解码(Decoding)
解码来显示影像,把以上所有操作反过来走一遍就好了。
使用 JPEG 编码的频域学习
现在大部分基于图像的任务,都是通过 RGB 图像进行学习,也就是空域。而频域学习的意思就是将 RGB 图像变换到频域(例如 DCT ),然后在频域空间上进行学习。
Faster Neural Networks Straight from JPEG用 ResNet50 在大的分类数据集 ImageNet 上做了许多频域学习的实验。
对于数据集中 JPEG 格式的图像,本文魔改了 libjpeg
库,丢掉了 JPEG 解码的最后一步计算,直接从原始图像得到 DCT 系数,然后直接输入卷积神经网络中。

如果输入图像大小为 224×224
,分为 8×8
的组块,一共 28×28
个块,输出 28×28
个系数矩阵。把相同频率(即系数矩阵相同位置)的系数按照位置关系放到同一个 channel 中,这样就得到了大小为 28×28
,channel 数为 8×8×3=192
的 feature map。
本文作者指出,该过程实际上等价于一个卷积操作,kernel size 为 8×8
,stride 为 8×8
,输入 channel 数为 1,输出 channel 数为 64 。只不过卷积的参数不用学习,是先验的。而且卷积过滤器是正交的,参数化学习很难学到同样特性的过滤器参数。
当然,为了适应新的输入,需要对原有的卷积神经网络的前几层进行少量的修改。经过测试,这篇文章的方法更快且精度更高,在达到同样精度的情况下能够比 Resnet50 基线快 1.77 倍。
基于学习的通道筛选
Learning in the Frequency Domain 是达摩院发表在 CVPR 2010 的一项工作。提出的方法和 Faster Neural Networks Straight from JPEG 基本一样,主要贡献是在实例分割上做了些实验,验证了频域学习在实例分割任务上同样有效。另一个贡献就是提出了一个基于学习的通道选择,实验验证在 ImageNet 分类任务中,能够修剪多达 87.5% 的频率信道,而没有精度下降。

上图就是这篇文章提出的 gate 模块,实现基于学习的频率通道选择。因为不同的通道代表了不同的频率,而有些频率(主要是高频)对于图像分类和实例检测任务的精度贡献有限,所以可以删除一些通道而不会影响模型精度。本文的 gate 模块对每一个频率通道置顶了一个二元评分,0 表示丢掉,1 表示保留。这样做的结果就是输入数据的大小大幅减少,降低了计算复杂度和通信带宽。该门模块很简单,可以作为模型的一部分,应用于在线推理中。
具体的,输入张量的形状为 H×W×C
,经过平均池化得到形状为 1×1×C
的张量 2 。随后再经过 1×1
的卷积得到形状为 1×1×C
的张量 3 。从张量 1 到张量 3 的部分实际上是一个两层的 squeeze-and-excitation block(SE-Block),SE-Block 利用通道信息来强调信息量大的特征并抑制信息量小的特征。然后将张量 3 与两个可学习的参数相乘得到形状为 1×1×C×2
的张量 4,在推断阶段,张量 4 每一个通道的两个数归一化后作为选择该通道的概率,在 Bernoulli 分布中采样进行选择。
又因为 Bernoulli 采样是不可微的,不能反向传播,所以需要一些数学近似。这篇文章使用的方法是 Gumbel Softmax trick,使得 Bernoulli 采样可以反向传播训练。
实验略。
总结
频域学习的优点:
- 图像处理更高效:直接魔改 libjpeg 包就能从原始 jpg 图像中直接得到图形输入,减少了转换为 RGB 色彩空间的开销。
- 模型训练,推断更快:首先是 JPEG 算法本身就是一个有损图像压缩算法,所以输入带宽和计算开销变小了,其次是空域学习相当于给 CNN 前几层引入了一个很强的先验知识(直接定好的参数),所以让模型训练更容易。
光明正大的作弊,更大的输入尺寸。
Reference
- 本文标题:论文笔记:从 JPEG 中学习
- 本文作者:Tilden Ji
- 创建时间:2021-05-26 09:13:13
- 本文链接:https://itiandong.com/2021/paper-learning-from-JPEG/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!