Увеличение данных на лету для семантической сегментации. Является ли мое определение уровня Python правильным?

Я не эксперт в caffe а также Python, но я стараюсь учиться шаг за шагом. Я немного сбит с толку, поэтому я был бы очень признателен, если бы эксперты посмотрели мои вопросы.

Я работаю над сегментацией изображения. Я пытаюсь сделать on-the-fly увеличение данных путем добавления слоев Python. Для моего набора данных я хотел бы сделать перевод (+10,-10) как по оси x, так и по оси y (4 перевода дополнительно), добавив гауссов шум и горизонтальное отражение.

Мои вопросы:

  1. Как caffe синхронизирует изображение с меткой? Например, если я отправляю изображение по data слой к сети и на стороне, label отправлено SoftmaxWithLoss (например). Я нарисовал (вручную) схематическое представление об увеличении и нормальном потоке данных, и я не уверен, насколько мое понимание верно!

    Как видно из рисунка, для перевода нам нужно переводить изображение и основную истину синхронно (или для переворачивания мы также должны перевернуть метку); например, если я смещаю изображение на -10 и -10 пикселей по оси x и по оси y соответственно, то истинное изображение земли также необходимо соответственно переместить. Как это можно сделать в слое 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 ответ

Решение

В целом ваше понимание выглядит правильным. Но:

  1. Капли Caffe (вверху, внизу) хранят изображения в виде (каналы * строки * столбцы) в отличие от обычной формы (строки * столбцы * каналы). Это не имеет значения в случае 1-канального изображения (например, меток), но в случае цветных изображений это имеет значение. У меня есть сомнения, если tf.warp работает правильно в этом случае.

  2. Я не вижу смысла делать отдельные слои для всех видов увеличения (сдвиг, переворот и т. Д.). Нет проблем сделать все их в одном слое python. Но я не понимаю твоей идеи иметь много дна и вершины в этом случае. Более того, слой Python, который вы показали, не создает никаких дополнений, потому что он просто создает набор одинаково смещенных изображений вместо оригинальных. Это не улучшит процесс обучения. Обычно используемый подход к оперативному расширению - это преобразование, которое не влияет на форму сети, но помещает случайно (!) Преобразованные данные вместо исходных. Таким образом, сеть обрабатывает одно и то же входное изображение в разные эпохи обучения, фактически обрабатывает разные изображения, полученные из этого входного изображения путем случайного преобразования. Таким образом, вы должны завершить свой пример со случайным выбором x_trans,y_trans. В общем случае вы также можете добавить случайный переворот и случайный гауссовский шум и т. Д. Эти преобразования можно применять одновременно или вы можете выбрать один из них случайным образом. В любом случае, слой должен иметь только 1 пару данных + метку как днища и как вершины.

Другие вопросы по тегам