示例#1
0
def set_threshold(i, c_id, th_val):
    """
        Sets the thresold of a Trigger to th_val
        :param i: Ensemble of models (system) representing an individual
        :param c_id: Classifier affected
        :param step: Value to which increment or decrement the threshold
        :return: Nothing
        """

    c_file = i.get(c_id).classifier_file
    if i.get(c_id).component_id != '':

        trigger_id = i.get(c_id).component_id
        trigger_old = i.get(trigger_id)
        assert trigger_old.DESCRIPTOR.name == "Trigger", "Classifiers should be connected to triggers in the chain"

        trigger_name = "trigger_classifier_" + str(th_val) + "_" + c_id
        trigger_classifier_file = os.path.join(os.environ['FCM'], os.environ['TMP'], trigger_name + '.pkl')

        if not os.path.exists(trigger_classifier_file):
            data = __make_data_and_dataset(i, trigger_name, c_file, th_val)
            i.replace(trigger_old.classifier.data_id, data)
            trigger = make.make_trigger(trigger_name,
                                        make.make_empty_classifier(id="", data_id=data.id),
                                        component_ids=trigger_old.component_ids, model="probability")
        else:
            i.remove(trigger_old.classifier.data_id)  # Remove old data if exists
            trigger = make.make_trigger(trigger_name,
                                        make.make_classifier('', classifier_file=trigger_classifier_file),
                                        component_ids=trigger_old.component_ids)
        i.replace(trigger_old.id, trigger)
        c = i.get(c_id)
        c.component_id = trigger_name
        i.replace(c_id, c)
示例#2
0
def replace_classifier(i, c_id, c_id_new, c_file = None, trigger_name = None):

    """
    Replaces a classifier in the chain for a new classifier
    :param i: Ensemble of models (system) representing an individual
    :param c_id: Classifier's id to be replaced
    :param c_id_new: Classifier's id that replaces
    :return: Nothing
    """

    c_file = c_id_new if c_file is None else c_file
    existing_classifier_id = [c.id for c in i.get_message().classifier]

    if c_id_new not in existing_classifier_id:
        classifier = make.make_classifier(c_id_new, c_file)
        if i.get(c_id).component_id != '':

            # Check it is a trigger
            trigger_id = i.get(c_id).component_id
            assert i.get(trigger_id).DESCRIPTOR.name == "Trigger", \
                "ERROR: Classifier in chain should be connected to trigger"

            # Replace previous data component on the system for the new one
            trigger_classifier_old = i.get(trigger_id).classifier
            old_data_id = trigger_classifier_old.data_id
            th = float(trigger_id.split("_")[2])

            trigger_name = "trigger_classifier_" + str(th) + "_" + c_id_new
            trigger_classifier_file = os.path.join(os.environ['FCM'], os.environ['TMP'], trigger_name+'.pkl')

            if not os.path.exists(trigger_classifier_file):
                data = __make_data_and_dataset(i, trigger_name, c_file, th)
                i.replace(old_data_id, data)
                trigger = make.make_trigger(trigger_name, make.make_empty_classifier(id="", data_id=data.id),
                                            component_ids=i.get(trigger_id).component_ids, model="probability")
            else:
                trigger = make.make_trigger(trigger_name,
                                            make.make_classifier('', classifier_file=trigger_classifier_file),
                                            component_ids=i.get(trigger_id).component_ids)
            i.replace(trigger_id, trigger)

            # Link replacing classifier to trigger
            classifier.component_id = trigger_name

        # Replace classifier
        i.replace(c_id, classifier)

        # If first classifier, point at it
        if i.get_start() == c_id:
            i.set_start(c_id_new)

        # Get trigger connected to the old classifier
        trigger_names = i.get_message().trigger  # All triggers from the ensemble
        for trigger in trigger_names:
            trigger = i.get(trigger.id)
            for ic, c in enumerate(trigger.component_ids):
                if c_id == c:
                    trigger.component_ids[ic] = c_id_new
                    i.replace(trigger.id, trigger)
示例#3
0
def extend_chain_pt(i, c_id, th=None, c_file = None, trigger_name=None):

    """
    Extends the chain with a probability trigger and a classifier
    :param i: Ensemble of models (system) representing an individual
    :param c_id: Classifier to attach at the end fo the chain
    :param th: Threshold of the trigger
    :return: Nothing
    """

    th = 0.5 if th is None else th
    c_file = c_id if c_file is None else c_file
    existing_classifier_id = [c.id for c in i.get_message().classifier]

    if c_id not in existing_classifier_id:  # Add classifier if not present previously in the chain

        # Get the last model in the chain
        for c in i.get_message().classifier:
            if c.component_id == "":
                last_id = c.id

        # Create dataset for new trigger if trigger's classifier not existing
        trigger_name = "trigger_classifier_" + str(th) + "_" + last_id
        trigger_classifier_file = os.path.join(os.environ['FCM'], os.environ['TMP'], trigger_name+'.pkl')

        if not os.path.exists(trigger_classifier_file):
            data = __make_data_and_dataset(i, trigger_name, i.get(last_id).classifier_file, th)
            i.add_data(data)
            trigger = make.make_trigger(trigger_name, make.make_empty_classifier(id="", data_id=data.id), component_ids=[c_id], model="probability")
        else:
            trigger = make.make_trigger(trigger_name, make.make_classifier('', trigger_classifier_file), component_ids=[c_id])

        i.add_trigger(trigger)

        # Create new mutated classifier
        classifier = make.make_classifier(c_id, c_file)
        i.add_classifier(classifier)

        # Update last classifier to connect to trigger
        last_classifier = i.get(last_id)
        last_classifier.component_id = trigger_name
        i.replace(last_id, last_classifier)
示例#4
0
def extend_merged_chain(i, c_id_tail, c_id_new, th, c_file_new=None):

    """
    :param i: Individual
    :param c_id_tail: Last classifier at the chain
    :param c_id_new: Id of new last classifier at the chain
    :param th: Threshold value of the new trigger
    :param c_file_new: File location of the classifier at the chain
    :param t_id: Id of the new trigger
    :return: Nothing
    """

    existing_classifier_id = [c.id for c in i.get_message().classifier]

    if c_id_new not in existing_classifier_id:

        # Add new classifier to the ensemble
        c_file = c_id_new if c_file_new is None else c_file_new
        classifier = make.make_classifier(c_id_new, c_file)
        i.add_classifier(classifier)

        # Build the trigger
        trigger_name = "trigger_classifier_" + str(th) + "_" + c_id_tail
        trigger_classifier_file = os.path.join(os.environ['FCM'], os.environ['TMP'], trigger_name + '.pkl')

        if not os.path.exists(trigger_classifier_file):
            data = __make_data_and_dataset(i, trigger_name, i.get(c_id_tail).classifier_file, th)
            i.add_data(data)
            trigger = make.make_trigger(trigger_name, make.make_empty_classifier(id="", data_id=data.id),
                                        component_ids=[c_id_new], model="probability")
        else:
            trigger = make.make_trigger(trigger_name, make.make_classifier('', trigger_classifier_file),
                                        component_ids=[c_id_new])

        i.add_trigger(trigger)

        # Connect the (old) last classifier to the trigger
        last_classifier = i.get(c_id_tail)
        last_classifier.component_id = trigger_name
        i.replace(c_id_tail, last_classifier)
def build_chain(classifiers, id_classifiers, thresholds, id_triggers, data_id):

    assert len(classifiers) == len(
        id_triggers
    ) + 1, "ERROR: Number of triggers in the chain is not consistent"
    assert len(id_triggers) == len(
        thresholds), "ERROR: Each trigger should be assigned a threshold"
    assert len(classifiers) == len(
        id_classifiers
    ), "ERROR: Each classifier file should be assigned a classifier id"

    data_path = os.path.join(os.environ['FCM'], 'Data', data_id)

    if not os.path.exists(data_path):
        os.makedirs(data_path)

    sys = sb.SystemBuilder(verbose=False)
    for i in range(len(classifiers) - 1):

        # Create data for the trigger
        train_path = os.path.join(data_path, id_triggers[i] + "_test.pkl")
        test_path = os.path.join(data_path, id_triggers[i] + "_train.pkl")
        val_path = os.path.join(data_path, id_triggers[i] + "_val.pkl")
        source = make.make_source(train_path, test_path, 2, val_path=val_path)
        data = make.make_data("data_" + id_triggers[i], 1, 1, source=source)
        update_dataset(classifiers[i], train_path, test_path, val_path,
                       thresholds[i])
        sys.add_data(data)

        # Build trigger attached to classifier
        trigger = make.make_trigger(id_triggers[i],
                                    make.make_empty_classifier(
                                        id='',
                                        data_id="data_" + id_triggers[i]),
                                    [id_classifiers[i + 1]],
                                    model="probability")
        sys.add_trigger(trigger)

        # Build classifier
        c_file = classifiers[i]
        classifier = make.make_classifier(id_classifiers[i],
                                          c_file,
                                          component_id=id_triggers[i])
        sys.add_classifier(classifier)

        if i == 0:
            sys.set_start(id_classifiers[i])

    classifier = make.make_classifier(id_classifiers[-1], classifiers[-1])
    sys.add_classifier(classifier)
    return sys
示例#6
0
def evaluate(work, records, tid):
    lock = Lock()
    while True:

        m, th, m_ = work.get()
        print(m, th, m_)

        small_dict = io.read_pickle(m)
        test_images = len(small_dict['test']['gt'])
        train_images = len(small_dict['train']['gt'])
        data_path = "../../Data/"
        trigger_train_dataset = os.path.join(data_path,
                                             "train_trigger_" + str(tid))
        test_train_dataset = os.path.join(data_path,
                                          "test_trigger_" + str(tid))

        sys = sb.SystemBuilder(verbose=False)

        # Complex classifier
        bigClassifier = make.make_classifier("big", m_)
        sys.add_classifier(bigClassifier)

        # Data
        source = make.make_source(trigger_train_dataset, test_train_dataset, 2)
        data = make.make_data("trigger_data",
                              train_images,
                              test_images,
                              source=source)
        sys.add_data(data)
        update_dataset(m, th, trigger_train_dataset, test_train_dataset)

        # Trigger
        trigger = make.make_trigger(
            "trigger",
            make.make_empty_classifier(data_id="trigger_data"), ["big"],
            model="probability")
        sys.add_trigger(trigger)

        # Simple classifier
        smallClassifier = make.make_classifier("small", m, "trigger")
        sys.add_classifier(smallClassifier)

        results = eval.evaluate(sys, "small", check_classifiers=False)
        records["system_" + m + ';' + m_ + ';' + str(th)] = results.test

        lock.acquire()
        if m_ not in records:  # Evaluate individual models in order to plot
            records[m_] = eval.evaluate(sys, 'big').test
        lock.release()

        work.task_done()
示例#7
0

net1 = 'system_DenseNet201_cifar10.pkl_ResNet152_cifar10.pklth=0.7'
net2 = 'GoogleNet_cifar10.pkl'
m = Classifier_Path + net1
m_ = Classifier_Path + net2
th = 0.7

sys = sb.SystemBuilder(verbose=True)

name2 = m_
bigClassifier = make.make_empty_classifier("big")
bigClassifier.classifier_file = name2
sys.add_classifier(bigClassifier)

trigger = make.make_trigger("probability_threshold_trigger",
                            make.make_empty_classifier(), ["big"])
sys.add_trigger(trigger)

name1 = m
smallClassifier = make.make_empty_classifier("small",
                                             "probability_threshold_trigger")
model1_dict = io.read_pickle(name1, suffix="", verbose=False)
smallClassifier.classifier_file = name1
sys.add_classifier(smallClassifier)

classifier_trigger = build_train_trigger(model1_dict, th)
trigger = make.make_trigger("probability_threshold_trigger",
                            classifier_trigger, ["big"])
trigger.id = "probability_threshold_trigger"
sys.replace(trigger.id, trigger)
    small_cfile = "../Definitions/Classifiers/DenseNet121_cifar10"
    big_cfile = "../Definitions/Classifiers/DenseNet201_cifar10"
    th = 0.9

    sys = sb.SystemBuilder(verbose=False)

    bigClassifier = make.make_classifier("big", big_cfile)
    sys.add_classifier(bigClassifier)

    source = make.make_source(train_path, test_path, fcm.Data.Source.NUMPY)
    data = make.make_data("trigger_data", int(5e4), int(1e4), source=source)
    sys.add_data(data)
    update_dataset(small_cfile, th, train_path, test_path)

    trigger = make.make_trigger(
        "trigger",
        make.make_empty_classifier(data_id="trigger_data"), ["big"],
        model="probability")
    sys.add_trigger(trigger)

    smallClassifier = make.make_classifier("small", small_cfile, "trigger")
    sys.add_classifier(smallClassifier)

    r = eval.evaluate(sys, "small")
    eval.pretty_print(r)
    print(r.test['system'].instance_model)

    time = 0
    time_small = io.read_pickle(small_cfile)['metrics']['time'] / 128
    time_big = io.read_pickle(big_cfile)['metrics']['time'] / 128
    for id, model in r.test['system'].instance_model.items():
        time += time_small if len(model) == 1 else time_small + time_big

if __name__ == "__main__":

    small_cfile = "../Definitions/Classifiers/V001_DenseNet_s1_39"
    big_cfile = "../Definitions/Classifiers/V001_DenseNet_s1_80"
    c_dict_big = io.read_pickle(big_cfile)
    c_dict_small = io.read_pickle(small_cfile)
    th = 1.1

    # Building system skeleton
    sys = sb.SystemBuilder(verbose=False)
    big_classifier = make.make_classifier("big", big_cfile)
    sys.add_classifier(big_classifier)
    c = build_train_trigger(c_dict_small, th)
    trigger = make.make_trigger("trigger", c, ["big"])
    sys.add_trigger(trigger)
    small_classifier = make.make_classifier("small", small_cfile, "trigger")
    sys.add_classifier(small_classifier)

    # Test that times are consistent
    classifier, evaluation = sys.build_classifier_dict("built", "small")
    import Source.system_evaluator_utils as eval_utils
    eval_utils.pretty_print(evaluation)

    # assert (classifier['test']['time_instance'] == (c_dict_small['metrics']['time'] + c_dict_big['metrics']['time']/128.0)).all()
    print("All good with time!")
    acc_test = sum(
        np.argmax(classifier['test']['logits'], axis=1) == classifier['test']
        ['gt']) / 1e4
    assert (acc_test == evaluation.test['system'].accuracy)
    trigger0_train_dataset = os.path.join(data_path, "train_trigger0")
    trigger0_test_dataset = os.path.join(data_path, "test_trigger0")
    trigger1_train_dataset = os.path.join(data_path, "train_trigger1")
    trigger1_test_dataset = os.path.join(data_path, "test_trigger1")
    c0_file = "../Definitions/Classifiers/sota_models_gtsrb-32-dev_validation/V001_VGG13_ref_0.pkl"
    c1_file = "../Definitions/Classifiers/sota_models_gtsrb-32-dev_validation/V001_ResNet34_ref_0.pkl"
    c2_file = "../Definitions/Classifiers/sota_models_gtsrb-32-dev_validation/V001_DenseNet121_ref_0.pkl"

    # Classifier/Trigger 0
    c0 = make.make_classifier("c0", c0_file, component_id="trigger0")
    sys.add_classifier(c0)
    source = make.make_source(trigger0_train_dataset, trigger0_test_dataset, 2)
    data0 = make.make_data("trigger0_data", int(5e4), int(1e4), source=source)
    sys.add_data(data0)
    trigger0 = make.make_trigger(
        "trigger0",
        make.make_empty_classifier(data_id="trigger0_data"), ["c1", "c2"],
        model="probability_multiple_classifiers")
    sys.add_trigger(trigger0)

    # Classifier/Trigger 1
    source = make.make_source(trigger1_train_dataset, trigger1_test_dataset, 2)
    data1 = make.make_data("trigger1_data", int(5e4), int(1e4), source=source)
    sys.add_data(data1)
    update_dataset(c1_file, [0], trigger1_train_dataset, trigger1_test_dataset)
    trigger1 = make.make_trigger(
        "trigger1",
        make.make_empty_classifier(data_id="trigger1_data"), ["c2"],
        model="probability_multiple_classifiers")
    c1 = make.make_classifier("c1", c1_file, component_id="trigger1")
    sys.add_classifier(c1)
    sys.add_trigger(trigger1)
示例#11
0
    classifier = make.make_classifier(
        "trigger_classifier",
        "../../Definitions/Classifiers/tmp/trigger_random_threshold")
    return classifier


if __name__ == "__main__":

    Classifier_Path = "../../Definitions/Classifiers/front45_models/"
    R = {}

    # Creating system
    sys = sb.SystemBuilder(verbose=False)
    bigClassifier = make.make_empty_classifier("big")
    sys.add_classifier(bigClassifier)
    trigger = make.make_trigger("probability_threshold_trigger",
                                make.make_empty_classifier(), ["big"])
    sys.add_trigger(trigger)
    smallClassifier = make.make_empty_classifier(
        "small", "probability_threshold_trigger")
    sys.add_classifier(smallClassifier)

    # Selecting models
    import os
    model_names = [f for f in os.listdir(Classifier_Path) if ".pkl" in f]
    models = [io.read_pickle(Classifier_Path + name) for name in model_names]
    for i, model in enumerate(models):
        model['name'] = model_names[i]
    models_sorted = sorted(models, key=lambda item: item['metrics']['params'])

    pairs = 6
    indices = list(