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
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