我正在尝试使用
python-chess
和 stable_baselines3
Python 库构建一个 A2C 模型来下棋,但即使在 10 万次训练游戏之后,我的模型也没有显示出太大的进展。我正在使用继承自 ChessEnvironment()
的自定义环境 gymnasium.Env
,我认为问题与我构建动作空间的方式有关。简而言之,这是我的进口
import chess
import re
import gymnasium as gym
import numpy as np
from stable_baselines3 import A2C
from stable_baselines3.common.policies import ActorCriticPolicy
from torch.nn import ReLU
以及以我的自定义环境的 init 函数中的一个开头的相关代码片段:
def __init__(self):
super().__init__()
# Representing board as a 1-hot encoded 8x8 grid
self.observation_space = gym.spaces.Box(low=0, high=1, shape=(8, 8, 12), dtype=np.uint8)
# Initialize the chessboards
self.board = chess.Board()
self.last_board = self.board
# Action space
self.move_dict = make_move_list(self.board)
self.action_space = gym.spaces.Discrete(len(self.move_dict))
# ... Some more parameters ...
# Policy kwargs for A2C model
self.policy_kwargs = dict(
net_arch=dict(pi=[128, 128, 64], vf=[128, 128, 64]),
activation_fn=ReLU,
)
此外,这是我的完整步骤功能:
def step(self, action):
move = self.move_dict[action]
self.move_list.append(move)
# Save the board as is before making the move for reward calculation
self.last_board = self.board
# Execute the specified action on the chessboard
self.board.push_san(move)
self.sync_action_space()
# Convert the board to the observation format
observation = np.zeros((8, 8, 12), dtype=np.uint8)
for square, piece in self.board.piece_map().items():
piece_type = piece.piece_type
piece_color = int(piece.color)
observation[square // 8][square % 8][piece_type - 1 + 6 * piece_color] = 1
# Calculate the reward
reward = self.calculate_reward()
# Check if the episode is done
terminated = (self.board.result() != '*')
# Return the observation, reward, done flag, and additional info
return observation, reward, terminated, False, {}
我不完全确定为什么我的模型表现不佳(即 10 万场比赛后的模型与 10 万场比赛后的表现大致相同)。我最好的猜测是,问题源于每个位置如何重新创建动作空间 - 在步骤函数中进行移动后调用的
sync_action_space
函数如下
def sync_action_space(self):
self.move_dict = make_move_list(self.board)
self.action_space = gym.spaces.Discrete(len(self.move_dict))
其中
make_move_list
只是查询棋盘对象以获取给定状态的所有合法动作并将它们放入字典中。我是否正确地认为模型无法学习是(或至少主要受)行动空间不足的影响?或者我应该更多地使用超参数(我还可以调整奖励函数的不同启发式的权重)?预先感谢