Beispiel #1
0
def generate_noise(noise_mode: str,
                   size: torch.Size,
                   oe_limit: int,
                   logger: Logger = None,
                   datadir: str = None) -> torch.Tensor:
    """
    Given a noise_mode, generates noise images.
    :param noise_mode: one of the available noise_nodes, see MODES:
        'gaussian': choose pixel values based on Gaussian distribution.
        'uniform: choose pixel values based on uniform distribution.
        'blob': images of randomly many white rectangles of random size.
        'mixed_blob': images of randomly many rectangles of random size, approximately half of them
            are white and the others have random colors per pixel.
        'solid': images of solid colors, i.e. one random color per image.
        'confetti': confetti noise as seen in the paper. Random size, orientation, and number.
            They are also smoothened. Half of them are white, the rest is of one random color per rectangle.
        'imagenet': Outlier Exposure with ImageNet.
        'imagenet22k': Outlier Exposure with ImageNet22k, i.e. the full release fall 2011.
        'cifar100': Outlier Exposure with Cifar-100.
        'emnist': Outlier Exposure with EMNIST.
    :param size: number and size of the images (n x c x h x w)
    :param oe_limit: limits the number of different samples for Outlier Exposure
    :param logger: some logger
    :param datadir: the root directory of datsets (for Outlier Exposure)
    :return: a torch tensor of noise images
    """
    if noise_mode is not None:
        if noise_mode in ['gaussian']:
            generated_noise = (torch.randn(size) * 64)
        elif noise_mode in ['uniform']:
            generated_noise = (torch.rand(size)).mul(255)
        elif noise_mode in ['blob']:
            generated_noise = confetti_noise(size,
                                             0.002, ((6, 6), (6, 6)),
                                             fillval=255,
                                             clamp=False,
                                             awgn=0)
        elif noise_mode in ['mixed_blob']:
            generated_noise_rgb = confetti_noise(size,
                                                 0.00001, ((34, 34), (34, 34)),
                                                 fillval=255,
                                                 clamp=False,
                                                 awgn=0)
            generated_noise = confetti_noise(size,
                                             0.00001, ((34, 34), (34, 34)),
                                             fillval=255,
                                             clamp=False,
                                             awgn=0)
            generated_noise_rgb = colorize_noise(generated_noise_rgb,
                                                 (0, 0, 0), (255, 255, 255),
                                                 p=1)
            generated_noise = generated_noise_rgb + generated_noise
        elif noise_mode in ['solid']:
            generated_noise = solid(size)
        elif noise_mode in ['confetti']:
            generated_noise_rgb = confetti_noise(size,
                                                 0.000018, ((8, 8), (54, 54)),
                                                 fillval=255,
                                                 clamp=False,
                                                 awgn=0,
                                                 rotation=45,
                                                 colorrange=(-256, 0))
            generated_noise = confetti_noise(size,
                                             0.000012, ((8, 8), (54, 54)),
                                             fillval=-255,
                                             clamp=False,
                                             awgn=0,
                                             rotation=45)
            generated_noise = generated_noise_rgb + generated_noise
            generated_noise = smooth_noise(generated_noise, 25, 5, 1.0)
        elif noise_mode in ['imagenet']:
            generated_noise = next(
                iter(
                    OEImageNet(size, limit_var=oe_limit,
                               root=datadir).data_loader()))
        elif noise_mode in ['imagenet22k']:
            generated_noise = next(
                iter(
                    OEImageNet22k(size,
                                  limit_var=oe_limit,
                                  logger=logger,
                                  root=datadir).data_loader()))
        elif noise_mode in ['cifar100']:
            generated_noise = next(
                iter(
                    OECifar100(size, limit_var=oe_limit,
                               root=datadir).data_loader()))
        elif noise_mode in ['emnist']:
            generated_noise = next(
                iter(
                    OEEMNIST(size, limit_var=oe_limit,
                             root=datadir).data_loader()))
        elif noise_mode in ['mvtec', 'mvtec_gt']:
            raise NotImplementedError(
                'MVTec-AD and MVTec-AD with ground-truth maps is only available with only supervision.'
            )
        else:
            raise NotImplementedError(
                'Supervise noise mode {} unknown (offline version).'.format(
                    noise_mode))
        return generated_noise
Beispiel #2
0
 def __init__(self,
              ds: TorchvisionDataset,
              supervise_mode: str,
              noise_mode: str,
              oe_limit: int = np.infty,
              p: float = 0.5,
              exclude: [str] = ()):
     """
     This class is used as a Transform parameter for torchvision datasets.
     During training it randomly replaces a sample of the dataset retrieved via the get_item method
     by an artificial anomaly.
     :param ds: some AD dataset for which the OnlineSuperviser is used.
     :param supervise_mode: the type of artificial anomalies to be generated during training.
         See :meth:`fcdd.datasets.bases.TorchvisionDataset._generate_artificial_anomalies_train_set`.
     :param noise_mode: the type of noise used, see :mod:`fcdd.datasets.noise_mode`.
         In addition to the offline noise modes, the OnlineSuperviser offers Outlier Exposure with MVTec-AD.
         The oe_limit parameter for MVTec-AD limits the number of different samples per defection type
         (including "good" instances, i.e. nominal ones in the test set).
     :param oe_limit: the number of different Outlier Exposure samples used in case of outlier exposure based noise.
     :param p: the chance to replace a sample from the original dataset during training.
     :param exclude: all class names that are to be excluded in Outlier Exposure datasets.
     """
     self.ds = ds
     self.supervise_mode = supervise_mode
     self.noise_mode = noise_mode
     self.oe_limit = oe_limit
     self.p = p
     self.noise_sampler = None
     if noise_mode == 'imagenet':
         self.noise_sampler = cycle(
             OEImageNet((1, ) + ds.raw_shape,
                        limit_var=oe_limit,
                        root=ds.root,
                        exclude=exclude).data_loader())
     elif noise_mode == 'imagenet22k':
         self.noise_sampler = cycle(
             OEImageNet22k((1, ) + ds.raw_shape,
                           limit_var=oe_limit,
                           logger=ds.logger,
                           root=ds.root).data_loader())
     elif noise_mode == 'cifar100':
         self.noise_sampler = cycle(
             OECifar100((1, ) + ds.raw_shape,
                        limit_var=oe_limit,
                        root=ds.root).data_loader(), )
     elif noise_mode == 'emnist':
         self.noise_sampler = cycle(
             OEEMNIST((1, ) + ds.raw_shape,
                      limit_var=oe_limit,
                      root=ds.root).data_loader())
     elif noise_mode == 'mvtec':
         self.noise_sampler = cycle(
             OEMvTec((1, ) + ds.raw_shape,
                     ds.normal_classes,
                     limit_var=oe_limit,
                     logger=ds.logger,
                     root=ds.root).data_loader())
     elif noise_mode == 'mvtec_gt':
         self.noise_sampler = cycle(
             OEMvTec((1, ) + ds.raw_shape,
                     ds.normal_classes,
                     limit_var=oe_limit,
                     logger=ds.logger,
                     gt=True,
                     root=ds.root).data_loader())