我正在尝试使用Caffe进行简单的语义图像分割任务(即将图像中的每个像素分类为属于2个类别之一)。
我遇到两个问题:1)数据准备,以及2)网络层定义。
我试过阅读一些例子。
尽管链接很有用,但它们并不特别适用于2D图像的语义分割。
我会非常感谢(甚至是简短的)以下代码示例在平滑的管道中:
谢谢!
答案 0 :(得分:4)
虽然Caffe主线程上还没有 的任何教程,但是有很多关于在Caffe中进行语义分段的教程。对于初学者,您应该查看Fully Convolutional Networks master以及tutorial on using SegNet(GitHub单独here)或使用DeepLab的教程。这些都是使用Caffe进行语义分割的最先进方法。
更直接地回答您的问题,
1)数据准备:
作为对最近的深度学习方法表现出兴趣的人,您可能会发现没有一种方法可以进行数据准备。它们取决于数学上可能的东西(最终需要完全连接的层的网络需要相同比例的图像,通常具有相同的大小),以及改善性能的因素(平均减法)。话虽如此,有一些常见的技术(为了简单起见,我将在这一点上假设您可以使用不同尺度的图像,如同完全卷积网络。如果您想看看裁剪是如何工作的,那么就有一个好处在Caffe的ImageNet教程中解释这种类型的数据准备。使用Transformer
课程,大多数人会执行以下操作:
transformer.set_transpose('data', (2,0,1)) # move image channels to outermost dimension
transformer.set_mean('data', mu) # subtract the dataset-mean value in each channel
transformer.set_raw_scale('data', 255) # rescale from [0, 1] to [0, 255]
transformer.set_channel_swap('data', (2,1,0)) # swap channels from RGB to BGR
在细分的背景下,这就是你需要做的。语义标签本身就是图像形式(通常)。例如,在Pascal VOC Caffe示例中,您将标签读入为
n.data, n.label = L.Python(module = 'pascal_multilabel_datalayers', layer = datalayer, ntop = 2, param_str=str(data_layer_params))
** 2)网络层定义**
对于网络层定义,请记住,关于神经网络的一个亮点是除了输入和输出之外,它们可以处理各种各样的数据类型。因此,您的所有中间层都是相同的,实际上在您的情况下,输入也是相同的。最后你需要用什么来评估相对于图像的交叉熵损失。对于DeepLab,他们写了"Interp" layer来做到这一点。另一方面,SegNet写了"Upsample" layer type,他们在softmax之前使用它来使网络输出与标签大小相同,然后simply use a Softmax
我认为所有这一切的缺点是,在Caffe中没有一种明确的方法可以正确地做到这一点,但好的是有很多成功完成的例子。希望这有帮助