我不是caffe
和Python
的专家,但我正在努力逐步学习。我有点困惑,所以如果专家看看我的问题,我真的很感激。
我正致力于图像分割。我试图通过添加python层来进行on-the-fly
数据扩充。对于我的数据集,我想在x轴和y轴(另外4个平移)中进行(+ 10,-10)的平移,添加高斯噪声和水平翻转。
我的问题是:
caffe如何将图像与标签同步?例如,如果我通过data
图层向网络发送图像,并将侧边label
发送给SoftmaxWithLoss
(例如)。
我已经(手动)绘制了增强和正常数据流的示意图,我不确定我的理解是多么正确!
从图中可以看出,对于翻译,我们必须以同步方式翻译图像和地面实况(或者为了翻转,我们也必须翻转标签);例如,如果我将图像分别在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
?如果是,我怎么知道哪个顶部与哪个底部相关?
在高斯噪声添加的情况下,我们与输入图像具有相同的标签,这个的层定义如何?
答案 0 :(得分:1)
一般来说,您的理解看起来是正确的。但是:
Caffe blobs(顶部,底部)将图像存储为(通道*行*列)形式,与通常的形式(行*列*通道)不同。在1通道图像(如标签)的情况下它没有区别,但在彩色图像的情况下它确实如此。我怀疑在这种情况下tf.warp是否正常工作。
我认为没有理由为各种增强(移位,翻转等)制作单独的图层。在一个python层中完成所有这些操作没有问题。但在这种情况下,我不明白你有很多底部和顶部的想法。此外,你已经显示的python层没有增加,因为它只是产生一组相似的移位图像来代替原始图像。它不会改善培训过程。通常使用的即时增强方法是一种变换,它不会影响净形状,但会随机(!)转换数据代替原始数据。因此,网络在不同的训练时期处理相同的输入图像,它实际上处理通过随机变换从该输入图像产生的不同图像。所以你必须随机选择x_trans,y_trans来完成你的例子。在通常情况下,您还可以添加随机翻转和随机高斯噪声等。这种转换可以同时应用,也可以随机选择其中一种。无论如何,该层必须只有一对数据+标签作为底部和顶部。