vAIbe_2048 / README.md
forthezero's picture
Upload 13 files
0642513 verified
# 2048 AI Trainer
基于 Transformer 的 2048 游戏人工智能训练器,使用 PPO(Proximal Policy Optimization)强化学习算法,让 AI 学会玩 2048 游戏。
## 项目简介
本项目实现了一个完整的 2048 游戏 AI 训练系统,包括:
- **游戏引擎**: 完整的 2048 游戏逻辑实现
- **深度学习模型**: 基于 Transformer 架构的策略网络
- **强化学习训练**: PPO 算法实现
- **可视化界面**: PyQt5 图形界面,支持训练监控和演示
- **命令行工具**: 支持无 GUI 的训练和演示模式
## 功能特点
### 1. Transformer 模型
采用小型 Transformer 架构,专为 CPU 训练优化:
- **参数量**: 约 77,000 个参数(~300KB)
- **输入处理**:
- 棋盘状态编码为 16 个 token(每个格子对应一个 token)
- 分数特征(累积分数、局面分数)作为额外输入
- 位置编码:行/列位置嵌入
- **网络结构**:
- 2 层 Transformer Encoder
- 4 个注意力头
- 隐藏维度 64
- 前馈网络维度 128
- **输出**:
- 策略头:4 个动作(上/下/左/右)的概率分布
- 价值头:当前状态的价值评估
### 2. 双评分机制
#### 累积分数(Accumulated Score)
传统 2048 计分方式,每次合成砖块获得合成后砖块的数值作为分数。
#### 局面分数(Situational Score)
综合评估当前局面的质量,鼓励 AI 保持良好局面:
```
局面分数 = 空格数 × 10 + 最大连续相邻数 × 15 + log₂(最大砖块) × 5 + 单调性奖励
```
- **空格数**: 空格越多,操作空间越大
- **连续相邻数**: 如 512-1024-2048 连续排列,便于后续合并
- **单调性**: 鼓励数字按方向有序排列
### 3. PPO 训练算法
使用 Proximal Policy Optimization 算法进行训练:
- **优势估计**: GAE(Generalized Advantage Estimation)
- **策略裁剪**: 防止策略更新过大
- **价值函数**: 辅助训练,提供状态价值估计
- **熵正则化**: 鼓励探索
### 4. GUI 界面
基于 PyQt5 的图形界面:
- **训练模式**:
- 设置训练局数
- 实时显示训练进度
- 分数曲线可视化
- 训练完成后自动保存模型
- **演示模式**:
- 键盘手动操作
- AI 托管模式
- 单步执行
- 自动连续执行
- 实时局面分数曲线
## 安装
### 环境要求
- Python 3.8+
- Windows / Linux / macOS
### 安装依赖
```bash
cd game2048
pip install -r requirements.txt
```
### 依赖列表
```
torch>=2.0.0 # 深度学习框架
numpy<2 # 数值计算
PyQt5>=5.15.0 # GUI 框架
matplotlib>=3.7.0 # 绘图库
```
## 使用方法
### 1. GUI 模式
```bash
python main.py
```
启动图形界面后:
**训练模式**:
1. 选择 "Training Mode"
2. 设置训练局数(默认 500)
3. 点击 "Start Training" 开始训练
4. 训练完成后自动保存到 `checkpoints/model.pt`
5. 可随时点击 "Stop Training" 停止
**演示模式**:
1. 选择 "Demo Mode"
2. 点击 "Load Model" 加载已训练模型
3. 使用方式:
- 键盘方向键:手动操作
- "AI Mode":切换 AI 托管
- "Step":AI 单步执行
- "Auto":AI 自动连续执行
- "Reset":重新开始游戏
### 2. 命令行训练
```bash
# 训练 1000 局
python main.py --train --games 1000
# 使用 4 个并行环境
python main.py --train --games 1000 --envs 4
# 设置随机种子
python main.py --train --games 1000 --seed 42
```
### 3. 演示模式
```bash
# 加载模型并演示 5 局
python main.py --demo --model checkpoints/model.pt --games 5
# 不加载模型(随机权重)
python main.py --demo --games 3
```
### 4. 简单训练脚本
```bash
python train_simple.py
```
修改脚本末尾可调整训练参数:
```python
train_simple(num_games=500, save_path="checkpoints/model.pt")
```
## 项目结构
```
game2048/
├── TASK.md # 任务需求文档
├── PLAN.md # 项目计划文档
├── README.md # 本文件
├── main.py # 程序入口
├── game.py # 2048 游戏核心逻辑
│ ├── Game2048 # 游戏类
│ ├── move() # 移动操作
│ ├── get_state() # 获取状态
│ └── calculate_situational_score() # 计算局面分数
├── model.py # Transformer 模型
│ ├── Game2048Transformer # Transformer 模型
│ ├── Game2048CNN # CNN 备选模型
│ └── get_action() # 动作选择
├── trainer.py # PPO 训练器
│ ├── PPOTrainer # PPO 训练类
│ ├── RolloutBuffer # 经验缓冲区
│ ├── Transition # 状态转移数据结构
│ └── TrainingStats # 训练统计
├── parallel.py # 并行训练环境
│ ├── ParallelGameEnv # 并行游戏环境
│ ├── TrainingWorker # 训练工作器
│ └── TrainingLoop # 训练循环
├── gui.py # GUI 界面
│ ├── MainWindow # 主窗口
│ ├── GameBoardWidget # 游戏面板
│ ├── ScoreWidget # 分数显示
│ ├── PlotCanvas # 曲线绑图
│ └── SimpleTrainingThread # 训练线程
├── train_simple.py # 简化训练脚本
├── utils.py # 工具函数
├── requirements.txt # 依赖列表
└── checkpoints/ # 模型保存目录
└── model.pt # 训练好的模型
```
## 模型架构详解
### 输入表示
```python
# 棋盘状态 (4, 4)
# 每个格子值转换为 log₂(value),空格为 0
state = [[0, 1, 2, 0], # 对应 [空, 2, 4, 空]
[1, 2, 3, 1], # 对应 [2, 4, 8, 2]
...]
# 分数特征 (2,)
# [归一化累积分数, 归一化局面分数]
scores = [0.05, 0.85]
```
### 网络结构
```
Input: (batch, 4, 4) board + (batch, 2) scores
Position Embedding: (batch, 16, 64)
+ Spatial Embedding: (batch, 16, 64)
+ Score Embedding: (batch, 1, 64)
Transformer Encoder (2 layers)
- Multi-Head Attention (4 heads)
- Feed-Forward Network (dim=128)
Global Mean Pooling: (batch, 64)
├── Policy Head → (batch, 4) # 动作概率
└── Value Head → (batch, 1) # 状态价值
```
## 训练策略
### 奖励设计
```python
reward = 局面分数变化 × 0.7 + 累积分数增量 × 0.003
# 游戏结束惩罚
if game_over:
reward -= 10.0
```
### 超参数
| 参数 | 值 |
|------|-----|
| Learning Rate | 3e-4 |
| Batch Size | 64 |
| PPO Clip Ratio | 0.2 |
| GAE Lambda | 0.95 |
| Discount Factor (γ) | 0.99 |
| Entropy Coefficient | 0.01 |
## 训练结果
### 500 局训练后
| 指标 | 数值 |
|------|------|
| 平均分数 | ~2500 |
| 最高分数 | 6812 |
| 最大砖块 | 512 |
| 训练时间 | ~9 分钟 |
### 分数分布
```
随机权重: 平均 ~800, 最高 ~2000
训练 500 局: 平均 ~2500, 最高 ~6800
```
## 开发说明
### 添加新功能
1. **修改局面评分**: 编辑 `game.py` 中的 `calculate_situational_score()`
2. **调整模型**: 修改 `model.py` 中的网络结构
3. **优化训练**: 调整 `trainer.py` 中的超参数
### 调试模式
```python
# 在 game.py 中测试游戏逻辑
if __name__ == "__main__":
game = Game2048()
print(game)
game.move(Game2048.LEFT)
print(game)
```
## 已知问题
- Windows 下 PyTorch 可能需要特定版本以避免 DLL 加载问题
- NumPy 2.x 与 PyTorch 存在兼容性问题,建议使用 NumPy < 2
## 参考资料
- [PPO 论文](https://arxiv.org/abs/1707.06347)
- [Transformer 论文](https://arxiv.org/abs/1706.03762)
- [2048 游戏](https://play2048.co/)
## 许可证
MIT License
---
*本项目由 GLM-5 开发实现*