ImportError:无法从neat导入nn模块的技术问题咨询
Hey there, let's tackle this ImportError and break down your code step by step!
一、先解决ImportError问题
The ImportError: cannot import name 'nn' from 'neat' you're hitting is almost certainly due to using the wrong package or an outdated version of NEAT. Here's how to fix it:
1. Install the correct NEAT library
Most people accidentally install a random package named neat instead of the official neuroevolution library, neat-python. Uninstall the wrong one and install the right one:
pip uninstall neat -y pip install neat-python
2. Update your import statements and code
The module structure in neat-python is different from older, unmaintained NEAT versions. Your original imports won't work—here's what to replace them with:
- Replace
from neat import nn, population, statisticswith:from neat.nn.feed_forward import FeedForwardNetwork from neat import Population, StatisticsReporter import neat - The old
nn.create_feed_forward_phenotype(g)is now replaced with:
Note: You'll need anet = FeedForwardNetwork.create(g, config)configobject (loaded from a NEAT config file) to define your network's structure—this is a required part of modern neat-python.
二、代码解析与修复
Let's go through your original code point by point, fixing bugs and explaining what each part does:
Original Code (with issues marked)
from __future__ import print_function import numpy as np import itertools import os from neat import nn, population, statistics # BROKEN IMPORT with open('data.csv', 'rU') as f: #打开PW文件 reader = csv.reader(f) # csv module NOT imported! data = list(list(rec) for rec in csv.reader(f, delimiter=',')) #重复调用csv.reader会跳过第一行 f.close() # 多余:with语句会自动关闭文件 def eval_fitness(genomes): fitness = 0 something = 0 # 未使用的变量 best_fitness = -99999 for g in genomes: fitness = 0 net = nn.create_feed_forward_phenotype(g) # BROKEN METHOD CALL
Key Issues & Fixes
- Missing
csvimport: You usecsv.readerbut never import thecsvmodule—addimport csvat the top. - Broken CSV reading: Calling
csv.reader(f)twice moves the file pointer, so you'll skip the first row of your data. Use a single reader instance instead. - Redundant
f.close(): Thewithstatement automatically closes the file when the block ends, so this line is unnecessary. - Incomplete fitness function: Your
eval_fitnessfunction creates a neural network but doesn't calculate or assign a fitness value to the genome. NEAT needs this to evolve better networks.
Fixed & Complete Example Code
Here's a polished version of your code that works with neat-python:
from __future__ import print_function import numpy as np import itertools import os import csv # 补上缺失的csv导入 from neat.nn.feed_forward import FeedForwardNetwork from neat import Population, StatisticsReporter import neat # 读取CSV数据(修复文件读取逻辑) data = [] with open('data.csv', 'r') as f: reader = csv.reader(f, delimiter=',') data = [list(rec) for rec in reader] # 更简洁的列表推导式 # 加载NEAT配置文件(你需要创建这个文件,定义网络结构等参数) config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction, neat.DefaultSpeciesSet, neat.DefaultStagnation, 'config-feedforward.txt') def eval_fitness(genomes, config): best_fitness = -99999 for genome_id, genome in genomes: # 创建前馈神经网络 net = FeedForwardNetwork.create(genome, config) # 计算适应度(示例逻辑:用CSV数据做输入,对比输出与目标值) fitness = 0 for row in data: # 假设CSV每行前n-1列是输入,最后一列是目标输出 inputs = [float(val) for val in row[:-1]] target_output = float(row[-1]) # 运行神经网络得到输出 network_output = net.activate(inputs)[0] # 适应度:误差越小,适应度越高(这里用负绝对误差) fitness -= abs(network_output - target_output) # 给基因组赋值适应度,NEAT会用这个来选择下一代 genome.fitness = fitness if fitness > best_fitness: best_fitness = fitness # 初始化种群和统计报告器 population = Population(config) stats = StatisticsReporter() population.add_reporter(stats) # 运行NEAT演化(运行50代) population.run(eval_fitness, 50)
内容的提问来源于stack exchange,提问作者Ashraf Hussain

