Преобразовать функцию потерь PyTorch в функцию потерь Keras - PullRequest
0 голосов
/ 14 апреля 2020

Может ли кто-нибудь помочь мне преобразовать следующую функцию потери PyTorch в функцию потери Keras? Первая часть - это метри c, а затем соответствующая ей функция суррогатных потерь. Я не нашел точного соответствия между каждой функцией PyTorch с функцией Keras. Я думаю, что опытному инженеру понадобится всего 2 минуты для этого преобразования. Спасибо заранее за вашу помощь. Эта функция потерь была получена из следующей статьи: https://arxiv.org/abs/2003.07311. На последних страницах вы можете найти эту реализацию.

    # clDice measure
from skimage.morphology import skeletonize
import numpy as np

def cl_score(v, s):
    return np.sum(v ∗ s) / np.sum(s)

def clDice(v_p, v_l):
    tprec = cl_score(v_p, skeletonize(v_l))
    tsens = cl_score(v_l, skeletonize(v_p))
    return 2 ∗ tprec ∗ tsens / (tprec + tsens)

# clDice loss
import torch.nn.functional as F

def soft_erode(img):
    p1 = −F.max_pool2d(−img, (3, 1), (1, 1), (1, 0))
    p2 = −F.max_pool2d(−img, (1, 3), (1, 1), (0, 1))
    return torch.min(p1, p2)

def soft_dilate(img):
    return F.max_pool2d(img, (3, 3), (1 ,1), (1, 1))

def soft_open(img):
    return soft_dilate(soft_erode(img))

def soft_skel(img, iter):
    img1 = soft_open(img)
    skel = F.relu(img−img1)
    for j in range (iter):
        img = soft_erode(img)
        img1 = soft_open(img)
        delta = F.relu(img−img1)
        skel = skel + F.relu(delta − skel ∗ delta)
    return skel

def soft_clDice(v_p, v_l, iter = 50, smooth = 1):
    s_p = soft_skel(v_p, iter)
    s_l = soft_skel(v_l, iter)
    tprec = ((s_p ∗ v_l).sum() + smooth) / (s_p.sum() + smooth)
    tsens = ((s_l ∗ v_p).sum() + smooth) / (s_l.sum() + smooth )
    return 2 ∗ tprec ∗ tsens / (tprec + tsens)

До сих пор я создал следующее:


import keras

def soft_clDice_loss(gt, pr, iter=50,smooth=1):

    def soft_erode(img):
        p1 = −keras.backend.pool2d(−img, (3, 1), (1, 1), (1, 0))
        p2 = −keras.backend.pool2d(−img, (1, 3), (1, 1), (0, 1))
        return keras.backend.min(p1, p2)

    def soft_dilate(img):
        return keras.backend.pool2d(img, (3, 3), (1 ,1), (1, 1))

    def soft_open(img):
        img = soft_erode(img)
        img = soft_dilate(img)
        return img

    def soft_skel(img, iters):
        img1 = soft_open(img)
        skel = keras.backend.relu(img−img1)

        for j in range(iter):
            img = soft_erode(img)
            img1 = soft_open(img)
            delta = keras.backend.relu(img-img1)
            intersect = keras.backend.dot(skel, delta)
            skel += keras.backend.relu(delta-intersect)
        return skel

    def soft_clDice_loss(iters = 50):
        def loss(y_true, y_pred):
            smooth = 1.
            skel_pred = soft_skel(y_pred, iters)
            skel_true = soft_skel(y_true, iters)
            pres = (keras.backend.sum(keras.backend.dot(skel_pred, y_true)[:,1:,:,:,:])+smooth)/(keras.backend.sum(skel_pred[:,1:,:,:,:])+smooth)    
            rec = (keras.backend.sum(keras.backend.dot(skel_true, y_pred)[:,1:,:,:,:])+smooth)/(keras.backend.sum(skel_true[:,1:,:,:,:])+smooth)    
            cl_dice = 1.- 2.0*(pres*rec)/(pres+rec)
            return cl_dice
        return loss

...