def repeated_classifiers(a, b, pointB, level):

    # Point to the head of the chain in the ensemble
    level = level[0:2] if str.isdecimal(level[0]) and level[1] == '_' else ""
    if len(a.get_message().merger) > 0:
        merger = a.get_message().merger[0]
        for m_id in merger.merged_ids:
            if m_id[0:2] == level or (level == "" and not str.isdecimal(m_id[0]) and not m_id[1] == "_"):
                start_chain = m_id
                break
    else:
        start_chain = a.get_start()

    # Store all classifiers in the non-replaced part of the chain
    i = 0
    classifiers = []
    while get_classifier_index(a, i, point=start_chain) is not None:
        classifiers.append(get_classifier_index(a, i, start_chain))
        i+=1
    classifiers += [classifier[2:] for classifier in classifiers]

    # Look for repetitions in classifiers when concatenating the two parts of chain a and chain b
    next = [pointB]
    while len(next) > 0:
        assert len(next) == 1, "ERROR: Support only for chain ensemble with crossover operations"
        next_id = next[0]
        c = b.get(next_id)
        if c.DESCRIPTOR.name == "Classifier":
            if c.id in classifiers or c.id[2:] in classifiers:
                return True
            next = [c.component_id] if c.component_id != '' else []
        elif c.DESCRIPTOR.name == "Trigger":
            next = c.component_ids  # El classificador del trigger ha d'estar entrenat

    return False
Exemplo n.º 2
0
def crossover_operation(P, fit_vals):

    ai = selection.spin_roulette(fit_vals)
    #ai = random.randint(0, len(P) - 1)
    bi = selection.spin_roulette(fit_vals)
    #bi = random.randint(0, len(P) - 1)

    classifiersA = P[ai].get_message().classifier
    classifiersB = P[bi].get_message().classifier

    offspring = []

    if len(classifiersA) > 1 and len(classifiersB) > 1:
        random_number = random.randint(
            0, min(len(classifiersA) - 1,
                   len(classifiersB) - 1))
        pointA = utils.get_classifier_index(P[ai], random_number)
        pointB = utils.get_classifier_index(P[bi], random_number)

        offspring = ob.singlepoint_crossover(P[ai], P[bi], pointA, pointB)
        for o in offspring:
            o.set_sysid(utils.generate_system_id_chain(
                o))  # Create ids for the offspring individuals
            assert len(o.get_message().classifier
                       ) < 4, "ERROR: Offspring > 3 classifiers chain"

    return offspring
def evaluate_population(P, phases=['test', 'val']):

    R = [ev.Results] * len(P)

    if main.args.cores:

        assert main.args.device != 'cpu', "ERROR: Code does not evaluate the chain ensemble on PyTorch w\ CPU"

        from multiprocessing import Process, Manager
        processes = []
        R_manager = Manager().list(R)
        for i in range(main.args.cores):
            processes.append(
                Process(target=evaluate_process,
                        args=(P, i, R_manager, main.args.cores, phases)))
            processes[i].start()
        for i in range(main.args.cores):
            processes[i].join()
        return list(R_manager)

    else:
        for i, p in enumerate(P):
            R[i] = ev.evaluate(p, p.get_start(), phases=phases)

            if main.args.device == 'cpu':
                from Source.iotnets.main_run_chain import chain_inference_time

                classifiers_chain = [utils.get_classifier_index(P[i], 0)] * 3
                ths = [0, 0]

                if len(P[i].get_message().classifier) > 1:
                    c_id = utils.get_classifier_index(P[i], 1)
                    t_id = P[i].get(classifiers_chain[0]).component_id
                    classifiers_chain[1] = c_id
                    ths[0] = float(t_id.split("_")[2])

                if len(P[i].get_message().classifier) > 2:
                    c_id = utils.get_classifier_index(P[i], 2)
                    t_id = P[i].get(classifiers_chain[1]).component_id
                    classifiers_chain[2] = c_id
                    ths[1] = float(t_id.split("_")[2])

                update = R[i]
                if 'val' in phases:
                    update.val['system'].time = chain_inference_time(
                        main.args.dataset,
                        classifiers_chain,
                        ths,
                        bs=128,
                        phase='val')
                if 'test' in phases:
                    update.test['system'].time = chain_inference_time(
                        main.args.dataset,
                        classifiers_chain,
                        ths,
                        bs=128,
                        phase='test')
                R[i] = update

    return R