我可以只在特定的输出神经元上应用 softmax 吗?

问题描述

我正在 pytorch 中构建一个 Actor-Critic 神经网络模型,以训练代理玩 Quoridor 游戏(希望如此)。出于这个原因,我有一个有两个头的神经网络,一个用于演员输出,它对所有可能的移动进行 softmax,另一个用于评论输出,它只有一个神经元(用于回归输入状态的值)。

现在,在 quoridor 中,大多数时候并非所有移动都是合法的,因此我想知道是否可以排除演员头部与输入状态的非法移动相对应的输出神经元,例如通过传递与合法移动相对应的所有神经元的索引列表。因此,我不想在 softmax 的分母上对这些输出求和。

pytorch 上有这样的功能吗(因为我找不到)?我是否应该尝试自己实现这样的 softmax(有点害怕,pytorch 可能最了解,我也被建议使用 Logsoftmax)?

此外,您认为这种处理非法动作的方法好吗?或者我应该让他猜测非法动作并为此惩罚他(负奖励),希望最终它不会选择非法动作?

或者我应该让 softmax 覆盖所有输出,然后将非法输出设置为零?其余的总和不会为 1,但也许我可以通过简单的归一化(即除以 L2 范数)来解决这个问题?

解决方法

一个简单的解决方案是用大的负值掩盖非法移动,这实际上会强制使用非常低的(log)softmax 值(下面的示例)。

# 3 dummy actions for a batch size of 2
>>> actions = torch.rand(2,3)     
>>> actions
tensor([[0.9357,0.2386,0.3264],[0.0179,0.8989,0.9156]])
# dummy mask assigning 0 to valid actions and 1 to invalid ones
>>> mask = torch.randint(low=0,high=2,size=(2,3))
>>> mask
tensor([[1,0],[0,0]])
# set actions marked as invalid to very large negative value
>>> actions = actions.masked_fill_(mask.eq(1),value=-1e10)
>>> actions
tensor([[-1.0000e+10,2.3862e-01,3.2636e-01],[ 1.7921e-02,8.9890e-01,9.1564e-01]])
# softmax assigns no probability mass to illegal actions
>>> actions.softmax(dim=-1)
tensor([[0.0000,0.4781,0.5219],[0.1704,0.4113,0.4183]])