You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于遗传算法的Flappy Bird AI无性能提升问题求助

Flappy Bird遗传算法训练无提升问题排查

以下是针对你的代码和训练无提升问题的几个关键排查点:

1. 适应度计算函数未实现(核心问题)

你提到适应度是小鸟存活时长的帧计数,但未提供calculateFitness()的实现代码。如果这个函数没有正确计算并赋值每只鸟的fitness属性,会导致:

  • 轮盘赌选择(rouletteWheelSelection)中的totalFitness为0或无意义值,选择逻辑完全随机,无法筛选出优秀个体。
  • 遗传算法失去进化压力,种群无法向更优方向迭代。

修正建议:
实现calculateFitness(),比如将存活帧数作为原始适应度,再进行归一化处理(避免个别高适应度个体垄断选择):

const calculateFitness = () => {
  // 计算总存活帧数
  let totalFrames = savedBirds.reduce((sum, bird) => sum + bird.score, 0);
  // 归一化适应度,让总和为1(可选,也可以用原始值但需确保差距合理)
  savedBirds.forEach(bird => {
    bird.fitness = bird.score / totalFrames;
  });
}

注:需确保每只鸟的score属性在存活期间正确累加帧计数

2. 交叉函数存在数组越界与参数不匹配问题

你的crossOver函数中,用同一个splitPoint对所有权重和偏置数组进行交叉,但不同参数数组的长度差异极大:

  • weights_ih.data:4输入×4隐藏层 = 16个元素
  • weights_ho.data:4隐藏层×1输出 = 4个元素
  • bias_h.data:4个元素(隐藏层偏置)
  • bias_o.data:1个元素(输出层偏置)

当splitPoint大于4时,循环中访问weights_ho.data[i]、bias_h.data[i]会越界,导致:

  • 代码报错(可能被忽略)
  • 错误地覆盖不存在的数组位置,破坏神经网络参数
  • 偏置bias_o永远不会被交叉(因为splitPoint几乎必然大于0,而它只有1个元素)

修正建议:
为不同的参数数组单独生成交叉点,避免越界:

const crossOver = (bird1, bird2) => {
  let offspring = bird1.brain.copy();
  
  // 输入层到隐藏层权重交叉
  const ihSplit = Math.floor(Math.random() * offspring.weights_ih.data.length);
  for (let i = ihSplit; i < offspring.weights_ih.data.length; i++) {
    offspring.weights_ih.data[i] = bird2.brain.weights_ih.data[i];
  }
  
  // 隐藏层到输出层权重交叉
  const hoSplit = Math.floor(Math.random() * offspring.weights_ho.data.length);
  for (let i = hoSplit; i < offspring.weights_ho.data.length; i++) {
    offspring.weights_ho.data[i] = bird2.brain.weights_ho.data[i];
  }
  
  // 隐藏层偏置交叉
  const hBiasSplit = Math.floor(Math.random() * offspring.bias_h.data.length);
  for (let i = hBiasSplit; i < offspring.bias_h.data.length; i++) {
    offspring.bias_h.data[i] = bird2.brain.bias_h.data[i];
  }
  
  // 输出层偏置交叉(单独处理,因为只有1个元素)
  if (Math.random() > 0.5) {
    offspring.bias_o.data[0] = bird2.brain.bias_o.data[0];
  }
  
  return offspring;
}

3. 轮盘赌选择的边界处理缺陷

当totalFitness为0时(比如所有鸟的fitness未正确赋值),Math.random() * totalFitness会得到0,此时循环中fitnessSum累加后可能永远无法满足fitnessSum >= rand,导致函数返回undefined,进而在crossOver中报错。

修正建议:
在rouletteWheelSelection开头增加边界判断,确保至少能返回一个个体:

const rouletteWheelSelection = () => {
  let totalFitness = savedBirds.reduce((sum, bird) => sum + bird.fitness, 0);
  
  // 处理总适应度为0的情况,随机返回一个个体
  if (totalFitness === 0) {
    return savedBirds[Math.floor(Math.random() * savedBirds.length)];
  }
  
  const rand = Math.random() * totalFitness;
  let fitnessSum = 0;
  for (let i = 0; i < savedBirds.length; i++) {
    fitnessSum += savedBirds[i].fitness;
    if (fitnessSum >= rand) return savedBirds[i];
  }
  
  // 兜底:如果循环结束未返回,返回最后一个个体
  return savedBirds[savedBirds.length - 1];
}

4. 神经网络输入与输出的合理性问题

  • 输入范围异常:如果管道的top值为负数(超出屏幕顶部),closest.top / height会得到负数,而神经网络通常期望输入在0-1范围内,可能导致模型无法有效学习。建议将输入调整为相对位置,比如小鸟到管道顶部的距离除以高度:
    inputs[1] = (this.y - closest.top) / height; // 小鸟与顶部管道的相对距离
    inputs[2] = (closest.bottom - this.y) / height; // 小鸟与底部管道的相对距离
    
  • 输出阈值与激活函数匹配:如果神经网络输出层使用sigmoid激活,0.5是中间值,但如果初始权重随机范围过大,可能导致输出持续偏向0或1。可以尝试调整变异幅度,或者将阈值改为动态值(比如基于种群平均输出)。

5. 种群保存逻辑的潜在漏洞

在draw函数中,当管道超出屏幕时执行pipes.splice(i, 1),但此时嵌套的鸟类碰撞判断循环可能未完成所有鸟的检测。建议将管道删除逻辑移到鸟类碰撞检测之外:

function draw() {
  if (counter % 150 == 0) {
    pipes.push(new Pipe());
  }
  counter++;
  
  // 先处理管道更新和鸟类碰撞
  for (var i = pipes.length - 1; i >= 0; i--) {
    pipes[i].update();

    for (let j = birds.length - 1; j >= 0; j--) {
      if (pipes[i].hits(birds[j])) {
        savedBirds.push(birds.splice(j, 1)[0]);
      }
    }
  }
  
  // 单独处理管道删除,避免嵌套循环中的索引混乱
  for (var i = pipes.length - 1; i >= 0; i--) {
    if (pipes[i].offscreen()) {
      pipes.splice(i, 1);
    }
  }
  
  // 剩下的逻辑不变
  for (let bird of birds) {
    bird.think(pipes);
    bird.update();
  }
  if (birds.length == 0 ) {
    counter = 0;
    nextGeneration();
    pipes = [];
  }
  background(bgImg);
  for (let bird of birds) {
    bird.show();
  }
  for (let pipe of pipes) {
    pipe.show();
  }
}

内容的提问来源于stack exchange,提问作者Nathace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:40:34