Example #1
0
    def do_work(self, max_gen):
        Log.info('*'*25)
        # the step 1
        if StatusUpdateTool.is_evolution_running():
            Log.info('Initialize from existing population data')
            gen_no = Utils.get_newest_file_based_on_prefix('begin')
            if gen_no is not None:
                Log.info('Initialize from %d-th generation'%(gen_no))
                pops = Utils.load_population('begin', gen_no)
                self.pops = pops
            else:
                raise ValueError('The running flag is set to be running, but there is no generated population stored')
        else:
            gen_no = 0
            Log.info('Initialize...')
            self.initialize_population()
        Log.info('EVOLVE[%d-gen]-Begin to evaluate the fitness'%(gen_no))
        self.fitness_evaluate()
        Log.info('EVOLVE[%d-gen]-Finish the evaluation'%(gen_no))
        gen_no += 1
        for curr_gen in range(gen_no, max_gen):
            self.params['gen_no'] = curr_gen
            #step 3
            Log.info('EVOLVE[%d-gen]-Begin to crossover and mutation'%(curr_gen))
            self.crossover_and_mutation()
            Log.info('EVOLVE[%d-gen]-Finish crossover and mutation'%(curr_gen))

            Log.info('EVOLVE[%d-gen]-Begin to evaluate the fitness'%(curr_gen))
            self.fitness_evaluate()
            Log.info('EVOLVE[%d-gen]-Finish the evaluation'%(curr_gen))

            self.environment_selection()
            Log.info('EVOLVE[%d-gen]-Finish the environment selection'%(curr_gen))

        StatusUpdateTool.end_evolution()
Example #2
0
    def do_alter_resnet_mutation(self, position, indi):
        """
        ----out_channel of resnet
        ----amount in one resnet
        """
        mutation_p_type = ''
        mutation_p_count = 0

        u_ = random.random()
        if u_ < 0.5:
            mutation_p_type = 'RESNET_OUT_CHANNEL'
            channel_list = StatusUpdateTool().get_output_channel()
            index_ = int(np.floor(np.random.random() * len(channel_list)))
            if indi.units[position].out_channel != channel_list[index_]:
                self.log.info(
                    'Unit at %d changes its output channel from %d to %d' %
                    (position, indi.units[position].out_channel,
                     channel_list[index_]))
                indi.units[position].out_channel = channel_list[index_]

                keep_out_channel = channel_list[index_]
                for i in range(position + 1, len(indi.units)):
                    if indi.units[i].type == 1 or indi.units[i].type == 3:
                        self.log.info(
                            'Due to above, the unit at %d should change 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

                mutation_p_count = 1
                indi.reset_acc()
        else:
            mutation_p_type = 'RESNET_AMOUNT'
            min_resnet_unit, max_resnet_unit = StatusUpdateTool.get_resnet_unit_length_limit(
            )
            amount = np.random.randint(min_resnet_unit, max_resnet_unit)
            if amount != indi.units[position].amount:
                self.log.info('Unit at %d changes its amount from %d to %d' %
                              (position, indi.units[position].amount, amount))
                indi.units[position].amount = amount
                mutation_p_count = 1
                indi.reset_acc()
        return mutation_p_type, mutation_p_count
Example #3
0
    def do_alter_densenet_mutation(self, position, indi):
        mutation_p_type = 'DENSENET_AMOUNT'
        mutation_p_count = 0

        k = indi.units[position].k
        if k == 12:
            _, amount_lower_limit, amount_upper_limit = StatusUpdateTool.get_densenet_k12(
            )
        elif k == 20:
            _, amount_lower_limit, amount_upper_limit = StatusUpdateTool.get_densenet_k20(
            )
        elif k == 40:
            _, amount_lower_limit, amount_upper_limit = StatusUpdateTool.get_densenet_k40(
            )
        amount = np.random.randint(amount_lower_limit, amount_upper_limit + 1)
        if amount != indi.units[position].amount:
            self.log.info('Unit at %d changes its amount from %d to %d' %
                          (position, indi.units[position].amount, amount))
            if indi.units[position].amount < amount:
                new_out_channel = (amount - indi.units[position].amount
                                   ) * k + indi.units[position].out_channel

            else:
                new_out_channel = indi.units[position].out_channel - (
                    indi.units[position].amount - amount) * k
            indi.units[position].amount = amount
            self.log.info(
                'Due to the above mutation, unit at %d changes its output channel from %d to %d'
                %
                (position, indi.units[position].out_channel, new_out_channel))
            indi.units[position].out_channel = new_out_channel

            keep_out_channel = new_out_channel
            for i in range(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

            mutation_p_count = 1
            indi.reset_acc()
        return mutation_p_type, mutation_p_count
Example #4
0
 def initialize_population(self):
     '''
     种群初始化
     '''
     # utils 中.ini [IS_RUNNING] 参数置1
     StatusUpdateTool.begin_evolution()
     pops = Population(params, 0)
     pops.initialize()
     self.pops = pops
     Utils.save_population_at_begin(str(pops), 0)
Example #5
0
 def initialize_population(self):
     '''
     种群初始化
     '''
     # ini文件IS_RUNNING参数置1
     StatusUpdateTool.begin_evolution()
     # 初始化种群,传入ini文件的参数
     pops = Population(params, 0)
     pops.initialize()
     self.pops = pops
     # 建立并写入种群begin文件
     Utils.save_population_at_begin(str(pops), 0)
Example #6
0
    def __init__(self, learning_rate):
        '''
        需传入: 学习率、data
        '''
        # trainloader, validate_loader = data_loader.get_train_valid_loader('/home/yanan/train_data', batch_size=128, augment=True, valid_size=0.1, shuffle=True, random_seed=2312390, show_sample=False, num_workers=1, pin_memory=True)
        #testloader = data_loader.get_test_loader('/home/yanan/train_data', batch_size=128, shuffle=False, num_workers=1, pin_memory=True)

        net = EvoCNNModel()
        cudnn.benchmark = True
        # net = net.cuda()
        criterion = nn.CrossEntropyLoss()
        best_acc = 0.0

        self.data = MadeData()
        self.net = net
        self.criterion = criterion
        self.best_acc = best_acc
        # self.trainloader = trainloader
        # self.validate_loader = validate_loader
        self.file_id = os.path.basename(__file__).split('.')[0]
        #self.testloader = testloader
        #self.log_record(net, first_time=True)
        #self.log_record('+'*50, first_time=False)
        self.num_class = StatusUpdateTool.get_num_class()
        self.learning_rate = learning_rate
Example #7
0
 def process(self):
     total_epoch = StatusUpdateTool.get_epoch_size()
     train_loader, testloader = self.data.CIFR10()
     for p in range(total_epoch):
         self.train(p, train_loader)
         self.test(total_epoch, testloader)
     return self.best_acc
    def do_mutation(self):
        _stat_param = {'offspring_new':0, 'offspring_from_parent':0, 'ADD':0, 'REMOVE':0, 'CHANNEL':0, 'POOLING_TYPE':0}

        mutation_list = StatusUpdateTool.get_mutation_probs_for_each()
        for indi in self.individuals:
            p_ = random.random()
            if p_ < self.prob:
                _stat_param['offspring_new'] += 1
                mutation_type = self.select_mutation_type(mutation_list)
                if mutation_type == 0:
                    _stat_param['ADD'] += 1
                    self.do_add_unit_mutation(indi)
                elif mutation_type == 1:
                    _stat_param['REMOVE'] += 1
                    self.do_remove_unit_mutation(indi)
                elif mutation_type == 2:
                    _stat_param['CHANNEL'] += 1
                    self.do_modify_conv_mutation(indi)
                elif mutation_type == 3:
                    _stat_param['POOLING_TYPE'] += 1
                    self.do_modify_pooling_type_mutation(indi)
                else:
                    raise TypeError('Error mutation type :%d, validate range:0-4'%(mutation_type))
            else:
                _stat_param['offspring_from_parent'] += 1
        self.log.info('MUTATION-mutated individuals:%d[ADD:%2d,REMOVE:%2d,CHANNEL:%2d,POOL:%2d, no_changes:%d'%(_stat_param['offspring_new'], \
                      _stat_param['ADD'], _stat_param['REMOVE'], _stat_param['CHANNEL'], _stat_param['POOLING_TYPE'],  _stat_param['offspring_from_parent']))
Example #9
0
    def do_mutation(self):
        _stat_param = {'offspring_new':0, 'offspring_from_parent':0, 'ADD':0, 'REMOVE':0, 'ALTER':0, 'RESNET_OUT_CHANNEL':0, 'RESNET_AMOUNT':0, 'DENSENET_AMOUNT':0, 'POOLING_TYPE':0}

        mutation_list = StatusUpdateTool.get_mutation_probs_for_each()
        for indi in self.individuals:
            p_ = random.random()
            if p_ < self.prob:
                _stat_param['offspring_new'] += 1
                mutation_type = self.select_mutation_type(mutation_list)
                if mutation_type == 0:
                    _stat_param['ADD'] += 1
                    self.do_add_unit_mutation(indi)
                elif mutation_type == 1:
                    _stat_param['REMOVE'] += 1
                    self.do_remove_unit_mutation(indi)
                elif mutation_type == 2:
                    mutation_p_type, mutation_p_count = self.do_alter_mutation(indi)
                    _stat_param[mutation_p_type] = mutation_p_count + _stat_param[mutation_p_type]
                    _stat_param['ALTER'] += mutation_p_count
                    if mutation_p_count == 0:
                        _stat_param['offspring_new'] -= 1
                        _stat_param['offspring_from_parent'] += 1
                else:
                    raise TypeError('Error mutation type :%d, validate range:0-4'%(mutation_type))
            else:
                _stat_param['offspring_from_parent'] += 1
        self.log.info('MUTATION-mutated individuals:%d[ADD:%2d,REMOVE:%2d,ALTER:%2d,RESNET_OUT_CHANNEL:%2d, RESNET_AMOUNT:%2d, DENSENET_AMOUNT:%2d, POOLING_TYPE:%2d, no_changes:%d'%(_stat_param['offspring_new'], \
                      _stat_param['ADD'], _stat_param['REMOVE'], _stat_param['ALTER'], _stat_param['RESNET_OUT_CHANNEL'], _stat_param['RESNET_AMOUNT'], _stat_param['DENSENET_AMOUNT'], _stat_param['POOLING_TYPE'],  _stat_param['offspring_from_parent']))
Example #10
0
def test_individual(params=None, indi_no=2):
    if params is None:
        from utils import StatusUpdateTool
        params = StatusUpdateTool.get_init_params()
    ind = Individual(params, indi_no)
    ind.initialize()
    print(ind)
    print(ind.uuid())
Example #11
0
def test_population(params=None, gen_no=0):
    if params is None:
        from utils import StatusUpdateTool
        params = StatusUpdateTool.get_init_params()
        gen_no = 20
    pop = Population(params, gen_no)
    pop.initialize()
    print(pop)
Example #12
0
    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()
Example #13
0
    def do_modify_conv_mutation(self, indi):
        self.log.info('Do the CHANNEL mutation for indi:%s'%(indi.id))
        conv_index_list = []
        for i, unit in enumerate(indi.units):
            if unit.type == 1:
                conv_index_list.append(i)
        if len(conv_index_list) == 0:
            self.log.warn('No CONV unit exist in current individual, no mutation occurs')
        else:
            selected_index = int(np.floor(np.random.rand()*len(conv_index_list)))
            self.log.info('Mutation position %d'%(conv_index_list[selected_index]))

            channel_list = StatusUpdateTool().get_output_channel()
            index_ = int(np.floor(np.random.random()*len(channel_list)))
            if indi.units[conv_index_list[selected_index]].in_channel != channel_list[index_]:
                indi.reset_acc()
                if selected_index > 0:
                    self.log.info('Unit at %d changes its input channel from %d to %d'%(conv_index_list[selected_index], indi.units[conv_index_list[selected_index]].in_channel, channel_list[index_]))
                    indi.units[conv_index_list[selected_index]].in_channel = channel_list[index_]
                    self.log.info('Due to above, the unit at %d should change its output channel from %d to %d'%(conv_index_list[selected_index-1], indi.units[conv_index_list[selected_index-1]].out_channel, channel_list[index_]))
                    indi.units[conv_index_list[selected_index-1]].out_channel = channel_list[index_]
                else:
                    self.log.warn('Mutation position is 0, the input channel should not be changed')
            else:
                self.log.info('Unit at %d changes its input channel from %d to %d'%(conv_index_list[selected_index], indi.units[conv_index_list[selected_index]].in_channel, channel_list[index_]))

            index_ = int(np.floor(np.random.random()*len(channel_list)))
            if indi.units[conv_index_list[selected_index]].out_channel != channel_list[index_]:
                indi.reset_acc()
                self.log.info('Unit at %d changes its out channel from %d to %d'%(conv_index_list[selected_index], indi.units[conv_index_list[selected_index]].out_channel, channel_list[index_]))
                indi.units[conv_index_list[selected_index]].out_channel = channel_list[index_]
                if selected_index < len(conv_index_list)-1:
                    self.log.info('Due to above, the unit at %d should change its input channel from %d to %d'%(conv_index_list[selected_index+1], indi.units[conv_index_list[selected_index+1]].in_channel, channel_list[index_]))
                    indi.units[conv_index_list[selected_index+1]].in_channel = channel_list[index_]
                else:
                    self.log.info('Unit at %d is the last unit in the individual, therefore no need to change the input channel of the next unit')
            else:
                self.log.info('Unit at %d changes its out channel from %d to %d'%(conv_index_list[selected_index], indi.units[conv_index_list[selected_index]].out_channel, channel_list[index_]))
Example #14
0
 def process(self):
     total_epoch = StatusUpdateTool.get_epoch_size()
     for p in range(total_epoch):
         self.train(p)
         self.test(total_epoch)
     return self.best_acc
Example #15
0
 def __init__(self, individuals, prob_, _log):
     self.individuals = individuals
     self.prob = prob_
     self.log = _log
     self.pool_limit = StatusUpdateTool.get_pool_limit()[1]
Example #16
0
    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()
Example #17
0
    def do_crossover(self):
        _stat_param = {'offspring_new':0, 'offspring_from_parent':0}
        new_offspring_list = []
        for _ in range(len(self.individuals)//2):
            ind1, ind2 = self._choose_two_diff_parents()

            parent1, parent2 = copy.deepcopy(self.individuals[ind1]), copy.deepcopy(self.individuals[ind2])
            p_ = random.random()
            if p_ < self.prob:
                _stat_param['offspring_new'] += 2
                """
                exchange their units from these parent individuals, the exchanged units must satisfy
                --- the number of pooling layer should not be more than the predefined setting
                --- if their is no changing after this crossover, keep the original acc -- a mutation should be given [to do---]
                """
                first_begin_is_pool, second_begin_is_pool = True, True
                while first_begin_is_pool is True or second_begin_is_pool is True:
                    pos1, pos2, pool_len1, pool_len2 = self._calculate_pool_numbers(parent1, parent2)
                    try_count = 1
                    while pool_len1 > self.pool_limit or pool_len2 > self.pool_limit:
                        pos1, pos2, pool_len1, pool_len2 = self._calculate_pool_numbers(parent1, parent2)
                        try_count += 1
                        self.log.warn('The %d-th try to find the position for do crossover'%(try_count))
                    self.log.info('Position %d for %s, positions %d for %s'%(pos1, parent1.id, pos2, parent2.id))
                    unit_list1, unit_list2 = [], []
                    for i in range(0, pos1):
                        unit_list1.append(parent1.units[i])
                    for i in range(pos2, len(parent2.units)):
                        unit_list1.append(parent2.units[i])

                    for i in range(0, pos2):
                        unit_list2.append(parent2.units[i])
                    for i in range(pos1, len(parent1.units)):
                        unit_list2.append(parent1.units[i])
                    first_begin_is_pool = True if unit_list1[0].type == 2 else False
                    second_begin_is_pool = True if unit_list2[0].type == 2 else False

                    if first_begin_is_pool is True:
                        self.log.warn('Crossovered individual#1 starts with a pooling layer, redo...')
                    if second_begin_is_pool is True:
                        self.log.warn('Crossovered individual#2 starts with a pooling layer, redo...')



                # reorder the number of each unit based on its order in the list
                for i, unit in enumerate(unit_list1):
                    unit.number = i
                for i, unit in enumerate(unit_list2):
                    unit.number = i

                # re-adjust the in_channel of the next layer
                last_output_from_list1 = 0
                if pos1 == 0:
                    last_output_from_list1 = StatusUpdateTool.get_input_channel()
                    j = 0
                    i = -1
                else:
                    for i in range(pos1-1, -1, -1):
                        if unit_list1[i].type == 1 or unit_list1[i].type == 3:
                            last_output_from_list1 = unit_list1[i].out_channel
                            break


                keep_out_channel = last_output_from_list1
                for j in range(pos1, len(unit_list1)):
                    if unit_list1[j].type == 1 or unit_list1[j].type == 3:
                        self.log.info('Change the input channel of unit at %d to %d that is the output channel of unit at %d in %s'%(j, keep_out_channel, i, parent1.id))
                        unit_list1[j].in_channel = keep_out_channel
                        if unit_list1[j].type == 1:
                            break
                        elif unit_list1[j].type ==  3:
                            estimated_out_channel = unit_list1[j].k*unit_list1[j].amount + unit_list1[j].in_channel
                            if estimated_out_channel > unit_list1[j].out_channel:
                                break;
                            else:
                                self.log.info('Due to the above change, unit at %d changes its output channel from %d to %d'%(j, unit_list1[j].out_channel, estimated_out_channel))
                                unit_list1[j].out_channel = estimated_out_channel
                                keep_out_channel = estimated_out_channel


                last_output_from_list2 = 0
                if pos2 == 0:
                    last_output_from_list2 = StatusUpdateTool.get_input_channel()
                    j = 0
                    i = -1
                else:
                    for i in range(pos2-1, -1, -1):
                        if unit_list2[i].type == 1 or unit_list2[i].type == 3:
                            last_output_from_list2 = unit_list2[i].out_channel
                            break

                keep_out_channel = last_output_from_list2
                for j in range(pos2, len(unit_list2)):
                    if unit_list2[j].type == 1 or unit_list2[j].type == 3:
                        self.log.info('Change the input channel of unit at %d to %d that is the output channel of unit at %d in %s'%(j, keep_out_channel, i, parent2.id))
                        unit_list2[j].in_channel = keep_out_channel
                        if unit_list2[j].type == 1:
                            break
                        elif unit_list2[j].type == 3:
                            estimated_out_channel = unit_list2[j].k*unit_list2[j].amount + unit_list2[j].in_channel
                            if estimated_out_channel > unit_list2[j].out_channel:
                                break;
                            else:
                                self.log.info('Due to the above change, unit at %d changes its output channel from %d to %d'%(j, unit_list2[j].out_channel, estimated_out_channel))
                                unit_list2[j].out_channel = estimated_out_channel
                                keep_out_channel = estimated_out_channel

                parent1.units = unit_list1
                parent2.units = unit_list2
                offspring1, offspring2 = parent1, parent2
                offspring1.reset_acc()
                offspring2.reset_acc()
                new_offspring_list.append(offspring1)
                new_offspring_list.append(offspring2)
            else:
                _stat_param['offspring_from_parent'] += 2
                new_offspring_list.append(parent1)
                new_offspring_list.append(parent2)

        self.log.info('CROSSOVER-%d offspring are generated, new:%d, others:%d'%(len(new_offspring_list), _stat_param['offspring_new'],_stat_param['offspring_from_parent']))
        return new_offspring_list
Example #18
0
 def initialize_population(self):
     StatusUpdateTool.begin_evolution()
     pops = Population(params, 0)
     pops.initialize()
     self.pops = pops
     Utils.save_population_at_begin(str(pops), 0)
Example #19
0
        self.fitness_evaluate()
        Log.info('EVOLVE[%d-gen]-Finish the evaluation' % (gen_no))

        gen_no += 1
        for curr_gen in range(gen_no, max_gen):
            self.params['gen_no'] = curr_gen
            # step 3
            # .1 交叉变异 .2 估计适应度 .3 筛选
            Log.info('EVOLVE[%d-gen]-Begin to crossover and mutation' %
                     (curr_gen))
            self.crossover_and_mutation()
            Log.info('EVOLVE[%d-gen]-Finish crossover and mutation' %
                     (curr_gen))

            Log.info('EVOLVE[%d-gen]-Begin to evaluate the fitness' %
                     (curr_gen))
            self.fitness_evaluate()
            Log.info('EVOLVE[%d-gen]-Finish the evaluation' % (curr_gen))

            self.environment_selection()
            Log.info('EVOLVE[%d-gen]-Finish the environment selection' %
                     (curr_gen))

        StatusUpdateTool.end_evolution()


if __name__ == '__main__':
    params = StatusUpdateTool.get_init_params()
    evoCNN = EvolveCNN(params)
    evoCNN.do_work(max_gen=5)