用于语义分割的动态数据扩充,我的 python 层定义是否正确?

Data augmentation on-the-fly for semantic segmentation, Is my python layer definition correct?

我不是 caffePython 方面的专家,但我正在尝试逐步学习。我有点困惑,所以如果专家能看看我的问题,我将不胜感激。

我正在研究图像分割。我正在尝试通过添加 python 层来进行 on-the-fly 数据扩充。对于我的数据集,我想在 x 轴和 y 轴上进行 (+10,-10) 的平移(另外还有 4 个平移),添加高斯噪声和水平翻转。

我的问题是:

  1. caffe如何同步图片和label?例如,如果我通过 data 层将图像发送到网络,并且在侧面,label 被发送到 SoftmaxWithLoss(例如)。 我已经(手动)画了一个数据增广和正常流动的示意图,不知道我的理解对了多少!

    从图中可以看出,对于翻译,我们必须以同步的方式翻译图像和ground truth(或者对于翻转,我们也必须翻转标签);例如,如果我分别在 x 轴和 y 轴上将图像移动 -10 和 -10 像素,则地面实况图像也需要相应地重新定位。如何在 caffe Python 层中完成此操作。我的理解是否正确(根据图)?我写了python层如下:

import caffe
import numpy as np
from skimage import transform as tf
from skimage.transform import AffineTransform

class ShiftLayer(caffe.Layer):

    def setup(self,bottom,top):
        assert len(bottom)==2,  #requires two inputs bottom(1:image, 2:label)
        assert len(top)==2      #requires two layer top

    def reshape(self,bottom,top):
        top[0].reshape(*bottom[0].data.shape)   #HOW CAN WE KNOW LABEL or DATA is GOING TO "bottom[0]" or "bottom[1]"?????
        top[1].reshape(*bottom[1].data.shape)

    def forward(self,bottom,top):
        x_trans=-10 
        y_trans=-10
        top[0].data[...]=tf.warp(bottom[0].data, AffineTransform(translation=(x_trans,y_trans)))
        top[1].data[...]=tf.warp(bottom[1].data, AffineTransform(translation=(x_trans,y_trans)))


    def backward(self,top,propagate_down,bottom):
        pass

这是图层定义:

layer {
  name: "shift_layer"
  type: "Python"
  bottom: "data"
  bottom: "label"
  top: "data"
  top: "label"
  include {
  phase: TRAIN
  }
  python_param {
    module: "myshift_layer"
    layer: "ShiftLayer"
  }
}
  1. 如果我要向网络添加其他增强技术,我应该为每个技术编写单独的模块吗?或者我可以写一个 python 层,包括许多 bottoms 和相应的 tops 吗?如果是,我怎么知道哪个顶部与哪个底部相关?

  2. 在加高斯噪声的情况下,我们确实有与输入图像相同的标签,这个的层定义如何?

总的来说你的理解应该是正确的。但是:

  1. Caffe blob(顶部、底部)将图像存储为(通道 * 行 * 列)形式,不同于通常的形式(行 * 列 * 通道)。它在 1 通道图像(如标签)的情况下没有区别,但在彩色图像的情况下却有区别。我怀疑 tf.warp 在这种情况下是否能正常工作。

  2. 我认为没有理由为各种增强(移动、翻转等)制作单独的图层。在一个 python 层中完成所有这些没有问题。但我不明白你想在这种情况下有很多底部和顶部。此外,您显示的 python 层实际上没有进行任何增强,因为它只是生成一组相似的移位图像来代替原始图像。它不会改善培训过程。常用的即时增强方法是一种转换,它不会影响网络形状,但会随机(!)转换数据代替原始数据。因此,网络在不同的训练时期处理相同的输入图像,它实际上处理不同的图像,这些图像是通过随机变换从该输入图像生成的。因此,您必须随机选择 x_trans、y_trans 来完成您的示例。通常情况下,您还可以添加随机翻转和随机高斯噪声等。可以同时应用这些变换,也可以随机选择其中之一。无论如何,图层必须只有一对数据+标签作为底部和顶部。