示例#1
0
def gradcam(
    features: Module, classifier: Module, input_image: Tensor, n_top_classes: int = 3
) -> Tensor:
    """Performs GradCAM on an input image.

    For further explanations about GradCam, see https://arxiv.org/abs/1610.02391.

    Args:
        features: the spatial feature part of the model, before classifier
        classifier: the classifier part of the model, after spatial features
        input_image: image tensor of dimensions (c, h, w) or (1, c, h, w)
        n_top_classes: the number of classes to calculate GradCAM for

    Returns:
        a GradCAM heatmap of dimensions (h, w)

    """
    # Get selector for top k classes
    input_image = _prepare_input(input_image)
    class_selector = _top_k_selector(
        Sequential(features.eval(), classifier.eval()), input_image, n_top_classes
    )
    # Apply spatial GradAM on classes
    gradam = GradAM(classifier, class_selector, features, SpatialSplit())
    result = gradam.visualize(input_image)
    return _upscale(result, tuple(input_image.size()[2:]))
示例#2
0
 def remove(self, module: Module) -> None:
     with torch.no_grad():
         weight = self.compute_weight(module, do_power_iteration=False)
     delattr(module, self.name)
     delattr(module, self.name + "_u")
     delattr(module, self.name + "_v")
     delattr(module, self.name + "_orig")
     module.register_parameter(self.name, torch.nn.Parameter(weight.detach()))
示例#3
0
	def create_optimizer(self,opts, model: Module):
		optimopts = opts.optimizeropts
		if opts.epocheropts.gpu:
			device = torch.device("cpu")
			model = model.to(device=device)

		optim = globals()[optimopts.type](model.parameters(),
		                                  lr=optimopts.lr,
		                                  momentum=optimopts.momentum,
		                                  weight_decay=optimopts.weight_decay,
		                                  dampening=optimopts.dampening,
		                                  nesterov=optimopts.nestrov)
		opts.optimizeropts.lr_sched = LambdaLR(optim, opts.optimizeropts.lr_sched_lambda, last_epoch=-1)
		return optim
示例#4
0
 def load_pytorch_model(self,
                        model: Module,
                        identifier,
                        *tags,
                        checkpoint_number=None):
     load_dir = build_checkpoint_path(AgentBase.CHECKPOINT_DIR_NAME,
                                      AgentBase.PYTORCH_PLATFORM,
                                      identifier, *tags)
     if not checkpoint_number:
         checkpoint_number = self.get_next_index(load_dir)
     load_path = os.path.join(load_dir,
                              (AgentBase.FILENAME + AgentBase.SEPARATOR +
                               str(checkpoint_number)))
     LOG.info("Loading pytorch model at " + load_path)
     model.load_state_dict(torch.load(load_path))
示例#5
0
def class_visualization(net: Module, class_index: int) -> Tensor:
    """Visualizes a class for a classification network.

    Args:
        net: the network to visualize for
        class_index: the index of the class to visualize

    """
    if class_index < 0:
        raise ValueError(f"Invalid class: {class_index}")

    img = PixelActivation(
        net.eval(),
        SplitSelector(NeuronSplit(), [class_index]),
        opt_n=500,
        iter_n=20,
        init_size=50,
        transform=RandomTransform(scale_fac=0)
        + BilateralTransform()
        + ResizeTransform(1.1),
        regularization=[TVRegularization(5e1), WeightDecay(1e-9)],
    ).visualize()

    return PixelActivation(
        net,
        SplitSelector(NeuronSplit(), [class_index]),
        opt_n=100,
        iter_n=int(50),
        transform=RandomTransform() + BilateralTransform(),
        regularization=[TVRegularization(), WeightDecay()],
    ).visualize(img)
示例#6
0
    def validate(self, model: Module, data_loader: DataLoader, use_cuda: bool,
                 criterion: Module) -> float:
        """Performs one epoch of validating of the model and returns the
        obtained validation loss.

        :param model: model to be validated
        :param data_loader: validation data loader
        :param use_cuda: a flag whether CUDA can be used
        :param criterion: loss function
        :return: validation loss
        """
        valid_loss = 0.0
        model.eval()
        for batch_idx, (data, target) in enumerate(tqdm(data_loader)):
            data = self.move_to_gpu(data, use_cuda)
            output = model.forward(*data)
            loss = criterion(*output)
            valid_loss += ((1 / (batch_idx + 1)) * (loss.data - valid_loss))
        return valid_loss
示例#7
0
 def save_pytorch_model(self, model: Module, identifier, *tags):
     save_dir = build_checkpoint_path(AgentBase.CHECKPOINT_DIR_NAME,
                                      AgentBase.PYTORCH_PLATFORM,
                                      identifier, *tags)
     self.init_dir(save_dir)
     save_path = os.path.join(save_dir,
                              (AgentBase.FILENAME + AgentBase.SEPARATOR +
                               str(self.get_next_index(save_dir))))
     LOG.info("Saving pytorch model at " + save_path)
     torch.save(model.state_dict(), save_path)
示例#8
0
def sgd(
    model: Module,
    lr: float = 0.01,
    momentum: float = 0.9,
    weight_decay: float = 5e-4,
) -> OptimizerSchedulerBundle:
    optimizer = SGD(model.parameters(),
                    lr=lr,
                    momentum=momentum,
                    weight_decay=weight_decay)
    return OptimizerSchedulerBundle(optimizer=optimizer)
示例#9
0
def lrs(model: Module,
        lr: float = 0.1,
        momentum: float = 0.9,
        weight_decay: float = 5e-4,
        step_size: int = 30) -> OptimizerSchedulerBundle:
    optimizer = SGD(model.parameters(),
                    lr=lr,
                    momentum=momentum,
                    weight_decay=weight_decay)
    scheduler = StepLR(optimizer, step_size=step_size)
    return OptimizerSchedulerBundle(optimizer=optimizer, scheduler=scheduler)
示例#10
0
    def train(self, model: Module, data_loader: DataLoader, use_cuda: bool,
              criterion: Module, optimizer: Optimizer) -> float:
        """Performs one epoch of training of the model and returns the obtained
        training loss.

        :param model: model to be trained
        :param data_loader: training data loader
        :param use_cuda: a flag whether CUDA can be used
        :param criterion: loss function
        :param optimizer: optimizer
        :return: training loss
        """
        train_loss = 0.0
        model.train()
        for batch_idx, (data, target) in enumerate(tqdm(data_loader)):
            data = self.move_to_gpu(data, use_cuda)
            optimizer.zero_grad()
            output = model(*data)
            loss = criterion(*output)
            loss.backward()
            optimizer.step()
            train_loss += ((1 / (batch_idx + 1)) * (loss.data - train_loss))
        return train_loss
示例#11
0
def _top_k_selector(net: Module, img: Tensor, k: int) -> NeuronSelector:
    """Creates a top-k classes selector.

    Args:
        net: network
        img: prepared input image
        k: number of classes

    Returns:
        neuron selector for the top k classes

    """
    net = net.to(midnite.get_device())
    out = net(img).squeeze(0)
    mask = _top_k_mask(out, k)

    return SimpleSelector(mask)
示例#12
0
def occlusion(net: Module, input_image: Tensor, n_top_classes: int = 3) -> Tensor:
    """Creates a attribution heatmap by occluding parts of the input image.

    Args:
        net: the network to visualize attribution for
        input_image: image tensor of dimensions (c, h, w) or (1, c, h, w)
        n_top_classes: the number of classes to account for

    Returns:
        a occlusion heatmap of dimensions (h, w)

    """
    input_image = _prepare_input(input_image)
    class_selector = _top_k_selector(net.eval(), input_image, n_top_classes)
    # Apply occlusion
    occlusion_ = Occlusion(net, class_selector, SpatialSplit(), [1, 10, 10], [1, 5, 5])
    result = occlusion_.visualize(input_image)
    return _upscale(result, tuple(input_image.size()[2:]))
示例#13
0
    def apply(
        module: Module, name: str, coeff: float, n_power_iterations: int, dim: int, eps: float,
    ) -> "SpectralNorm":
        for k, hook in module._forward_pre_hooks.items():
            if isinstance(hook, SpectralNorm) and hook.name == name:
                raise RuntimeError("Cannot register two spectral_norm hooks on " "the same parameter {}".format(name))

        fn = SpectralNorm(coeff, name, n_power_iterations, dim, eps)
        weight = module._parameters[name]

        with torch.no_grad():
            weight_mat = fn.reshape_weight_to_matrix(weight)

            h, w = weight_mat.size()
            # randomly initialize `u` and `v`
            u = normalize(weight.new_empty(h).normal_(0, 1), dim=0, eps=fn.eps)
            v = normalize(weight.new_empty(w).normal_(0, 1), dim=0, eps=fn.eps)

        delattr(module, fn.name)
        module.register_parameter(fn.name + "_orig", weight)
        # We still need to assign weight back as fn.name because all sorts of
        # things may assume that it exists, e.g., when initializing weights.
        # However, we can't directly assign as it could be an nn.Parameter and
        # gets added as a parameter. Instead, we register weight.data as a plain
        # attribute.
        setattr(module, fn.name, weight.data)
        module.register_buffer(fn.name + "_u", u)
        module.register_buffer(fn.name + "_v", v)
        module.register_buffer(fn.name + "_sigma", torch.ones(1).to(weight.device))

        module.register_forward_pre_hook(fn)
        module._register_state_dict_hook(SpectralNormStateDictHook(fn))
        module._register_load_state_dict_pre_hook(SpectralNormLoadStateDictPreHook(fn))
        return fn
示例#14
0
def radam(model: Module) -> OptimizerSchedulerBundle:
    optimizer = RAdam(model.parameters())
    return OptimizerSchedulerBundle(optimizer=optimizer)