Keras - ฟังก์ชันการสูญเสียแบบกำหนดเอง - ระยะลบมุม

ฉันกำลังพยายามแบ่งส่วนวัตถุโดยใช้ฟังก์ชันการสูญเสียแบบกำหนดเองตามที่กำหนดไว้ด้านล่าง:

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 คือผลลัพธ์ของ U-net ของฉัน y_true_f คือผลลัพธ์ของการแปลงระยะทางแบบยุคลิดบนมาสก์ป้ายกำกับความจริงภาคพื้นดิน x ดังแสดงด้านล่าง:

distTrans = ndimage.distance_transform_edt(1 - x)

ในการคำนวณระยะทาง Chamfer คุณจะต้องคูณภาพที่คาดการณ์ไว้ (ตามหลักแล้วคือมาสก์ที่มี 1 และ 0) ด้วยการแปลงระยะทางความจริงภาคพื้นดิน และเพียงรวมพิกเซลทั้งหมด ในการดำเนินการนี้ ฉันจำเป็นต้องได้มาสก์ y_pred_mask_f ด้วยขีดจำกัด y_pred_f จากนั้นคูณด้วย y_true_f และรวมพิกเซลทั้งหมด

y_pred_f ให้ช่วงค่าที่ต่อเนื่องกันใน [0,1] และฉันได้รับข้อผิดพลาด None type not supported ที่การประเมิน y_true_mask_f ฉันรู้ว่าฟังก์ชันการสูญเสียจะต้องสร้างความแตกต่างได้ และ greater_equal และ cast ไม่ใช่ แต่มีวิธีหลีกเลี่ยงสิ่งนี้ใน Keras หรือไม่? อาจใช้วิธีแก้ไขปัญหาบางอย่างใน Tensorflow ใช่ไหม


comment
ไม่สามารถหาความแตกต่างได้ แต่คุณต้องมีการไล่ระดับสีเพื่อปรับให้เหมาะสมหากคุณใช้การไล่ระดับสีจากมากไปน้อย คุณมีการไล่ระดับสีที่กำหนดด้วยตนเองหรือไม่? หากเป็นเช่นนั้น คุณสามารถคำนวณการไล่ระดับสีด้วยตนเองและใส่เข้าไป ดูชื่อ stackoverflow.com/questions/43839431/   -  person THN    schedule 05.02.2018


คำตอบ (1)


นี่มันเป็นเรื่องยุ่งยาก สาเหตุเบื้องหลังข้อผิดพลาดของคุณคือ ไม่มีการพึ่งพาอย่างต่อเนื่อง ระหว่างการสูญเสียและเครือข่ายของคุณ เพื่อคำนวณการไล่ระดับสีของการสูญเสียของคุณ w.r.t. ไปยังเครือข่าย การสูญเสียของคุณจะต้องคำนวณความชันของตัวบ่งชี้หากเอาต์พุตของคุณมากกว่า 0.5 (เนื่องจากนี่เป็นการเชื่อมต่อเดียวระหว่างค่าการสูญเสียสุดท้ายของคุณกับเอาต์พุต y_pred จากเครือข่ายของคุณ) สิ่งนี้เป็นไปไม่ได้เนื่องจากตัวบ่งชี้นี้มีความคงที่บางส่วนและไม่ต่อเนื่อง

วิธีแก้ปัญหาที่เป็นไปได้ - ทำให้ตัวบ่งชี้ของคุณราบรื่น:

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)

เนื่องจาก sigmoid เป็นเวอร์ชันต่อเนื่องของฟังก์ชันขั้นตอน หากผลลัพธ์ของคุณมาจาก sigmoid คุณสามารถใช้ y_pred_f แทน y_pred_mask_f ได้

person Marcin Możejko    schedule 04.02.2018