首页 > 后端开发 > Python教程 > 使用 DQN 构建国际象棋代理

使用 DQN 构建国际象棋代理

Susan Sarandon
发布: 2024-12-30 01:55:07
原创
539 人浏览过

我最近尝试实现一个基于 DQN 的国际象棋代理。

现在,任何知道 DQN 和国际象棋如何工作的人都会告诉你这是一个愚蠢的想法。

确实如此,但作为一个初学者,我仍然很喜欢它。在这篇文章中,我将分享我在这方面工作时学到的见解。


了解环境。

在开始实现 Agent 本身之前,我必须熟悉将要使用的环境,并在其之上制作一个自定义包装器,以便它可以在训练期间与 Agent 交互。

  • 我使用了 kaggle_environments 库中的国际象棋环境。

     from kaggle_environments import make
     env = make("chess", debug=True)
    
    登录后复制
    登录后复制
  • 我还使用了 Chessnut,这是一个轻量级的 Python 库,可以帮助解析和验证国际象棋游戏。

     from Chessnut import Game
     initial_fen = env.state[0]['observation']['board']
     game=Game(env.state[0]['observation']['board'])
    
    登录后复制
    登录后复制

在此环境中,板的状态以 FEN 格式存储。

Building a Chess Agent using DQN

它提供了一种紧凑的方式来表示棋盘上的所有棋子和当前活跃的玩家。但是,由于我计划将输入提供给神经网络,因此我必须修改状态的表示。


将 FEN 转换为矩阵格式

Building a Chess Agent using DQN

由于棋盘上有 12 种不同类型的棋子,因此我创建了 12 个 8x8 网格通道来表示棋盘上每种类型的状态。


为环境创建一个包装器

class EnvCust:
    def __init__(self):
        self.env = make("chess", debug=True)
        self.game=Game(env.state[0]['observation']['board'])
        print(self.env.state[0]['observation']['board'])
        self.action_space=game.get_moves();
        self.obs_space=(self.env.state[0]['observation']['board'])

    def get_action(self):
        return Game(self.env.state[0]['observation']['board']).get_moves();


    def get_obs_space(self):
        return fen_to_board(self.env.state[0]['observation']['board'])

    def step(self,action):
        reward=0
        g=Game(self.env.state[0]['observation']['board']);
        if(g.board.get_piece(Game.xy2i(action[2:4]))=='q'):
            reward=7
        elif g.board.get_piece(Game.xy2i(action[2:4]))=='n' or g.board.get_piece(Game.xy2i(action[2:4]))=='b' or g.board.get_piece(Game.xy2i(action[2:4]))=='r':
            reward=4
        elif g.board.get_piece(Game.xy2i(action[2:4]))=='P':
            reward=2
        g=Game(self.env.state[0]['observation']['board']);
        g.apply_move(action)
        done=False
        if(g.status==2):
            done=True
            reward=10
        elif g.status == 1:  
            done = True
            reward = -5 
        self.env.step([action,'None'])
        self.action_space=list(self.get_action())
        if(self.action_space==[]):
            done=True
        else:
            self.env.step(['None',random.choice(self.action_space)])
            g=Game(self.env.state[0]['observation']['board']);
            if g.status==2:
                reward=-10
                done=True

        self.action_space=list(self.get_action())
        return self.env.state[0]['observation']['board'],reward,done
登录后复制

这个包装器的目的是为代理提供奖励策略以及用于在训练期间与环境交互的步骤函数。

Chessnut 有助于获取信息,例如当前棋盘状态下可能的合法走法,以及在游戏过程中识别将死者。

我尝试制定奖励政策,为将死并消灭敌方棋子给予正分,而为输掉比赛给予负分。


创建重播缓冲区

Building a Chess Agent using DQN

重播缓冲区在训练期间用于保存 Q 网络输出的(状态、动作、奖励、下一个状态),并在以后随机用于目标网络的反向传播


辅助功能

Building a Chess Agent using DQN

Building a Chess Agent using DQN

Chessnut 以 UCI 格式返回合法动作,看起来像“a2a3”,但是为了与神经网络交互,我使用基本模式将每个动作转换为不同的索引。总共有 64 个方块,所以我决定为每个动作设置 64*64 个唯一索引。
我知道并非所有 64*64 的棋步都是合法的,但我可以使用 Chessnut 来处理合法性,而且模式足够简单。


神经网络结构

 from kaggle_environments import make
 env = make("chess", debug=True)
登录后复制
登录后复制

该神经网络使用卷积层接收 12 个通道输入,并使用有效的动作索引来过滤奖励输出预测。


实施代理

 from Chessnut import Game
 initial_fen = env.state[0]['observation']['board']
 game=Game(env.state[0]['observation']['board'])
登录后复制
登录后复制

这显然是一个非常基本的模型,实际上不可能表现良好(而且也没有),但它确实帮助我理解了 DQN 如何更好地工作。

Building a Chess Agent using DQN

以上是使用 DQN 构建国际象棋代理的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板