Convert a PyTorch loss function to its Keras version

Can anyone help me convert the following PyTorch Loss function to a Keras loss function? The first part is a metric and then its corresponding surrogate loss function. I didn’t find the exact correspondence between every PyTorch function with a Keras function. I think that an experienced engineer will need just 2 minutes for this conversion. Thank you in advance for your help. This loss function was retrieved from the following paper: https://arxiv.org/abs/2003.07311. In the last page you can find this implementation.

    # 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)

So far I have created the following:


import keras

def soft_clDice_loss(gt, pr,iters=50, smooth=1.0, **kwargs):
    r"""Implementation of soft clDice loss    

    """
    backend = kwargs['backend']

    # clip to prevent NaN's and Inf's
    pr = backend.clip(pr, backend.epsilon(), 1.0 - backend.epsilon())

    def soft_erode(img):
        img = -img
        p1 = backend.pool2d(img, (3, 1), (1, 1))
        p2 = backend.pool2d(img, (1, 3), (1, 1))
        p1 = -p1
        p2 = -p2
        return backend.minimum(p1, p2)

    def soft_dilate(img):
        return backend.pool2d(img, (3, 3), (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)
        diff = img-img1
        skel = backend.relu(diff)

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

    smooth = 1.
    skel_pred = soft_skel(pr, iters)
    skel_true = soft_skel(gt, iters)
    pres = (backend.sum(backend.dot(skel_pred, gt))+smooth)/(backend.sum(skel_pred)+smooth)    
    rec = (backend.sum(backend.dot(skel_true, pr))+smooth)/(backend.sum(skel_true)+smooth)    
    loss = 1.- 2.0*(pres*rec)/(pres+rec)
        
    return loss

Unfortunatelly, I still receive errors. Can you help me understand what kind of computations are happening in the PyTorch tensors? Do you know how to match them with the corresponding Keras functions? Thank you very much for your time in advance.