def test(trans_configs, model_configs,
         data_configs, save=False, output_dir=None):
    """
    Apply transformation(s) on images.
    :param trans_configs: dictionary. The collection of the parameterized transformations to test.
        in the form of
        { configsx: {
            param: value,
            }
        }
        The key of a configuration is 'configs'x, where 'x' is the id of corresponding weak defense.
    :param model_configs:  dictionary. Defines model related information.
        Such as, location, the undefended model, the file format, etc.
    :param data_configs: dictionary. Defines data related information.
        Such as, location, the file for the true labels, the file for the benign samples,
        the files for the adversarial examples, etc.
    :param save: boolean. Save the transformed sample or not.
    :param output_dir: path or str. The location to store the transformed samples.
        It cannot be None when save is True.
    :return:
    """
    # load weak defenses into a pool
    pool, _ = load_pool(trans_configs=trans_configs, model_configs=model_configs)
    # load the benign samples
    data_file = os.path.join(data_configs.get('dir'), data_configs.get('bs_file'))
    data_bs = np.load(data_file)
    img_rows, img_cols = data_bs.shape[1], data_bs.shape[2]
    # load the corresponding true labels
    label_file = os.path.join(data_configs.get('dir'), data_configs.get('label_file'))
    labels = np.load(label_file)
    print('SHAPES:', data_bs.shape, labels.shape)

    # test the loaded weak defenses one by one
    for id, model in pool.items():
        if id == 0: # skip the undefended model, which does not transform the image
            continue

        key = 'configs{}'.format(id)
        trans_args = trans_configs.get(key)
        print('TRANS CONFIG:', trans_args)
        # transform a small subset
        data_trans = transform(data_bs[:50], trans_args)
        # predict the transformed images by the corresponding model (weak defense)
        pred = model.predict(data_trans)

        # plotting a sample
        img_idx = 30
        img = data_trans[img_idx].reshape((img_rows, img_cols))
        plt.imshow(img, cmap='gray')
        title = '{}, {}'.format(trans_args.get('description'), np.argmax(pred[img_idx]))
        plt.title(title)
        plt.show()
        plt.close()

        # save the transformed sample as required
        if save:
            if output_dir is None:
                raise ValueError("Cannot save images to a none path.")
            file = os.path.join(output_dir, "{}.png".format(time.monotonic()))
            image.imsave(file, img)
Esempio n. 2
0
def random_rotations(X, num_samples, minval, maxval):
    samples = []
    num_images = X.shape[0]
    pool = np.asarray([i for i in range(minval, maxval + 1)])
    angles = np.random.choice(pool, size=num_samples, replace=False)

    trans_params = {
        'type': TRANSFORMATION.ROTATE.value,
        'subtype': '',
    }

    print('Random angles:', angles)
    rotated = []
    for angle in angles:
        trans_params['description'] = 'rotate{}'.format(angle)
        trans_params['angle'] = angle
        X_rot = transform(X, attack_args=trans_params)
        rotated.append(X_rot)

    rotated = np.asarray(rotated)
    print('ROTATED SHAPE:', rotated.shape)
    for i in range(num_images):
        for j in range(num_samples):
            samples.append(rotated[j][i])
    samples = np.asarray(samples)

    print('SAMPLE SHAPES:', samples.shape)
    return samples
Esempio n. 3
0
    def predict(self, x, batch_size=128, **kwargs):
        """
        Perform prediction for a batch of inputs.

        :param x: Test set.
        :type x: `np.ndarray`
        :param batch_size: Size of batches.
        :type batch_size: `int`
        :return: Array of predictions of shape `(nb_inputs, nb_classes)`.
        :rtype: `np.ndarray`
        """
        from art.config import ART_NUMPY_DTYPE

        # Apply transformation
        x_preprocessed = transform(x, self._trans_configs)

        # Apply preprocessing
        x_preprocessed, _ = self._apply_preprocessing(x_preprocessed,
                                                      y=None,
                                                      fit=False)

        # Run predictions with batching
        predictions = np.zeros((x_preprocessed.shape[0], self.nb_classes()),
                               dtype=ART_NUMPY_DTYPE)
        for batch_index in range(
                int(np.ceil(x_preprocessed.shape[0] / float(batch_size)))):
            begin, end = batch_index * batch_size, min(
                (batch_index + 1) * batch_size, x_preprocessed.shape[0])
            predictions[begin:end] = self._model.predict(
                [x_preprocessed[begin:end]])

        # Apply postprocessing
        predictions = self._apply_postprocessing(preds=predictions, fit=False)

        return predictions
Esempio n. 4
0
    def predict(self, x, batch_size=128, **kwargs):
        """
        Perform prediction for a batch of inputs.

        :param x: Test set.
        :type x: `np.ndarray`
        :param batch_size: Size of batches.
        :type batch_size: `int`
        :return: Array of predictions of shape `(nb_inputs, nb_classes)`.
        :rtype: `np.ndarray`
        """
        import torch

        # Apply transformation
        x_preprocessed = transform(set_channels_last(x), self._trans_configs)
        x_preprocessed = set_channels_first(x_preprocessed)

        # Apply preprocessing
        x_preprocessed, _ = self._apply_preprocessing(x_preprocessed, y=None, fit=False)

        # Run prediction with batch processing
        results = np.zeros((x_preprocessed.shape[0], self.nb_classes()), dtype=np.float32)
        num_batch = int(np.ceil(len(x_preprocessed) / float(batch_size)))
        for m in range(num_batch):
            # Batch indexes
            begin, end = m * batch_size, min((m + 1) * batch_size, x_preprocessed.shape[0])

            model_outputs = self._model(torch.from_numpy(x_preprocessed[begin:end]).to(self._device))
            output = model_outputs[-1]
            results[begin:end] = output.detach().cpu().numpy()

        # Apply postprocessing
        predictions = self._apply_postprocessing(preds=results, fit=False)

        return predictions
Esempio n. 5
0
def get_augmented_aeloaders(dataset, batch, dataroot, ae_file, trans_type=TRANSFORMATION.clean):
    train_sampler, trainloader, validloader, _ = get_dataloaders(dataset,
                                                                 batch,
                                                                 dataroot,
                                                                 trans_type)
    _, test_aug = get_augmentation(dataset)
    _, (_, y_test) = load_data(dataset)

    x_ae = load_model(ae_file)
    x_ae = transform(x_ae, trans_type)
    x_ae = data_utils.rescale(x_ae)

    x_ae = data_utils.set_channels_first(x_ae)

    testset = MyDataset(x_ae, y_test, aug=test_aug)
    testloader = torch.utils.data.DataLoader(
        testset, batch_size=batch, shuffle=False, num_workers=32, pin_memory=torch.cuda.is_available(),
        drop_last=False)

    return train_sampler, trainloader, validloader, testloader
def train(trainset, testset, processor=None, **kwargs):
    # get network
    model = cnn()

    X_train, Y_train = trainset
    X_test, Y_test = testset

    # apply transformation
    X_train = transform(X_train, processor)

    learning_rate = 0.001
    validation_rate = 0.2

    optimizer = kwargs.get('optimizer',
                           keras.optimizers.Adam(lr=learning_rate))
    loss_func = kwargs.get('loss', keras.losses.categorical_crossentropy)
    metrics = kwargs.get('metrics', 'default')

    print('Training weak defense [{}]...'.format(processor.description))
    print('>>> optimizer: {}'.format(optimizer))
    print('>>> loss function: {}'.format(loss_func))
    print('>>> metrics: {}'.format(metrics))

    nb_examples, img_rows, img_cols, nb_channels = X_train.shape

    nb_training = int(nb_examples * (1. - validation_rate))
    train_examples = X_train[:nb_training]
    train_labels = Y_train[:nb_training]
    val_examples = X_train[nb_training:]
    val_labels = Y_train[nb_training:]
    """
	compile data
	"""
    if ('default' == metrics):
        model.compile(optimizer=optimizer,
                      loss=loss_func,
                      metrics=['accuracy'])
    else:
        model.compile(optimizer=optimizer,
                      loss=loss_func,
                      metrics=['accuracy', metrics])

    # train the model
    history = model.fit(train_examples,
                        train_labels,
                        batch_size=64,
                        epochs=20,
                        verbose=2,
                        validation_data=(val_examples, val_labels))

    model_dir = kwargs.get('model_dir', 'models')
    save_file = kwargs.get('model_name', 'demo')
    postfix = kwargs.get('model_format', '.h5')
    model.save(os.path.join(model_dir, save_file + postfix))
    print('Saved the model to file [{}]'.format(
        os.path.join(model_dir, save_file + postfix)))

    # evaluate the model
    scores_train = model.evaluate(train_examples,
                                  train_labels,
                                  batch_size=128,
                                  verbose=0)
    scores_val = model.evaluate(val_examples,
                                val_labels,
                                batch_size=128,
                                verbose=0)

    X_test = transform(X_test, processor)
    scores_test = model.evaluate(X_test, Y_test, batch_size=128, verbose=0)
    """
	report
	"""
    print('\t\t\t loss, \t acc (BS/AE)')
    print('training set: {}'.format(scores_train))
    print('validation set: {}'.format(scores_val))
    print('test set: {}'.format(scores_test))
    print('')

    log_dir = kwargs.get('checkpoint_folder', 'checkpoints')
    save_file = save_file.replace(postfix, '')
    file.dict2csv(history.history,
                  '{}/checkpoint-{}.csv'.format(log_dir, save_file))
Esempio n. 7
0
def load_data(dataset, trans_type=TRANSFORMATION.clean, channel_first=False, trans_set='both'):
    assert dataset in DATA.get_supported_datasets()
    assert trans_set is None or trans_set in ['none', 'train', 'test', 'both']

    X_train = None
    Y_train = None
    X_test = None
    Y_test = None
    img_rows = 0
    img_cols = 0
    nb_channels = 0
    nb_classes = 0

    if DATA.mnist == dataset:
        """
        Dataset of 60,000 28x28 grayscale images of the 10 digits,
        along with a test set of 10,000 images.
        """
        (X_train, Y_train), (X_test, Y_test) = mnist.load_data()

        nb_examples, img_rows, img_cols = X_test.shape
        nb_channels = 1
        nb_classes = 10
    elif DATA.fation_mnist == dataset:
        """
        Dataset of 60,000 28x28 grayscale images of 10 fashion categories,
        along with a test set of 10,000 images. The class labels are:
        Label   Description
        0       T-shirt/top
        1       Trouser
        2       Pullover
        3       Dress
        4       Coat
        5       Sandal
        6       Shirt
        7       Sneaker
        8       Bag
        9       Ankle boot
        """
        (X_train, Y_train), (X_test, Y_test) = fashion_mnist.load_data()

        nb_examples, img_rows, img_cols = X_test.shape
        nb_channels = 1
        nb_classes = 10
    elif DATA.cifar_10 == dataset:
        """
        Dataset of 50,000 32x32 color training images, labeled over 10 categories, and 10,000 test images.
        """
        (X_train, Y_train), (X_test, Y_test) = cifar10.load_data()

        nb_examples, img_rows, img_cols, nb_channels = X_test.shape
        nb_classes = 10
    elif DATA.cifar_100 == dataset:
        (X_train, Y_train), (X_test, Y_test) = cifar100.load_data(label_mode='fine')
        nb_examples, img_rows, img_cols, nb_channels = X_test.shape
        nb_classes = 100

    X_train = X_train.reshape(-1, img_rows, img_cols, nb_channels)
    X_test = X_test.reshape(-1, img_rows, img_cols, nb_channels)

    """
    cast pixels to floats, normalize to [0, 1] range
    """
    X_train = X_train.astype(np.float32)
    X_test = X_test.astype(np.float32)
    X_train = data_utils.rescale(X_train, range=(0., 1.))
    X_test = data_utils.rescale(X_test, range=(0., 1.))

    """
    one-hot-encode the labels
    """
    Y_train = keras.utils.to_categorical(Y_train, nb_classes)
    Y_test = keras.utils.to_categorical(Y_test, nb_classes)

    """
    transform images
    """
    if trans_set is not None:
        if trans_set in ['train', 'both']:
            X_train = transform(X_train, trans_type)
            X_train = data_utils.rescale(X_train, range=(0., 1.))

        if trans_set in ['test', 'both']:
            X_test = transform(X_test, trans_type)
            X_test = data_utils.rescale(X_test, range=(0., 1.))

    if channel_first:
        X_train = data_utils.set_channels_first(X_train)
        X_test = data_utils.set_channels_first(X_test)
    """
    summarize data set
    """
    print('Dataset({}) Summary:'.format(dataset.upper()))
    print('Train set: {}, {}'.format(X_train.shape, Y_train.shape))
    print('Test set: {}, {}'.format(X_test.shape, Y_test.shape))
    return (X_train, Y_train), (X_test, Y_test)
Esempio n. 8
0
def sample_from_distribution(x, distribution_args):
    """
    Apply transformations from the specific distributions on given input x.
    :param x: the legitimate sample.
    :param distribution_args: dictionary. configuration of the distribution.
    :return:
    """
    if len(x.shape) == 4 and x.shape[0] > 1:
        raise ValueError(
            "This method does not support sampling for a batch. Function `batch_sample_from_distribution` is for batch sampling."
        )

    transformation = distribution_args.get(
        "transformation", TRANSFORMATION_DISTRIBUTION.RANDOM.value)

    # channel_index = distribution_args.get("channel_index", 3)
    # if channel_index not in [1, 3]:
    #     raise ValueError("`channel_index` must be 1 or 3, but found {}.".format(channel_index))

    # if channel_index == 1:
    x = set_channels_last(x)

    x = x.astype(np.float32)
    if transformation == TRANSFORMATION_DISTRIBUTION.RANDOM.value:
        # select a random transformation
        distribution = TRANSFORMATION_DISTRIBUTION.distributions()[1:]
        transformation = random.choice(distribution)

    if transformation == TRANSFORMATION_DISTRIBUTION.ROTATION.value:
        # randomly rotate the input x
        trans_args = {
            "type": "rotate",
            "subtype": "",
            "id": -1,
        }

        # the interval of rotation angle
        min_angle = distribution_args.get("min_angle", -15)
        max_angle = distribution_args.get("max_angle", 15)

        # rotate the x by a random angle
        angle = random.randint(min_angle, max_angle)
        trans_args["angle"] = angle
        trans_args["description"] = "rotate[{}]".format(angle)
        x_trans = transform(x, trans_args)[0]

    elif transformation == TRANSFORMATION_DISTRIBUTION.GAUSSIAN_NOISE.value:
        # add random gaussian noise to the input
        # magnitude of noise
        eta = distribution_args.get("eta", 0.03)

        clip_min = distribution_args.get("clip_min", 0.)
        clip_max = distribution_args.get("clip_max", 1.)

        # add noise
        noise = np.random.normal(loc=0, scale=1, size=x.shape)
        noisy_x = np.clip((x + noise * eta), clip_min, clip_max)
        x_trans = noisy_x.reshape(x.shape)

    elif transformation == TRANSFORMATION_DISTRIBUTION.TRANSLATION.value:
        # randomly translate the input
        trans_args = {
            "type": "shift",
            "subtype": "",
            "id": -1,
        }

        # interval of translation offsets
        min_offset = distribution_args.get("min_offset", -0.20)
        max_offset = distribution_args.get("max_offset", 0.20)
        # random offsets in x- and y-axis
        x_offset = random.uniform(min_offset, max_offset)
        y_offset = random.uniform(min_offset, max_offset)
        trans_args["x_offset"] = x_offset
        trans_args["y_offset"] = y_offset
        trans_args["description"] = "shift[{},{}]".format(x_offset, y_offset)
        x_trans = transform(x, trans_args)[0]

    elif transformation == TRANSFORMATION_DISTRIBUTION.AFFINE.value:
        # apply random affine transformation
        trans_args = {
            "type": "affine",
            "subtype": "",
            "id": -1,
        }

        # interval of transformation offsets
        min_offset = distribution_args.get("min_offset", 0.1)
        max_offset = distribution_args.get("max_offset", 0.5)

        if min_offset <= 0 or max_offset <= 0:
            raise ValueError(
                "`min_offset` and `max_offset` must be positive, but found {} and {}."
                .format(min_offset, max_offset))

        if min_offset >= max_offset:
            raise ValueError(
                "`min_offset` must be less than `max_offset`, but found {} and {}."
                .format(min_offset, max_offset))

        # apply random affine transformation
        op1 = random.uniform(min_offset, max_offset)
        op2 = random.uniform(min_offset, max_offset)
        origin_point1 = distribution_args.get("origin_point1", (op1, op1))
        origin_point2 = distribution_args.get("origin_point2", (op1, op2))
        origin_point3 = distribution_args.get("origin_point3", (op2, op1))
        np1 = random.uniform(min_offset, max_offset)
        np2 = random.uniform(min_offset, max_offset)
        np3 = random.uniform(min_offset, max_offset)
        np4 = random.uniform(min_offset, max_offset)
        new_point1 = distribution_args.get("new_point1", (np1, np2))
        new_point2 = distribution_args.get("new_point2", (np1, np3))
        new_point3 = distribution_args.get("new_point3", (np4, np2))

        trans_args["origin_point1"] = origin_point1
        trans_args["origin_point2"] = origin_point2
        trans_args["origin_point3"] = origin_point3
        trans_args["new_point1"] = new_point1
        trans_args["new_point2"] = new_point2
        trans_args["new_point3"] = new_point3
        trans_args["description"] = "affine[{},{},{};{},{},{}]".format(
            origin_point1, origin_point2, origin_point3, new_point1,
            new_point2, new_point3)

        x_trans = transform(x, trans_args)[0]

    else:
        raise ValueError(
            "Distribution {} is not supported.".format(transformation))

    # if channel_index == 1:
    #     x_trans = set_channels_first(x_trans)

    return x_trans.astype(np.float32)