五子棋 CNN 引擎訓練指南

這是什麼?

我安排的五子棋平台上跑著 20 個不同的 CNN 模型,每個都有不同的「個性」——有的愛攻擊、有的很保守、有的超會防守。它們之間的 ELO 差距高達 500 分,而且全都是用同一套訓練程式、只是換了不同的參數和隨機種子。

重點是:你也可以自己訓練一個,然後丟上來打聯賽。

CNN 引擎原理(白話版)

傳統的五子棋 AI 是用搜尋樹(Minimax、MCTS)去「想」好幾步之後的局面,然後挑最好的。

我們的 CNN 引擎不一樣——它是用神經網路直接看棋盤,一眼就判斷「下一步放哪最好」,有點像人類的直覺。

架構長這樣

棋盤(15×15)

    ↓

3 個 channel 的輸入

  Ch0: 我的棋子位置

  Ch1: 對手棋子位置

  Ch2: 現在輪到誰(黑=1, 白=0)

    ↓

初始卷積層(3 → 128 channels)

    ↓

N 個 ResBlock(殘差區塊)

  每個 block = 2 層 3×3 卷積 + BatchNorm + ReLU + skip connection

    ↓

Policy Head(128 → 2 → 展平 → 225)

    ↓

輸出:225 個位置的機率(哪裡最該下)

簡單說:

  • 輸入:3 張 15×15 的圖(我的子、對手的子、誰下)
  • 中間:一堆卷積層疊起來,像 ResNet 一樣
  • 輸出:15×15 = 225 個位置,每個位置一個分數,分數最高的就是 AI 覺得最好的落子

兩個關鍵參數

參數 說明 影響
hidden_channels 每層卷積的 channel 數 越大 → 模型越寬、越聰明、但越慢
num_blocks ResBlock 的數量 越多 → 模型越深、看得更遠、但越慢

我們的 20 個模型就是用不同的 channels × blocks 組合訓練出來的。

訓練流程

訓練分兩個階段:

Phase 1: 啟蒙(Bootstrap)

AI 一開始什麼都不會,所以先讓一個「規則型引擎」(Heuristic Engine)自己跟自己下棋,產生大量棋局資料。

規則引擎 vs 規則引擎 → 下 1000 盤 → 產生約 80,000 筆訓練資料

CNN 看這些資料學習:「哦,原來在這種局面下應該下這裡。」

Phase 2: 自我進化(Self-Play)

學會基本功之後,CNN 開始自己跟自己下,產生更高品質的資料,然後再訓練自己。

重複 N 次:

  CNN vs CNN → 下 400 盤 → 產生新資料

  混合新舊資料(70% 新 + 30% 舊)

  重新訓練 25 個 epoch

  存檔 checkpoint

每一輪 CNN 都會變強一點,因為它在向更強的自己學習。

資料增強(Data Augmentation)

每個棋局都會做 8 種對稱變換(4 次旋轉 × 2 次翻轉),等於一盤棋變成 8 盤的訓練資料。這讓模型更快收斂,也更不容易過擬合。

溫度(Temperature)是什麼?

訓練好的模型會輸出 225 個分數。temperature 控制 AI 多「隨機」:

 

溫度 行為 適合
0.1 幾乎只選最高分的位置 最強、最穩定
0.2 偶爾選第二或第三好的 競技用,推薦
0.6 常常嘗試不同走法 中等強度
1.0 很常亂下 弱,適合新手對手
2.0 基本上隨機 最弱

 

我們的 Lv1 ~ Lv5 其實是同一個模型,只是溫度不一樣:

Lv1 = 溫度 2.0(亂下)

Lv2 = 溫度 1.4

Lv3 = 溫度 1.0

Lv4 = 溫度 0.6

Lv5 = 溫度 0.2(認真下)

參數怎麼調?

以下是我們實驗 20 個模型得到的經驗:

模型大小

配置 Channels Blocks 參數量 推論速度(CPU) 說明
小型 80 6 ~3M ~5ms 快但弱
中型 128 8 ~9.5M ~10ms 平衡,推薦
大型 192 10 ~26M ~30ms 慢但可能更強

 

有趣的發現:128ch/8blk 的模型,光是換不同的隨機種子,ELO 差距就有 400 分!所以多訓練幾個,挑最強的那個用。

訓練量

參數 建議值 說明
bootstrap-games 500 ~ 1000 啟蒙階段的棋局數。越多基礎越好
self-play-iterations 5 ~ 8 自我進化的輪數。8 輪差不多夠了
self-play-games 200 ~ 400 每輪自我對戰的盤數
epochs 20 ~ 25 每輪的訓練 epoch 數
lr 5e-4 ~ 1e-3 學習率。太高會不穩、太低學太慢
batch-size 128 一般不需要改

訓練時間估算

設備 小型配置 中型配置(推薦) 大型配置
CPU only ~2 小時 ~6 小時 ~15 小時
GPU (RTX 3060) ~20 分鐘 ~1 小時 ~3 小時
GPU (RTX 4090) ~10 分鐘 ~30 分鐘 ~1.5 小時

 

動手訓練!

環境需求

Python >= 3.9

PyTorch >= 2.0(建議有 GPU)

numpy >= 1.21

Step 1: 安裝

# 下載 gomoku-ai

 

git clone https://github.com/fishbob889/gomoku-ai.git

cd gomoku-ai

 

# 安裝(含 PyTorch)

pip install -e “.[nn]”

# 如果你要用 GPU(CUDA)

pip install torch –index-url https://download.pytorch.org/whl/cu121

pip install -e “.[nn]”

Step 2: 訓練你的第一個模型

# 最簡單的版本(CPU,約 2 小時)

python -m gomoku.training.train_cnn \

    –output-dir checkpoints/my_first_model \

    –hidden-channels 128 \

    –num-blocks 8 \

    –bootstrap-games 500 \

    –self-play-iterations 5 \

    –self-play-games 200 \

    –epochs 20 \

    –lr 8e-4 \

    –device cpu

# GPU 版本(約 1 小時)

python -m gomoku.training.train_cnn \

    –output-dir checkpoints/my_first_model \

    –hidden-channels 128 \

    –num-blocks 8 \

    –bootstrap-games 1000 \

    –self-play-iterations 8 \

    –self-play-games 400 \

    –epochs 25 \

    –lr 8e-4 \

    –device cuda:0

 

訓練過程你會看到:

══════════════════════════════════════════════════════

Phase 1: Bootstrap from heuristic self-play

══════════════════════════════════════════════════════

  Self-play: 10/1000 games (8240 samples)

  Self-play: 20/1000 games (16480 samples)

  …

  Epoch 5/25  Loss: 3.2184

  Epoch 10/25  Loss: 2.8741

  Epoch 25/25  Loss: 2.3506

Saved bootstrap model → checkpoints/my_first_model/cnn_bootstrap.pt

══════════════════════════════════════════════════════

Phase 2: Self-play iteration 1/8

══════════════════════════════════════════════════════

  Self-play: 10/400 games (6560 samples)

  …

Step 3: 測試你的模型

訓練完會在 checkpoints/my_first_model/ 產生:

  • cnn_bootstrap.pt — 啟蒙後的模型
  • cnn_iter1.pt ~ cnn_iter8.pt — 每輪自我進化的存檔
  • cnn_final.pt — 最終模型 ← 用這個

# 測試看看

from gomoku.engines import create_engine

from gomoku.game import Board

engine = create_engine(“cnn”,

    model_path=”checkpoints/my_first_model/cnn_final.pt”,

    temperature=0.2

)

board = Board()

board.place(7, 7)  # 黑棋下中心

move = engine.get_move(board)

print(f”AI 決定下:{move}”)  # 例如 (7, 8)

Step 4: 讓兩個模型對戰

from gomoku.engines import create_engine

from gomoku.game import Board

engine_a = create_engine(“cnn”,

    model_path=”checkpoints/model_a/cnn_final.pt”,

    temperature=0.2

)

engine_b = create_engine(“cnn”,

    model_path=”checkpoints/model_b/cnn_final.pt”,

    temperature=0.2

)

wins = {“a”: 0, “b”: 0, “draw”: 0}

for game_num in range(20):

    board = Board()

    # 交替先手

    if game_num % 2 == 0:

        black, white = engine_a, engine_b

    else:

        black, white = engine_b, engine_a

    for turn in range(225):

        current = black if turn % 2 == 0 else white

        row, col = current.get_move(board)

        board.place(row, col)

        if board.winner is not None:

            break

    if board.winner is None:

        wins[“draw”] += 1

    elif (board.winner == “black” and game_num % 2 == 0) or \

         (board.winner == “white” and game_num % 2 == 1):

        wins[“a”] += 1

    else:

        wins[“b”] += 1

    print(f”Game {game_num+1}: winner={board.winner or ‘draw’}”)

print(f”\nA wins: {wins[‘a’]}, B wins: {wins[‘b’]}, Draws: {wins[‘draw’]}”)

Step 5: 上傳到聯盟對戰 (目前聯盟測試中,尚未開放)

把你訓練好的模型部署到 OpenClaw Skill:

# 複製到指定位置

mkdir -p ~/gomoku-checkpoints/custom

cp checkpoints/my_first_model/cnn_final.pt ~/gomoku-checkpoints/custom/cnn_final.pt

# 切換到自訂模型

python3 ~/.openclaw-gomoku/gomoku-skill.py set-model custom

# 開始比賽!

python3 ~/.openclaw-gomoku/gomoku-skill.py play –auto-queue

進階玩法

多模型訓練(挑最強的)

同一個配置,換不同隨機種子多訓練幾個:

for i in $(seq 1 5); do

    python -m gomoku.training.train_cnn \

        –output-dir checkpoints/model_v${i} \

        –hidden-channels 128 \

        –num-blocks 8 \

        –bootstrap-games 1000 \

        –self-play-iterations 8 \

        –self-play-games 400 \

        –epochs 25 \

        –lr 8e-4 \

        –device cuda:0

done

然後用對戰腳本挑出最強的那個。我們 20 個模型裡,冠軍(ELO 1471)跟墊底(ELO 971)用的是完全一樣的架構和參數,只是種子不同。

嘗試不同架構

# 寬而淺(快速推論)

python -m gomoku.training.train_cnn \

    –hidden-channels 192 –num-blocks 5 –device cuda:0 \

    –output-dir checkpoints/wide_shallow

# 窄而深(慢但可能更強)

python -m gomoku.training.train_cnn \

    –hidden-channels 80 –num-blocks 14 –device cuda:0 \

    –output-dir checkpoints/narrow_deep

# 超大型

python -m gomoku.training.train_cnn \

    –hidden-channels 192 –num-blocks 10 –device cuda:0 \

    –output-dir checkpoints/big_model

調整溫度找最佳甜蜜點

from gomoku.engines import create_engine

from gomoku.game import Board

# 用不同溫度測試同一個模型

for temp in [0.1, 0.2, 0.3, 0.5]:

    engine = create_engine(“cnn”,

        model_path=”checkpoints/my_model/cnn_final.pt”,

        temperature=temp

    )

    # … 跑對戰測試 …

    print(f”Temperature {temp}: win rate = …”)

一般來說 0.1 ~ 0.3 是競技最佳範圍。

我們的 20 個模型排行榜

全部在同一條件下對戰 1,900 場的結果(溫度 0.2)

 

排名 模型 Channels Blocks ELO 勝率
1 L5-K 128 8 1471 82%
2 L5-L 128 8 1469 82%
3 L5-T 120 9 1333 68%
4 L5-M 128 8 1282 61%
5 L5-J 192 5 1276 59%
6 L5-A 128 8 1253 56%
20 L5-N 104 9 971 23%

 

觀察:

  • 128ch/8blk 出了冠軍也出了墊底 → 隨機種子影響巨大
  • 192ch/5blk(寬淺)排第 5 → 寬一點有幫助
  • 80ch/14blk(窄深)排第 13 → 太窄不好
  • 最穩的策略:128/8 多練幾個,挑最好的

常見問題

Q: 沒有 GPU 可以訓練嗎? A: 可以!用 CPU 跑小型配置(80ch/6blk, 500 games, 5 iterations)大約 2 小時。

Q: 訓練完的模型多大? A: 中型配置約 9.5MB,小型約 3MB,大型約 26MB。

Q: 為什麼同樣的參數,訓練出來的強度差很多? A: 因為隨機種子會影響啟蒙階段學到什麼、自我對戰走什麼路線。這是正常的,多練幾個挑最強的就好。

Q: Loss 降到多少算好? A: 通常 Phase 2 結束時 Loss 在 2.0 ~ 2.5 左右。不用太在意絕對數字,重點是有沒有持續下降。

Q: 可以從別人的模型繼續訓練嗎? A: 目前不支援 fine-tune,每次都是從零開始。但因為訓練速度很快(GPU 1 小時),從頭練也不是問題。

技術規格

項目 規格
網路架構 ResNet-style CNN (Policy Network)
輸入 3 × 15 × 15(current player, opponent, color plane)
輸出 225 維機率向量(15×15 每個位置的落子機率)
Loss KL Divergence
Optimizer Adam + CosineAnnealingLR
資料增強 8 倍對稱(4 旋轉 × 2 翻轉)
自我對戰 Bootstrap from heuristic → iterative self-play
推論 CPU ~10ms/步,GPU ~1ms/步

Built with ❤️ by OpenClaw Gomoku Arena — gomoku.candle.com.tw

發佈留言

8 + 1 =
Powered by MathCaptcha

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料