用于语义分割的动态数据扩充,我的 python 层定义是否正确?
Data augmentation on-the-fly for semantic segmentation, Is my python layer definition correct?
我不是 caffe
和 Python
方面的专家,但我正在尝试逐步学习。我有点困惑,所以如果专家能看看我的问题,我将不胜感激。
我正在研究图像分割。我正在尝试通过添加 python 层来进行 on-the-fly
数据扩充。对于我的数据集,我想在 x 轴和 y 轴上进行 (+10,-10) 的平移(另外还有 4 个平移),添加高斯噪声和水平翻转。
我的问题是:
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"
}
}
如果我要向网络添加其他增强技术,我应该为每个技术编写单独的模块吗?或者我可以写一个 python 层,包括许多 bottoms
和相应的 tops
吗?如果是,我怎么知道哪个顶部与哪个底部相关?
在加高斯噪声的情况下,我们确实有与输入图像相同的标签,这个的层定义如何?
总的来说你的理解应该是正确的。但是:
Caffe blob(顶部、底部)将图像存储为(通道 * 行 * 列)形式,不同于通常的形式(行 * 列 * 通道)。它在 1 通道图像(如标签)的情况下没有区别,但在彩色图像的情况下却有区别。我怀疑 tf.warp 在这种情况下是否能正常工作。
我认为没有理由为各种增强(移动、翻转等)制作单独的图层。在一个 python 层中完成所有这些没有问题。但我不明白你想在这种情况下有很多底部和顶部。此外,您显示的 python 层实际上没有进行任何增强,因为它只是生成一组相似的移位图像来代替原始图像。它不会改善培训过程。常用的即时增强方法是一种转换,它不会影响网络形状,但会随机(!)转换数据代替原始数据。因此,网络在不同的训练时期处理相同的输入图像,它实际上处理不同的图像,这些图像是通过随机变换从该输入图像生成的。因此,您必须随机选择 x_trans、y_trans 来完成您的示例。通常情况下,您还可以添加随机翻转和随机高斯噪声等。可以同时应用这些变换,也可以随机选择其中之一。无论如何,图层必须只有一对数据+标签作为底部和顶部。
我不是 caffe
和 Python
方面的专家,但我正在尝试逐步学习。我有点困惑,所以如果专家能看看我的问题,我将不胜感激。
我正在研究图像分割。我正在尝试通过添加 python 层来进行 on-the-fly
数据扩充。对于我的数据集,我想在 x 轴和 y 轴上进行 (+10,-10) 的平移(另外还有 4 个平移),添加高斯噪声和水平翻转。
我的问题是:
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"
}
}
如果我要向网络添加其他增强技术,我应该为每个技术编写单独的模块吗?或者我可以写一个 python 层,包括许多
bottoms
和相应的tops
吗?如果是,我怎么知道哪个顶部与哪个底部相关?在加高斯噪声的情况下,我们确实有与输入图像相同的标签,这个的层定义如何?
总的来说你的理解应该是正确的。但是:
Caffe blob(顶部、底部)将图像存储为(通道 * 行 * 列)形式,不同于通常的形式(行 * 列 * 通道)。它在 1 通道图像(如标签)的情况下没有区别,但在彩色图像的情况下却有区别。我怀疑 tf.warp 在这种情况下是否能正常工作。
我认为没有理由为各种增强(移动、翻转等)制作单独的图层。在一个 python 层中完成所有这些没有问题。但我不明白你想在这种情况下有很多底部和顶部。此外,您显示的 python 层实际上没有进行任何增强,因为它只是生成一组相似的移位图像来代替原始图像。它不会改善培训过程。常用的即时增强方法是一种转换,它不会影响网络形状,但会随机(!)转换数据代替原始数据。因此,网络在不同的训练时期处理相同的输入图像,它实际上处理不同的图像,这些图像是通过随机变换从该输入图像生成的。因此,您必须随机选择 x_trans、y_trans 来完成您的示例。通常情况下,您还可以添加随机翻转和随机高斯噪声等。可以同时应用这些变换,也可以随机选择其中之一。无论如何,图层必须只有一对数据+标签作为底部和顶部。