def update(self, model_output, target, **kwargs): """ args: model_output: tensor of shape (B, C) where each value is either logit or class probability. target: tensor of shape (B, C), which is one-hot / multi-label encoded, or tensor of shape (B) / (B, 1), integer encoded """ # Convert target to 0/1 encoding if isn't target = maybe_convert_to_one_hot(target, model_output) _, pred_classes = model_output.topk(max(self._topk), dim=1, largest=True, sorted=True) pred_mask_tensor = torch.zeros(target.size()) for i, k in enumerate(self._topk): pred_mask_tensor.zero_() self._curr_correct_predictions_k[i] += torch.sum( # torch.min is used to simulate AND between binary # tensors. If tensors are not binary, this will fail. torch.min( pred_mask_tensor.scatter_(1, pred_classes[:, :k], 1.0), target.float(), )).item() self._curr_sample_count += model_output.shape[0]
def update(self, model_output, target, **kwargs): """ args: model_output: tensor of shape (B, C) where each value is either logit or class probability. target: tensor of shape (B, C), which is one-hot / multi-label encoded, or tensor of shape (B) / (B, 1), integer encoded """ # Due to dummy samples, in some corner cases, the whole batch could # be dummy samples, in that case we want to not update meters on that # process if model_output.shape[0] == 0: return # Convert target to 0/1 encoding if isn't target = maybe_convert_to_one_hot(target, model_output) _, pred = model_output.topk(max(self._topk), dim=1, largest=True, sorted=True) for i, k in enumerate(self._topk): self._curr_correct_predictions_k[i] += (torch.gather( target, dim=1, index=pred[:, :k]).long().max(dim=1).values.sum().item()) self._curr_sample_count += model_output.shape[0]
def update(self, model_output, target, **kwargs): """ args: model_output: tensor of shape (B, C) where each value is either logit or class probability. target: tensor of shape (B, C), which is one-hot / multi-label encoded, or tensor of shape (B) / (B, 1), integer encoded """ # Convert target to 0/1 encoding if isn't target = maybe_convert_to_one_hot(target, model_output) # If Pytorch AMP is being used, model outputs are probably fp16 # Since .topk() is not compatible with fp16, we promote the model outputs to full precision _, pred = model_output.float().topk( max(self._topk), dim=1, largest=True, sorted=True ) for i, k in enumerate(self._topk): self._curr_correct_predictions_k[i] += ( torch.gather(target, dim=1, index=pred[:, :k]) .max(dim=1) .values.sum() .item() ) self._curr_sample_count += model_output.shape[0]
def update(self, model_output, target, **kwargs): """ args: model_output: tensor of shape (B, C) where each value is either logit or class probability. target: tensor of shape (B, C), which is one-hot / multi-label encoded, or tensor of shape (B) / (B, 1), integer encoded """ # Convert target to 0/1 encoding if isn't target = maybe_convert_to_one_hot(target, model_output) _, pred = model_output.topk(max(self._topk), dim=1, largest=True, sorted=True) for i, k in enumerate(self._topk): self._curr_correct_predictions_k[i] += ( torch.gather(target, dim=1, index=pred[:, :k]) .max(dim=1) .values.sum() .item() ) self._curr_sample_count += model_output.shape[0]