Создание Unet с помощью предварительно обученного кодировщика Resnet34 с Keras - PullRequest
0 голосов
/ 05 мая 2020

Я новичок в сегментации изображений. Я пытался создать модель Unet с предварительно обученным Resnet34 (imag enet) в качестве кодировщика. Что касается сравнения, я использовал API моделей сегментации, чтобы получить ту же модель. Однако моя модель не так хороша, как импортированная, хотя их структура и основа одинаковы.

Моя модель:

Я использовал следующий код для import Pretrained Resnet34:

ResNet34, preprocess_input = Classifiers.get('resnet34')
Resmodel = ResNet34((256, 256, 3), weights='imagenet') 

Затем сделал блок свертки:

def ConvBlock(X,channel,kernel_size,bn=True):
  x=layers.Conv2D(filters=channel,kernel_size=(kernel_size,kernel_size),strides=(1,1),dilation_rate=(1,1),padding='SAME',kernel_initializer='he_normal')(X)
  if bn:
    x=layers.BatchNormalization()(x)
  x=layers.Activation('relu')(x)

  x=layers.Conv2D(filters=channel,kernel_size=(kernel_size,kernel_size),strides=(1,1),dilation_rate=(1,1),padding='SAME',kernel_initializer='he_normal')(x)
  if bn:
    x=layers.BatchNormalization()(x)
  x=layers.Activation('relu')(x)
  return x

И, наконец, построил эту модель:

def new_model(output_channel,output_activation):
  inp=Resmodel.input

  skip1=Resmodel.layers[5].output #128x128x64
  skip2=Resmodel.layers[37].output #64x64x64
  skip3=Resmodel.layers[74].output #32x32x128
  skip4=Resmodel.layers[129].output #16x16x256
  encoder_final=Resmodel.layers[157].output #8x8x512

  #upsample 
  filters=256
  k=1

  x=layers.UpSampling2D()(encoder_final) #returns 16x16x256
  x=layers.Concatenate()([x,skip4]) #returns 16x16x512
  x=ConvBlock(x,filters,kernel_size=3) #returns 16x16x256
  filters //=2

  x=layers.UpSampling2D()(x) #returns 32x32x128
  x=layers.Concatenate()([x,skip3]) #returns 32x32x256
  x=ConvBlock(x,filters,kernel_size=3) #returns 32x32x128
  filters //=2

  x=layers.UpSampling2D()(x) #returns 64x64x64
  x=layers.Concatenate()([x,skip2]) #returns 64x64x128
  x=ConvBlock(x,filters,kernel_size=3) #returns 64x64x64
  filters //=2 

  x=layers.UpSampling2D()(x) #returns 128x128x64
  x=layers.Concatenate()([x,skip1]) #returns 128x128x128
  x=ConvBlock(x,filters,kernel_size=3) #returns 128x128x32
  filters //=2

  x=layers.UpSampling2D()(x) #returns 256x256x32
  x=ConvBlock(x,filters,kernel_size=3) #returns 256x256x16
  x = layers.Conv2D(output_channel, kernel_size= (1,1), strides=(1,1), padding= 'same')(x)  #returns 256x256x1
  x=layers.Activation('sigmoid')(x)
  model=Model(inputs=inp,outputs=x)
  return model

Как способ измерить, насколько я все сделали правильно, я использовал библиотеку Pypi для моделей сегментации, чтобы импортировать Unet с магистралью Resnet34.

Импортированная модель:

from segmentation_models import Unet
from segmentation_models.utils import set_trainable

model = Unet(backbone_name='resnet34', encoder_weights='imagenet', encoder_freeze=True)
model.summary()

Но проблема в том, что импортированная модель из segmentation_models API, похоже, работает намного лучше (более высокая оценка Iou), чем модель, которую я создал . хотя структура и основа почти такие же. Так что я делаю не так в своей модели? Спасибо, что прочитали такой длинный пост.

Ответы [ 3 ]

0 голосов
/ 05 мая 2020

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

Также следует отметить, что цитирую из приведенного выше ответа Timbus Calin , поскольку decoder_block_type='upsampling' по умолчанию. Так что это не проблема. Тем не менее, пожалуйста, проверьте обе сводки моделей, чтобы убедиться, что нет различий, особенно количество фильтров и обучаемых слоев.

0 голосов
/ 07 мая 2020

Проблема была в коде, который я использовал для замораживания слоев ResNet34. Я также по ошибке замораживал слои BatchNorm, что приводило к снижению производительности. После выборочного замораживания всех слоев Resnet34, кроме слоев BatchNorm, модель работала на должном уровне.

0 голосов
/ 05 мая 2020

Проверяли ли вы реализацию UNet в этой конкретной c библиотеке?

Насколько я помню, слои UpSampling() были заменены на Conv2DTranspose(), следовательно, возможная причина

В дополнение к этому убедитесь, что у вас точно такие же обучаемые слои, как в segmentation_models

...