Flappy Bird线性Q学习近似智能体无学习效果,求技术帮助
我来自瑞士,英语并非母语,在此先致歉。目前我正在开发一个强化学习智能体来玩Flappy Bird,采用线性Q学习近似方法,但智能体似乎无法学习。它持续获得相同的奖励,我不确定是代码存在问题,还是需要更长的训练时长(比如8小时)。我甚至尝试过DQN算法,但仍然没有效果。
以下是你的代码:
import flappy_bird_gymnasium # Assuming this is a custom environment import gymnasium as gym import numpy as np import matplotlib.pyplot as plt from tqdm import tqdm from random import * env = gym.make("FlappyBird-v0", render_mode="rgb_array") lr = 0.01 decay = 0.0000001 max_steps = 1000 gamma = 0.95 min_eps = 0.001 max_eps = 1 neps = 100000 W = np.random.rand(12, 2) print(env.observation_space) def plot_win_rate(rewards_all_episodes): rewards_optimal = np.array(rewards_all_episodes) rewards_optimal = np.array([0 if x == -1 else x for x in rewards_optimal]) rewards_optimal = rewards_optimal.cumsum() win_rate_optimal = rewards_optimal / np.arange(1, len(rewards_all_episodes) + 1) plt.plot(np.arange(1, len(rewards_all_episodes) + 1), win_rate_optimal) plt.xlabel('Episode') plt.ylabel('Win Rate') plt.title('Win Rate per Episode') plt.show() def f(state): return np.array(state).reshape(12, -1) def epsilon_greedy(W, epsilon, state): features = f(state) if np.random.uniform(0, 1) > epsilon: action = np.argmax(np.dot(W.T, features)) retur=0 else: action = 0 if uniform(0,1)>0.07 else 1 retur=1 return action, retur def gradient(X,W,Y): m = X.shape[0] return (1/m) * (X.T @ (X @ W - Y)) def regression(X, W,Y): W-=lr*gradient(X,W,Y) return W def update(W, state, reward, newstate): q_values = np.dot(f(state).T, W) next_q_values = np.dot(f(newstate).T, W) W += lr * np.outer(f(state), (reward + gamma * np.max(next_q_values) - q_values)) return W def train(neps, min_eps, max_eps, decay, env, max_steps, W, fr): rewards_all_episodes = [] for episode in tqdm(range(1, neps + 1)): epsilon = min_eps + (max_eps - min_eps) * np.exp(-decay * episode) state, _ = env.reset() rewards = 0 X=[] Y=[] while True: action, retur= epsilon_greedy(W, epsilon, state) new_state, reward, done, _, _ = env.step(action) W=update(W, state, reward, new_state) rewards += reward X.append(reward) Y.append(state) if done: rewards_all_episodes.append(rewards) break state = new_state if episode % fr == 0: q_values = np.dot(f(state).T, W) print(W) print("epsilon ", epsilon) print("\nQ-values:", q_values) print("Episode {}: Average Reward: {}".format(episode, rewards)) return W, rewards_all_episodes W, rewards_all_episodes = train(neps, min_eps, max_eps, decay, env, max_steps, W, 2500) plot_win_rate(rewards_all_episodes) np.save("trained_weightsQL.npy", W) print(rewards_all_episodes, "gamma**step*") while True: pass
核心问题排查与修正建议
特征映射函数
f(state)逻辑错误
FlappyBird-v0的观测空间通常是4维(鸟的y坐标、垂直速度、管道x偏移、管道间隙y坐标),你直接将其reshape为12维,本质是对原始特征的无意义拆分,导致Q值计算完全偏离预期。正确做法是做特征扩展,比如生成原始特征的二次组合、常数项等,示例:def f(state): s = np.array(state) # 基础特征+二次组合+常数项,扩展到11维(可调整) features = np.concatenate([s, s**2, s[:2]*s[2:], [1]]) return features.reshape(-1, 1)同时要对应调整权重
W的维度(比如11×2)。ε-贪心策略的随机动作分布不合理
代码中随机动作93%概率选0(不跳),7%选1(跳),这种极端分布会让智能体无法探索到有效的跳跃时机。改成均匀随机选择动作:action = np.random.choice([0, 1])ε衰减系数过小
当前decay=0.0000001导致10万轮训练后ε仍接近1,智能体几乎全程随机探索,根本无法利用学到的策略。调整为decay=0.0001,让ε快速降到合理的探索-利用平衡区间。学习率设置偏大
lr=0.01对于线性近似来说容易导致权重震荡,建议先降到0.001,根据训练曲线再微调。冗余代码干扰逻辑
gradient、regression函数以及train中的X、Y列表均未被使用,直接删除以简化代码,避免混淆。奖励处理错误
plot_win_rate中将-1的奖励改为0,会扭曲训练的反馈信号,直接用原始奖励计算即可:def plot_win_rate(rewards_all_episodes): rewards_cumsum = np.cumsum(rewards_all_episodes) win_rate = rewards_cumsum / np.arange(1, len(rewards_all_episodes)+1) plt.plot(np.arange(1, len(rewards_all_episodes)+1), win_rate) plt.xlabel('Episode') plt.ylabel('Average Cumulative Reward') plt.title('Reward Trend per Episode') plt.show()
训练建议
先修正上述问题后,尝试跑1-2万轮训练,观察奖励曲线是否有上升趋势。如果仍无改善,再考虑:
- 调整γ值(比如0.99,增强长期奖励的权重)
- 尝试对观测特征做归一化处理
- 验证环境的奖励机制是否符合预期(比如每存活一步+1,撞管道-1)
内容的提问来源于stack exchange,提问作者Aleksander

