卷积神经网络应用:基于Tensorflow的CNN/CRF图像分割技术
Image TensorFlow 卷积神经网络 条件随机场 后处理 图像分割 上采样
摘要: 本篇文章验证了卷积神经网络应用于图像分割领域时存在的一个问题——粗糙的分割结果。根据像素间交叉熵损失的定义,我们在简化的场景下进行了模型的训练,并使用后向传播来更新权重。我们使用条件随机场(CRFs)来解决分割结果粗糙的问题,并取得了很好的效果。本文中的代码注释详细、功能完善,也便于读者阅读。
这是一篇翻译文章。介绍了一种基于最近发布的TF-Slim库与预训练模型来进行图像分割的方法。本篇文章的内容包括基于条件随机场的模型训练与后处理过程。
引言
在之前的文章中,我们实现了上采样操作,并通过将其与scikit-image库中的对应实现作比较,以确保上采样过程的正确性。更具体地说,我们实现了论文《Fully convolutional networks for semantic segmentation》中描述的FCN-32分割网络。
在本篇文章中,我们将进行一个简单的训练:我们将从PASCAL VOC数据集中选取一张样本图像以及它的标注信息,基于样本图像与标注训练来我们的网络,并在同样的图像上测试我们训练好的网络。之所以这样做,是因为这样我们就可以使用CPU来训练模型——只需要10次迭代就能完成训练。本篇文章的另一个目的在于,证明我们这个网络(FCN-32s)的分割结果是很粗糙的——即使在用于训练的图像上进行分割,结果也同样如此。在本篇文章中,我们使用条件随机场的后处理阶段来解决这个问题,其综合考虑图像中的RGB纯色特征以及模型输出的预测概率,进而改善图像的分割效果。总的来说,我们得到了改善后的分割结果。我们刻意在文章中使用了非常简单的训练环境。类似的分割方法在Chen等人发表的论文《Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs》中也有所提及。请注意,本篇文章中的训练环境仅为了说明FCN-32s模型的局限,如果要在真实场景中进行训练,我们建议读者参考这篇论文《Fully convolutional networks for semantic segmentation》。
本篇文章使用Jupyter Notebook创建。在每个代码块后,你可以看到模型的评估结果。你也可以从这里获得本文对应的笔记文档。本篇文章的部分内容也借鉴了TF-Slim库的演示教程。
准备阶段
为了运行下面的代码,你需要安装Tensorflow。我使用的版本是r0.12。你可能需要使用Tensorflow的这个分支。
在这篇教程中,我也使用了scikit-imag库、numpy以及其他的一些依赖。你可以通过下载Anaconda的Python软件包来安装这些软件。
此外,你还需要按照之前几篇文章介绍的步骤来配置你的训练环境——包括如何下载VGG-16模型以及其他所有的必需操作。
上采样辅助函数与图像加载
在这一部分中,我们定义前一篇文章使用的辅助函数。如果你还记得的话,我们使用了上采样技术对我们从网络中获得的下采样预测结果进行采样。我们从VGG-16模型使用的最大值池化层中获得模型的下采样预测结果。
我们也为图像与各个实际分割区域的加载操作编写了程序。这些代码加入了足够的注释,所以不必担心无法理解它。
import numpy as np
def get_kernel_size(factor):
"""
给定所需的上采样因子,确定卷积核的大小
"""
return 2 * factor - factor % 2
def upsample_filt(size):
"""
创建一个给定(h, w) 大小的适用于上采样过程的二维双线性卷积核
"""
factor = (size + 1) // 2
if size % 2 == 1:
center = factor - 1
else:
center = factor - 0.5
og = np.ogrid[:size, :size]
return (1 - abs(og[0] - center) / factor) * \
(1 - abs(og[1] - center) / factor)
def bilinear_upsample_weights(factor, number_of_classes):
"""
使用双线性卷积核,为转置卷积创建权重矩阵
初始化
"""
filter_size = get_kernel_siz