精华内容
下载资源
问答
  • 拓扑 神经网络
    2021-12-09 00:55:34

    遗传拓扑神经网络训练贪吃蛇

    先给出NEAT-Python模块官网文档链接

    遗传拓扑神经网络简单来说是利用遗传算法的思想来优化神经网络的结构。但是对我这种入门小白来说肯定是很复杂的。但是所幸有这个NEAT-Python模块,在开始使用该模块前一定要去原汁原味的阅读一下文档(不要网页翻译!翻译有坑!)

    然后我是照着这个视频来的,也推荐亲自去看看,也所幸这个贪吃蛇可以完全按照上面的来。

    首先我们需要嫖三个文件:

    1.neat_TEST.py

    # 用于测试训练出来的模型结果
    import os
    import pickle
    import neat
    import gym
    
    # 加载训练的神经网络
    with open('model', 'rb') as f:
        c = pickle.load(f)
    
    print('Loaded genome:')
    print(c)
    
    local_dir = os.path.dirname(__file__)
    config_path = os.path.join(local_dir, 'config')
    config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                         neat.DefaultSpeciesSet, neat.DefaultStagnation,
                         config_path)
    
    net = neat.nn.FeedForwardNetwork.create(c, config)
    # 初始化环境
    env = gym.make('GreedySnake-v0')
    observation = env.reset()
    
    # 用模型的输出预测值进行游戏
    done = False
    while not done:
        predict = net.activate(observation)
        maxn = -10.
        index = 0
        for i in range(len(predict)):
            if predict[i] > maxn:
                index = i
                maxn = predict[i]
        action = index
        observation, reward, done, info = env.step(action)
        env.render()
    

    2.neat_TRAIN.py

    # 用于训练
    import multiprocessing
    import os
    import pickle
    import neat
    import numpy as np
    import gym
    
    runs_per_net = 2
    
    # 视频上说的只用改这个函数,而我只改了那个环境233
    def eval_genome(genome, config):
        net = neat.nn.FeedForwardNetwork.create(genome, config)
    
        fitnesses = []
    
        for runs in range(runs_per_net):
            env = gym.make('GreedySnake-v0')
    
            observation = env.reset(is_GUI=False)
            fitness = 0.0
            done = False
            while not done:
                action = net.activate(observation)
                observation, reward, done, info = env.step(action)
                fitness += reward
    
            fitnesses.append(fitness)
    
        return np.mean(fitnesses)
    
    
    def eval_genomes(genomes, config):
        for genome_id, genome in genomes:
            genome.fitness = eval_genome(genome, config)
    
    
    def run():
        local_dir = os.path.dirname(__file__)
        config_path = os.path.join(local_dir, 'config')
        config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                             neat.DefaultSpeciesSet, neat.DefaultStagnation,
                             config_path)
    
        pop = neat.Population(config)
        stats = neat.StatisticsReporter()
        pop.add_reporter(stats)
        pop.add_reporter(neat.StdOutReporter(True))
    
        pe = neat.ParallelEvaluator(multiprocessing.cpu_count(), eval_genome)
        model = pop.run(pe.evaluate)
    
        with open('model', 'wb') as f:
            pickle.dump(model, f)
    
        print(model)
    
    
    if __name__ == '__main__':
        run()
    

    3.config

    这个是训练的配置文件,主要贪吃蛇的训练我改的是加了中文注释的几个,使用的时候把注释删掉吧。

    至于其他的可以自行看文档理解调整。

    # NEAT configuration for the bit-sequence memory experiment.
    
    # The `NEAT` section specifies parameters particular to the NEAT algorithm
    # or the experiment itself.  This is the only required section.
    [NEAT]
    fitness_criterion     = max #[max/min/mean]适应方式 最大值、最小值、均值
    fitness_threshold     = 150.0 #适应度的阈值,以某种适应方式到达该阈值就会结束训练
    pop_size              = 500 #人口数,也是开的进程数,看自己电脑水平开吧
    reset_on_extinction   = 0
    
    [DefaultGenome]
    num_inputs              = 2500 #输入层单元数
    num_hidden              = 2		#隐藏层层数
    num_outputs             = 4    #输出层单元数
    initial_connection      = partial_direct 0.5
    feed_forward            = True
    compatibility_disjoint_coefficient    = 1.0
    compatibility_weight_coefficient      = 0.6
    conn_add_prob           = 0.2
    conn_delete_prob        = 0.2
    node_add_prob           = 0.2
    node_delete_prob        = 0.2
    activation_default      = clamped
    activation_options      = clamped
    activation_mutate_rate  = 0.00
    aggregation_default     = sum
    aggregation_options     = sum
    aggregation_mutate_rate = 0.0
    bias_init_mean          = 0.0
    bias_init_stdev         = 1.0
    bias_replace_rate       = 0.1
    bias_mutate_rate        = 0.7
    bias_mutate_power       = 0.5
    bias_max_value          = 30.0
    bias_min_value          = -30.0
    response_init_mean      = 1.0
    response_init_stdev     = 0.0
    response_replace_rate   = 0.0
    response_mutate_rate    = 0.0
    response_mutate_power   = 0.0
    response_max_value      = 30.0
    response_min_value      = -30.0
    
    weight_max_value        = 30
    weight_min_value        = -30
    weight_init_mean        = 0.0
    weight_init_stdev       = 1.0
    weight_mutate_rate      = 0.8
    weight_replace_rate     = 0.1
    weight_mutate_power     = 0.5
    enabled_default         = True
    enabled_mutate_rate     = 0.01
    
    [DefaultSpeciesSet]
    compatibility_threshold = 3.0
    
    [DefaultStagnation]
    species_fitness_func = max
    max_stagnation  = 20
    
    [DefaultReproduction]
    elitism            = 2
    survival_threshold = 0.2
    

    然后我们先运行之前贪吃蛇的env_TEST.py确保环境没问题。

    然后运行neat_TRAIN进行训练,期间风扇会吵得你睡不着觉,所以建议白天跑,然后出去喝茶?

    训练结束后就运行neat_TEST看看训练效果吧!(当然如果你太过粗暴的话可能训练效果也不会好)

    更多相关内容
  • 很好的一篇整合当下流行的神经网络和单片机相关项目的论文
  • 人工智能-基于增强拓扑神经网络的自平衡车研究.pdf
  • 固定拓扑神经网络进化。 功能 (1 + 1)-ES (并发)基于种群的进化/遗传算法 示例/测试 test-fixed-topology-simple-es-xor.sh:使用 1+1 进化策略优化 2-2-1 神经网络的权重以解决 XOR 问题。 test-fixed-topology...
  • 遗传拓扑神经网络---Neat

    千次阅读 2019-10-20 13:08:32
    本期课程到这里,博主就默认大家已经对BP、CNN、RNN等基本的神经网络属性以及训练过程都有相应的认知了,如果还未了解最基本的知识,可以翻看博主制作的深度学习的学习路线,...

    本期课程到这里,博主就默认大家已经对BP、CNN、RNN等基本的神经网络属性以及训练过程都有相应的认知了,如果还未了解最基本的知识,可以翻看博主制作的深度学习的学习路线,按顺序阅读即可。

    深度学习的学习路线:往期课程

        

            Hello,又是一个分享的日子,之前博主给大家介绍了遗传演化神经网络,这期博主将在本期推文给大家介绍遗传拓扑神经网络遗传拓扑神经网络同样是结合了神经网络和遗传算法与进化策略产生的一种全新模型。它通过模仿自然界“适者生存”的原则来赋予神经网络在代际循环中优化的力量,能有效克服传统神经网络在训练过程中的缺点。它与上期介绍的遗传演化神经网络不同的地方在于加入了交叉操作,且它的年代比较久远了,是2003年的一篇论文,因为近些年来算力的提升与强化学习的兴起,又走进了人们的视野。好了,闲言少叙,我们这就走进遗传与深度学习的世界。

    Neat算法的论文

    《Evolving Neural Networks through Augmenting Topologies 》

    提取码:yxph

    https://pan.baidu.com/s/1SmMEsgSMEdUwnhvsmwfnPg&shfl=sharepset

    本文内容概要:

    1. 遗传拓扑神经网络(Neat算法)原理

    2. 遗传拓扑神经网络(Neat算法)实验

    3. 实验总结

    4. 新的征程---NLP修炼指北

    遗传拓扑神经网络的思想

     原理                                                                                     

            正如之前的遗传演化神经网络的推文所说,遗传算法是个通用框架,因此我们需要根据具体的问题来定义遗传算法。不过,既然它是框架,那它就会有通用的几部分供我们选择,因此博主在此给大家先讲下整体的流程。

        整体框架可分为三部分:交叉、变异与适应度。不过虽然整体的流程是一致的,但是因为问题不同,我们定义的基因也有所不同,那交叉与变异也会随之变化。

        这篇论文将神经元及其连接定义成基因组,而遗传演化神经网络论文是将网络层及其学习率定义成基因组,小伙伴们可以对比着学习两者的异同,这样也能更好地感受为什么说遗传算法是解决一般性问题的通用框架,就是因为我们可以根据问题去定义基因组。

    算法核心                                                                                

     

    A.个体基因与种群规模
      个体基因:(结点链接与结点类型)
      种群规模:150
      物种划分:基于权值相似度划分物种
     
     由于该论文已经有人写好了框架,因此以上参数在配置文件中修改
     即可,这将会在代码那里给大家演示。
    

    伪代码:

    while condition:
      if random.random < 交叉率:
        选择操作(适应度越高,越容易被选中)
        物种内交叉
        if random.random < 变异率:
          变异操作
        评估适应度
      else:  # 直接变异
        if random.random < 变异率:
           变异操作
         评估适应度
      # 淘汰操作
         每个物种保留一定数量的个体
      if random.random < 灭绝率:
         灭绝最差的物种
         种群间的物种交叉生成亚种, 弥补新的物种
     
     conditon:迭代次数 or fittness达到设定的阈值
     评估适应度:fitness = 1/(训练集的误差)^2
     这里的适应度函数是自定义的,大家可以根据自己的想法去定义。 
        
    
    

    交叉操作:

    交叉操作

        论文通过一个链表定义基因的节点连接,选择两个个体进行交叉的时候,按照链表的顺序,逐一操作,最后生成新的子代。

    变异操作:

    变异操作

        同样地,变异操作也是在链表中进行,且会有两种变异:增加网络连接和增加网络节点。

    实验

    实验环境                                                                                          

    windows 用户:
    cmd命令行输入以下命令
    conda install -c conda-forge graphviz
    conda install -c conda-forge python-graphviz
    
    
    linux 用户:
    命令行输入以下命令
    sudo apt-get install graphviz
    

     

     

    实验                                                                                                 

        这里实验使用官网的例子:实现一个能判断XOR异或操作的网络,让大家感受下具体如何操作。

    xor_inputs = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]
    xor_outputs = [(0.0,),    (1.0,),     (1.0,),     (0.0,)]
    """
    异或:输入相异,输出1, 输入相同,输出0
    """
    

         上文提到,有人已经实现了这篇论文的代码框架,我们只需要修改配置文件的相应参数,就可以运行Neat算法了,下面给大家介绍下Neat算法的配置文件,官网有对配置文件更详细的解释,这里博主只是标注一些自己用到的参数。

    neat算法配置文件详细解释

    https://neat-python.readthedocs.io/en/latest/config_file.html

    #--- parameters for the XOR-2 experiment ---#
    
    
    [NEAT]
    fitness_criterion     = max
    fitness_threshold     = 3.9  # 适应度的阈值
    pop_size              = 150  # 种群规模
    reset_on_extinction   = False
    
    
    [DefaultGenome]
    # node activation options  # 结点的激励函数
    activation_default      = sigmoid
    activation_mutate_rate  = 0.0
    activation_options      = sigmoid
    
    
    # node aggregation options  # 结点的聚合选择 (一般默认)
    aggregation_default     = sum
    aggregation_mutate_rate = 0.0
    aggregation_options     = sum
    
    
    # node bias options  # 结点的偏置选择
    bias_init_mean          = 0.0
    bias_init_stdev         = 1.0
    bias_max_value          = 30.0
    bias_min_value          = -30.0
    bias_mutate_power       = 0.5
    bias_mutate_rate        = 0.7
    bias_replace_rate       = 0.1
    
    
    # genome compatibility options
    compatibility_disjoint_coefficient = 1.0
    compatibility_weight_coefficient   = 0.5
    
    
    # connection add/remove rates
    conn_add_prob           = 0.5
    conn_delete_prob        = 0.5
    
    
    # connection enable options
    enabled_default         = True
    enabled_mutate_rate     = 0.01
    
    
    feed_forward            = True  # 是否加入RNN神经元
    initial_connection      = full
    
    
    # node add/remove rates  # 结点的添加和删除概率
    node_add_prob           = 0.2
    node_delete_prob        = 0.2
    
    
    # network parameters  # 输入层、输出层、隐藏层的神经元个数
    num_hidden              = 2
    num_inputs              = 2
    num_outputs             = 1
    
    
    # node response options
    response_init_mean      = 1.0
    response_init_stdev     = 0.0
    response_max_value      = 30.0
    response_min_value      = -30.0
    response_mutate_power   = 0.0
    response_mutate_rate    = 0.0
    response_replace_rate   = 0.0
    
    
    # connection weight options
    weight_init_mean        = 0.0
    weight_init_stdev       = 1.0
    weight_max_value        = 30
    weight_min_value        = -30
    weight_mutate_power     = 0.5
    weight_mutate_rate      = 0.8
    weight_replace_rate     = 0.1
    
    
    [DefaultSpeciesSet]  
    # genomic distance小于此距离被认为是同一物种
    compatibility_threshold = 3.0 
    
    
    [DefaultStagnation]
    species_fitness_func = max
    max_stagnation       = 20
    species_elitism      = 2
    
    
    [DefaultReproduction]
    elitism            = 2   # 保留最优的个体遗传到下一代的个数
    survival_threshold = 0.2  # 每一代每个物种的存活率
    
    
    

    代码                                                                                                 

    
    
    from __future__ import print_function
    import os
    import neat
    import visualize
    
    
    # XOR异或的输入输出数据
    xor_inputs = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]
    xor_outputs = [   (0.0,),     (1.0,),     (1.0,),     (0.0,)]
    
    
    
    
    def eval_genomes(genomes, config):
        # 评估函数    
        for genome_id, genome in genomes:
            genome.fitness = 4.0
            net = neat.nn.FeedForwardNetwork.create(genome, config)
            for xi, xo in zip(xor_inputs, xor_outputs):
                output = net.activate(xi)
                genome.fitness -= (output[0] - xo[0]) ** 2
    
    
    
    
    def run(config_file):
        # 读取配置配置文件
        config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                             neat.DefaultSpeciesSet, neat.DefaultStagnation,
                             config_file)
    
    
        # 创建种群
        p = neat.Population(config)
    
    
        # 打印训练过程
        p.add_reporter(neat.StdOutReporter(True))
        stats = neat.StatisticsReporter()
        p.add_reporter(stats)
        p.add_reporter(neat.Checkpointer(5))
    
    
        # 迭代300次
        winner = p.run(eval_genomes, 300)
        
        # 显示最佳网络
        print('\nBest genome:\n{!s}'.format(winner))
        print('\nOutput:')
        winner_net = neat.nn.FeedForwardNetwork.create(winner, config)
        for xi, xo in zip(xor_inputs, xor_outputs):
            output = winner_net.activate(xi)
            print("input {!r}, expected output {!r}, got {!r}".format(xi, xo, output))
    
    
        node_names = {-1:'A', -2: 'B', 0:'A XOR B'}
        visualize.draw_net(config, winner, True, node_names=node_names)
        visualize.plot_stats(stats, ylog=False, view=True)
        visualize.plot_species(stats, view=True)
    
    
        p = neat.Checkpointer.restore_checkpoint('neat-checkpoint-4')
        p.run(eval_genomes, 10)
    
    
    
    
    if __name__ == '__main__':
        config_path = os.path.join('config-feedforward')
        run(config_path)
    

    Git链接

    代码

    https://github.com/ChileWang0228/DeepLearningTutorial/blob/master/Neat/xor.ipynb

    训练结果                                                                                             

    生成的.svg后缀文件用google浏览器打开即可,显示的就是下面两张图。

    生成的网络结构

    fittness趋势图

    视频版                                                                                        

    视频版包含了代码讲解部分,不过博主的代码都做了相应的注释,相信大家都能看懂,喜欢视频版的小伙伴可以去观看~~~

    bilibili值得拥有~(っ•̀ω•́)っ✎⁾⁾ 我爱学习

    https://space.bilibili.com/299585150


    总结

            好了,到这里,我们就已经将遗传拓扑神经网络(Neat算法)的知识点讲完了。大家在掌握了整个流程之后,可以把官方代码下载下来,调一下配置文件,就可以运行了。当然,有些小伙伴可能会想着自己定义一个新的交叉或者变异操作,这就需要对着Neat算法的源码修改相应的代码了。

          最后总结一下,因为算力的提升,遗传算法+深度学习近年来逐渐走入人们的视野,不过应用比较广泛的是在强化学习领域。究其原因还是因为强化学习的本质和遗传算法一致,都是适者生存,不适者淘汰。比如有人用Neat算法训练了个超级马里奥,其实就是训练一个机器人在游戏环境中生存,适应度函数可以定义为在游戏里的得分亦或者是在游戏中的存活时间,在不断迭代过程中,存活下来的机器人一定是对当前环境反馈最佳的。

          当然了,这里提及Neat算法,主要是想让大家对比两期遗传算法的实验,掌握遗传算法的流程精髓,顺带了解一下强化学习是干嘛的。

          最后还要说一下,到这里为止,深度学习的基础课程也就告一段落了。下一期开始,博主就开始更新NLP方面的内容了,这是博主研究生的主攻方向,希望能在接下来的分享中,大家共同进步。

    ~~~~~完结撒花~~~~~

         

        

            如果本期推文有用,那就点个赞吧,你们的点赞是博主持续更新的动力,感谢每一位小伙伴的关注~

        


    展开全文
  • Neat算法讲解(遗传拓扑神经网络

    千次阅读 2020-05-13 18:22:55
    Neat算法讲解(遗传拓扑神经网络的原理)   遗传算法是个通用的框架,因此需要根据具体的问题来定义遗传算法。   整体框架可分为三部分:交叉、变异与适应度。不过虽然整体的流程是一致的,但是因为问题不同,...

    Neat算法讲解(遗传拓扑神经网络的原理)

      遗传算法是个通用的框架,因此需要根据具体的问题来定义遗传算法。
      整体框架可分为三部分:交叉、变异与适应度。不过虽然整体的流程是一致的,但是因为问题不同,我们定义的基因也有所不同,那交叉与变异也会随之变化。
      这篇论文将神经元及其连接定义成基因组
      而遗传演化神经网络论文是将网络层及其学习率定义为基因组,遗传算法是解决一般性问题的通用框架,就是因为我们可以根据问题去定义基因组。

    算法核心:超参数设置

      整体框架可分为三部分:交叉、变异与适应度
      1、超参数设置,个体基因:(节点连接与节点类型);种群规模:150;物种划分:基于权值相似度划分物种。

    伪代码:

    while condition:
    	if random.random < 交叉率:
    		选择操作(适应度越高,越容易被选中)
    		物种内交叉
    		if random.random < 变异率:
    			变异操作
    		评估适应度
    else:		#(random.random > 交叉率)直接变异
    	if random.random < 变异率:
    		变异操作
    	评估适应度
    	# 淘汰操作
    	每个物种保留一定数量的个体
    	if random.random < 灭绝率:
    		灭绝最差的物种
    		种群间的物种交叉生成新的子代
    
    condition: 迭代次数 or fitness达到设定的阈值
    评估适应度: fitness = 1/(训练集的误差)^2
    这里的适应度函数是自定义的
    

    算法核心:交叉操作

      论文通过一个链表定义基因的节点连接,选择两个个体进行交叉的时候,按照链表的顺序,逐一操作,最后生成新的子代

    算法核心:变异操作

      变异操作也是在链表中进行,且会有两种变异:增加网络连接增加网络节点

    conda软件版本

    python = 3.7.7
    pandas = 1.0.3
    neat-python = 0.92
    numpy = 1.17.0
    matplotlib = 3.1.1
    conda install graphviz = 2.38.0
    pip install graphviz = 0.13.2
    

    NEAT实验例子:训练一个XOR网络

    伪代码:

    异或:输入相异,输出为1,输入相同,输出为0

    xor_inputs = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]
    xor_outputs = [(0.0,), (1.0,), (1.0,), (0.0,)]

    NEAT配置文件(删除后面#的注释,保存为:config-feedforward)

      [NEAT]  
      fitness_criterion     = max  
      fitness_threshold     = 3.9  # 适应度的阈值  
      pop_size              = 150  # 种群规模  
      reset_on_extinction   = False  
        
      [DefaultGenome]  
      # node activation options  # 节点的激励函数  (一般默认)
      activation_default      = sigmoid  
      activation_mutate_rate  = 0.0  
      activation_options      = sigmoid  
        
      # node aggregation options  # 节点的聚合选择 (一般默认)  
      aggregation_default     = sum  
      aggregation_mutate_rate = 0.0  
      aggregation_options     = sum  
        
      # node bias options  # 节点的偏置选择  
      bias_init_mean          = 0.0  
      bias_init_stdev         = 1.0  
      bias_max_value          = 30.0  
      bias_min_value          = -30.0  
      bias_mutate_power       = 0.5  
      bias_mutate_rate        = 0.7  
      bias_replace_rate       = 0.1  
       
      # genome compatibility options  # 基因组兼容性选项 
      compatibility_disjoint_coefficient = 1.0  	#	兼容性不相交系数
      compatibility_weight_coefficient   = 0.5  	#	兼容性权重系数
        
      # connection add/remove rates  # 连接增加/删除的概率
      conn_add_prob           = 0.5  #	概率
      conn_delete_prob        = 0.5  
         
      # connection enable options  
      enabled_default         = True  
      enabled_mutate_rate     = 0.01  
        
      feed_forward            = True  # 是否加入RNN神经元 (循环神经网络)
      initial_connection      = full  #	初始连接全连接
        
      # node add/remove rates  # 结点的添加和删除概率  
      node_add_prob           = 0.2  
      node_delete_prob        = 0.2  
        
      # network parameters  # 输入层、输出层、隐藏层的神经元个数  
      num_hidden              = 2  
      num_inputs              = 2  
      num_outputs             = 1  
        
      # node response options  # 节点相应选项
      response_init_mean      = 1.0  
      response_init_stdev     = 0.0  
      response_max_value      = 30.0  
      response_min_value      = -30.0  
      response_mutate_power   = 0.0  
      response_mutate_rate    = 0.0  
      response_replace_rate   = 0.0  
        
      # connection weight options # 连接权重选项 
      weight_init_mean        = 0.0  
      weight_init_stdev       = 1.0  
      weight_max_value        = 30  
      weight_min_value        = -30  
      weight_mutate_power     = 0.5  
      weight_mutate_rate      = 0.8  
      weight_replace_rate     = 0.1  
        
      [DefaultSpeciesSet]    
      # genomic distance小于此距离被认为是同一物种  
      compatibility_threshold = 3.0   #	兼容性阈值
       
      [DefaultStagnation]  #	默认停滞
      species_fitness_func = max  
      max_stagnation       = 20  
      species_elitism      = 2  #	物种精英
       
      [DefaultReproduction]  	#	默认繁殖
      elitism            = 2   # 保留最优的个体遗传到下一代的个数  
      survival_threshold = 0.2  # 每一代每个物种的存活率  
    

    主函数代码:(保存为:run.py)

    import os
    import neat
    import visualize
    
    # 2个输入,1个输出的异或实验
    xor_inputs = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]
    xor_outputs = [(0.0,), (1.0,), (1.0,), (0.0,)]
    
    
    def eval_genomes(genomes, config):
        # 评估函数
        for genome_id, genome in genomes:  # 每一个个体
            genome.fitness = 4.0  # 适应度为4.0的评估,因为有4个结果全部猜对
            net = neat.nn.FeedForwardNetwork.create(genome, config)  # 生成一个网络
            for xi, xo in zip(xor_inputs, xor_outputs):  # 把它丢进去训练
                output = net.activate(xi)
                genome.fitness -= (output[0] - xo[0]) ** 2  # 训练完后得到一个fitness
    
    
    def run(config_file):
        # 读取配置文件
        config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                             neat.DefaultSpeciesSet, neat.DefaultStagnation,
                             config_file)
    
        # 创建种群
        p = neat.Population(config)
    
        # 打印训练过程
        p.add_reporter(neat.StdOutReporter(True))
        stats = neat.StatisticsReporter()
        p.add_reporter(stats)
        p.add_reporter(neat.Checkpointer(50))
    
        # 迭代300次
        winner = p.run(eval_genomes, 300)
    
        # 显示最佳网络
        print('\nBest genome:\n{!s}'.format(winner))
        print('\nOutput:')
        winner_net = neat.nn.FeedForwardNetwork.create(winner, config)
        for xi, xo in zip(xor_inputs, xor_outputs):
            output = winner_net.activate(xi)
            print("input {!r}, expected output {!r}, got {!r}".format(xi, xo, output))
    
        # 打印网络结构
        node_names = {-1: 'A', -2: 'B', 0: 'A XOR B'}
        visualize.draw_net(config, winner, True, node_names=node_names)
        visualize.plot_stats(stats, ylog=False, view=True)
        visualize.plot_species(stats, view=True)
    
        p = neat.Checkpointer.restore_checkpoint('neat-checkpoint-49')
        p.run(eval_genomes, 10)
    
    
    if __name__ == '__main__':
        local_dir = os.path.dirname(__file__)
        config_path = os.path.join(local_dir, 'config-feedforward')
        run(config_path)
    

    实验结果:

      生成的.svg后缀文件用浏览器就可以打开,实验结果显示的是遗传拓扑神经网络的结构图与其fitness趋势。

    图1.1 网络结构图

    在这里插入图片描述

    图1.2 fitness趋势图

    在这里插入图片描述

    图1.3 物种形成变化图

    在这里插入图片描述

    实验结果:

    ****** Running generation 139 ****** 
    
    Population's average fitness: 2.54573 stdev: 0.49305
    Best fitness: 3.92277 - size: (2, 5) - species 30 - id 18565
    
    Best individual in generation 139 meets fitness threshold - complexity: (2, 5)
    
    Best genome:
    Key: 18565
    Fitness: 3.9227726535092953
    Nodes:
    	0 DefaultNodeGene(key=0, bias=-0.36935409061892416, response=1.0, activation=sigmoid, aggregation=sum)
    	2815 DefaultNodeGene(key=2815, bias=-4.043413198029619, response=1.0, activation=sigmoid, aggregation=sum)
    Connections:
    	DefaultConnectionGene(key=(-2, 0), weight=1.2407529943809679, enabled=True)
    	DefaultConnectionGene(key=(-2, 2815), weight=3.280828495015102, enabled=True)
    	DefaultConnectionGene(key=(-1, 0), weight=1.094918491185449, enabled=True)
    	DefaultConnectionGene(key=(-1, 2815), weight=1.2692785642422044, enabled=True)
    	DefaultConnectionGene(key=(2815, 0), weight=-2.3709331394024136, enabled=True)
    
    # 解释:node_names = {-1: 'A', -2: 'B', 0: 'A XOR B'},2815:’中间一个节点’
    
    Output:
    input (0.0, 0.0), expected output (0.0,), got [0.1362525265929158]
    input (0.0, 1.0), expected output (1.0,), got [0.9837112565200653]
    input (1.0, 0.0), expected output (1.0,), got [0.9741136148621398]
    input (1.0, 1.0), expected output (0.0,), got [0.2402647859926438]
    Mean genetic distance 3.212, standard deviation 1.097
    Mean genetic distance 3.247, standard deviation 1.132
    Mean genetic distance 3.161, standard deviation 1.000
    Mean genetic distance 3.032, standard deviation 0.971
    Mean genetic distance 3.048, standard deviation 1.073
    Mean genetic distance 3.139, standard deviation 1.137
    Mean genetic distance 3.057, standard deviation 1.185
    Mean genetic distance 3.005, standard deviation 1.135
    Mean genetic distance 3.010, standard deviation 1.097
    Mean genetic distance 3.049, standard deviation 1.195
    

    所有代码和结果在我的码云里
    https://gitee.com/rengarwang/neat_XOR

    附加,RNN(循环神经网络)讲解:

      神经网络可以当做是能够拟合任意函数的黑盒子,只要训练数据足够,给定特定的x,就能得到希望的y
    在这里插入图片描述

      将神经网络模型训练好之后,在输入层给定一个x,通过网络之后就能够在输出层得到特定的y,那么既然有了这么强大的模型,为什么还需要RNN(循环神经网络)呢?
      他们都只能单独的处理一个个的输入,前一个输入和后一个输入是完全没有关系的。但是,某些任务需要能够更好的处理序列的信息,即前面的输入和后面的输入是有关系的。
      比如,当我们在理解一句话的意思时,孤立的理解这句话的每个词是不够的,我们需要处理这些词连接起来的整个序列;当我们处理视频的时候,我们也不能只单独的去分析每一帧,而要分析这些帧连接起来的整个序列。
      RNN结构,一个简单的循环神经网络,
    在这里插入图片描述

      如果把上面有W的那个带箭头的圈去掉,它就变成了最普通的全连接神经网络。x是一个向量,它表示输入层的值(这里面没有画出来表示神经元节点的圆圈);s是一个向量,它表示隐藏层的值(这里隐藏层面画了一个节点,你也可以想象这一层其实是多个节点,节点数与向量s的维度相同);U是输入层到隐藏层的权重矩阵,o也是一个向量,它表示输出层的值;V是隐藏层到输出层的权重矩阵。那么,现在我们来看看W是什么。循环神经网络的隐藏层的值s不仅仅取决于当前这次的输入x,还取决于上一次隐藏层的值s。权重矩阵 W就是隐藏层上一次的值作为这一次的输入的权重。
    在这里插入图片描述

      从上图就能够看到,上一时刻的隐藏层是如何影响当前时刻的隐藏层的。
      如果把上面的图展开,循环神经网络也可以成下面这个样子:
    在这里插入图片描述

      这个网络在t时刻接收到输入 之后,隐藏层的值是 ,输出值是 。关键一点是, 的值不仅仅取决于 ,还取决于 。我们可以用下面的公式来表示循环神经网络的计算方法:
    在这里插入图片描述
      为了简单说明问题,偏置都没有包含在公式里面。

    展开全文
  • 基于社交实值条件的拓扑神经网络推荐算法.pdf
  • 遗传拓扑神经网络

    2020-01-27 12:08:16
    上一节我们讲到了遗传演化神经网络今天为大家讲解遗传拓扑神经网络6.1 遗传拓扑神经网络Kenneth O. Stanley等人[9]提出的遗传拓扑神经网络(NEAT算法)同样也是结合了神...

    上一节我们讲到了

    遗传演化神经网络

    今天为大家讲解

    遗传拓扑神经网络

    6.1 遗传拓扑神经网络

    Kenneth O. Stanley等人[9]提出的遗传拓扑神经网络(NEAT算法)同样也是结合了神经网络和遗传算法产生的一种全新模型。它与6.1节介绍的遗传演化神经网络不同的地方在于加入了交叉操作。不过它的年代比较久远了,是来自2003年的一篇论文。因为近些年来计算机算力的提升与强化学习的兴起,遗传拓扑神经网络又走进了人们的视野。

    6.2.1 遗传拓扑神经网络原理

    正如之前的6.1节所说,遗传算法是个通用框架,因此我们需要根据具体的问题来定义遗传算法。不过,既然它是框架,那它就会有通用的几部分供我们选择,因此博主在此给大家先讲下整体的流程。

    整体框架可分为三部分:交叉、变异与适应度。不过虽然整体的流程是一致的,但是因为问题不同,我们定义的基因也有所不同,那交叉与变异也会随之变化。

    这篇论文将神经元及其连接定义成基因组,而遗传演化神经网络论文是将网络层及其学习率定义成基因组,大家可以对比着学习两者的异同,这样也能更好地感受为什么说遗传算法是解决一般性问题的通用框架,就是因为我们可以根据问题去定义基因组。

    6.2.2 算法核心

    1) 超参数设置

    个体基因:(结点链接与结点类型)

    种群规模:150

    物种划分:基于权值相似度划分物种

    2) 伪代码

    1.  while condition:  
    2.    if random.random < 交叉率:
    3.      选择操作(适应度越高,越容易被选中)  
    4.      物种内交叉  
    5.      if random.random < 变异率:
    6.        变异操作  
    7.      评估适应度  
    8.    else:  # 直接变异  
    9.      if random.random < 变异率:
    10.         变异操作  
    11.       评估适应度  
    12.    # 淘汰操作  
    13.       每个物种保留一定数量的个体  
    14.    if random.random < 灭绝率:
    15.       灭绝最差的物种  
    16.       种群间的物种交叉生成亚种, 弥补新的物种  
    17.     
    18.   conditon:迭代次数 or fittness达到设定的阈值  
    19.   评估适应度:fitness = 1/(训练集的误差)^2  
    20.   这里的适应度函数是自定义的,大家可以根据自己的想法去定义。 
    

    3) 交叉操作

    论文通过一个链表定义基因的节点连接,选择两个个体进行交叉的时候,按照链表的顺序,逐一操作,最后生成新的子代。如图 6.2所示。

    图 6.2 交叉操作

    4) 变异操作

    同样地,变异操作也是在链表中进行,且会有两种变异:增加网络连接和增加网络节点,如图 6.3所示。

    图 6.3 变异操作

    6.2.3 NEAT实验

    具体代码见链接

    https://github.com/ChileWang0228/Deep-Learning-With-Python/tree/master/chapter6/6_2_3_Neat

    论文作者开源了NEAT的代码,所以我们可以通过官网的例子来巩固刚刚所学。官网的例子为实现一个XOR异或操作的网络。伪代码如下:

    1.  """ 
    2.  异或:输入相异,输出1, 输入相同,输出0 
    3.  """  
    4.  xor_inputs = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]  
    5.  xor_outputs = [(0.0,),    (1.0,),     (1.0,),     (0.0,)]  
    

    1) 可视化操作

    而且论文的作者也在代码中加入了可视化操作,为了能使用其可视化功能,我们需在命令行输入以下命令。

    1.  windows 用户:
    2.  cmd命令行输入以下命令  
    3.  conda install -c conda-forge graphviz  
    4.  conda install -c conda-forge python-graphviz  
    5.    
    6.  linux 用户:
    7.  命令行输入以下命令  
    8.  sudo apt-get install graphviz  
    

    2) NEAT配置文件

    因为论文作者对整个算法进行了很好得包装,所以我们只需要修改配置文件的相应参数,就可以运行Neat算法了,下面给大家介绍下Neat算法的配置文件,官网有对配置文件更详细的解释,这里标注只是标注一些自己用到的参数。

    1.  #chapter6/6_2_3_Neat/config-feedforward
    2.  #实验的超参数设置#  
    3.  
    4.  [NEAT]  
    5.  fitness_criterion     = max  
    6.  fitness_threshold     = 3.9  # 适应度的阈值  
    7.  pop_size              = 150  # 种群规模  
    8.  reset_on_extinction   = False  
    9.    
    10.  [DefaultGenome]  
    11.  # node activation options  # 结点的激励函数  
    12.  activation_default      = sigmoid  
    13.  activation_mutate_rate  = 0.0  
    14.  activation_options      = sigmoid  
    15.    
    16.  # node aggregation options  # 结点的聚合选择 (一般默认)  
    17.  aggregation_default     = sum  
    18.  aggregation_mutate_rate = 0.0  
    19.  aggregation_options     = sum  
    20.    
    21.  # node bias options  # 结点的偏置选择  
    22.  bias_init_mean          = 0.0  
    23.  bias_init_stdev         = 1.0  
    24.  bias_max_value          = 30.0  
    25.  bias_min_value          = -30.0  
    26.  bias_mutate_power       = 0.5  
    27.  bias_mutate_rate        = 0.7  
    28.  bias_replace_rate       = 0.1  
    29.    
    30.  # genome compatibility options  # 基因组兼容性选项 
    31.  compatibility_disjoint_coefficient = 1.0  
    32.  compatibility_weight_coefficient   = 0.5  
    33.    
    34.  # connection add/remove rates  # 连接增加/删除的概率
    35.  conn_add_prob           = 0.5  
    36.  conn_delete_prob        = 0.5  
    37.    
    38.  # connection enable options  
    39.  enabled_default         = True  
    40.  enabled_mutate_rate     = 0.01  
    41.    
    42.  feed_forward            = True  # 是否加入RNN神经元  
    43.  initial_connection      = full  
    44.    
    45.  # node add/remove rates  # 结点的添加和删除概率  
    46.  node_add_prob           = 0.2  
    47.  node_delete_prob        = 0.2  
    48.    
    49.  # network parameters  # 输入层、输出层、隐藏层的神经元个数  
    50.  num_hidden              = 2  
    51.  num_inputs              = 2  
    52.  num_outputs             = 1  
    53.    
    54.  # node response options  # 节点相应选项
    55.  response_init_mean      = 1.0  
    56.  response_init_stdev     = 0.0  
    57.  response_max_value      = 30.0  
    58.  response_min_value      = -30.0  
    59.  response_mutate_power   = 0.0  
    60.  response_mutate_rate    = 0.0  
    61.  response_replace_rate   = 0.0  
    62.    
    63.  # connection weight options # 连接权重选项 
    64.  weight_init_mean        = 0.0  
    65.  weight_init_stdev       = 1.0  
    66.  weight_max_value        = 30  
    67.  weight_min_value        = -30  
    68.  weight_mutate_power     = 0.5  
    69.  weight_mutate_rate      = 0.8  
    70.  weight_replace_rate     = 0.1  
    71.    
    72.  [DefaultSpeciesSet]    
    73.  # genomic distance小于此距离被认为是同一物种  
    74.  compatibility_threshold = 3.0   
    75.    
    76.  [DefaultStagnation]  
    77.  species_fitness_func = max  
    78.  max_stagnation       = 20  
    79.  species_elitism      = 2  
    80.    
    81.  [DefaultReproduction]  
    82.  elitism            = 2   # 保留最优的个体遗传到下一代的个数  
    83.  survival_threshold = 0.2  # 每一代每个物种的存活率  
    

    3)主函数

    1.  # /chapter6/6_2_3_Neat/xor.ipynb
    2.  from __future__ import print_function  
    3.  import os  
    4.  import neat  
    5.  import visualize  
    6.    
    7.  # XOR异或的输入输出数据  
    8.  xor_inputs = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]  
    9.  xor_outputs = [   (0.0,),     (1.0,),     (1.0,),     (0.0,)]  
    10.    
    11.    
    12.  def eval_genomes(genomes, config):  
    13.      # 评估函数      
    14.      for genome_id, genome in genomes:  
    15.          genome.fitness = 4.0  
    16.          net = neat.nn.FeedForwardNetwork.create(genome, config)  
    17.          for xi, xo in zip(xor_inputs, xor_outputs):  
    18.              output = net.activate(xi)  
    19.              genome.fitness -= (output[0] - xo[0]) ** 2  
    20.    
    21.    
    22.  def run(config_file):  
    23.      # 读取配置配置文件  
    24.      config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,  
    25.                           neat.DefaultSpeciesSet, neat.DefaultStagnation,  
    26.                           config_file)  
    27.    
    28.      # 创建种群  
    29.      p = neat.Population(config)  
    30.    
    31.      # 打印训练过程  
    32.      p.add_reporter(neat.StdOutReporter(True))  
    33.      stats = neat.StatisticsReporter()  
    34.      p.add_reporter(stats)  
    35.      p.add_reporter(neat.Checkpointer(5))  
    36.    
    37.      # 迭代300次  
    38.      winner = p.run(eval_genomes, 300)  
    39.        
    40.      # 显示最佳网络  
    41.      print('\nBest genome:\n{!s}'.format(winner))  
    42.      print('\nOutput:')  
    43.      winner_net = neat.nn.FeedForwardNetwork.create(winner, config)  
    44.      for xi, xo in zip(xor_inputs, xor_outputs):  
    45.          output = winner_net.activate(xi)  
    46.          print("input {!r}, expected output {!r}, got {!r}".format(xi, xo, output))  
    47.    
    48.      node_names = {-1:'A', -2: 'B', 0:'A XOR B'}  
    49.      visualize.draw_net(config, winner, True, node_names=node_names)  
    50.      visualize.plot_stats(stats, ylog=False, view=True)  
    51.      visualize.plot_species(stats, view=True)  
    52.    
    53.      p = neat.Checkpointer.restore_checkpoint('neat-checkpoint-4')  
    54.      p.run(eval_genomes, 10)  
    55.    
    56.    
    57.  if __name__ == '__main__':  
    58.      config_path = os.path.join('config-feedforward')  
    59.      run(config_path)  
    

    4) 实验结果

    生成的.svg后缀文件用google浏览器打开即可。实验结果显示的是遗传拓扑神经网络的结构图与其fitness趋势,如图 6.4与图 6.5所示。大家在掌握了整个流程之后,可以把官方代码下载下来,调一下配置文件,就可以运行了。当然,有些读者可能会想着自己定义一个新的交叉或者变异操作,这就需要对着Neat算法的源码修改相应的代码了。

    图 6.4 网络结构图

    图 6.5 fitness趋势图

    小结

    好了,到这里,我们就已经将遗传算法与神经网络相结合的知识点讲完了。

    最后总结一下,由于近几年来算力与存储的提升,遗传算法与深度学习的结合逐渐走入人们的视野,不过应用比较广泛的仍然是在强化学习领域。究其原因还是因为强化学习的本质和遗传算法一致,都是适者生存,不适者淘汰。

    比如有人用Neat算法训练了个超级马里奥,其实就是训练一个机器人在游戏环境中生存,适应度函数可以定义为在游戏里的得分亦或者是在游戏中的存活时间,在迭代过程中,存活下来的机器人一定是对当前环境反馈最佳的。

    当然了,这里提及两期遗传算法的实验,主要是想让大家对比其中异同,掌握遗传算法的流程精髓,顺带了解一下强化学习的本质。

    参考文献

    [9] Stanley K O, Miikkulainen R. Evolving neural networks through augmenting topologies[J]. Evolutionary computation, 2002, 10(2): 99-127.

    下一期,我们将讲授

    生成对抗网络

    敬请期待~

    关注我的微信公众号~不定期更新相关专业知识~

    内容 |阿力阿哩哩 

    编辑 | 阿璃 

    点个“在看”,作者高产似那啥~

    展开全文
  • 一个利用VB语言编写的BP人工神经网络拓扑优化算法,包含文件,代码在文件里面
  • SnakeAI - 使用遗传算法训练一个神经网络来玩贪吃蛇
  • BP(back propagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,是目前应用最广泛的神经网络
  • 常见神经网络结构拓扑

    千次阅读 2021-03-19 11:38:18
    神经网络的结构呈指数型增长的趋势,下图展示了多部分神经网络经典的拓扑结构。 P --> FF : 增加了一层隐藏层,所有节点为全连接 FF --> RBF : 使用径向基函数(Radical Basis Function,RBF)作为激活函数...
  • 提出了一种采用拓扑学习神经网络进行度量学习和嵌入的框架。 为了强调常规嵌入方法(例如多维缩放和Isomap)在时间和空间上效率低下的问题,我们利用了拓扑学习神经网络(例如增长的神经气体和自组织增量)的增量...
  •  当使用演化算法开发神经网络拓扑时,我们可以设想有一幅可以用来代表适应性大小的、起伏不平的场景图(landscape),在这一场景图中,每一个点代表网络结构的一种类型。所谓 演化型人工神经网络 EANN ...
  • 基于拓扑结构神经网络的绩效管理评价研究.pdf
  • 人工智能-脉冲神经网络拓扑结构的模型构建与仿真分析.pdf
  • 提出一种在大规模光电混合神经网络系统中实现可编程拓扑重构的有效方法。文中介绍了这种方法的原理、运用技术以及采用这种方法在已有NP1024光学数字神经网络处理器中运行单层反馈型和多层前馈型等不同网络拓扑结构的...
  • 不同拓扑结构脉冲神经网络抗扰功能对比分析.pdf
  • 基于基团拓扑的遗传神经网络工质临界温度预测.pdf
  • 具有拓扑学习神经网络的增量非参数回归的高斯混合框架
  • 木马神经网络拓扑检测_Topological Detection of Trojaned Neural Networks.pdf
  • 该算法使用神经网络对不同相似性指标的数值特征进行学习,同时采用标准粒子群算法对神经网络进行了优化,并通过优化学习后的神经网络模型计算出融合指标。多个真实网络数据集上实验表明,该算法的预测精度明显高于...
  • 基于卷积神经网络拓扑量子码译码研究.pdf
  • 多路阀阀芯节流槽拓扑结构组合的神经网络模型.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,599
精华内容 7,439
关键字:

拓扑 神经网络