本文为 AI 研习社编译的技术博客,原标题 Learning to perform linear filtering using natural image data,作者为 Josef Taher 。
翻译 | 张泽坤 王霏 校对 | 余杭 整理 | MY
卷积神经网络通常从训练数据中学习有用的特征。第一个卷积层学习到的特征往往是视任务而定的一些训练数据的基本元素。例如,在图像数据中,学习到的特征可以体现边缘和斑点。在后续的网络层中,这些学习到的特征可以表现更加抽象,更高级的特点。
将学习到的特征以及它们随时间的变化可视化,可以提供一些关于网络如何学习的有效信息。实际上,网络结构远远不仅是几层网络那么简单,大量的卷积核使得直观解释和分析学习到的特征变得十分困难。
然而,我们可以通过对照实验证明卷积核的权重是如何随着网络的学习而实时发展。由于网络应该学习到的特点已经被提前知道,即产生数据的过程和参数是被完全定义并且完全在我们的掌控之中,学习任务可以很容易的被确定。我们可以通过构建一个非常简单的单层卷积网络并训练它利用多种核进行线性滤波来实现上述过程。
在接下来的实验中,我们在数据集上运用一种图像处理和计算机视觉中常用的传统边缘检测方式——Sobel 边缘滤波,并训练我们的模型进行类似的线性映射。我们也尝试着利用比 Sobel 滤波器更大一些的核去学习一些形式更为普通和任意的滤波器。
这些可以帮我们感受神经网络中的卷积层如何对输入数据进行操作,卷积核的权重在训练中如何变化以及神经网络的训练是如何被视为最小化问题的。
首先,我们必须用线性滤波器去处理图像数据 X 来获取原始图像滤波后的结果 Y。线性滤波器操作可以被总结为如下形式:
对任何一组参数 (卷积核) 或我们所能想到的输入数据,线性滤波器都具有良好定义的操作。
我们现在可以构造一个单层,单核的近似线性滤波的卷积神经网络。在线性滤波器和卷积神经网络这两种方式中发生的计算除了我们要从数据中学习到的卷积核参数外是完全一样的。
我们可以画出如下的线性滤波器与卷积神经网络间的联系:
学习任务可以被转化为最小化线性滤波器的输出与卷积神经网络的输出的均方误差的最小化问题:
处理图像数据的线性滤波器的参数被称为卷积核。我们的实验采用称为 Sobel 算子的 3 x 3 的卷积核来对图像数据进行滤波,操作顺序为先沿 x 方向再沿 y 方向。Sobel 算子为:
我们使用基于 TensorFlow 的 Keras 框架实现这些实验。
x 方向上的 Sobel 滤波器
首先,我们需要定义一组辅助函数来对图像进行预处理。数据集被加载后,图像被转换成灰度形式,图像强度范围被归一化然后对数据集中的每个图像进行线性滤波。
城市和自然景观类的数据来作为训练和测试数据 - 数据集(Oliva, A. & Torralba, A. (2001).Modeling the Shape of the Scene: A Holistic Representation of the Spatial Envelope)(http://cvcl.mit.edu/Papers/IJCV01-Oliva-Torralba.pdf)由麻省理工学院麻省理工学院计算视觉认知实验室收集整理。
原始的数据集包括八个类别的自然景观的彩色图像(分辨率: 256 x 256)。我们从中选取街道,城市中心以及高层建筑三个类别进行使用。这样,我们就获得了充足的固定大小的训练集和测试集(764 个训练集样本和 192 个测试集样本),因此训练不会发生过拟合并且可以在更加合适的硬件和时间框架中完成。选定的三个分类是自然景观(大量的人类建筑物)中具有明显边缘的代表,便于我们比较结果。
接下来,我们可以可视化的观察数据集中原始图像、经过灰度转换后的图像以及 Sobel 滤波后的图像:
原始图像(左),灰度图像(中间)以及在 x 方向上进行 Sobel 滤波后的图像(右)。
我们仅对单通道图像使用线性滤波器。实际上,这意味着模型被训练成将灰度转换后的图像到 Sobel 过滤后的图像的映射。
接下来,我们定义一个模型:单层,单核的线性激活的卷积网络。例如采用 identity 激活函数。卷积核的大小设定为 3 x 3,以便于与 Sobel 滤波器的尺寸兼容。
利用使用 Nesterov 动量的随机梯度下降的优化器模型进行 100 轮的训练。在每一轮中,卷积层的权重都被保存以便进一步的可视化。
在训练结束后,我们可以画出训练和验证的损失值来观察训练是否过拟合。
训练过程中的训练损失和验证损失是平稳的,模型看上去似乎是收敛的。
每个轮次保存的权重以数值矩阵的方式呈现出来,矩阵中的数值代表了像素的灰度值。声明了用于进行可视化的函数,并为每个轮次创建了可视化功能。
现在我们可以可视化每一个轮次,能够为每一个轮次创建一个动图,观察权重是如何下降的。
模型的卷积层权重被训练后,权重值收敛到接近 x 方向上的 Sobel 算子。
在模型的学习过程中,通过动图可以清晰的看到卷积核权重值组建收敛至 x 方向上的 Sobel 滤波器。前 10 到 15 个轮次的收敛很快,这之后,收敛率很快稳定下来。如果我们在本次实验中使用了比线性滤波器更加复杂的学习任务,我们仍然能看到类似的行为。卷积核的值会收敛到最优的参数值从而能够从数据中学习到有用的特征。在本次实验中,有用的特征是由 Sobel 操作器提供的图像 x 方向上的边缘信息。我们能够找到几乎精准的,由第一手训练数据产生的卷积核参数,大部分原因是因为我们设置的问题非常简单。但是在现实问题中,这是极少可能发生的,因为训练数据不是典型的从输入到输出的线性映射。
为了测试模型,我们可以对比模型的预测结果与 x 方向上的 Sobel 滤波器。
左边是模型的输出,右边是同一幅图像上,x 方向的 Sobel 滤波器的结果。
在图的上方,我们可以同时观察到模型的输出和 x 方向上 Sobel 算子的结果。通过观察可以发现两幅图像看上去很相似。事实上,两幅图像在像素灰度值上仅能发现很细微的差异,因为训练过的卷积核参数已经收敛到接近原始 Sobel 算子的值了。
y 方向上的 Sobel 操作器
同样的代码也可以被用到与 y 方向的 Sobel 算子进行线性滤波。我们要做的就是改变图像滤波函数用 y 方向上的滤波取代 x 方向,再次加载和滤波训练数据,同时用新数据训练模型。
在下方图中,我们可以观察到,Sobel 滤波器现在更加强调图像在竖直方向上的图像灰度边缘。
原始图像(左侧),灰度图像(中间)和 y 方向上的 Sobel 滤波图像(右侧)
我们能够再一次的观察到卷积核的权重逐步趋向 y 方向的 Sobel 滤波器,随着网络不断的从训练数据中学习。这个收敛行为与之前 x 方向的 Sobel 算子非常接近。
模型训练卷积层权重的过程,权重值收敛到接近于 y 方向上的 Sobel 算子。
相类似的,下方的图是在同一测试图像上模型的输出结果和 Sobel 滤波器的版本,有着相同的形状。从人眼角度,不可能区分这两个图像的差别。
模型的输出(左边)和相同图像 y 方向 Sobel 滤波器的结果(右边)
笑脸滤波器
之前学习的 Sobel 滤波器非常的简单,仅需要学习非常少量的参数。现在我们看一下我们能不能学习一个有着更大卷积核的滤波器。
这个滤波器核在接下来的实验中将会被用在一个 32 x 32 像素的笑脸图像上。这个滤波器被加载进来,训练数据通过笑脸滤波器滤波灰度图像得到。由于滤波核的尺寸很大,实质上核已经扩展到了图像的外面。图像的边界通过补 0 操作抵消由于卷积操作导致的图像分辨率的降低。
归一化的笑脸滤波器核
在下方图中,我们可以看到一个滤波后的笑脸图像与原始图像以及灰度图像的区别。
原始图像(左侧),灰度图像(中间)笑脸滤波图像(右侧)。
我们的方法再次使用了一个简单的层,单个核的卷积神经网络,其中激活函数也是一样的。这次,我们设根据笑脸滤波器核的尺寸设置卷积核核的大小是 32 x 32。作为之前实验的增强版本,我们用更加强大的 Adam 优化器替换随机梯度下降优化器。
这个模型被训练了 100 次,在每个轮次中卷积核参数都被保存了下来。训练和验证损失大概在 10 个轮次的时候就快速的收敛了,这之后在两个损失变化中都只能看到很小的波动。
保存的卷积核权重值可以被可视化并组合成一个 gif 动图。这个结果被高亮出来了:模型看上去很好的学习到了原始笑脸滤波器的核,从下面的 gif 图中可以清晰的看出。在大约 10 轮迭代后,卷积核权重值相对较早的呈现出笑脸的形状,但是核权重仍然包含较大的噪声。随着训练的进行,噪声慢慢的消失,相邻的权重值之间互相变得更加稳定。
通过分析验证集的损失和卷积核权重的可以完成一个重要的观察。尽管在 10 轮迭代后验证集的损失看上去很平稳,卷积核的权重仍然向原始的笑脸核逼近了足够多的量。线性尺度的训练和验证集的损失曲线可能偶尔有一点误导,因为在计算损失时,初始损失在后阶段的改进中可能主导损失可视化的结果。
模型训练卷积层权重的过程。权重值逐渐收敛到接近笑脸滤波器
现在我们已经有一个训练好的模型,我们可以可视化,并在测试图像上比较模型的输出和笑脸滤波器的处理结果。在下面的图像中,我们可以观察到模型和笑脸滤波器在测试图像上产生了一个类似笑脸的形状。与 Sobel 滤波器滤波的图像类似,模型产生的图像也由从数据中学习到了 Sobel 滤波器的特性,区分笑脸滤波器滤波的图像和模型输出的图像是非常难区分的。
模型的输出(左侧)和由笑脸滤波器在同一张图像上得到的结果(右侧)。
终言
我希望这三个线性滤波器的实验走狗清晰的阐述卷积核的权重是如何由网络从数据训练中得到的。此外,我希望你能够捕捉到一些洞察力以便理解卷积核对输入数据上的操作方式。实验结果不适合推广到卷积网络在图像分类上的例子,但是作为一个优化问题仍然为理解卷积层背后的现象和学习提供了一个基础。
如果你对在自己的电脑运行这个实验感兴趣,这里是 github 上的链接路径,包含了所有重复执行必须的内容:
https://github.com/vexcel/Keras-LearnLinearFilter .
https://towardsdatascience.com/learning-to-perform-linear-filtering-using-natural-image-data-db289d0b0457
想知道关于计算机视觉更多知识?
领取专属 10元无门槛券
私享最新 技术干货