def net_process(self, image: np.ndarray, flip: bool = True) -> torch.Tensor: """ Feed input through the network. In addition to running a crop through the network, we can flip the crop horizontally, run both crops through the network, and then average them appropriately. Afterwards, apply softmax, then convert the prediction to the label taxonomy. Args: - image: - flip: boolean, whether to average with flipped patch output Returns: - output: Pytorch tensor representing network predicting in evaluation taxonomy (not necessarily model taxonomy) """ input = torch.from_numpy(image.transpose((2, 0, 1))).float() normalize_img(input, self.mean, self.std) input = input.unsqueeze(0) if self.use_gpu: input = input.cuda() if flip: # add another example to batch dimension, that is the flipped crop input = torch.cat([input, input.flip(3)], 0) with torch.no_grad(): output = self.model(input) _, _, h_i, w_i = input.shape _, _, h_o, w_o = output.shape if (h_o != h_i) or (w_o != w_i): output = F.interpolate(output, (h_i, w_i), mode='bilinear', align_corners=True) prediction_conversion_req = self.model_taxonomy != self.eval_taxonomy if prediction_conversion_req: # Either (model_taxonomy='naive', eval_taxonomy='test_dataset') # Or (model_taxonomy='universal', eval_taxonomy='test_dataset') output = self.tc.transform_predictions_test( output, self.args.dataset) else: # model & eval tax match, so no conversion needed assert self.model_taxonomy in ['universal', 'test_dataset'] # todo: determine when .cuda() needed here output = self.softmax(output) if flip: # take back out the flipped crop, correct its orientation, and average result output = (output[0] + output[1].flip(2)) / 2 else: output = output[0] # output = output.data.cpu().numpy() # convert CHW to HWC order # output = output.transpose(1, 2, 0) # output = output.permute(1,2,0) return output
def net_process(self, image: np.ndarray, flip: bool = True): """ Feed input through the network. In addition to running a crop through the network, we can flip the crop horizontally, run both crops through the network, and then average them appropriately. Args: - model: - image: - flip: boolean, whether to average with flipped patch output Returns: - output: """ input = torch.from_numpy(image.transpose((2, 0, 1))).float() normalize_img(input, self.mean, self.std) input = input.unsqueeze(0) if self.use_gpu: input = input.cuda() if flip: # add another example to batch dimension, that is the flipped crop input = torch.cat([input, input.flip(3)], 0) with torch.no_grad(): output = self.model(input) _, _, h_i, w_i = input.shape _, _, h_o, w_o = output.shape if (h_o != h_i) or (w_o != w_i): output = F.interpolate(output, (h_i, w_i), mode='bilinear', align_corners=True) if self.output_taxonomy == 'universal': output = self.softmax(output) elif self.output_taxonomy == 'test_dataset': output = self.convert_pred_to_label_tax_and_softmax(output) else: print('Unrecognized output taxonomy. Quitting....') quit() # print(time.time() - start1, image_scale.shape, h, w) if flip: # take back out the flipped crop, correct its orientation, and average result output = (output[0] + output[1].flip(2)) / 2 else: output = output[0] # output = output.data.cpu().numpy() # convert CHW to HWC order # output = output.transpose(1, 2, 0) # output = output.permute(1,2,0) return output
def test_normalize_img_test_mean_only(): """ Take image of shape HWC, i.e. (2 x 2 x 3) """ image = np.array([[[20, 22, 24], [26, 28, 30]], [[32, 34, 36], [38, 40, 42]]]).astype(np.uint8) input = torch.from_numpy(image.transpose((2, 0, 1))).float() # tensor is now CHW, i.e. (3,2,2) mean = [30, 30, 30] normalize_img(input, mean) # subtract 30 from all entries gt_input = torch.tensor([[[-10, -8, -6], [-4, -2, 0]], [[2, 4, 6], [8, 10, 12]]]) gt_input = gt_input.permute(2, 0, 1).float() assert torch.allclose(input, gt_input) assert isinstance(input, torch.Tensor)