Main MSE Loss function, includes direction loss Args: pred (torch.tensor): predicted values y (torch.tensor): true values perts (list): list of perturbations ctrl (str): control perturbation direction_lambda (float): direction loss weight hyperparame
(pred, y, perts, ctrl = None, direction_lambda = 1e-3, dict_filter = None)
| 738 | |
| 739 | |
| 740 | def loss_fct(pred, y, perts, ctrl = None, direction_lambda = 1e-3, dict_filter = None): |
| 741 | """ |
| 742 | Main MSE Loss function, includes direction loss |
| 743 | |
| 744 | Args: |
| 745 | pred (torch.tensor): predicted values |
| 746 | y (torch.tensor): true values |
| 747 | perts (list): list of perturbations |
| 748 | ctrl (str): control perturbation |
| 749 | direction_lambda (float): direction loss weight hyperparameter |
| 750 | dict_filter (dict): dictionary of perturbations to conditions |
| 751 | |
| 752 | """ |
| 753 | gamma = 2 |
| 754 | mse_p = torch.nn.MSELoss() |
| 755 | perts = np.array(perts) |
| 756 | losses = torch.tensor(0.0, requires_grad=True).to(pred.device) |
| 757 | |
| 758 | for p in set(perts): |
| 759 | pert_idx = np.where(perts == p)[0] |
| 760 | |
| 761 | # during training, we remove the all zero genes into calculation of loss. |
| 762 | # this gives a cleaner direction loss. empirically, the performance stays the same. |
| 763 | if p!= 'ctrl': |
| 764 | retain_idx = dict_filter[p] |
| 765 | pred_p = pred[pert_idx][:, retain_idx] |
| 766 | y_p = y[pert_idx][:, retain_idx] |
| 767 | else: |
| 768 | pred_p = pred[pert_idx] |
| 769 | y_p = y[pert_idx] |
| 770 | losses = losses + torch.sum((pred_p - y_p)**(2 + gamma))/pred_p.shape[0]/pred_p.shape[1] |
| 771 | |
| 772 | ## direction loss |
| 773 | if (p!= 'ctrl'): |
| 774 | losses = losses + torch.sum(direction_lambda * |
| 775 | (torch.sign(y_p - ctrl[retain_idx]) - |
| 776 | torch.sign(pred_p - ctrl[retain_idx]))**2)/\ |
| 777 | pred_p.shape[0]/pred_p.shape[1] |
| 778 | else: |
| 779 | losses = losses + torch.sum(direction_lambda * (torch.sign(y_p - ctrl) - |
| 780 | torch.sign(pred_p - ctrl))**2)/\ |
| 781 | pred_p.shape[0]/pred_p.shape[1] |
| 782 | return losses/(len(set(perts))) |
| 783 | def evaluate(loader, model, uncertainty, device): |
| 784 | """ |
| 785 | Run model in inference mode using a given data loader |
no test coverage detected