1
$\begingroup$

I used a CNN network unet for a segmentation task.

This is the architecture I used:

  
inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))
s = Lambda(lambda x: x / 255) (inputs)


c1 = Conv2D(16, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (s)
c1 = Dropout(0.1) (c1)
c1 = Conv2D(16, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c1)
p1 = MaxPooling2D((2, 2)) (c1)

c2 = Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (p1)
c2 = Dropout(0.1) (c2)
c2 = Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c2)
p2 = MaxPooling2D((2, 2)) (c2)

c3 = Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (p2)
c3 = Dropout(0.2) (c3)
c3 = Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c3)
p3 = MaxPooling2D((2, 2)) (c3)

c4 = Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (p3)
c4 = Dropout(0.2) (c4)
c4 = Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c4)
p4 = MaxPooling2D(pool_size=(2, 2)) (c4)

c5 = Conv2D(256, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (p4)
c5 = Dropout(0.3) (c5)
c5 = Conv2D(256, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c5)

u6 = Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same') (c5)
u6 = concatenate([u6, c4])
c6 = Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (u6)
c6 = Dropout(0.2) (c6)
c6 = Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c6)

u7 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (c6)
u7 = concatenate([u7, c3])
c7 = Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (u7)
c7 = Dropout(0.2) (c7)
c7 = Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c7)

u8 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (c7)
u8 = concatenate([u8, c2])
c8 = Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (u8)
c8 = Dropout(0.1) (c8)
c8 = Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c8)

u9 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (c8)
u9 = concatenate([u9, c1], axis=3)
c9 = Conv2D(16, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (u9)
c9 = Dropout(0.1) (c9)
c9 = Conv2D(16, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same') (c9)

outputs = Conv2D(1, (1, 1), activation='sigmoid') (c9)

model = Model(inputs=[inputs], outputs=[outputs])
model.compile(optimizer='SGD', loss='binary_crossentropy', metrics=['accuracy' ])
model.summary()


earlystopper = EarlyStopping(patience=5, verbose=1)
checkpointer = ModelCheckpoint('./accuracy.h5', verbose=1, save_best_only=True)

results = model.fit(x_train, y_train, shuffle=True, validation_split=0.1 , batch_size=16, epochs=50,callbacks=[earlystopper, checkpointer])

I used SGD optimizer and accuracy as the metric.

These are the learning graphs for loss and accuracy:

enter image description here

enter image description here

And this is the code for the prediction:

model = load_model('......../accuracy.h5') 
PRED_PATH = '....../predict/' folder to save the predicted images
TEST_path = '...../testing/' folder for the test images 
test_ids=os.listdir(TEST_PATH)
########## read the test images #############

preds_test = model.predict(X, verbose=1)
preds_test_thresholded=255*(preds_test > 0.5).astype(np.uint8)
ctr=0
for i in range(len(test_ids)):
   file_name=test_ids[i]+'_pred.png'
   img=preds_test_thresholded[ctr]
   imsave(PRED_PATH+file_name,img)
   ctr= ctr+1

During the training, accuracy = 0.977.

After prediction and to evaluate my model performance, I calculated the Dice_coefficient for all the images. I got 0. It seems like everything is working! Could anyone explain to me why got but results?

$\endgroup$
6
  • $\begingroup$ Seems like your data may be imbalanced. Check to see if your predicted classes for each pixel are all the same (if they are then this indicates your model isn't learning anything due to class imbalance). You might want to (i) get more data so that the model can learn the minority class (ii) modify/change your loss function to incorporate class weights. $\endgroup$ – antsatsui Nov 15 '20 at 19:44
  • $\begingroup$ yes it's the same ! if I modify my loss function what should it be ? @antsatsui $\endgroup$ – abby Nov 15 '20 at 19:50
  • $\begingroup$ Your loss is currently $-\frac{1}{n} \sum_{i=1}^n [y_i\log(p(y_i)) + (1-y_i)\log(1-p(y_i))]$. If you find class 0 to be the majority class, you might wish to weight misclassification of class 1 higher like so $-\frac{1}{n} \sum_{i=1}^n [\theta y_i\log(p(y_i)) + (1-y_i)\log(1-p(y_i))]$ where $\theta > 1$. These seem to be good resources ( 1, 2 ). $\endgroup$ – antsatsui Nov 15 '20 at 20:20
  • $\begingroup$ thank you for the help @antsatsui $\endgroup$ – abby Nov 15 '20 at 20:27
  • $\begingroup$ Can you add prediction code snippet might be issue in that part $\endgroup$ – Swapnil Pote Nov 15 '20 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.