Esempio n. 1
0
    def _run_single_set(self, param):
        """Run TCAV with provided for one set of (target, concepts).
        Args:
          param: parameters to run
        Returns:
          a dictionary of results (panda frame)
        """
        bottleneck = param.bottleneck
        concepts = param.concepts
        target_class = param.target_class
        activation_generator = param.activation_generator
        alpha = param.alpha
        mymodel = param.model
        cav_dir = param.cav_dir
        
        # Get acts
        acts = activation_generator.process_and_load_activations(
            [bottleneck], concepts + [target_class])
        # Get CAVs
        cav_hparams = CAV.default_hparams()
        cav_hparams.alpha = alpha
        cav_instance = get_or_train_cav(
            concepts, bottleneck, acts, cav_dir=cav_dir,
            cav_hparams=cav_hparams)

        # clean up
        for c in concepts:
            del acts[c]

        # Hypo testing
        a_cav_key = CAV.cav_key(concepts, bottleneck, cav_hparams.model_type,
                                cav_hparams.alpha)
        target_class_for_compute_tcav_score = target_class

        for cav_concept in concepts:
            if cav_concept is self.random_counterpart or 'random' not in cav_concept:
                i_up = self.compute_tcav_score(
                    mymodel, target_class_for_compute_tcav_score, cav_concept,
                    cav_instance, acts[target_class][cav_instance.bottleneck])
                val_directional_dirs = self.get_directional_dir(
                    mymodel, target_class_for_compute_tcav_score, cav_concept,
                    cav_instance, acts[target_class][cav_instance.bottleneck])
                result = {'cav_key' : a_cav_key, 'cav_concept' : cav_concept,
                          'target_class' : target_class, 'i_up' : i_up,
                          'val_directional_dirs_abs_mean' :
                          np.mean(np.abs(val_directional_dirs)), 
                          'val_directional_dirs_mean' :
                          np.mean(val_directional_dirs),
                          'val_directional_dirs_std' :
                          np.std(val_directional_dirs),
                          'note' : 'alpha_%s ' % (alpha),
                          'alpha' : alpha,
                          'bottleneck' : bottleneck}
        del acts
        return result
Esempio n. 2
0
    def setUp(self):
        """Makes a cav instance and writes it to tmp direcotry.

    The cav instance uses preset values.
    """
        self.hparams = tf.contrib.training.HParams(model_type='linear',
                                                   alpha=.01)
        self.concepts = ['concept1', 'concept2']
        self.bottleneck = 'bottleneck'
        self.accuracies = {'concept1': 0.8, 'concept2': 0.5, 'overall': 0.65}
        self.cav_vecs = [[1, 2, 3], [4, 5, 6]]

        self.test_subdirectory = os.path.join(FLAGS.test_tmpdir, 'test')
        self.cav_dir = self.test_subdirectory
        self.cav_file_name = CAV.cav_key(self.concepts, self.bottleneck,
                                         self.hparams.model_type,
                                         self.hparams.alpha) + '.pkl'
        self.save_path = os.path.join(self.cav_dir, self.cav_file_name)
        self.cav = CAV(self.concepts, self.bottleneck, self.hparams)
        # pretend that it was trained and cavs are stored
        self.cav.cavs = np.array(self.cav_vecs)
        shape = (1, 3)
        self.acts = {
            concept: {
                self.bottleneck: np.tile(i * np.ones(shape), (4, 1))
            }
            for i, concept in enumerate(self.concepts)
        }

        if os.path.exists(self.cav_dir):
            shutil.rmtree(self.cav_dir)
        os.mkdir(self.cav_dir)
        with open(self.save_path, 'w') as pkl_file:
            pickle.dump(
                {
                    'concepts': self.concepts,
                    'bottleneck': self.bottleneck,
                    'hparams': self.hparams,
                    'accuracies': self.accuracies,
                    'cavs': self.cav_vecs,
                    'saved_path': self.save_path
                }, pkl_file)
Esempio n. 3
0
class CavTest(googletest.TestCase):
    def setUp(self):
        """Makes a cav instance and writes it to tmp direcotry.

    The cav instance uses preset values.
    """
        self.hparams = tf.contrib.training.HParams(model_type='linear',
                                                   alpha=.01)
        self.concepts = ['concept1', 'concept2']
        self.bottleneck = 'bottleneck'
        self.accuracies = {'concept1': 0.8, 'concept2': 0.5, 'overall': 0.65}
        self.cav_vecs = [[1, 2, 3], [4, 5, 6]]

        self.test_subdirectory = os.path.join(FLAGS.test_tmpdir, 'test')
        self.cav_dir = self.test_subdirectory
        self.cav_file_name = CAV.cav_key(self.concepts, self.bottleneck,
                                         self.hparams.model_type,
                                         self.hparams.alpha) + '.pkl'
        self.save_path = os.path.join(self.cav_dir, self.cav_file_name)
        self.cav = CAV(self.concepts, self.bottleneck, self.hparams)
        # pretend that it was trained and cavs are stored
        self.cav.cavs = np.array(self.cav_vecs)
        shape = (1, 3)
        self.acts = {
            concept: {
                self.bottleneck: np.tile(i * np.ones(shape), (4, 1))
            }
            for i, concept in enumerate(self.concepts)
        }

        if os.path.exists(self.cav_dir):
            shutil.rmtree(self.cav_dir)
        os.mkdir(self.cav_dir)
        with open(self.save_path, 'w') as pkl_file:
            pickle.dump(
                {
                    'concepts': self.concepts,
                    'bottleneck': self.bottleneck,
                    'hparams': self.hparams,
                    'accuracies': self.accuracies,
                    'cavs': self.cav_vecs,
                    'saved_path': self.save_path
                }, pkl_file)

    def test_default_hparams(self):
        hparam = CAV.default_hparams()
        self.assertEqual(hparam.alpha, 0.01)
        self.assertEqual(hparam.model_type, 'linear')

    def test_load_cav(self):
        """Load up the cav file written in setup function and check values.
    """
        cav_instance = CAV.load_cav(self.save_path)
        self.assertEqual(cav_instance.concepts, self.concepts)
        self.assertEqual(cav_instance.cavs, self.cav_vecs)

    def test_cav_key(self):
        self.assertEqual(
            self.cav.cav_key(self.concepts, self.bottleneck,
                             self.hparams.model_type, self.hparams.alpha),
            '-'.join(self.concepts) + '-' + self.bottleneck + '-' +
            self.hparams.model_type + '-' + str(self.hparams.alpha))

    def test_check_cav_exists(self):
        exists = self.cav.check_cav_exists(self.cav_dir, self.concepts,
                                           self.bottleneck, self.hparams)
        self.assertTrue(exists)

    def test__create_cav_training_set(self):
        x, labels, labels2text = self.cav._create_cav_training_set(
            self.concepts, self.bottleneck, self.acts)
        # check values of some elements.
        self.assertEqual(x[0][0], 0)
        self.assertEqual(x[5][0], 1)
        self.assertEqual(labels[0], 0)
        self.assertEqual(labels[5], 1)
        self.assertEqual(labels2text[0], 'concept1')

    def test_perturb_act(self):
        perturbed = self.cav.perturb_act(np.array([1., 0, 1.]),
                                         'concept1',
                                         operation=np.add,
                                         alpha=1.0)
        self.assertEqual(2., perturbed[0])
        self.assertEqual(2., perturbed[1])
        self.assertEqual(4., perturbed[2])

    def test_get_key(self):
        self.assertEqual(
            CAV.cav_key(self.concepts, self.bottleneck,
                        self.hparams.model_type, self.hparams.alpha),
            '-'.join([str(c) for c in self.concepts]) + '-' + self.bottleneck +
            '-' + self.hparams.model_type + '-' + str(self.hparams.alpha))

    def test_get_direction(self):
        idx_concept1 = self.cav.concepts.index('concept1')
        cav_directly_from_member = self.cav.cavs[idx_concept1]
        cav_via_get_direction = self.cav.get_direction('concept1')
        for i in xrange(len(cav_directly_from_member)):
            self.assertEqual(cav_directly_from_member[i],
                             cav_via_get_direction[i])

    def test_train(self):
        self.cav.train({c: self.acts[c] for c in self.concepts})
        # check values of some elements.
        # the two coefficients of the classifier must be negative.
        self.assertLess(self.cav.cavs[0][0] * self.cav.cavs[1][0], 0)

    def test__train_lm(self):
        lm = linear_model.SGDClassifier(alpha=self.hparams.alpha)
        acc = self.cav._train_lm(lm, np.array([[0], [0], [0], [1], [1], [1]]),
                                 np.array([0, 0, 0, 1, 1, 1]), {
                                     0: 0,
                                     1: 1
                                 })
        # the given data is so easy it should get this almost perfect.
        self.assertGreater(acc[0], 0.99)
        self.assertGreater(acc[1], 0.99)

    def test_get_or_train_cav_save_test(self):
        cav_instance = get_or_train_cav(self.concepts,
                                        self.bottleneck,
                                        self.acts,
                                        cav_dir=self.cav_dir,
                                        cav_hparams=self.hparams)
        # check values of some elements.
        self.assertEqual(cav_instance.cavs[0][0], self.cav_vecs[0][0])
        self.assertEqual(cav_instance.cavs[1][2], self.cav_vecs[1][2])
Esempio n. 4
0
 def test_get_key(self):
     self.assertEqual(
         CAV.cav_key(self.concepts, self.bottleneck,
                     self.hparams.model_type, self.hparams.alpha),
         '-'.join([str(c) for c in self.concepts]) + '-' + self.bottleneck +
         '-' + self.hparams.model_type + '-' + str(self.hparams.alpha))
Esempio n. 5
0
    def _run_single_set(self, params):
        """
		Run TCAV with provided for one set of (target, concepts).

		:param params: parameters to run
		:return: a dict of results (pandas dataframe)
		"""
        bottleneck = params.bottleneck
        concepts = params.concepts
        target_class = params.target_class
        activation_generator = params.activation_generator
        alpha = params.alpha
        black_box = params.black_box
        cav_dir = params.cav_dir

        tf.logging.info('running %s %s' % (target_class, concepts))

        acts = activation_generator(black_box, bottlenecks,
                                    concepts + [target_class])
        cav_hparams = CAV.default_hparams()
        cav_hparams.alpha = alpha
        cav_instance = get_or_train_cav(concepts,
                                        bottlenecks,
                                        acts,
                                        cav_dir=cav_dir,
                                        cav_hparams=cav_hparams)

        for concept in concepts:
            del acts[concept]

        a_cav_key = CAV.cav_key(concepts, bottlenecks, cav_hparams.model_type,
                                cav_hparams.alpha)
        target_class_for_compute_tcav_score = target_class

        for cav_concept in concepts:
            if cav_concept is self.random_counterpart or 'random' not in cav_concept:
                i_up = self.compute_tcav_score(
                    black_box, target_class_for_compute_tcav_score,
                    cav_concept.cav_instance,
                    acts[target_class][cav_instance.bottleneck])
                val_dir_derivatives = self.get_dir_derivative(
                    black_box, target_class_for_compute_tcav_score,
                    cav_concept.cav_instance,
                    acts[target_class][cav_instance.bottleneck])
                result = {
                    'cav_key':
                    a_cav_key,
                    'cav_concept':
                    cav_concept,
                    'target_class':
                    target_class,
                    'i_up':
                    i_up,
                    'val_dir_derivatives_abs_mean':
                    np.mean(np.abs(val_dir_derivatives)),
                    'val_dir_derivatives_mean':
                    np.mean(val_dir_derivatives),
                    'val_dir_derivatives_std':
                    np.std(val_dir_derivatives),
                    'note':
                    'alpha_%s' % (alpha),
                    'alpha':
                    alpha,
                    'bottleneck':
                    bottlenecks
                }
        del acts
        return result