Как получить хороший результат от сегментации двоичного спутникового изображения с помощью U-Net? - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть четыре орто-спутниковых изображения (размер пикселя 50 см) и их маски. Я хочу предсказать размер здания, используя U-Net, я хочу сделать сегментацию изображения. Я разделил четыре орто-спутниковых изображения и их маски на патч 128 * 128 и сохранил их в виде двух массивов data_all и label_all. Также я нормализовал numpy в [-1,1]. Я обучил модель U-Net, но не смог добиться хороших результатов во время тестирования, даже когда тестировал модель на обучающих образцах.

Как получить хорошие результаты?

Есть мой код

def weighted_binary_crossentropy(y_true, y_pred):
class_loglosses = K.mean(K.binary_crossentropy(y_true, y_pred), axis=[0, 1, 2])
return K.sum(class_loglosses * K.constant([0.2]))

def unet_model_v4(n_classes, im_sz, n_channels, n_filters_start, growth_factor, upconv=True):
droprate = 0.25
n_filters = n_filters_start
inputs = Input((im_sz, im_sz, n_channels))
# inputs = BatchNormalization()(inputs)
conv1 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(inputs)
conv1 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
pool1 = Dropout(droprate)(pool1)

n_filters *= growth_factor
pool1 = BatchNormalization()(pool1)
conv2 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(pool1)
conv2 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv2)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
pool2 = Dropout(droprate)(pool2)

n_filters *= growth_factor
pool2 = BatchNormalization()(pool2)
conv3 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(pool2)
conv3 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv3)
pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)
pool3 = Dropout(droprate)(pool3)

n_filters *= growth_factor
pool3 = BatchNormalization()(pool3)
conv4_0 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(pool3)
conv4_0 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv4_0)
pool4_0 = MaxPooling2D(pool_size=(2, 2))(conv4_0)
pool4_0 = Dropout(droprate)(pool4_0)

n_filters *= growth_factor
pool4_0 = BatchNormalization()(pool4_0)
conv4_1 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(pool4_0)
conv4_1 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv4_1)
pool4_1 = MaxPooling2D(pool_size=(2, 2))(conv4_1)
pool4_1 = Dropout(droprate)(pool4_1)

n_filters *= growth_factor
pool4_1 = BatchNormalization()(pool4_1)
conv4_2 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(pool4_1)
conv4_2 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv4_2)
pool4_2 = MaxPooling2D(pool_size=(2, 2))(conv4_2)
pool4_2 = Dropout(droprate)(pool4_2)

n_filters *= growth_factor
pool4_2 = BatchNormalization()(pool4_2)
conv5 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(pool4_2)
conv5 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv5)
conv5 = Dropout(droprate)(conv5)

n_filters //= growth_factor
if upconv:
    up6 = concatenate([Conv2DTranspose(n_filters, (2, 2), strides=(2, 2), padding='same')(conv5), conv4_2])
else:
    up6 = concatenate([UpSampling2D(size=(2, 2))(conv5), conv4_2])
up6 = BatchNormalization()(up6)
conv6 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(up6)
conv6 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv6)
conv6 = Dropout(droprate)(conv6)

n_filters //= growth_factor
if upconv:
    up6_1 = concatenate([Conv2DTranspose(n_filters, (2, 2), strides=(2, 2), padding='same')(conv6), conv4_1])
else:
    up6_1 = concatenate([UpSampling2D(size=(2, 2))(conv6), conv4_1])
up6_1 = BatchNormalization()(up6_1)
conv6_1 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(up6_1)
conv6_1 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv6_1)
conv6_1 = Dropout(droprate)(conv6_1)

n_filters //= growth_factor
if upconv:
    up6_2 = concatenate([Conv2DTranspose(n_filters, (2, 2), strides=(2, 2), padding='same')(conv6_1), conv4_0])
else:
    up6_2 = concatenate([UpSampling2D(size=(2, 2))(conv6_1), conv4_0])
up6_2 = BatchNormalization()(up6_2)
conv6_2 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(up6_2)
conv6_2 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv6_2)
conv6_2 = Dropout(droprate)(conv6_2)

n_filters //= growth_factor
if upconv:
    up7 = concatenate([Conv2DTranspose(n_filters, (2, 2), strides=(2, 2), padding='same')(conv6_2), conv3])
else:
    up7 = concatenate([UpSampling2D(size=(2, 2))(conv6_2), conv3])
up7 = BatchNormalization()(up7)
conv7 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(up7)
conv7 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv7)
conv7 = Dropout(droprate)(conv7)

n_filters //= growth_factor
if upconv:
    up8 = concatenate([Conv2DTranspose(n_filters, (2, 2), strides=(2, 2), padding='same')(conv7), conv2])
else:
    up8 = concatenate([UpSampling2D(size=(2, 2))(conv7), conv2])
up8 = BatchNormalization()(up8)
conv8 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(up8)
conv8 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv8)
conv8 = Dropout(droprate)(conv8)

n_filters //= growth_factor
if upconv:
    up9 = concatenate([Conv2DTranspose(n_filters, (2, 2), strides=(2, 2), padding='same')(conv8), conv1])
else:
    up9 = concatenate([UpSampling2D(size=(2, 2))(conv8), conv1])
up9 = BatchNormalization()(up9)
conv9 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(up9)
conv9 = Conv2D(n_filters, (3, 3), activation='relu', padding='same')(conv9)

conv10 = Conv2D(n_classes, (1, 1), activation='sigmoid')(conv9)

model = Model(inputs=inputs, outputs=conv10)

return model

epoch_no = 500
patiance_no = 25
learning_rate = 1e-3
patiance_reduce = 10
shrink_rate = 5
min_learningRate = 1e-5
# --- training and predict parameters ---
N_CLASSES = 1
# 1 for binary classification. This has not been designed for multi-label 
#classification
# The prediction result is a single matrix where high probablity (>0.5) 
#represents the object of interest
Growth_factor = 2
UPCONV = True
N_CLASSES=1
bSize = 128
maxbands = 3
N_filters_start = 32

model = unet_model_v4(N_CLASSES, bSize, maxbands, N_filters_start, 
Growth_factor, UPCONV)
parallel_model = model
adam = optimizers.Adam(lr=learning_rate)
parallel_model.compile(loss=weighted_binary_crossentropy, 
optimizer=adam,metrics=['accuracy'])

earlystop = EarlyStopping(monitor='val_loss', min_delta=0, 
patience=patiance_no,verbose=1, mode='auto')
model_checkpoint = ModelCheckpoint(model_path, monitor='val_loss', 
save_best_only=True)
tensorboard = TensorBoard(log_dir=log_folder, write_graph=True, 
write_images=True)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, 
patience=patiance_reduce, min_lr=min_learningRate)
callbacks_list = [earlystop, model_checkpoint, tensorboard, reduce_lr]

class_w = [1.5,3.0]
model_info = parallel_model.fit(data_all, label_all, 
validation_split=0.25,
batch_size=batch_size, callbacks=callbacks_list, 
epochs=epoch_no,shuffle=True,class_weight=class_w)

U-Net результат

Маска

...