自研进化模拟器生物往复晃动不趋近食物 代码问题排查求助
存在的核心问题
- 训练目标设定错误:原代码中
move函数内计算的ny、nx作为训练目标完全不符合预期,导致网络学习方向完全错误 - 权重更新逻辑错误:
Think模块的adjust方法中更新weightbx时错误使用了y方向的误差erry,而非x方向的errx - 数值计算错误:主模块
move函数中计算nx时误写为减dely,应该减delx - 学习率过大:初始学习率
lr=1会导致权重更新幅度过大,模型参数反复振荡,表现为生物来回移动 - 类属性误用:
Creature的brain被定义为类属性,所有实例会共用同一个神经网络 - 代码缩进错误:多处Python缩进不符合规范,会直接导致运行报错
修复后代码
主程序模块
import turtle, random, Think, time world = turtle.Screen() world.setup(400, 400) # 坐标范围O(0,0),X(180,0),X'(-185,0),Y(0,185),Y'(0,-180) def growfood(): food = turtle.Turtle() food.color("green") food.shape("circle") food.shapesize(0.4) food.penup() food.speed(0) food.goto(random.randint(-185, 180), random.randint(-180, 185)) return food class Creature: body = None def __init__(self): self.body = turtle.Turtle() self.body.penup() # 取消注释避免留下移动轨迹 self.body.color("blue") self.body.shape("square") self.body.shapesize(0.5) self.brain = Think.neuron() # 改为实例属性,每个生物单独一个脑 def move(self, y, x, dely, delx): self.body.goto(self.body.xcor() + x*5, self.body.ycor() + y*5) # 修正训练目标:目标输出为距离的符号,即向食物方向移动 target_y = 1 if dely > 0 else (-1 if dely < 0 else 0) target_x = 1 if delx > 0 else (-1 if delx < 0 else 0) self.brain.adjust(dely, delx, target_y, target_x, y, x) def locatefood(self): delx = food.xcor() - self.body.xcor() dely = food.ycor() - self.body.ycor() return dely, delx def think(self): dely, delx = self.locatefood() y, x = self.brain.think(dely, delx) print(f"(x,y)=({x},{y})") self.move(y, x, dely, delx) crt = Creature() food = growfood() run = 0 while run < 120: world.update() crt.think() if crt.body.distance(food) < 15: food = growfood() time.sleep(0.2) # 调小等待时间运行更流畅
Think神经网络模块
from math import tanh from random import random class neuron: def __init__(self): self.biasy, self.biasx = 1, 1 self.lr = 0.0001 # 调小学习率避免振荡 self.weighty, self.weightx, self.weightby, self.weightbx = random(), random(), random(), random() def adjust(self, dely, delx, target_y, target_x, y, x): # 修正y方向权重更新 erry = target_y - y self.weighty += erry * dely * self.lr self.weightby += erry * self.biasy * self.lr # 修正x方向权重更新,使用x方向误差errx errx = target_x - x self.weightx += errx * delx * self.lr self.weightbx += errx * self.biasx * self.lr # 修正此处误用erry的问题 def think(self, dely, delx): y = dely * self.weighty + self.biasy * self.weightby x = delx * self.weightx + self.biasx * self.weightbx y = tanh(y) if y > 0: y = 1 elif y < 0: y = -1 else: y = 0 x = tanh(x) if x > 0: x = 1 elif x < 0: x = -1 else: x = 0 return y, x
内容的提问来源于stack exchange,提问作者Himel
相关产品推荐
相关产品推荐

