Пример #1
0
 def getHasVarNeurons(self, varname):
     '''
     取得拥有某个名称变量的所有神经元
     :param varname:
     :return:
     '''
     neurons = self.getNeurons()
     return collections.findall(
         neurons, lambda n: n.getVariable(varname) is not None)
Пример #2
0
    def getNeurons(self, layer=-1, activation=None):
        '''
        取得特定层,且满足激活状态的神经元
        :param layer:        int 层,-1表示所有层
        :param activation:   bool 激活状态,None表示所有状态
        :return:
        '''
        if len(self.neurons) <= 0: return []

        r = []
        collections.foreach(self.neurons, lambda ns: r.extend(ns))
        if layer < 0 and activation is None:
            return r

        return collections.findall(
            r, lambda n: (layer < 0 or n.layer == layer) and
            (r['activation'] == activation))
Пример #3
0
 def getOutputSynapse(self, neuronId):
     '''取得指定神经元的输出突触'''
     return collections.findall(self.synapses,
                                lambda s: s.fromId == neuronId)
Пример #4
0
 def getInputSynapse(self, neuronId):
     '''取得指定神经元的输入突触'''
     return collections.findall(self.synapses, lambda s: s.toId == neuronId)
Пример #5
0
    def execute(self,session):
        # 执行算法选择个体
        sel_inds = self.select(session)

        # 将要函数的个体删除
        individuals = session.pop.inds
        totalSize = len(individuals)
        removeInds = [ind for ind in individuals if ind not in sel_inds]
        removeIndids = [ind.id for ind in individuals if ind not in sel_inds]
        removeInd_count = len(removeInds)
        session.monitor.recordDebug(NSGA2.name, '删除的个体',
                                    collections.mapreduce(removeIndids, reducefunc=lambda i, j: str(i) + ',' + str(j)))
        for removeInd in removeInds:
            session.pop.removeInd(removeInd)
        individuals = session.pop.inds

        # 对剩余的个体按照分别按照不同的适应度函数排序
        sortedinds = {}
        for eva,i in enumerate(session.popParam.features):
            sortedinds[eva.key] = sorted(individuals,key=lambda x: x[eva.key] + 0.000001)
        featurekeys = [key for key,eva in session.popParam.features.items()]

        # 选择待交叉的个体
        corssmeateInds = []
        keyIndex = 0
        for i in range(removeInd_count):
            if len(individuals) == 1:
                corssmeateInds.append((individuals[0], individuals[0]))
            elif len(individuals) == 2:
                corssmeateInds.append((individuals[0], individuals[1]))
            else:
                indspar = self.roulette(individuals,2,featurekeys[keyIndex])
                keyIndex = 0 if keyIndex>=len(featurekeys)-1 else keyIndex + 1
                corssmeateInds.append(indspar[0],indspar[1])
        sdebug = ''
        for cross in corssmeateInds:
            if strs.isVaild(sdebug): sdebug += ','
            sdebug += str(cross[0]) + '-' + str(cross[1])
        session.monitor.recordDebug(NSGA2.name, '交叉的个体', sdebug)

        # region 第四步:对所有个体按照适应度从高到低排序,随机选择其中一部分作为变异个体
        metateinds = []
        # 计算变异个体数量
        mutateCount = int(session.runParam.mutate.propotion) if session.runParam.mutate.propotion >= 1 else int(
            totalSize * session.runParam.mutate.propotion)
        if mutateCount <= 0:
            return True, '', (corssmeateInds, metateinds)

        # 对所有个体按照适应度从高到低排序
        session.pop.inds.sort(key=lambda x: x['fitness'] + 0.000001 if x in session.pop.eliest else 0, reverse=True)
        # 选择候选变异个体(精英个体将被排除)
        candidateInds = collections.findall(session.pop.inds, lambda ind: ind not in session.pop.eliest)
        # 为每个个体计算一个选择概率(适应度越低的被选择的概率就高)
        if len(candidateInds) <= 0:
            max, avg, min, stdev = 0., 0., 0., 0.
            print('变异个体数量无效,' + str(session.pop.eliest))
            return True, '选择操作完成,其中淘汰个体数量=' + str(len(removeIndids)) + ',交叉个体数量=' + str(
                len(corssmeateInds)) + ',变异个体数量=0', (
                       corssmeateInds, [])

        else:
            max, avg, min, stdev = collections.rangefeature(list(map(lambda ind: ind['fitness'], candidateInds)))
        # fitnesssum = sum(list(map(lambda ind:ind['fitness'],candidateInds)))
        mutateSelProb = [1 - ((ind['fitness'] - min) / ((max - min) if max != min else 1)) for index, ind in
                         enumerate(candidateInds)]
        mutateSelProb = np.array(mutateSelProb)
        p = mutateSelProb / mutateSelProb.sum()
        np.random.seed(0)
        # p = np.array(mutateSelProb)
        mutateinds = np.random.choice(candidateInds, size=mutateCount, p=p.ravel())
        session.monitor.recordDebug(NSGA2.name, '变异的个体',
                                    reduce(lambda i, j: i + ',' + j, map(lambda ind: str(ind.id), mutateinds)))

        return True, '选择操作完成,其中淘汰个体数量=' + str(len(removeIndids)) + ',交叉个体数量=' + str(
            len(corssmeateInds)) + ',变异个体数量=' + str(len(mutateinds)), (
               corssmeateInds, list(map(lambda ind: ind.id, mutateinds)))
Пример #6
0
    def execute(self, session):
        #region 第一步:规划每个物种中应有的个体数量
        # 取得物种集合,并按平均适应度排序
        species = session.pop.getSpecies()
        if collections.isEmpty(species):
            raise RuntimeError('NEAT选择操作失败:物种集合为空')
        species.sort(key=lambda s: s['fitness']['average'], reverse=True)

        # 根据物种的平均适应度在所有物种中占的比重,计算每个物种的目标个体数量
        specie_total_fitness = sum(
            list(map(lambda sp: sp['fitness']['average'], species)))

        totalSize = 0
        for i in range(len(species)):
            specie = species[i]
            # 根据物种适应度计算目标个体数量
            speicesFitness = specie['fitness']['average']
            specie.targetSize = int((speicesFitness / specie_total_fitness) *
                                    len(session.pop.inds))
            totalSize += specie.targetSize

        # 如果所有物种的目标个体数量之和仍小于种群个体数量,将不足的部分加到适应度最高的物种上(按照上面计算,不会出现大于的情况)
        if totalSize < len(session.pop.inds):
            species[0].targetSize += len(session.pop.inds) - totalSize
        totalSize = len(session.pop.inds)

        session.monitor.recordDebug(
            'neat_selection', '物种的目标个体数量',
            reduce(lambda x, y: x + "," + y,
                   map(lambda s: str(s.id) + "=" + str(s.targetSize),
                       species)))

        #endregion

        #region 第二步:遍历每个物种,如果物种中实际个体数量大于前面计算的每个物种的目标个体数量,则将适应度差的个体淘汰
        removeIndids = []
        for i in range(len(species)):
            specie = species[i]
            # 将物种中个体按照适应度由高到低排序,其中精英个体尽管排前面
            specie.indids.sort(
                key=lambda indid: session.pop[indid]['fitness'] + 0.000001
                if session.pop[indid] in session.pop.eliest else 0,
                reverse=True)
            # 实际个体数量不多于目标个体数量,不需要淘汰
            if len(specie.indids) <= specie.targetSize:
                continue

            # 删除适应度最小的个体,直到实际个体数量与目标个体数量相等(这样的删除方法,有可能会导致精英个体也被删除)
            while len(specie.indids) > specie.targetSize:
                removeIndid = specie.indids[-1]
                removeInd = session.pop[removeIndid]
                removeIndids.append(removeIndid)
                del specie.indids[-1]  # 从物种记录中删除
                session.pop.inds.remove(removeInd)  # 从种群记录中删除
        session.monitor.recordDebug(
            'neat_selection', '删除的个体',
            collections.mapreduce(
                removeIndids, reducefunc=lambda i, j: str(i) + ',' + str(j)))

        # 遍历所有物种,如果有物种个体数量为0,则将该物种删除
        species = [s for s in species if len(s.indids) > 0]
        #endregion

        #region 第三步:对每个物种,随机选择需要交叉操作的个体
        corssmeateInds = []
        for specie in species:
            if len(specie.indids) >= specie.targetSize:
                continue
            for i in range(specie.targetSize - len(specie.indids)):
                if len(specie.indids) == 1:
                    corssmeateInds.append((specie.indids[0], specie.indids[0]))
                elif len(specie.indids) == 2:
                    corssmeateInds.append((specie.indids[0], specie.indids[1]))
                else:
                    indexpair = random.sample(range(len(specie.indids)), 2)
                    corssmeateInds.append((specie.indids[indexpair[0]],
                                           specie.indids[indexpair[1]]))

        # 有错误:session.monitor.recordDebug('neat_selection', '交叉的个体',  reduce(lambda i, j: str(list(i)[0])+"-"+str(list(i)[1]) + ',' + str(list(j)[0])+"-"+str(list(j)[1]), corssmeateInds))
        # reduce(lambda i,j:str(i[0])+'-'+str(i[1])+','+str(j[0])+'-'+str(j[1]),[(0,1),(2,3)])  --->  0-1,2-3
        # reduce(lambda i,j:str(i[0])+'-'+str(i[1])+','+str(j[0])+'-'+str(j[1]),[(0,1),(2,3),(4,5)]) ---> 0--,4-5
        sdebug = ''
        for cross in corssmeateInds:
            if strs.isVaild(sdebug): sdebug += ','
            sdebug += str(cross[0]) + '-' + str(cross[1])
        session.monitor.recordDebug('neat_selection', '交叉的个体', sdebug)

        #region 第四步:对所有个体按照适应度从高到低排序,随机选择其中一部分作为变异个体
        metateinds = []
        # 计算变异个体数量
        mutateCount = int(session.runParam.mutate.propotion
                          ) if session.runParam.mutate.propotion >= 1 else int(
                              totalSize * session.runParam.mutate.propotion)
        if mutateCount <= 0:
            return True, '', (corssmeateInds, metateinds)

        # 对所有个体按照适应度从高到低排序
        session.pop.inds.sort(key=lambda x: x['fitness'] + 0.000001
                              if x in session.pop.eliest else 0,
                              reverse=True)
        # 选择候选变异个体(精英个体将被排除)
        candidateInds = collections.findall(
            session.pop.inds, lambda ind: ind not in session.pop.eliest)
        # 为每个个体计算一个选择概率(适应度越低的被选择的概率就高)
        if len(candidateInds) <= 0:
            max, avg, min, stdev = 0., 0., 0., 0.
            print('变异个体数量无效,' + str(session.pop.eliest))
            return True, '选择操作完成,其中淘汰个体数量=' + str(
                len(removeIndids)) + ',交叉个体数量=' + str(
                    len(corssmeateInds)) + ',变异个体数量=0', (corssmeateInds, [])

        else:
            max, avg, min, stdev = collections.rangefeature(
                list(map(lambda ind: ind['fitness'], candidateInds)))
        #fitnesssum = sum(list(map(lambda ind:ind['fitness'],candidateInds)))
        mutateSelProb = [
            1 - ((ind['fitness'] - min) / ((max - min) if max != min else 1))
            for index, ind in enumerate(candidateInds)
        ]
        mutateSelProb = np.array(mutateSelProb)
        p = mutateSelProb / mutateSelProb.sum()
        np.random.seed(0)
        #p = np.array(mutateSelProb)
        mutateinds = np.random.choice(candidateInds,
                                      size=mutateCount,
                                      p=p.ravel())
        session.monitor.recordDebug(
            'neat_selection', '变异的个体',
            reduce(lambda i, j: i + ',' + j,
                   map(lambda ind: str(ind.id), mutateinds)))

        return True, '选择操作完成,其中淘汰个体数量=' + str(
            len(removeIndids)) + ',交叉个体数量=' + str(
                len(corssmeateInds)) + ',变异个体数量=' + str(len(mutateinds)), (
                    corssmeateInds, list(map(lambda ind: ind.id, mutateinds)))
Пример #7
0
    def activate(self, net, inputs):
        '''
        激活网络
        :param net:  测试网络
        :param task: 测试任务
        :return: outputs
        '''
        # 取得输入
        inputNeurons = net.getInputNeurons()

        # 重置神经元和突触状态
        collections.foreach(net.getNeurons(), lambda n: n.reset())
        collections.foreach(net.getSynapses(), lambda s: s.reset())

        # 设置输入
        for d, v in enumerate(inputs):
            if d >= len(inputNeurons): break
            model = models.nervousModels.find(
                inputNeurons[d].modelConfiguration.modelid)
            model.execute(inputNeurons[d], net, value=v)

            s = net.getOutputSynapse(inputNeurons[d].id)
            if collections.isEmpty(s): continue

            collections.foreach(s, lambda x: x.getModel().execute(x, net))

        # 反复执行
        ns = net.getNeurons()
        neuronCount = net.getNeuronCount()
        iterCount = 0
        outputNeurons = net.getOutputNeurons()
        #while not collections.all(outputNeurons,lambda n:'value' in n.states.keys()) and iterCount<=neuronCount:
        while not collections.all(
                outputNeurons,
                lambda n: 'value' in n.states) and iterCount <= neuronCount:
            iterCount += 1
            #uncomputeNeurons = collections.findall(ns,lambda n:'value' not in n.states.keys())
            uncomputeNeurons = collections.findall(
                ns, lambda n: 'value' not in n.states)
            if collections.isEmpty(uncomputeNeurons): break
            for n in uncomputeNeurons:
                model = n.getModel()
                synapses = net.getInputSynapse(n.id)
                if collections.isEmpty(synapses): continue
                #if not collections.all(synapses,lambda s:'value' in s.states.keys()):continue
                if not collections.all(synapses,
                                       lambda s: 'value' in s.states):
                    continue
                model.execute(n, net)

                synapses = net.getOutputSynapse(n.id)
                if collections.isEmpty(synapses): continue
                collections.foreach(synapses,
                                    lambda s: s.getModel().execute(s, net))

        # 将没结果的输出神经元的值设置为0
        #outputNeuronsWithNoResult = collections.findall(outputNeurons,lambda n:'value' not in n.states.keys())
        outputNeuronsWithNoResult = collections.findall(
            outputNeurons, lambda n: 'value' not in n.states)
        if not collections.isEmpty(outputNeuronsWithNoResult):
            collections.foreach(outputNeuronsWithNoResult,
                                lambda n: exec("n['value']=0"))
        # 取得结果
        outputs = list(map(lambda n: n['value'], outputNeurons))
        if len(outputs) == 1: outputs = outputs[0]
        return outputs