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

PyTorch优化器未更新权重求助:训练俄罗斯方块AI遇问题

问题分析与修复建议

我帮你梳理下代码里导致权重不更新和y_batch不变的几个关键问题,都是DQN实现里容易踩的坑:

一、模型结构的核心问题(直接导致梯度无法有效传递)

你的CNN模型存在维度不匹配、激活层使用错误的问题,这会让梯度要么消失要么无法计算:

  • Conv2d层输出维度异常:self.hidden1 = Conv2d(1, 1, (22, 10)),假设你的BoardMatrix是(22,10)的棋盘,输入是(1,1,22,10)(batch, channel, H, W),经过这个卷积后输出是(1,1,1,1),再经过MaxPool2d(2,2)直接变成无效张量(核大小超过特征图尺寸),后续Linear层的输入维度完全不对,梯度根本传不回卷积层。
  • 输出层与激活层不匹配:DQN需要输出每个动作对应的Q值,但你最后一层是Linear(10,1)+Softmax(dim=1),输出维度是(batch,1),Softmax起不到任何作用。应该把输出层改成对应动作数量的维度,且DQN通常不需要Softmax(直接输出Q值即可)。
  • Linear层输入维度错误:self.hidden2 = Linear(1, 30)依赖前面卷积的1x1输出,但前面的Pool操作已经破坏了特征图,导致后续层的梯度传递中断。

修复后的模型示例:

class CNN(nn.Module):
    def __init__(self, board_height, board_width):
        super(CNN, self).__init__()
        self.number_of_actions = 5  # left, right, down, up, space
        self.gamma = 0.99  # DQN中gamma通常用0.99,0.01太小会削弱长期奖励影响
        self.final_epsilon = 0.0001
        self.initial_epsilon = 0.1
        self.number_of_iterations = 2000000
        self.replay_memory_size = 10000
        self.minibatch_size = 32
        
        # 输入格式:(batch, channel, H, W) → 比如(32,1,22,10)
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
        self.act1 = nn.ReLU()
        self.pool1 = nn.MaxPool2d(2, 2)  # 输出(16,11,5)
        
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.act2 = nn.ReLU()
        self.pool2 = nn.MaxPool2d(2, 2)  # 输出(32,5,2)
        
        # 计算全连接层输入维度:32*5*2=320
        self.fc1 = nn.Linear(32*5*2, 256)
        self.act3 = nn.ReLU()
        self.fc2 = nn.Linear(256, self.number_of_actions)  # 输出每个动作的Q值

    def forward(self, x):
        x = self.pool1(self.act1(self.conv1(x)))
        x = self.pool2(self.act2(self.conv2(x)))
        x = x.view(x.size(0), -1)  # 展平成一维张量
        x = self.act3(self.fc1(x))
        x = self.fc2(x)
        return x

二、学习循环的逻辑错误(y_batch不变+权重不更新的直接原因)

1. Reward固定为0,y_batch自然无变化

你定义了reward = torch.tensor([[0.]], requires_grad=True),但从未根据游戏结果更新奖励值。比如:消一行给+100分,游戏结束给-1000分,方块成功下落给+1分,这样y_batch才会随游戏过程变化。

2. Replay Memory存储错误

DQN的经验回放需要存储**(state, action, reward, next_state, done)** 五元组,而你只存了self.BoardMatrix,导致采样minibatch时拿不到动作、奖励、下一个状态等关键信息,无法计算TD目标值。

修改回放存储逻辑:

# 每次动作执行后存储经验
state = self.BoardMatrix.copy()
action_idx = 0  # 对应动作的索引:0=left,1=right,2=down,3=up,4=space
reward = self.calculate_reward()  # 自己实现奖励计算函数
next_state = self.BoardMatrix.copy()
done = self.game_over  # 是否游戏结束
replay_memory.append((state, action_idx, reward, next_state, done))

3. Action Batch处理错误

你用action_batch = 0.8这种标量计算q_value完全错误。DQN中应该根据选择的动作,取出对应的Q值,比如用one-hot编码或直接索引:

# 假设action是(minibatch_size,)的张量,每个元素是动作索引
q_value = outputs.gather(1, action.unsqueeze(1)).squeeze(1)

4. Y_batch构建逻辑错误

你现在的y_batch完全依赖固定的reward,没有用到下一个状态的Q值。正确的TD目标计算应该是:

# 拆分minibatch中的元素
states, actions, rewards, next_states, dones = zip(*minibatch)
# 转换为模型可接受的张量格式
states = torch.tensor(states, dtype=torch.float32).unsqueeze(1)
next_states = torch.tensor(next_states, dtype=torch.float32).unsqueeze(1)
rewards = torch.tensor(rewards, dtype=torch.float32)
dones = torch.tensor(dones, dtype=torch.bool)

# 计算下一个状态的最大Q值
next_q_values = model(next_states).max(1)[0]
# TD目标:游戏结束则仅取reward,否则reward + gamma*下一个状态的最大Q值
y_batch = rewards + self.gamma * next_q_values * (~dones)
y_batch = y_batch.detach()  # 避免梯度回传到目标网络

5. 优化器与损失函数问题

  • 初始化时用了CrossEntropyLoss(),但DQN是回归任务(预测Q值),应该用MSELoss(),且不要在循环里重复定义criterion,初始化一次即可。
  • 学习率1e-6太小,建议改成1e-4或1e-3,否则权重更新极慢甚至看不到变化。

三、其他细节问题

  • 输入张量inputs = torch.tensor([[self.BoardMatrix]])需要转换成float32并增加channel维度,比如inputs = torch.tensor([[self.BoardMatrix]], dtype=torch.float32),否则Conv2d会报错。
  • 缺少Epsilon贪心策略:当前逻辑直接根据Q值选动作,会导致探索不足,应该加入随机选动作的逻辑,比如:
epsilon = max(self.final_epsilon, self.initial_epsilon - (self.initial_epsilon - self.final_epsilon)*iteration/self.number_of_iterations)
if random.random() < epsilon:
    action_idx = random.randint(0, self.number_of_actions-1)
else:
    q_values = model(inputs)
    action_idx = q_values.argmax().item()

把这些问题修复后,模型权重应该就能正常更新,y_batch也会随着游戏过程产生变化了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:03:45