CNNと囲碁の融合
DeepMindが囲碁を処理するために**畳み込みニューラルネットワーク(CNN)**を選んだことは、天才的な設計判断でした。
CNNはもともと画像認識のために設計されました。なぜ囲碁にも適しているのでしょうか?この記事ではCNNの動作原理と、囲碁との完璧な相性を深く探求します。
なぜCNNは盤面に適しているのか?
盤面は「画像」である
ある観点から見ると、19×19の囲碁盤は一枚の画像です:
| 画像 | 囲碁盤 |
|---|---|
| ピクセル | 交点 |
| RGBチャンネル | 特徴プレーン(黒、白、空...) |
| 224×224 | 19×19 |
| 猫・犬を識別 | 良い手・悪い手を判断 |
この類似は偶然ではありません。CNNが画像を得意とする理由は、盤面を得意とする理由でもあります。
3つの重要な特性
CNNには3つの特性があり、盤面タイプのデータに特に適しています:
1. 局所接続(Local Connectivity)
CNNの畳み込みカーネルは局所領域のみを見ます。これは囲碁の特性と完璧にマッチします:
| 画像認識 | 囲碁 |
|---|---|
| 猫の耳は局所的な特徴 | 「眼」は局所的な石形 |
| 画像全体を見る必要はない | 盤面全体を見る必要はない |
3×3 領域の例(眼形):
| ○ | ● | ○ |
| ● | · | ● |
| ○ | ● | ○ |
多くの囲碁の概念は「局所的」です:
- 眼:2×2 または 3×3 の領域
- アタリ:3×3 の領域
- ツギ・キリ:2×2 の領域
2. 重み共有(Weight Sharing)
同じ畳み込みカーネルが盤面全体をスキャンします。つまり:
盤面左上の「眼」と右下の「眼」は、同じ方法で識別される
これは合理的です——囲碁のルールは位置によって変わりません(辺・隅は例外ですが、辺・隅の特徴プレーンで対処できます)。
重み共有はパラメータ数も大幅に削減します:
| 方法 | パラメータ数 |
|---|---|
| 全結合ネットワーク | 361 × 361 × チャンネル数 = 数千万 |
| CNN | 3 × 3 × チャンネル数 × フィルタ数 = 数百万 |
3. 平行移動等変性(Translation Equivariance)
入力が平行移動すると、CNNの出力も対応して平行移動します:
入力:
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | · | · | · | · | · |
| 2 | · | ● | · | · | · |
| 3 | · | · | · | · | · |
出力(高確率領域):
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | · | · | · | · | · |
| 2 | · | * | · | · | · |
| 3 | · | · | · | · | · |
入力を平行移動後:
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | · | · | · | · | · |
| 2 | · | · | · | · | · |
| 3 | · | · | ● | · | · |
出力も平行移動:
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | · | · | · | · | · |
| 2 | · | · | · | · | · |
| 3 | · | · | * | · | · |
これは囲碁にとって重要です:同じ局所的な石形は、盤面のどこに現れても類似した評価を受けるべきです。
畳み込み演算
基本原理
畳み込み演算はCNNの核心です。これは「スライディングウィンドウ」操作です:
入力 (5x5):
| 1 | 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 | 1 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 0 | 1 |
畳み込みカーネル (3x3):
| 1 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 1 |
出力 (5x5, padding=same):
| 2 | 1 | 3 | 1 | 2 |
| 1 | 4 | 3 | 3 | 1 |
| 3 | 3 | 5 | 3 | 3 |
| 1 | 3 | 3 | 4 | 1 |
| 2 | 1 | 3 | 1 | 2 |
計算過程(中心点を例に):
出力[2,2] = 1×1 + 1×0 + 1×1 +
1×0 + 1×1 + 1×0 +
1×1 + 1×0 + 1×1
= 1 + 0 + 1 + 0 + 1 + 0 + 1 + 0 + 1
= 5
マルチチャンネル畳み込み
入力が複数のチャンネル(例:48の特徴プレーン)を持つ場合、畳み込みカーネルも3Dになります:
各畳み込みカーネルは全ての入力チャンネルをまたいで計算し、1つの出力チャンネルを生成します。
複数のフィルタ
AlphaGoは192のフィルタを使用し、各フィルタが異なる特徴を学習します:
各フィルタは異なる石形を学習する可能性があります:
- フィルタ1:眼形検出
- フィルタ2:キリ点検出
- フィルタ3:連結検出
- ...
- フィルタ192:ある複雑なパターン
受容野
受容野とは?
**受容野(Receptive Field)**とは、出力の1つの位置が、入力のどの位置から影響を受けるかを指します。
単層畳み込み
3×3畳み込みカーネルを使用する場合、出力の各位置は入力の3×3領域のみから影響を受けます:
入力:
| . | . | . | . | . |
| . | ● | ● | ● | . |
| . | ● | ● | ● | . |
| . | ● | ● | ● | . |
| . | . | . | . | . |
受容野 3x3
出力:
| . | . | . | . |
| . | ● | . | . |
| . | . | . | . |
| . | . | . | . |
多層畳み込み
複数の畳み込み層を積み重ねると、受容野は拡大します:
| 層数 | 受容野 | 計算 |
|---|---|---|
| 1 | 3×3 | 3 |
| 2 | 5×5 | 3 + (3-1) = 5 |
| 3 | 7×7 | 5 + (3-1) = 7 |
| ... | ... | ... |
| 12 | 25×25 | 3 + 11×2 = 25 |
AlphaGoの12層畳み込みは25×25の受容野を与え、すでに19×19の盤面を超えています!
これは意味します:
- 出力の各位置が盤面全体を「見る」ことができる
- しかし「見る」方法が異なる:近くは細部がはっきり、遠くは概要
- これは人間の棋士の思考方法に似ている
受容野と囲碁
受容野の概念は、AlphaGoが「全局的」な問題を処理できる理由を説明します:
局所的な問題(3×3 受容野): 全局的な問題(25×25 受容野):
- ここに眼があるか? - この石の一団に眼形があるか?
- アタリにできるか? - シチョウは有利か?
- ツグことができるか? - 全局の形勢はどうか?
浅い層は局所的な特徴を処理し、深い層は全局的な特徴を処理します。
局所 vs 全局特徴
CNNの階層構造
CNNは自然に階層構造を形成します:
入力層: 黒石、白石、空点
↓
浅層 (1-3): 眼、ツギ、キリ、アタリ
↓
中層 (4-8): 石形、活き石、死に石
↓
深層 (9-12): 勢力、厚み、大場
↓
出力層: 着手確率 / 勝率
これは人間が囲碁を学ぶ過程と驚くほど似ています:
- まずルールを学ぶ(どこに石があるか)
- 次に戦術を学ぶ(石の取り方)
- そして石形を学ぶ(良い形とは何か)
- 最後に大局観を学ぶ(全局の判断)
隠れ層の可視化
研究者たちは、CNNの隠れ層が確かに意味のある特徴を学習していることを発見しました:
浅層フィルタ
フィルタA(眼形検出):
| + | - | + |
| - | + | - |
| + | - | + |
フィルタB(アタリ検出):
| + | + | + |
| + | - | - |
| + | + | + |
深層フィルタ
深層のフィルタはより抽象的で、直接解釈するのが難しいですが、複雑な石形パターンを捉えています。
活性化関数の選択
ReLU:シンプルで効果的
AlphaGoは全ての畳み込み層の後に**ReLU(Rectified Linear Unit)**を使用します:
def relu(x):
return max(0, x)
ReLU関数の動作:
- 負の入力値の場合:出力 = 0(x軸に沿った水平線)
- 正の入力値の場合:出力 = 入力(45度の上昇線)
- この関数は原点から始まる「傾斜」を形成する
なぜ他の関数を使わないのか?
| 活性化関数 | 式 | 利点 | 欠点 |
|---|---|---|---|
| ReLU | max(0, x) | 計算が速い、勾配が良好 | 負の値の死滅 |
| Sigmoid | 1/(1+e^-x) | 出力が有界 | 勾配消失 |
| Tanh | (e^x-e^-x)/(e^x+e^-x) | ゼロ中心 | 勾配消失 |
| LeakyReLU | max(0.01x, x) | 死滅問題を解決 | ハイパーパラメータが1つ増える |
深いネットワークでは、ReLUの優位性は明らかです:
- 計算が簡単:比較と最大値を取るだけ
- 勾配が消失しない:正の領域では勾配が常に1
- スパースな活性化:多くのニューロンが0を出力し、効率を高める
囲碁におけるReLUの意味
ReLUのスパース性は、囲碁において興味深い解釈を持ちます:
あるフィルタが「キリ点」を検出する:
- キリ点がある → 正の値を出力(活性化)
- キリ点がない → ゼロを出力(活性化なし)
これは棋士が「何かある」位置だけに注目するようなもの
バッチ正規化
バッチ正規化とは?
**バッチ正規化(Batch Normalization)**は、各層の出力を安定した分布に維持する技術です:
def batch_norm(x, gamma, beta):
# バッチの平均と標準偏差を計算
mean = x.mean(axis=0)
std = x.std(axis=0)
# 正規化
x_norm = (x - mean) / (std + 1e-8)
# スケーリングとシフト
return gamma * x_norm + beta
なぜ必要なのか?
内部共変量シフト
ネットワークが訓練されるとき、各層の入力分布は前の層の重みの変化に伴って変化します。これは「内部共変量シフト」と呼ばれます:
第1層の重み更新 → 第1層の出力分布が変化
↓
第2層の入力分布が変化 → 第2層が再適応する必要
↓
...(伝播していく)
バッチ正規化は、各層の入力を固定の分布(平均0、標準偏差1)に強制することで、訓練を安定させます。
AlphaGoでの応用
AlphaGoは各畳み込み層の後、活性化関数の前にバッチ正規化を使用します:
Conv → BatchNorm → ReLU → Conv → BatchNorm → ReLU → ...
利点:
- 訓練が速い:より大きな学習率を使用できる
- より安定:初期化への感度が低下
- 正則化効果:軽いドロップアウト効果がある
推論時の処理
訓練時は現在のバッチの統計量を使用します。推論時は訓練セット全体の統計量(移動平均)を使用します:
# 訓練時
mean = batch_mean
var = batch_var
# 推論時
mean = running_mean # 訓練中に蓄積された平均
var = running_var # 訓練中に蓄積された分散
AlphaGoの具体的な構成
完全なアーキテクチャ
入力: 19×19×48
第1層:
Conv2D(5×5, 192 filters, padding='same')
BatchNorm
ReLU
出力: 19×19×192
第2-12層(計11層):
Conv2D(3×3, 192 filters, padding='same')
BatchNorm
ReLU
出力: 19×19×192
出力層(Policy):
Conv2D(1×1, 1 filter)
Flatten
Softmax
出力: 361次元の確率
出力層(Value):
Conv2D(1×1, 1 filter)
Flatten
Dense(256)
ReLU
Dense(1)
Tanh
出力: 単一の数値
パラメータ設定
| パラメータ | 値 | 説明 |
|---|---|---|
| 入力チャンネル | 48 | 特徴プレーン数 |
| フィルタ数 | 192 | 各層のチャンネル数 |
| カーネルサイズ | 3×3(第1層は5×5) | 受容野 |
| 層数 | 13(出力層含む) | 深さ |
| 活性化関数 | ReLU | 非線形 |
| 正規化 | BatchNorm | 訓練の安定化 |
PyTorch実装
import torch
import torch.nn as nn
class AlphaGoCNN(nn.Module):
def __init__(self, input_channels=48, num_filters=192, num_layers=12):
super().__init__()
# 第1層(5×5 畳み込み)
self.conv1 = nn.Sequential(
nn.Conv2d(input_channels, num_filters, kernel_size=5, padding=2),
nn.BatchNorm2d(num_filters),
nn.ReLU(inplace=True)
)
# 中間層(3×3 畳み込み)
self.conv_layers = nn.Sequential(*[
nn.Sequential(
nn.Conv2d(num_filters, num_filters, kernel_size=3, padding=1),
nn.BatchNorm2d(num_filters),
nn.ReLU(inplace=True)
)
for _ in range(num_layers - 1)
])
# Policy出力ヘッド
self.policy_head = nn.Sequential(
nn.Conv2d(num_filters, 1, kernel_size=1),
nn.Flatten(),
nn.Softmax(dim=1)
)
# Value出力ヘッド
self.value_head = nn.Sequential(
nn.Conv2d(num_filters, 1, kernel_size=1),
nn.Flatten(),
nn.Linear(361, 256),
nn.ReLU(inplace=True),
nn.Linear(256, 1),
nn.Tanh()
)
def forward(self, x):
# 共有特徴抽出
x = self.conv1(x)
x = self.conv_layers(x)
# 分岐出力
policy = self.policy_head(x)
value = self.value_head(x)
return policy, value
他のアーキテクチャとの比較
全結合ネットワーク
全結合ネットワークで囲碁を処理する場合:
| 特性 | 全結合 | CNN |
|---|---|---|
| パラメータ数 | 極めて大(数億) | 比較的小(数百万) |
| 位置不変性 | なし | あり |
| 局所特徴 | 学習困難 | 自然に捉える |
| 訓練効率 | 低い | 高い |
全結合ネットワークは盤面の空間構造を活用できず、効率が極めて低いです。
リカレントニューラルネットワーク(RNN)
RNNは系列データ(棋譜の履歴など)に適していますが:
| 特性 | RNN | CNN |
|---|---|---|
| 空間処理 | 弱い | 強い |
| 系列処理 | 強い | 弱い(履歴プレーンが必要) |
| 並列化 | 難しい | 容易 |
| 長距離依存 | LSTMが必要 | 深い層で可能 |
AlphaGoはCNN + RNNではなく、CNN + 履歴プレーンを選択しました。
残差ネットワーク(ResNet)
AlphaGo ZeroはResNetにアップグレードしました:
通常のCNN: ResNet:
x x
↓ ↓
Conv Conv
↓ ↓
ReLU ReLU
↓ ↓
Conv Conv
↓ ↓
y y + x ← 残差接続
残差接続により勾配がより流れやすくなり、より深いネットワーク(40層 vs 12層)を訓練できます。
詳細は双頭ネットワークと残差ネットワークをご覧ください。
視覚的な理解
畳み込みプロセス
入力盤面(5×5に簡略化):
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | · | · | · | · | · |
| 2 | · | ● | · | · | · |
| 3 | · | · | ○ | · | · |
| 4 | · | · | · | ● | · |
| 5 | · | · | · | · | · |
あるフィルタ(3×3、「十字形」検出):
| 0 | 1 | 0 |
| 1 | 1 | 1 |
| 0 | 1 | 0 |
畳み込み出力:
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 1 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0 | 0 |
| 5 | 0 | 0 | 0 | 0 | 0 |
中心で強い応答(十字形がマッチ)
多層特徴
第1層出力(192チャンネル中の4つ):
チャンネル1(眼形):
| 0 | 0 | 0 | 0 |
| 0 | 0.9 | 0 | 0 |
| 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 |
チャンネル2(辺線):
| 0.8 | 0 | 0 | 0 |
| 0.8 | 0 | 0 | 0 |
| 0.8 | 0 | 0 | 0 |
| 0.8 | 0 | 0 | 0 |
チャンネル3(キリ点):
| 0 | 0 | 0 | 0 |
| 0 | 0 | 0.7 | 0 |
| 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 |
チャンネル4(連結):
| 0 | 0 | 0 | 0 |
| 0 | 0.5 | 0 | 0 |
| 0 | 0.8 | 0 | 0 |
| 0 | 0.5 | 0 | 0 |
これらの特徴はより深い層でより複雑な概念に組み合わされる...
アニメーション対応
この記事で扱う核心概念とアニメーション番号:
| 番号 | 概念 | 物理/数学対応 |
|---|---|---|
| D9 | 畳み込み演算 | フィルタ応答 |
| D10 | 受容野 | 局所→全局 |
| D11 | バッチ正規化 | 分布安定化 |
| D1 | マルチチャンネル入力 | テンソル演算 |
関連記事
- 前の記事:入力特徴量の設計 — 48特徴プレーン詳解
- 次の記事:教師あり学習フェーズ — 人間の棋譜から学ぶ方法
- 発展トピック:双頭ネットワークと残差ネットワーク — AlphaGo Zeroのネットワークアップグレード
重要ポイント
- CNNは盤面に自然に適している:局所接続、重み共有、平行移動等変性
- 畳み込みは局所特徴を抽出:3×3領域のパターン認識
- 深いネットワークは全局的視野を獲得:12層 → 25×25 受容野
- ReLUは高速で効果的:シンプルな非線形活性化
- BatchNormは訓練を安定化:各層の出力を標準化
CNNはAlphaGoが盤面を「見る」ことを可能にしました——人間が目で画像を見るのと同じくらい自然に。
参考資料
- LeCun, Y., Bengio, Y., & Hinton, G. (2015). "Deep learning." Nature, 521, 436-444.
- He, K., et al. (2015). "Deep Residual Learning for Image Recognition." CVPR.
- Ioffe, S., & Szegedy, C. (2015). "Batch Normalization: Accelerating Deep Network Training." ICML.
- Krizhevsky, A., Sutskever, I., & Hinton, G. E. (2012). "ImageNet Classification with Deep Convolutional Neural Networks." NeurIPS.