Keras - fungsi kerugian khusus - jarak talang

Saya mencoba segmentasi objek menggunakan fungsi kerugian khusus seperti yang didefinisikan di bawah ini:

def chamfer_loss_value(y_true, y_pred):           

    # flatten the batch 
    y_true_f = K.batch_flatten(y_true)
    y_pred_f = K.batch_flatten(y_pred)

    # ==========
    # get chamfer distance sum

    // error here
    y_pred_mask_f = K.cast(K.greater_equal(y_pred_f,0.5), dtype='float32')

    finalChamferDistanceSum = K.sum(y_pred_mask_f * y_true_f, axis=1, keepdims=True)  

    return K.mean(finalChamferDistanceSum)

def chamfer_loss(y_true, y_pred):   
    return chamfer_loss_value(y_true, y_pred)

y_pred_f adalah hasil U-net saya. y_true_f merupakan hasil transformasi jarak euclidean pada ground truth label mask x seperti gambar dibawah ini:

distTrans = ndimage.distance_transform_edt(1 - x)

Untuk menghitung jarak Chamfer, Anda mengalikan gambar yang diprediksi (idealnya, masker dengan 1 dan 0) dengan transformasi jarak kebenaran dasar, dan cukup menjumlahkan semua piksel. Untuk melakukan ini, saya perlu mendapatkan topeng y_pred_mask_f dengan melakukan ambang batas y_pred_f, lalu mengalikannya dengan y_true_f, dan menjumlahkan semua piksel.

y_pred_f memberikan rentang nilai berkelanjutan di [0,1], dan saya mendapatkan kesalahan None type not supported pada evaluasi y_true_mask_f. Saya tahu fungsi kerugian harus dapat dibedakan, dan greater_equal dan cast tidak. Tapi, apakah ada cara untuk menghindari hal ini di Keras? Mungkin menggunakan beberapa solusi di Tensorflow?


person Eagle    schedule 04.02.2018    source sumber
comment
Ini tidak dapat dibedakan tetapi Anda memerlukan gradien untuk mengoptimalkan jika Anda menggunakan penurunan gradien. Apakah Anda memiliki gradien yang ditentukan secara manual? Jika demikian, Anda dapat menghitung gradien secara manual dan memasukkannya. Lihat di sini judul stackoverflow.com/questions/43839431/   -  person THN    schedule 05.02.2018


Jawaban (1)


Ya, ini rumit. Alasan di balik kesalahan Anda adalah tidak ada ketergantungan yang berkelanjutan antara kehilangan dan jaringan Anda. Untuk menghitung gradien kerugian Anda, w.r.t. ke jaringan, kerugian Anda harus menghitung gradien indikator jika keluaran Anda lebih besar dari 0.5 (karena ini adalah satu-satunya hubungan antara nilai kerugian akhir dan keluaran y_pred dari jaringan Anda). Hal ini tidak mungkin karena indikator ini sebagian konstan dan tidak kontinu.

Solusi yang mungkin - memperlancar indikator Anda:

def chamfer_loss_value(y_true, y_pred):           

    # flatten the batch 
    y_true_f = K.batch_flatten(y_true)
    y_pred_f = K.batch_flatten(y_pred)

    y_pred_mask_f = K.sigmoid(y_pred_f - 0.5)

    finalChamferDistanceSum = K.sum(y_pred_mask_f * y_true_f, axis=1, keepdims=True)  

    return K.mean(finalChamferDistanceSum)

Karena sigmoid adalah versi berkelanjutan dari fungsi langkah. Jika keluaran Anda berasal dari sigmoid - Anda cukup menggunakan y_pred_f daripada y_pred_mask_f.

person Marcin Możejko    schedule 04.02.2018