def do_add_unit_mutation(self, indi): self.log.info('Do the ADD mutation for indi:%s'%(indi.id)) """ choose one position to add one unit, adding one conv or pooling unit is determined by a probability of 0.5. However, if the maximal number of pooling units have been added into the current individual, only conv unit will be add here """ # determine the position where a unit would be added mutation_position = int(np.floor(np.random.random()*len(indi.units))) self.log.info('Mutation position occurs at %d'%(mutation_position)) # determine the unit type for adding u_ = random.random() type_ = 1 if u_ < 0.5 else 2 self.log.info('A %s unit would be added due to the probability of %.2f'%('CONV' if type_ ==1 else 'POOLING', u_)) if type_ == 2: num_exist_pool_units = 0 for unit in indi.units: if unit.type == 2: num_exist_pool_units +=1 if num_exist_pool_units > StatusUpdateTool.get_pool_limit()[1]-1: type_ = 1 self.log.info('The added unit is changed to CONV because the existing number of POOLING exceeds %d, limit size:%d'%(num_exist_pool_units, StatusUpdateTool.get_pool_limit()[1])) #do the details if type_ == 2: add_unit = indi.init_a_pool(mutation_position+1, _max_or_avg=None) else: for i in range(mutation_position, -1, -1): if indi.units[i].type == 1: _in_channel = indi.units[i].out_channel break add_unit = indi.init_a_conv(mutation_position+1, _in_channel=_in_channel, _out_channel=None) for i in range(mutation_position+1, len(indi.units)): if indi.units[i].type == 1: indi.units[i].in_channel = add_unit.out_channel break new_unit_list = [] # add to the new list and update the number for i in range(mutation_position+1): new_unit_list.append(indi.units[i]) new_unit_list.append(add_unit) for i in range(mutation_position+1, len(indi.units)): unit = indi.units[i] unit.number += 1 new_unit_list.append(unit) indi.number_id += 1 indi.units = new_unit_list indi.reset_acc()
def __init__(self, individuals, prob_, _log): self.individuals = individuals self.prob = prob_ self.log = _log self.pool_limit = StatusUpdateTool.get_pool_limit()[1]
def do_add_unit_mutation(self, indi): self.log.info('Do the ADD mutation for indi:%s'%(indi.id)) """ choose one position to add one unit, adding one resnet/densenet or pooling unit is determined by a probability of 1/3. However, if the maximal number of pooling units have been added into the current individual, only resnet/densenet unit will be add here """ # determine the position where a unit would be added mutation_position = int(np.floor(np.random.random()*len(indi.units))) self.log.info('Mutation position occurs at %d'%(mutation_position)) # determine the unit type for adding u_ = random.random() if u_ < 0.333: type_ = 1 elif u_ < 0.666: type_ = 2 else: type_ = 3 type_string_list = ['RESNET', 'POOLING', 'DENSENET'] self.log.info('A %s unit would be added due to the probability of %.2f'%(type_string_list[type_-1], u_)) if type_ == 2: num_exist_pool_units = 0 for unit in indi.units: if unit.type == 2: num_exist_pool_units +=1 if num_exist_pool_units > StatusUpdateTool.get_pool_limit()[1]-1: u_ = random.random() type_ = 1 if u_ < 0.5 else 3 self.log.info('The added unit is changed to %s because the existing number of POOLING exceeds %d, limit size:%d'%('RESNET' if type_ == 1 else 'DENSENET', num_exist_pool_units, StatusUpdateTool.get_pool_limit()[1])) #do the details if type_ == 2: add_unit = indi.init_a_pool(mutation_position+1, _max_or_avg=None) else: for i in range(mutation_position, -1, -1): if indi.units[i].type == 1 or indi.units[i].type == 3: _in_channel = indi.units[i].out_channel break if type_ == 1: add_unit = indi.init_a_resnet(mutation_position+1, _amount=None, _in_channel=_in_channel, _out_channel=None) if type_ == 3: add_unit = indi.init_a_densenet(mutation_position+1, _amount=None, _k=None, _max_input_channel=None, _in_channel=_in_channel) keep_out_channel = add_unit.out_channel for i in range(mutation_position+1, len(indi.units)): if indi.units[i].type == 1 or indi.units[i].type == 3 : self.log.info('Due to the above mutation, unit at %d changes its input channel from %d to %d'%(i, indi.units[i].in_channel, keep_out_channel)) indi.units[i].in_channel = keep_out_channel if indi.units[i].type == 1: break elif indi.units[i].type == 3: estimated_out_channel = indi.units[i].k*indi.units[i].amount + indi.units[i].in_channel if estimated_out_channel > indi.units[i].out_channel: break else: self.log.info('Due to the above mutation, unit at %d changes its output channel from %d to %d'%(i, indi.units[i].out_channel, estimated_out_channel)) indi.units[i].out_channel = estimated_out_channel keep_out_channel = estimated_out_channel new_unit_list = [] # add to the new list and update the number for i in range(mutation_position+1): new_unit_list.append(indi.units[i]) new_unit_list.append(add_unit) for i in range(mutation_position+1, len(indi.units)): unit = indi.units[i] unit.number += 1 new_unit_list.append(unit) indi.number_id += 1 indi.units = new_unit_list indi.reset_acc()