跳到主要内容

Value Network 详解

如果说 Policy Network 告诉 AlphaGo「下一步应该下哪里」,那么 Value Network 回答的是一个更根本的问题:

「这盘棋,我会赢吗?」


什么是 Value Network?

核心功能

Value Network 是一个深度卷积神经网络,它的任务是:

给定当前棋盘状态,预测最终的胜率

用数学表示:

v = f_θ(s)

其中:

  • s:当前棋盘状态
  • f_θ:Value Network(θ 是网络参数)
  • v:一个介于 -1 到 +1 之间的数值

输出的含义

输出值含义
+1当前玩家必胜
+0.5当前玩家约 75% 胜率
0双方胜率相等
-0.5当前玩家约 25% 胜率
-1当前玩家必败

为什么需要单一数值?

比较不同选择

在下棋时,我们经常需要在多个选项中做选择。Value Network 让这个比较变得简单:

选项 A 的局面价值:0.3
选项 B 的局面价值:0.5
选项 C 的局面价值:0.2

→ 选择 B(最高的价值)

如果没有单一数值,我们如何比较「吃掉对方一块棋」和「围住一大块空」哪个更好?

取代大量模拟

在传统的蒙地卡罗树搜索中,评估一个局面需要进行 随机模拟(rollout)

  1. 从当前局面开始
  2. 双方随机下棋直到游戏结束
  3. 记录胜负
  4. 重复数千次,计算胜率

这非常慢。Value Network 可以一次前向传播就给出评估,速度快几个数量级。

方法评估时间精度
1000 次随机模拟~2000 毫秒较低
15000 次随机模拟~30000 毫秒中等
Value Network~3 毫秒高(等价于 15000 次模拟)

网络架构

与 Policy Network 的相似性

Value Network 的架构与 Policy Network 非常相似,都是深度卷积神经网络:

输入层

与 Policy Network 相同,输入是 19×19×49 的特征张量:

  • 19×19:棋盘大小
  • 49:48 个特征平面 + 1 个表示当前轮到谁的平面

多出的 1 个平面很重要:Value Network 需要知道是谁的回合,因为同一局面对黑棋和白棋的价值是相反的。

卷积层

与 Policy Network 相同:

  • 12 层卷积层
  • 192 个滤波器
  • 3×3 卷积核(第一层 5×5)
  • ReLU 激活函数

输出层的差异

这是 Value Network 与 Policy Network 的关键差异:

Policy Network 输出

19×19×192 → 1×1 卷积 → 19×19×1 → 展平 → 361维 → Softmax → 概率分布

Value Network 输出

19×19×192 → 1×1 卷积 → 19×19×1 → 展平 → 361维 → 全连接256 → ReLU → 全连接1 → Tanh → 单一数值

Tanh 激活函数

Value Network 的最后一层使用 Tanh(双曲正切)函数:

Tanh(x) = (e^x - e^(-x)) / (e^x + e^(-x))

Tanh 的输出范围是 (-1, +1),正好对应胜负。

为什么用 Tanh 而非 Sigmoid?

Sigmoid 的输出范围是 (0, 1),也可以表示胜率。但 Tanh 有几个优点:

  1. 对称性:以 0 为中心,输出可正可负
  2. 梯度更好:在 0 附近梯度接近 1
  3. 语意清晰:正值赢、负值输、零是平局

完整架构图

参数数量

计算参数数量
卷积层同 Policy Network~3.9M
全连接层 1361×256 + 25692,672
全连接层 2256×1 + 1257
总计~4.0M

约 400 万个参数,比 Policy Network 略多。


训练的挑战

过拟合问题

Value Network 的训练比 Policy Network 困难得多。主要问题是过拟合

什么是过拟合?

过拟合是指模型「记住」了训练资料,而非学会泛化。表现为:

  • 训练集上表现很好
  • 测试集上表现很差

为什么 Value Network 容易过拟合?

考虑一盘棋的资料:

局面 1 → 局面 2 → 局面 3 → ... → 局面 200 → 结果:黑胜

如果直接用这些资料训练:

  • 这 200 个局面有很强的相关性
  • 它们来自同一盘棋,有相同的结果
  • 模型可能学会「认出」这盘棋,而非理解局面

DeepMind 发现:如果用相同的人类棋谱训练 Policy 和 Value Network,Value Network 会严重过拟合。

解决方案:自我对弈资料

DeepMind 的解决方案是用自我对弈生成新的训练资料:

1. 用训练好的 RL Policy Network 自我对弈
2. 从每盘棋中只取一个局面(避免相关性)
3. 这个局面的标签是该盘棋的最终结果
4. 生成 3000 万个这样的样本

为什么这能解决过拟合?

  1. 资料量大:3000 万个独立的局面
  2. 无相关性:每盘棋只取一个局面
  3. 分布不同:自我对弈的局面分布不同于人类棋谱

训练资料的产生

# 伪代码
training_data = []

for game_id in range(30_000_000):
# 自我对弈一盘
states, result = self_play(rl_policy_network)

# 随机选取一个局面
random_index = random.randint(0, len(states) - 1)
state = states[random_index]

# 记录局面和结果
training_data.append((state, result))

训练目标与方法

均方误差损失

Value Network 使用**均方误差(MSE)**作为损失函数:

L(θ) = (1/n) × Σ (v_θ(s) - z)²

其中:

  • v_θ(s):模型预测的价值
  • z:实际结果(+1 或 -1)

为什么用 MSE 而非交叉熵?

  • 交叉熵适合分类问题(离散的标签)
  • MSE 适合回归问题(连续的数值)

虽然结果只有 +1 或 -1,但模型预测的是连续值(-1 到 +1 之间的任何数)。MSE 让模型学会预测接近 +1 或 -1 的值。

训练过程

# 伪代码
for epoch in range(num_epochs):
for batch in dataloader:
states, outcomes = batch

# 前向传播
values = network(states) # (batch, 1)

# 计算损失(MSE)
loss = mse_loss(values, outcomes)

# 反向传播
loss.backward()
optimizer.step()

训练细节:

  • 优化器:SGD with momentum
  • 学习率:0.003
  • 批次大小:32
  • 训练时间:约 1 周(50 GPUs)

准确度分析

与随机模拟的比较

DeepMind 在论文中进行了详细的比较:

评估方法预测误差
1000 次随机模拟较高
15000 次随机模拟中等
Value Network与 15000 次模拟相当

这意味着一次 Value Network 评估 ≈ 15000 次随机模拟,但速度快约 1000 倍。

各阶段的准确度

Value Network 的准确度取决于游戏进程:

阶段剩余手数预测难度准确度
开局~300很难较低
中盘~150困难中等
收官~50较易较高
终局~10简单很高

这是直觉上合理的:越接近游戏结束,结果越确定。

输出分布

一个训练良好的 Value Network 的输出分布:

        频率
|
| *
| * *
| * *
| * *
|* *
+----+----+---- 输出值
-1 0 +1

大多数输出集中在 -1 和 +1 附近
(因为大多数局面有明确的胜负倾向)

不确定的局面

当 Value Network 输出接近 0 时,表示局面非常复杂,胜负难料。这些局面通常是:

  • 大型战斗中
  • 双方势均力敌
  • 存在多个可能的变化

在 MCTS 中,这些节点会获得更多的搜索资源(因为不确定性高)。


在 MCTS 中的作用

叶节点评估

Value Network 在 MCTS 的 Evaluation 阶段发挥关键作用:

MCTS 搜索树:

根节点 (当前局面)
/ \
A B
/ \ / \
A1 A2 B1 B2 ← 叶节点
↓ ↓ ↓ ↓
评估 评估 评估 评估

当 MCTS 到达一个叶节点时,需要评估这个局面的价值。有两种方法:

  1. 随机模拟(Rollout):从叶节点随机下到游戏结束
  2. Value Network 评估:直接用神经网络预测

AlphaGo 结合了两者:

V(leaf) = (1-λ) × V_network(leaf) + λ × V_rollout(leaf)

其中 λ = 0.5,即各占一半权重。

为什么要结合?

  • Value Network 更准确,但可能有系统性偏差
  • 随机模拟 较不准确,但提供独立的估计
  • 结合两者可以互补

AlphaGo Zero 的简化

后来的 AlphaGo Zero 完全弃用了随机模拟:

V(leaf) = V_network(leaf)

这大大简化了系统,同时棋力更强。这证明了 Value Network 足够可靠,不需要随机模拟的「保险」。

回溯更新

评估完叶节点后,这个值会沿路径回溯更新:

v3 = V(leaf) = 0.6

A2 的 Q 值更新

A 的 Q 值更新

根节点的统计更新

每个节点维护的 Q 值是所有经过它的叶节点评估的平均:

Q(s, a) = (1/N(s,a)) × Σ V(leaf)

视觉化分析

价值曲面

想像一个简化的 3×3 棋盘。Value Network 学到的是一个「价值曲面」:

价值矩阵示例(黑子位置 vs 白子位置)

黑\白123
1+0.3-0.1+0.2
2-0.2+0.5-0.3
3+0.1-0.2+0.4

这个曲面告诉我们每个位置组合的价值。正值有利于黑棋,负值有利于白棋。

训练过程中的演变

随着训练进行,Value Network 的预测逐渐变得更准确:

训练进程中的预测误差

训练步数预测误差
01.0
100K0.6
500K0.15
1M0.1

误差会快速下降,然后趋于稳定。

困难局面的识别

Value Network 可以帮助识别困难局面:

输出含义应对策略
接近 +1大优稳健下法
接近 -1大劣寻找翻盘机会
接近 0复杂局面需要深入计算

AlphaGo 会在接近 0 的局面投入更多思考时间。


实作要点

PyTorch 实现

import torch
import torch.nn as nn
import torch.nn.functional as F

class ValueNetwork(nn.Module):
def __init__(self, input_channels=49, num_filters=192, num_layers=12):
super().__init__()

# 第一卷积层(5×5)
self.conv1 = nn.Conv2d(input_channels, num_filters,
kernel_size=5, padding=2)

# 中间卷积层(3×3)×11
self.conv_layers = nn.ModuleList([
nn.Conv2d(num_filters, num_filters,
kernel_size=3, padding=1)
for _ in range(num_layers - 1)
])

# 输出卷积层
self.conv_out = nn.Conv2d(num_filters, 1, kernel_size=1)

# 全连接层
self.fc1 = nn.Linear(361, 256)
self.fc2 = nn.Linear(256, 1)

def forward(self, x):
# x: (batch, 49, 19, 19)

# 卷积层
x = F.relu(self.conv1(x))
for conv in self.conv_layers:
x = F.relu(conv(x))
x = self.conv_out(x)

# 展平
x = x.view(x.size(0), -1) # (batch, 361)

# 全连接层
x = F.relu(self.fc1(x))
x = torch.tanh(self.fc2(x))

return x.squeeze(-1) # (batch,)

训练循环

def train_value_network(model, optimizer, states, outcomes):
"""
states: (batch, 49, 19, 19) - 棋盘特征
outcomes: (batch,) - 游戏结果 (+1 或 -1)
"""
# 前向传播
values = model(states) # (batch,)

# MSE 损失
loss = F.mse_loss(values, outcomes)

# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()

# 计算准确率(预测正确的胜负)
predictions = (values > 0).float() * 2 - 1 # 转换为 +1/-1
accuracy = (predictions == outcomes).float().mean()

return loss.item(), accuracy.item()

避免过拟合的技巧

# 1. 资料增强(8重对称性)
def augment(state, outcome):
augmented = []
for rotation in [0, 90, 180, 270]:
s = rotate(state, rotation)
augmented.append((s, outcome))
augmented.append((flip(s), outcome))
return augmented

# 2. Dropout
class ValueNetworkWithDropout(ValueNetwork):
def __init__(self, *args, dropout_rate=0.5, **kwargs):
super().__init__(*args, **kwargs)
self.dropout = nn.Dropout(dropout_rate)

def forward(self, x):
# ... 卷积层 ...
x = self.dropout(x) # 在全连接层前 dropout
# ... 全连接层 ...

# 3. 早停(Early Stopping)
best_val_loss = float('inf')
patience = 10
counter = 0

for epoch in range(max_epochs):
train_loss = train_one_epoch()
val_loss = evaluate()

if val_loss < best_val_loss:
best_val_loss = val_loss
save_model()
counter = 0
else:
counter += 1
if counter >= patience:
print("Early stopping!")
break

与 Policy Network 的协作

互补关系

Policy Network 和 Value Network 在 AlphaGo 中互补:

网络回答的问题输出MCTS 角色
Policy下一步下哪里?概率分布引导搜索方向
Value这盘棋会赢吗?单一数值评估叶节点

统一的双头网络

在 AlphaGo Zero 中,这两个网络被合并成一个双头网络

这种设计的优点:

  • 参数共享:减少计算量
  • 特征共享:Policy 和 Value 使用相同的特征
  • 训练更稳定:两个目标互相正则化

详见 双头网络与残差网络


动画对应

本文涉及的核心概念与动画编号:

编号概念物理/数学对应
🎬 E2Value Network势能面
🎬 D4价值函数期望报酬
🎬 C6叶节点评估函数逼近
🎬 H3时序差分引导学习

延伸阅读


关键要点

  1. Value Network 预测胜率:输出 -1 到 +1 之间的单一数值
  2. Tanh 输出:确保输出在正确的范围内
  3. MSE 损失:将预测值逼近实际结果
  4. 过拟合挑战:需要用自我对弈资料来避免
  5. 取代随机模拟:一次评估 ≈ 15000 次模拟

Value Network 是 AlphaGo 的「判断力」——它让 AI 能够评估任何局面的好坏,而不需要穷尽所有可能。


参考资料

  1. Silver, D., et al. (2016). "Mastering the game of Go with deep neural networks and tree search." Nature, 529, 484-489.
  2. Silver, D., et al. (2017). "Mastering the game of Go without human knowledge." Nature, 551, 354-359.
  3. Sutton, R. S., & Barto, A. G. (2018). Reinforcement Learning: An Introduction. MIT Press.
  4. Tesauro, G. (1995). "Temporal difference learning and TD-Gammon." Communications of the ACM, 38(3), 58-68.