MuGo 源码逐行解读:从特征提取到蒙特卡洛树搜索
MuGo 是一个模仿 AlphaGo 的极简 Go(围棋)引擎,使用 Python 实现。本文将深入剖析 MuGo 的核心技术架构,从棋盘特征提取到蒙特卡洛树搜索(MCTS)的完整实现流程,帮助开发者理解 AI 围棋引擎的基本工作原理。
核心功能概述
MuGo 复刻了 AlphaGo 的核心逻辑,主要包含三大模块:
- 特征提取系统:将围棋棋盘状态转化为神经网络可理解的特征平面
- 策略网络:预测落子概率分布的神经网络模型
- 蒙特卡洛树搜索:结合策略网络进行高效搜索的决策系统
项目结构清晰,核心代码集中在以下文件:
- features.py:棋盘特征提取实现
- strategies.py:MCTS 和各类玩家策略
- policy.py:策略网络定义
- main.py:训练和推理入口
特征提取:将棋盘转化为数字信号
围棋 AI 的第一步是将复杂的棋盘状态转化为计算机可处理的数字特征。MuGo 采用了与 AlphaGo 类似的多平面特征表示方法,定义在 features.py 中。
核心特征平面
MuGo 提取的特征按重要性排序包括:
- 棋子颜色特征(3 个平面)
- 当前玩家棋子、对手棋子和空位的位置分布
- 实现于 stone_color_feature 函数,通过独热编码区分三种状态
- 常量平面(1 个平面)
- 全 1 矩阵,帮助神经网络感知棋盘边界
- 关键代码:ones_feature 函数返回全 1 数组
- 气数特征(8 个平面)
- 表示每个交叉点的气数(棋子的自由点数)
- 通过 liberty_feature 函数实现,使用 make_onehot 进行独热编码
- 最近落子特征(8 个平面)
- 记录最近 8 步的落子位置
- 实现于 recent_move_feature,使用时间衰减的方式编码历史信息
- 捕获大小特征(8 个平面)
- 预测落子后可捕获的对方棋子数量
- 通过 would_capture_feature 计算潜在捕获收益
特征提取流程
特征提取的核心函数是 extract_features,它将上述特征平面串联成一个高维数组:
def extract_features(position, features=DEFAULT_FEATURES):
return np.concatenate([feature(position) for feature in features], axis=2)
这段代码将多个特征平面在深度维度上拼接,形成形状为 (19, 19, N) 的输入张量(其中 N 为特征平面总数),作为策略网络的输入。
蒙特卡洛树搜索:AI 决策的核心引擎
MuGo 的决策系统基于蒙特卡洛树搜索(MCTS),完整实现位于 strategies.py。MCTS 通过模拟大量可能的棋局来评估落子质量,主要包含四个步骤:选择、扩展、评估和回溯。
MCTS 节点结构
MCTS 的基本单元是 MCTSNode 类,每个节点包含:
- Q 值:节点的平均价值估计
- U 值:探索 bonus(基于 PUCT 算法)
- N 值:节点访问次数
- 先验概率:来自策略网络的初始估值
- 子节点:可能的后续落子
核心代码片段:
class MCTSNode():
def __init__(self, parent, move, prior):
self.parent = parent # 父节点指针
self.move = move # 导致当前节点的落子
self.prior = prior # 策略网络给出的先验概率
self.children = {} # 子节点字典
self.Q = 0 # 平均价值
self.U = prior # 探索项
self.N = 0 # 访问次数
搜索过程详解
MCTS 的搜索循环在 MCTS.suggest_move 方法中实现:
回溯阶段:将评估价值反向传播更新路径上所有节点的 Q 值和 U 值
def backup_value(self, value):
self.N += 1
self.Q = self.Q + (value - self.Q) / self.N
self.U = c_PUCT * math.sqrt(self.parent.N) * self.prior / self.N
self.parent.backup_value(-value) # 反转价值(对手视角)
评估阶段:通过快速走子(rollout)评估当前节点价值
def estimate_value(self, root, chosen_leaf):
# 通过策略网络模拟直到终局
current = copy.deepcopy(leaf_position)
while current.n < self.max_rollout_depth:
move_probs = self.policy_network.run(current)
current = self.play_valid_move(current, move_probs)
return current.score() * perspective
扩展阶段:对叶子节点进行扩展,通过策略网络生成可能的落子及其概率
def expand(self, move_probabilities):
self.children = {move: MCTSNode(self, move, prob) for move, prob in np.ndenumerate(move_probabilities)}
self.children[None] = MCTSNode(self, None, 0) # 添加 Pass 选项
选择阶段:从根节点开始,根据 action_score = Q + U 选择最优子节点,直到到达叶子节点
def select_leaf(self):
current = self
while current.is_expanded():
current = max(current.children.values(), key=lambda node: node.action_score)
return current
策略网络:从数据到决策
策略网络是 MuGo 的'大脑',负责预测落子概率分布。虽然具体实现位于 policy.py,但其与 MCTS 的集成在 strategies.py 中体现。
网络推理流程
策略网络的推理过程在 PolicyNetworkBestMovePlayer.suggest_move 中实现:
def suggest_move(self, position):
move_probabilities = self.policy_network.run(position)
return select_most_likely(position, move_probabilities)
这段代码调用策略网络生成落子概率分布,然后选择概率最高的合法落子。
网络训练流程
根据 README.md,训练策略网络需要以下步骤:
模型评估:通过 GTP 协议与其他 AI 对战
python main.py gtp mcts --read-file=/tmp/savedmodel
模型训练:使用预处理数据训练策略网络
python main.py train processed_data/ --save-file=/tmp/savedmodel --epochs=10
数据准备:预处理 SGF 格式的棋谱
python main.py preprocess data/kgs-*
实战应用:如何运行 MuGo
环境准备
首先克隆项目仓库:
git clone [repository_url]
cd MuGo
pip install -r requirements.txt
基本使用流程
运行单元测试:
python -m unittest discover tests
与 AI 对战:
python main.py gtp mcts --read-file=models/policy.h5
训练策略网络:
python main.py train processed_data/ --save-file=models/policy.h5 --epochs=50
预处理棋谱数据:
python main.py preprocess path/to/sgf_files
项目特点与局限性
MuGo 作为 AlphaGo 的极简实现,具有以下特点:
优势:
- 代码简洁易懂,适合学习 AI 围棋基础原理
- 纯 Python 实现,易于部署和修改
- 完整的 MCTS 和策略网络集成
局限:
- 性能有限,不适合高水准对战
- 缺少 AlphaGo 的价值网络和强化学习模块
- 项目已停止维护(自 2017 年中起)
官方推荐后续学习可参考 TensorFlow Minigo 项目,这是 MuGo 工作的延续。
总结
MuGo 通过特征提取、策略网络和蒙特卡洛树搜索的有机结合,实现了一个简化版的 AlphaGo。其核心价值在于提供了一个可理解的 AI 围棋引擎实现,帮助开发者掌握深度学习与博弈论结合的关键技术。
通过阅读 features.py 和 strategies.py 的源代码,开发者可以深入理解:
- 如何将复杂的棋盘状态转化为神经网络输入
- MCTS 如何高效探索游戏树
- 策略网络如何引导搜索方向
对于希望入门 AI 博弈的开发者,MuGo 提供了一个理想的学习起点。
