{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":84969,"databundleVersionId":10033515,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport torch\nimport torch.nn as nn\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\n\n# A try of making a Loss from a soft version of F-beta\n# I've obtained similar results than for weighted CE but with more chaotic trainings\n# Any suggestion will be appreciated :)\n# https://math-projects.elte.hu/media/works/187/report/tversky_loss_and_variants.pdf\n# https://scikit-learn.org/1.5/modules/generated/sklearn.metrics.fbeta_score.html\nclass myLoss(nn.Module):\n    def __init__(\n            self,\n            beta=4\n    ):\n        super(myLoss, self).__init__()\n        self.beta = beta\n        \n    def forward(\n            self,\n            pred,\n            label,\n            weight=torch.tensor([\n                1.,\n                2.,\n                1.,\n                2.,\n                1.\n            ]).to(device),\n            smooth=1e-5\n        ):\n        pred = pred.softmax(1)\n        FB = W = torch.tensor([smooth]).to(device)\n        for k in range(len(TARGETS)):\n            m = label == k + 1\n            if m.sum() > 0:\n                bm = m.view(len(m),-1).sum(-1) > 0\n                y_true = m[bm].view(bm.sum(),-1).float()\n                y_pred = pred[bm,k+1,:,:,:].view(bm.sum(),-1)\n#               We'll check the max value other than ith, doesn't needs to evercome all of them to be positive\n                y_pred_max = torch.cat([\n                    pred[bm,:k+1],\n                    pred[bm,k+2:]\n                ],1).max(1)[0].detach().view(bm.sum(),-1)\n                y_pred = y_pred/(y_pred+y_pred_max)\n\n                TP = (y_pred*y_true).sum(-1)\n                FN = ((1-y_pred)*y_true).sum(-1)\n                FP = (y_pred*(1-y_true)).sum(-1)\n                \n                FB = FB + (weight[k]*((1 + self.beta*self.beta)*TP + smooth) / ((1 + self.beta*self.beta)*TP + FP + self.beta*self.beta*FN + smooth)).mean()\n                W = W + weight[k]\n\n        return 1 - FB/W","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null}]}