def get_cam_image(self, input_tensor, target_layer, target_category, activations, grads, eigen_smooth): return get_2d_projection(grads * activations)
def get_cam_image(self, input_tensor, target_layer, target_category, activations, grads, eigen_smooth): spatial_weighted_activations = np.maximum(grads, 0) * activations if eigen_smooth: cam = get_2d_projection(spatial_weighted_activations) else: cam = spatial_weighted_activations.sum(axis=1) return cam
def get_cam_image(self, input_tensor, target_layer, target_category, activations, grads, eigen_smooth): elementwise_activations = np.maximum(grads * activations, 0) if eigen_smooth: cam = get_2d_projection(elementwise_activations) else: cam = elementwise_activations.sum(axis=1) return cam
def objectiveness_mask_from_svd(self, activations, threshold=0.01): """ Experimental method to get a binary mask to compare if the activation is worth ablating. The idea is to apply the EigenCAM method by doing PCA on the activations. Then we create a binary mask by comparing to a low threshold. Areas that are masked out, are probably not interesting anyway. """ projection = get_2d_projection(activations[None, :])[0, :] projection = np.abs(projection) projection = projection - projection.min() projection = projection / projection.max() projection = projection > threshold return projection
def get_cam_image(self, input_tensor, target_category, activations, grads, eigen_smooth=False): weights = self.get_cam_weights(input_tensor, target_category, activations, grads) weighted_activations = weights[:, :, None, None] * activations if eigen_smooth: cam = get_2d_projection(weighted_activations) else: cam = weighted_activations.sum(axis=1) return cam
def get_cam_image(self, input_tensor: torch.Tensor, target_layer: torch.nn.Module, targets: List[torch.nn.Module], activations: torch.Tensor, grads: torch.Tensor, eigen_smooth: bool = False) -> np.ndarray: weights = self.get_cam_weights(input_tensor, target_layer, targets, activations, grads) weighted_activations = weights[:, :, None, None] * activations if eigen_smooth: cam = get_2d_projection(weighted_activations) else: cam = weighted_activations.sum(axis=1) return cam
def compute_cam_per_layer(self, input_tensor, target_category, eigen_smooth): input_grad = input_tensor.grad.data.cpu().numpy() grads_list = [ g.cpu().data.numpy() for g in self.activations_and_grads.gradients ] cam_per_target_layer = [] target_size = self.get_target_width_height(input_tensor) gradient_multiplied_input = input_grad * input_tensor.data.cpu().numpy( ) gradient_multiplied_input = np.abs(gradient_multiplied_input) gradient_multiplied_input = scale_accross_batch_and_channels( gradient_multiplied_input, target_size) cam_per_target_layer.append(gradient_multiplied_input) # Loop over the saliency image from every layer assert (len(self.bias_data) == len(grads_list)) for bias, grads in zip(self.bias_data, grads_list): bias = bias[None, :, None, None] # In the paper they take the absolute value, # but possibily taking only the positive gradients will work # better. bias_grad = np.abs(bias * grads) result = scale_accross_batch_and_channels(bias_grad, target_size) result = np.sum(result, axis=1) cam_per_target_layer.append(result[:, None, :]) cam_per_target_layer = np.concatenate(cam_per_target_layer, axis=1) if eigen_smooth: # Resize to a smaller image, since this method typically has a very large number of channels, # and then consumes a lot of memory cam_per_target_layer = scale_accross_batch_and_channels( cam_per_target_layer, (target_size[0] // 8, target_size[1] // 8)) cam_per_target_layer = get_2d_projection(cam_per_target_layer) cam_per_target_layer = cam_per_target_layer[:, None, :, :] cam_per_target_layer = scale_accross_batch_and_channels( cam_per_target_layer, target_size) else: cam_per_target_layer = np.sum(cam_per_target_layer, axis=1)[:, None, :] return cam_per_target_layer