程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python:neat-python遺傳拓撲神經網絡初步使用

編輯:Python

neat-python是對遺傳算法的拓展,結合了神經網絡和遺傳算法的模型,本文旨在使用不在講解。

本文利用neat計算x²來進行一個neat的初步使用,通過本文教程可以大致使用neat完成一些基礎任務。

安裝neat

pip install neat-python

一、配置config文件

neat利用config文件來進行參數配置,具體的配置文件模板可以在官方文檔中找到:配置文件模板地址。

1.1 模板

[NEAT]
fitness_criterion = max
fitness_threshold = 3.9
pop_size = 50
reset_on_extinction = False
[DefaultGenome]
# node activation options
activation_default = square
activation_mutate_rate = 0.0
activation_options = square
# 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
initial_connection = full
# node add/remove rates
node_add_prob = 0.2
node_delete_prob = 0.2
# network parameters
num_hidden = 0
num_inputs = 1
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]
compatibility_threshold = 3.0
[DefaultStagnation]
species_fitness_func = max
max_stagnation = 20
species_elitism = 2
[DefaultReproduction]
elitism = 2
survival_threshold = 0.2

文件取名為config-feedforward.txt。
本文將不闡述每一個參數的內容,僅介紹將會使用的一些參數。

1.2.1 選擇激活函數

在本文中,我們需要計算x²,所以首先在腦海中需要明白我們的圖形產出是一個二次方程圖形:

所以我們選擇了:

activation_default = square
activation_mutate_rate = 0.0
activation_options = square

其他的激活函數可以查看官方文檔:激活函數列表。
在使用neat時,需要明白我們輸出的結果是什麼,比如本文,我們知道結果是平方,所以用square;如果需要輸出是或否,那可以選擇sigmoid。

1.2.2 輸入輸出

在本文中,我們只有一個x,得到的結果只有一個y,例如2輸出4,3輸出9,所以在這部分我們設置為:

num_hidden = 0
num_inputs = 1
num_outputs = 1

我們沒有隱藏層,如果需要隱藏層,可以設置num_hidden。

1.2.3 種群數量及適應值阈值

本文中,將每一個族群設置為50個,阈值設為3.9,表示每一次計算會有50個子代,當適應值達到3.9,將停止迭代:

fitness_threshold = 3.9
pop_size = 50

1.2.4 其他參數

我們需要設置的參數絕大部分都是上面的內容,其他參數特殊情況特殊配置,一般使用情況下可以直接使用默認參數值。

二、編寫neat

local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward.txt') # 配置文件名稱
config = neat.config.Config(
neat.DefaultGenome,
neat.DefaultReproduction,
neat.DefaultSpeciesSet,
neat.DefaultStagnation,
config_path
)# 配置文件中每一組
p = neat.Population(config)
p.add_reporter(neat.StdOutReporter(True))
stats = neat.StatisticsReporter()
p.add_reporter(stats)
winner = p.run(eval_genomes, 1000) # 定義一個eval_genomes方法進行迭代,總共迭代100次

2.1 eval_genomes函數

def eval_genomes(genomes, config):
# x ** 2
x_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 樣本
y_list = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] # 樣本結果
for genome_id, genome in genomes: # 循環50個子代
genome.fitness = 4.0 # 初始化適應度
net = neat.nn.FeedForwardNetwork.create(genome, config) # 創建前饋網絡
for i, x in enumerate(x_list):
output = net.activate((x, )) # 計算
genome.fitness -= (output[0] - y_list[i]) ** 2 # 使用誤差來進行適應值的降低

當進行p.run函數時,將進行eval_genomes函數的調用,在eval_genomes函數中,適當地給予每一個子代(基因)適應度的調整,來選擇合適的子代,當子代達到我們的適應值阈值時,將會停止迭代。

三、運行

Population's average fitness: -42724756.48750 stdev: 220655177.29976
Best fitness: 3.98619 - size: (1, 1) - species 1 - id 3838
Best individual in generation 87 meets fitness threshold - complexity: (1, 1)

本次運行結果到第87代已經產生最佳適應度為3.98612的子代,我們可以通過保存計算結果來進行使用。

四、保存計算結果

4.1 保存

pickle.dump(winner, open("best.pickle", "wb"))

4.2 調用

path = "xx/xx/xx/best.pickle"
with open(path, "rb") as f:
net = pickle.load(f)
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward.txt')
config = neat.config.Config(
neat.DefaultGenome,
neat.DefaultReproduction,
neat.DefaultSpeciesSet,
neat.DefaultStagnation,
config_path
)
net = neat.nn.FeedForwardNetwork.create(net, config)
output = net.activate((4,))
print(output[0])

輸出結果為:

15.842392247827298

可以看到,結果已經是我們想要的了。

五、完整代碼

# -*- coding: utf-8 -*-
import os
import neat
import pickle
def eval_genomes(genomes, config):
# x ** 2
x_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_list = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
for genome_id, genome in genomes:
genome.fitness = 4.0
net = neat.nn.FeedForwardNetwork.create(genome, config)
for i, x in enumerate(x_list):
output = net.activate((x, ))
genome.fitness -= (output[0] - y_list[i]) ** 2
if __name__ == '__main__':
path = "xx/xx/xx/best.pickle"
with open(path, "rb") as f:
net = pickle.load(f)
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward.txt')
config = neat.config.Config(
neat.DefaultGenome,
neat.DefaultReproduction,
neat.DefaultSpeciesSet,
neat.DefaultStagnation,
config_path
)
net = neat.nn.FeedForwardNetwork.create(net, config)
output = net.activate((4,))
print(output[0])
# local_dir = os.path.dirname(__file__)
# config_path = os.path.join(local_dir, 'config-feedforward.txt')
#
# config = neat.config.Config(
# neat.DefaultGenome,
# neat.DefaultReproduction,
# neat.DefaultSpeciesSet,
# neat.DefaultStagnation,
# config_path
# )
#
# p = neat.Population(config)
#
# p.add_reporter(neat.StdOutReporter(True))
# stats = neat.StatisticsReporter()
# p.add_reporter(stats)
#
# winner = p.run(eval_genomes, 1000)
# pickle.dump(winner, open("best.pickle", "wb"))

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved