基于PyTorch的无损失函数梯度上升及多机器人覆盖优化疑问
多机器人覆盖研究中的两个PyTorch实现疑问
我目前正在开展多机器人覆盖相关研究,目标是优化参数化策略,生成状态间的转移矩阵,使各状态的稳态分布尽可能均匀。这可视为最大化状态熵,等价于最小化策略生成的稳态分布与均匀分布的KL散度,但因目标函数包含其他正则项,无明确损失函数。现有两个疑问:
疑问1:神经网络梯度能否正确反向传播?
以下代码中,通过将各状态的one-hot向量输入神经网络,得到状态转移概率向量并堆叠为转移矩阵,NN参数的梯度能否正确反向传播?
def forward(self): # Get transition matrix transitionMatrix = torch.stack([self.policy(self.policy.generateStateVector(i)) for i in range(self.policy.numS)]).to(self.policy.device).float() # Calculate stationary distribution PIE = torch.linalg.inv(transitionMatrix - torch.eye(self.policy.numS).to(self.policy.device) + torch.ones(self.policy.numS, self.policy.numS).to(self.policy.device)).float() stationaryDistribution = torch.matmul(torch.ones(1, self.policy.numS).to(self.policy.device), PIE)[0] return stationaryDistribution, transitionMatrix
解答
可以正确反向传播,但有几个关键注意点:
torch.stack和循环调用self.policy()的操作都是可微分的,只要self.policy是PyTorch的nn.Module子类且前向传播逻辑可微分,梯度就能沿着每个状态的计算路径正常传递。torch.linalg.inv支持自动微分,PyTorch会为矩阵求逆操作生成对应的反向传播算子。但矩阵求逆的梯度计算数值稳定性较差,当矩阵接近奇异时,容易出现梯度爆炸或消失,训练过程中要密切关注数值波动。- 确保所有张量的设备(CPU/GPU)和数据类型一致,避免因类型或设备不匹配中断微分流程。
疑问2:最大化目标函数的参数更新方式是否正确?
以下代码中,因optimizer.step()以减法更新参数,通过将obj取反实现θ=θ+grad*lr从而最大化目标函数的方式是否正确?
obj = self.gamma_1 * H_overall + self.gamma_2 * CE_overall - self.gamma_3 * H_P # Update parameters self.policy.optimizer.zero_grad() obj.backward() self.policy.optimizer.step()
解答
这种方式不正确,当前代码是在最小化obj,而非最大化。
要实现最大化目标函数,正确的做法有两种:
- 对目标函数取反后作为损失执行最小化(推荐,逻辑直观):
loss = -obj self.policy.optimizer.zero_grad() loss.backward() self.policy.optimizer.step()
因为optimizer.step()默认执行θ = θ - lr * grad(loss),当loss=-obj时,等价于θ = θ + lr * grad(obj),刚好实现最大化目标的参数更新。
- 自定义优化器更新方向(不推荐,增加代码复杂度):
修改优化器的参数更新规则,但这种方式不如取反目标函数简洁可靠,还容易引入额外bug。
另外补充:如果H_P是需要最小化的项,当前obj中的-self.gamma_3 * H_P是正确的,相当于把最小化H_P转化为最大化-H_P整合到目标中,但整体要最大化obj,必须对整个obj取反后作为损失优化。
内容的提问来源于stack exchange,提问作者Sean XIAO
相关产品推荐
相关产品推荐

