Ejemplo n.º 1
0
 def __init__(self, initial_seeds, target_model, train_dataset, const_K,
              mode='L', max_seed_num=1000):
     self.initial_seeds = initial_seeds
     self.target_model = check_model('model', target_model, Model)
     self.train_dataset = check_numpy_param('train_dataset', train_dataset)
     self.const_k = check_int_positive('const_k', const_K)
     self.mode = mode
     self.max_seed_num = check_int_positive('max_seed_num', max_seed_num)
     self.coverage_metrics = ModelCoverageMetrics(target_model, 1000, 10,
                                                  train_dataset)
Ejemplo n.º 2
0
def test_lenet_mnist_fuzzing():
    # upload trained network
    ckpt_name = './trained_ckpt_file/checkpoint_lenet-10_1875.ckpt'
    net = LeNet5()
    load_dict = load_checkpoint(ckpt_name)
    load_param_into_net(net, load_dict)
    model = Model(net)

    # get training data
    data_list = "./MNIST_unzip/train"
    batch_size = 32
    ds = generate_mnist_dataset(data_list, batch_size, sparse=True)
    train_images = []
    for data in ds.create_tuple_iterator():
        images = data[0].astype(np.float32)
        train_images.append(images)
    train_images = np.concatenate(train_images, axis=0)

    # initialize fuzz test with training dataset
    model_coverage_test = ModelCoverageMetrics(model, 1000, 10, train_images)

    # fuzz test with original test data
    # get test data
    data_list = "./MNIST_unzip/test"
    batch_size = 32
    ds = generate_mnist_dataset(data_list, batch_size, sparse=True)
    test_images = []
    test_labels = []
    for data in ds.create_tuple_iterator():
        images = data[0].astype(np.float32)
        labels = data[1]
        test_images.append(images)
        test_labels.append(labels)
    test_images = np.concatenate(test_images, axis=0)
    test_labels = np.concatenate(test_labels, axis=0)
    initial_seeds = []

    # make initial seeds
    for img, label in zip(test_images, test_labels):
        initial_seeds.append([img, label])

    initial_seeds = initial_seeds[:100]
    model_coverage_test.test_adequacy_coverage_calculate(
        np.array(test_images[:100]).astype(np.float32))
    LOGGER.info(TAG, 'KMNC of this test is : %s',
                model_coverage_test.get_kmnc())

    model_fuzz_test = Fuzzing(initial_seeds, model, train_images, 20)
    failed_tests = model_fuzz_test.fuzzing()
    if failed_tests:
        model_coverage_test.test_adequacy_coverage_calculate(
            np.array(failed_tests).astype(np.float32))
        LOGGER.info(TAG, 'KMNC of this test is : %s',
                    model_coverage_test.get_kmnc())
    else:
        LOGGER.info(TAG, 'Fuzzing test identifies none failed test')
Ejemplo n.º 3
0
def test_fuzzing_ascend():
    context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")
    # load network
    net = Net()
    model = Model(net)
    batch_size = 8
    num_classe = 10

    # initialize fuzz test with training dataset
    training_data = np.random.rand(32, 1, 32, 32).astype(np.float32)
    model_coverage_test = ModelCoverageMetrics(model, 1000, 10, training_data)

    # fuzz test with original test data
    # get test data
    test_data = np.random.rand(batch_size, 1, 32, 32).astype(np.float32)
    test_labels = np.random.randint(num_classe,
                                    size=batch_size).astype(np.int32)
    test_labels = (np.eye(num_classe)[test_labels]).astype(np.float32)

    initial_seeds = []
    for img, label in zip(test_data, test_labels):
        initial_seeds.append([img, label, 0])
    model_coverage_test.test_adequacy_coverage_calculate(
        np.array(test_data).astype(np.float32))
    LOGGER.info(TAG, 'KMNC of this test is : %s',
                model_coverage_test.get_kmnc())

    model_fuzz_test = Fuzzing(initial_seeds,
                              model,
                              training_data,
                              5,
                              max_seed_num=10)
    failed_tests = model_fuzz_test.fuzzing()
    model_coverage_test.test_adequacy_coverage_calculate(
        np.array(failed_tests).astype(np.float32))
    LOGGER.info(TAG, 'KMNC of this test is : %s',
                model_coverage_test.get_kmnc())
Ejemplo n.º 4
0
def test_lenet_mnist_coverage_cpu():
    context.set_context(mode=context.GRAPH_MODE, device_target="CPU")
    # load network
    net = Net()
    model = Model(net)

    # initialize fuzz test with training dataset
    training_data = (np.random.random((10000, 10))*20).astype(np.float32)
    model_fuzz_test = ModelCoverageMetrics(model, 10000, 10, training_data)

    # fuzz test with original test data
    # get test data
    test_data = (np.random.random((2000, 10))*20).astype(np.float32)
    test_labels = np.random.randint(0, 10, 2000).astype(np.int32)
    model_fuzz_test.test_adequacy_coverage_calculate(test_data)
    LOGGER.info(TAG, 'KMNC of this test is : %s', model_fuzz_test.get_kmnc())
    LOGGER.info(TAG, 'NBC of this test is : %s', model_fuzz_test.get_nbc())
    LOGGER.info(TAG, 'SNAC of this test is : %s', model_fuzz_test.get_snac())

    # generate adv_data
    loss = SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True)
    attack = FastGradientSignMethod(net, eps=0.3, loss_fn=loss)
    adv_data = attack.batch_generate(test_data, test_labels, batch_size=32)
    model_fuzz_test.test_adequacy_coverage_calculate(adv_data,
                                                     bias_coefficient=0.5)
    LOGGER.info(TAG, 'KMNC of this test is : %s', model_fuzz_test.get_kmnc())
    LOGGER.info(TAG, 'NBC of this test is : %s', model_fuzz_test.get_nbc())
    LOGGER.info(TAG, 'SNAC of this test is : %s', model_fuzz_test.get_snac())
Ejemplo n.º 5
0
def test_lenet_mnist_coverage_ascend():
    context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")
    # load network
    net = Net()
    model = Model(net)

    # initialize fuzz test with training dataset
    training_data = (np.random.random((10000, 10))*20).astype(np.float32)
    model_fuzz_test = ModelCoverageMetrics(model, 10000, 10, training_data)

    # fuzz test with original test data
    # get test data
    test_data = (np.random.random((2000, 10))*20).astype(np.float32)
    test_labels = np.random.randint(0, 10, 2000)
    test_labels = (np.eye(10)[test_labels]).astype(np.float32)
    model_fuzz_test.test_adequacy_coverage_calculate(test_data)
    LOGGER.info(TAG, 'KMNC of this test is : %s', model_fuzz_test.get_kmnc())
    LOGGER.info(TAG, 'NBC of this test is : %s', model_fuzz_test.get_nbc())
    LOGGER.info(TAG, 'SNAC of this test is : %s', model_fuzz_test.get_snac())

    # generate adv_data
    attack = FastGradientSignMethod(net, eps=0.3)
    adv_data = attack.batch_generate(test_data, test_labels, batch_size=32)
    model_fuzz_test.test_adequacy_coverage_calculate(adv_data,
                                                     bias_coefficient=0.5)
    LOGGER.info(TAG, 'KMNC of this test is : %s', model_fuzz_test.get_kmnc())
    LOGGER.info(TAG, 'NBC of this test is : %s', model_fuzz_test.get_nbc())
    LOGGER.info(TAG, 'SNAC of this test is : %s', model_fuzz_test.get_snac())
Ejemplo n.º 6
0
def test_lenet_mnist_coverage():
    context.set_context(mode=context.GRAPH_MODE, device_target="CPU")
    # upload trained network
    ckpt_name = './trained_ckpt_file/checkpoint_lenet-10_1875.ckpt'
    net = LeNet5()
    load_dict = load_checkpoint(ckpt_name)
    load_param_into_net(net, load_dict)
    model = Model(net)

    # get training data
    data_list = "./MNIST_unzip/train"
    batch_size = 32
    ds = generate_mnist_dataset(data_list, batch_size, sparse=True)
    train_images = []
    for data in ds.create_tuple_iterator():
        images = data[0].astype(np.float32)
        train_images.append(images)
    train_images = np.concatenate(train_images, axis=0)

    # initialize fuzz test with training dataset
    model_fuzz_test = ModelCoverageMetrics(model, 10000, 10, train_images)

    # fuzz test with original test data
    # get test data
    data_list = "./MNIST_unzip/test"
    batch_size = 32
    ds = generate_mnist_dataset(data_list, batch_size, sparse=True)
    test_images = []
    test_labels = []
    for data in ds.create_tuple_iterator():
        images = data[0].astype(np.float32)
        labels = data[1]
        test_images.append(images)
        test_labels.append(labels)
    test_images = np.concatenate(test_images, axis=0)
    test_labels = np.concatenate(test_labels, axis=0)
    model_fuzz_test.test_adequacy_coverage_calculate(test_images)
    LOGGER.info(TAG, 'KMNC of this test is : %s', model_fuzz_test.get_kmnc())
    LOGGER.info(TAG, 'NBC of this test is : %s', model_fuzz_test.get_nbc())
    LOGGER.info(TAG, 'SNAC of this test is : %s', model_fuzz_test.get_snac())

    # generate adv_data
    loss = SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True)
    attack = FastGradientSignMethod(net, eps=0.3, loss_fn=loss)
    adv_data = attack.batch_generate(test_images, test_labels, batch_size=32)
    model_fuzz_test.test_adequacy_coverage_calculate(adv_data,
                                                     bias_coefficient=0.5)
    LOGGER.info(TAG, 'KMNC of this test is : %s', model_fuzz_test.get_kmnc())
    LOGGER.info(TAG, 'NBC of this test is : %s', model_fuzz_test.get_nbc())
    LOGGER.info(TAG, 'SNAC of this test is : %s', model_fuzz_test.get_snac())
Ejemplo n.º 7
0
class Fuzzing:
    """
    Fuzzing test framework for deep neural networks.

    Reference: `DeepHunter: A Coverage-Guided Fuzz Testing Framework for Deep
    Neural Networks <https://dl.acm.org/doi/10.1145/3293882.3330579>`_

    Args:
        initial_seeds (list): Initial fuzzing seed, format: [[image, label, 0],
            [image, label, 0], ...].
        target_model (Model): Target fuzz model.
        train_dataset (numpy.ndarray): Training dataset used for determine
            the neurons' output boundaries.
        const_K (int): The number of mutate tests for a seed.
        mode (str): Image mode used in image transform, 'L' means grey graph.
            Default: 'L'.
    """
    def __init__(self,
                 initial_seeds,
                 target_model,
                 train_dataset,
                 const_K,
                 mode='L',
                 max_seed_num=1000):
        self.initial_seeds = initial_seeds
        self.target_model = check_model('model', target_model, Model)
        self.train_dataset = check_numpy_param('train_dataset', train_dataset)
        self.K = check_int_positive('const_k', const_K)
        self.mode = mode
        self.max_seed_num = check_int_positive('max_seed_num', max_seed_num)
        self.coverage_metrics = ModelCoverageMetrics(target_model, 1000, 10,
                                                     train_dataset)

    def _image_value_expand(self, image):
        return image * 255

    def _image_value_compress(self, image):
        return image / 255

    def _metamorphic_mutate(self, seed, try_num=50):
        if self.mode == 'L':
            seed = seed[0]
        info = [seed, seed]
        mutate_tests = []
        affine_trans = ['Contrast', 'Brightness', 'Blur', 'Noise']
        pixel_value_trans = ['Translate', 'Scale', 'Shear', 'Rotate']
        strages = {
            'Contrast': Contrast,
            'Brightness': Brightness,
            'Blur': Blur,
            'Noise': Noise,
            'Translate': Translate,
            'Scale': Scale,
            'Shear': Shear,
            'Rotate': Rotate
        }
        for _ in range(self.K):
            for _ in range(try_num):
                if (info[0] == info[1]).all():
                    trans_strage = self._random_pick_mutate(
                        affine_trans, pixel_value_trans)
                else:
                    trans_strage = self._random_pick_mutate(affine_trans, [])
                transform = strages[trans_strage](
                    self._image_value_expand(seed), self.mode)
                transform.random_param()
                mutate_test = transform.transform()
                mutate_test = np.expand_dims(
                    self._image_value_compress(mutate_test), 0)

                if self._is_trans_valid(seed, mutate_test):
                    if trans_strage in affine_trans:
                        info[1] = mutate_test
                    mutate_tests.append(mutate_test)
            if len(mutate_tests) == 0:
                mutate_tests.append(seed)
            return np.array(mutate_tests)

    def fuzzing(self, coverage_metric='KMNC'):
        """
        Fuzzing tests for deep neural networks.

        Args:
            coverage_metric (str): Model coverage metric of neural networks.
                Default: 'KMNC'.

        Returns:
            list, mutated tests mis-predicted by target dnn model.
        """
        seed = self._select_next()
        failed_tests = []
        seed_num = 0
        while len(seed) > 0 and seed_num < self.max_seed_num:
            mutate_tests = self._metamorphic_mutate(seed[0])
            coverages, results = self._run(mutate_tests, coverage_metric)
            coverage_gains = self._coverage_gains(coverages)
            for mutate, cov, res in zip(mutate_tests, coverage_gains, results):
                if np.argmax(seed[1]) != np.argmax(res):
                    failed_tests.append(mutate)
                    continue
                if cov > 0:
                    self.initial_seeds.append([mutate, seed[1], 0])
            seed = self._select_next()
            seed_num += 1

        return failed_tests

    def _coverage_gains(self, coverages):
        gains = [0] + coverages[:-1]
        gains = np.array(coverages) - np.array(gains)
        return gains

    def _run(self, mutate_tests, coverage_metric="KNMC"):
        coverages = []
        result = self.target_model.predict(
            Tensor(mutate_tests.astype(np.float32)))
        result = result.asnumpy()
        for index in range(len(mutate_tests)):
            mutate = np.expand_dims(mutate_tests[index], 0)
            self.coverage_metrics.test_adequacy_coverage_calculate(
                mutate.astype(np.float32), batch_size=1)
            if coverage_metric == "KMNC":
                coverages.append(self.coverage_metrics.get_kmnc())

        return coverages, result

    def _select_next(self):
        seed = choice(self.initial_seeds)
        return seed

    def _random_pick_mutate(self, affine_trans_list, pixel_value_trans_list):
        strage = choice(affine_trans_list + pixel_value_trans_list)
        return strage

    def _is_trans_valid(self, seed, mutate_test):
        is_valid = False
        alpha = 0.02
        beta = 0.2
        diff = np.array(seed - mutate_test).flatten()
        size = np.shape(diff)[0]
        L0 = np.linalg.norm(diff, ord=0)
        Linf = np.linalg.norm(diff, ord=np.inf)
        if L0 > alpha * size:
            if Linf < 256:
                is_valid = True
        else:
            if Linf < beta * 255:
                is_valid = True

        return is_valid