我正在研究一个神经网络,它可以玩一些棋盘游戏,比如黑白棋或井字游戏(零和游戏,两个玩家)。我正在尝试为所有游戏设置一个网络拓扑 - 我特别不想为可用操作的数量设置任何限制,因此我只使用状态价值网络。
我使用卷积网络——一些受 Alpha Zero 启发的残差块,然后是全局池化和线性层。对于给定的游戏状态,网络输出一个介于 0 和 1 之间的值——它的值。
对于每一个可能的动作,代理都会选择一个导致具有最高值的状态的动作,它使用 epsilon 贪婪策略。
每场比赛结束后,我都会记录状态和结果,并创建一个回放记忆。然后,为了训练网络,我从回放内存中采样并更新网络(如果做出导致当前状态的移动的玩家赢得了游戏,则状态的目标值为 1,否则为 0)。
问题是,经过一些训练后,模型作为其中一名玩家表现得相当好,但作为另一名玩家却输了(它比随机代理更差)。起初,我认为这是训练代码中的一个错误,但经过进一步调查,这似乎不太可能。它成功地训练了两个玩家对抗随机代理,当我只使用自我游戏时问题出现了。
我想我已经找到了一些解决方案 - 最初我针对随机玩家训练模型(一半游戏作为第一个玩家,一半作为第二个玩家),然后当模型知道哪些动作更好或更坏时,它开始对自己进行训练。我用这种方法取得了相当不错的结果——在井字游戏中,在 10k 场比赛之后,我对作为起始玩家的随机玩家有 98.5% 的胜率(大约 1% 平局),作为第二个玩家有 95% 的胜率(再次大约3% 平局)——它找到了一个近乎最优的策略。它似乎也适用于黑白棋和突破(在 10k 场比赛后,双方玩家都赢了 80% 以上的随机玩家)。它并不完美,但也没有那么糟糕,尤其是在只玩了 10k 游戏的情况下。
我相信,当从一开始就进行自我训练时,其中一名球员获得了显着的优势并在每场比赛中重复该策略,而另一名球员则在寻找反击方面苦苦挣扎。最后,与失败者对应的状态通常设置为 0,因此模型知道,每当轮到失败者时,它应该返回 0。我不知道如何处理这个问题,有没有具体方法?我还尝试将 epsilon(在 eps-greedy 中)最初设置为某个较大的值,例如 0.5(随机移动的 50% 机会),然后在训练期间逐渐减小它,但这并没有真正帮助。