'''
 * @author Waldinsamkeit
 * @email Zenglz_pro@163.com
 * @create date 2020-09-25 14:33:38
 * @desc 
'''

import torch


'''--------------------- Weighted Binary cross Entropy ----------------------'''

'''
In Torch BCELoss, weight is set to every element of input instead of to every class
'''
def weighted_binary_cross_entropy(output, target, weights=None):
    if weights is not None:
        assert len(weights) == 2
        
        loss = weights[1] * (target * torch.log(output)) + \
            weights[0] * ((1 - target) * torch.log(1 - output))
    else:
        loss = target * torch.log(output) + (1 - target) * torch.log(1 - output)

    return torch.neg(torch.mean(loss))


''' ---------------------- Binary focal loss function -------------------------- '''

'''
In some degree, it can reduce the influence of imbalanced dataset
'''

def focal_loss(y_true,y_pred,device):
    alpha,gamma = torch.tensor(0.25).to(device) , torch.tensor(2.0).to(device)
    y_pred=torch.clamp(y_pred,1e-7,1-1e-7)
    return - alpha * y_true * torch.log(y_pred) * (1 - y_pred) ** gamma\
        - (1 - alpha) * (1 - y_true) * torch.log(1 -  y_pred) * y_pred


[((980, 1017), 'torch.clamp', 'torch.clamp', (['y_pred', '(1e-07)', '(1 - 1e-07)'], {}), '(y_pred, 1e-07, 1 - 1e-07)\n', (991, 1017), False, 'import torch\n'), ((671, 687), 'torch.mean', 'torch.mean', (['loss'], {}), '(loss)\n', (681, 687), False, 'import torch\n'), ((592, 609), 'torch.log', 'torch.log', (['output'], {}), '(output)\n', (601, 609), False, 'import torch\n'), ((627, 648), 'torch.log', 'torch.log', (['(1 - output)'], {}), '(1 - output)\n', (636, 648), False, 'import torch\n'), ((908, 926), 'torch.tensor', 'torch.tensor', (['(0.25)'], {}), '(0.25)\n', (920, 926), False, 'import torch\n'), ((940, 957), 'torch.tensor', 'torch.tensor', (['(2.0)'], {}), '(2.0)\n', (952, 957), False, 'import torch\n'), ((1042, 1059), 'torch.log', 'torch.log', (['y_pred'], {}), '(y_pred)\n', (1051, 1059), False, 'import torch\n'), ((1124, 1145), 'torch.log', 'torch.log', (['(1 - y_pred)'], {}), '(1 - y_pred)\n', (1133, 1145), False, 'import torch\n'), ((471, 488), 'torch.log', 'torch.log', (['output'], {}), '(output)\n', (480, 488), False, 'import torch\n'), ((535, 556), 'torch.log', 'torch.log', (['(1 - output)'], {}), '(1 - output)\n', (544, 556), False, 'import torch\n')]