Как поступить, если изображение поезда слишком велико для однократной подачи в сеть? - PullRequest
2 голосов
/ 19 июня 2019

Я использую voxelmorph для регистрации изображений легких.Но мои изображения поездов слишком велики для подачи в сеть, изображения имеют различную форму, а формы не являются регулярными.Некоторые из них 513,436 ... (не степень 2, поэтому я не могу напрямую использовать U-NET или другой CNN).

Чтобы решить эти проблемы, я разделил изображения поездов на 128x128x128 подизображений с шагом= 100.это выглядит так:

разделить изображение на подизображения

В фазе прогнозирования я также разделил изображение на несколько подизображений и использовал сеть для прогнозированиякаждый субизображение, а затем объединил результаты.Но проблема в том, что границы подизображений выглядят по-разному с внутренней областью, например:

проблема границ

Мой наивный подход сглаживается, но янашел, что это не работает.Я думаю, что это общая проблема.Как это исправить?Пожалуйста, помогите.

Эта проблема с данными немного отличается. Потому что форма простого изображения поезда больше, чем 300x300x300.Поэтому не весь набор данных слишком велик, простые данные слишком велики.

Есть несколько примеров:

(430, 318, 168)  
(434, 354, 349)  
(428, 290, 439)  
(446, 290, 466)  
(452, 382, 373)  
(464, 290, 378)  
(424, 278, 217)  
(308, 202, 109)  
(420, 312, 537)  
(444, 314, 399)  
(418, 368, 323)  
(384, 432, 396)  
(412, 282, 408)  
(314, 188, 239)  
(428, 308, 422)  
(412, 302, 471)  
(276, 158, 127)  
(384, 432, 396)  
(394, 322, 370)  
(412, 322, 289)  
(412, 296, 458)  
(323, 250, 127)  
(448, 296, 431)  
(420, 302, 446)  
(438, 314, 393)  
(386, 424, 386) 

Сеть костей, подобная этой:

def conv_block(x_in, nf, strides=1):
    """
    specific convolution module including convolution followed by leakyrelu
    """
    ndims = len(x_in.get_shape()) - 2
    assert ndims in [1, 2, 3], "ndims should be one of 1, 2, or 3. found: %d" % ndims

    Conv = getattr(KL, 'Conv%dD' % ndims)
    x_out = Conv(nf, kernel_size=3, padding='same',
                 kernel_initializer='he_normal', strides=strides)(x_in)
    x_out = LeakyReLU(0.2)(x_out)
    return x_out

def unet_core(vol_size, enc_nf, dec_nf, full_size=True, src=None, tgt=None, src_feats=1, tgt_feats=1):
    """
    unet architecture for voxelmorph models presented in the CVPR 2018 paper. 
    You may need to modify this code (e.g., number of layers) to suit your project needs.
    :param vol_size: volume size. e.g. (256, 256, 256)
    :param enc_nf: list of encoder filters. right now it needs to be 1x4.
           e.g. [16,32,32,32]
    :param dec_nf: list of decoder filters. right now it must be 1x6 (like voxelmorph-1) or 1x7 (voxelmorph-2)
    :return: the keras model
    """
    ndims = len(vol_size)
    assert ndims in [1, 2, 3], "ndims should be one of 1, 2, or 3. found: %d" % ndims
    upsample_layer = getattr(KL, 'UpSampling%dD' % ndims)

    # inputs
    if src is None:
        src = Input(shape=[*vol_size, src_feats])
    if tgt is None:
        tgt = Input(shape=[*vol_size, tgt_feats])
    x_in = concatenate([src, tgt])


    # down-sample path (encoder)
    x_enc = [x_in]
    for i in range(len(enc_nf)):
        x_enc.append(conv_block(x_enc[-1], enc_nf[i], 2))

    # up-sample path (decoder)
    x = conv_block(x_enc[-1], dec_nf[0])
    x = upsample_layer()(x)
    x = concatenate([x, x_enc[-2]])
    x = conv_block(x, dec_nf[1])
    x = upsample_layer()(x)
    x = concatenate([x, x_enc[-3]])
    x = conv_block(x, dec_nf[2])
    x = upsample_layer()(x)
    x = concatenate([x, x_enc[-4]])
    x = conv_block(x, dec_nf[3])
    x = conv_block(x, dec_nf[4])

    # only upsampleto full dim if full_size
    # here we explore architectures where we essentially work with flow fields 
    # that are 1/2 size 
    if full_size:
        x = upsample_layer()(x)
        x = concatenate([x, x_enc[0]])
        x = conv_block(x, dec_nf[5])

    # optional convolution at output resolution (used in voxelmorph-2)
    if len(dec_nf) == 7:
        x = conv_block(x, dec_nf[6])

    return Model(inputs=[src, tgt], outputs=[x])

Есть статья, ссылающаяся на большое изображение в CNN, Новый подход к вычислению CNN для чрезвычайно больших изображений . A same boundary problem Это исправляет проблему границы, используя аддитивные отступы, ноописание не понятно.Я думаю, что это похоже на стратегию перекрытия.

Ответы [ 3 ]

0 голосов
/ 19 июня 2019

Решение

Здравствуйте, @ruokuanwu. Это очень распространенная проблема: у нас много данных для обучения глубокому обучению, и мы не можем сохранить все это в нашей памяти сразу. Данные могут быть в TeraBytes, так что для решения этой проблемы Keras имеет функцию flow_from_directory, с помощью которой Keras сможет получать партии непосредственно с диска. Теперь нам не нужно загружать все данные сразу. Эта функция берет пакет с диска, загружает его в память и передает его в модель для обработки. Таким образом решается проблема обучения на большом наборе данных.

Здесь вы можете увидеть пример прохождения через Image Generator.

Пример Notebook Kaggle Link

Требования:

если вы работаете над классификацией изображений, вы должны поместить каждый свой класс в отдельную папку и указать путь к родительской папке, в которой находится ваша отдельная папка классов.

0 голосов
/ 23 июня 2019

С моделью U-net было бы хорошо разделить входные данные на части и обработать их отдельно.

Следует обратить внимание на границу изображения: разделение 256x256 на 4 изображения 128x128 может привести к заметной границе (крестик в центре изображения) при сегментации. Чтобы избежать этого, имеет смысл разделить изображение с небольшим перекрытием и игнорировать границу.

Другими словами. Для изображения размером 256x256 при максимально возможном входе в память 128 следует следующий алгоритм:

  1. Выберите размер границы. Для unet с 4 слоями понижающей дискретизации было бы разумно выбрать границу, пропорциональную 2 ^ number_of_downsamplings = 2 ^ 4 = 16.
  2. Разбить входное изображение на квадраты 96x96, где 96 = 128-2 * border_size
  3. для каждого квадрата прикрепите еще 16 пикселей с каждой стороны к исходному изображению. В результате изображение 128x128
  4. После обработки изображения вырежьте внутренний квадрат 96х96 и используйте его, чтобы сшить окончательный прогноз.
0 голосов
/ 19 июня 2019

Если вашу проблему можно решить, сделав размер фигуры кратным 2, я бы предложил использовать openCV.

Вы можете просто расширить изображение, добавив белую / черную рамку.Вы также можете масштабировать изображение, в зависимости от того, что работает лучше в вашем случае.

Другой вариант - запустить ImageMagic, чтобы увеличить размер изображения меньшего размера.Пример:

magick convert -resize 400% smallImage.png Enlarged.png

Это увеличит размер меньшего изображения в 4 раза.

...