Policy Network 상세 해설
바둑의 어떤 국면에서든 합법적인 수는 평균 250가지가 있습니다. 컴퓨터가 무작위로 선택하게 하면, 결코 좋은 수를 둘 수 없습니다.
AlphaGo의 돌파구는 바로 이것입니다: '바둑판을 한 번 보고, 어떤 위치가 고려할 가치가 있는지 아는 것'을 배웠습니다.
이 능력은 **Policy Network(정책 네트워크)**에서 옵니다.
Policy Network란 무엇인가?
핵심 기능
Policy Network는 심층 컨볼루션 신경망으로, 그 임무는 다음과 같습니다:
현재 바둑판 상태가 주어지면, 각 위치에 돌을 놓을 확률을 출력한다
수학적으로 표현하면:
p = f_θ(s)
여기서:
s: 현재 바둑판 상태 (19×19 바둑판 + 기타 특성)f_θ: Policy Network (θ는 네트워크 파라미터)p: 361개 위치의 확률 분포 (pass 포함)
직관적 이해
당신이 프로 기사라고 상상해 보세요. 어떤 국면을 보면, 당신의 뇌는 자동으로 몇 개의 중요한 위치를 '밝게' 합니다 — 이것들이 당신이 직관적으로 고려할 가치가 있다고 생각하는 점입니다.
Policy Network는 바로 이 과정을 시뮬레이션하는 것입니다.
위의 히트맵은 Policy Network의 출력을 보여줍니다. 색상이 밝을수록 모델이 그 위치에 두는 것이 가치 있다고 생각합니다.
왜 Policy Network가 필요한가?
바둑의 탐색 공간은 너무 큽니다. 모든 가능한 수를 필터링 없이 탐색하면:
| 전략 | 수마다 고려하는 착수 | 10수 탐색의 노드 수 |
|---|---|---|
| 전부 고려 | 361 | 361^10 ≈ 10^25 |
| Policy Network 필터링 | ~20 | 20^10 ≈ 10^13 |
Policy Network는 탐색 공간을 10^12배(1조 배) 축소했습니다.
네트워크 아키텍처
전체 구조
AlphaGo의 Policy Network는 심층 컨볼루션 신경망(CNN) 아키텍처를 채택합니다:
입력층 → 컨볼루션층 ×12 → 출력 컨볼루션층 → Softmax
↓ ↓ ↓ ↓
19×19×48 19×19×192 19×19×1 362개 확률
입력층
입력은 19×19×48 특성 텐서입니다:
- 19×19: 바둑판 크기
- 48: 48개 특성 평면 (자세한 내용은 입력 특성 설계 참조)
이 48개 평면에는 다음이 포함됩니다:
- 흑돌 위치, 백돌 위치
- 최근 8수의 기록
- 활로 수, 단수, 축머리 등 특성
- 합법성 (어떤 위치에 둘 수 있는지)
컨볼루션층
네트워크는 12개의 컨볼루션층을 포함하며, 각 층의 구성:
| 파라미터 | 값 | 설명 |
|---|---|---|
| 필터 수 | 192 | 각 층에서 192개 특성 맵 출력 |
| 커널 크기 | 3×3 (첫 번째 층은 5×5) | 매번 3×3 영역을 봄 |
| 패딩 방식 | same | 19×19 크기 유지 |
| 활성화 함수 | ReLU | max(0, x) |
왜 192개 필터인가?
이것은 경험적인 값입니다. 너무 적으면 모델 용량이 제한되고, 너무 많으면 계산량과 과적합 위험이 증가합니다. DeepMind 팀은 실험을 통해 192가 좋은 균형점임을 확인했습니다.
왜 3×3 커널인가?
3×3은 컨볼루션 신경망에서 가장 일반적으로 사용되는 크기입니다. 이유는:
- 국소 패턴 포착에 충분: 바둑의 눈, 이음, 끊음 등이 모두 3×3 범위 내에 있음
- 계산 효율이 높음: 큰 커널에 비해 3×3은 파라미터가 적음
- 쌓을 수 있음: 여러 층의 3×3 컨볼루션은 큰 수용 영역 효과를 낼 수 있음
첫 번째 층은 왜 5×5를 사용하는가?
첫 번째 층은 더 큰 5×5 커널을 사용하는데, 이는 입력층에서 바로 약간 더 큰 범위의 패턴(예: 소목, 한 칸 뜀)을 포착하기 위해서입니다. 이것은 설계 선택이며, 나중에 AlphaGo Zero는 통일하여 3×3을 사용합니다.
ReLU 활성화 함수
각 컨볼루션층 뒤에 ReLU(Rectified Linear Unit) 활성화 함수가 붙습니다:
ReLU(x) = max(0, x)
왜 ReLU를 사용하는가?
- 계산이 간단함: 최댓값만 취하면 되어 sigmoid보다 훨씬 빠름
- 기울기 소실 완화: 양의 영역에서 기울기가 항상 1
- 희소 활성화: 음수 값은 0으로 되어 희소 표현 생성
출력층
마지막 층은 특별한 컨볼루션층입니다:
19×19×192 → 컨볼루션(1×1, 1개 필터) → 19×19×1 → 평탄화 → 362차원 벡터 → Softmax
1×1 컨볼루션
출력층은 1×1 컨볼루션을 사용하여 192개 채널을 1개로 압축합니다. 이는 각 위치의 192차원 특성에 선형 결합을 하는 것과 같습니다.
Softmax 출력
362차원 벡터(361개 바둑판 위치 + 1개 pass)는 Softmax 함수를 거칩니다:
Softmax(z_i) = exp(z_i) / Σ_j exp(z_j)
Softmax는 출력이 합법적인 확률 분포가 되도록 보장합니다:
- 모든 값이 0과 1 사이
- 모든 값의 합이 1
파라미터 수
네트워크의 총 파라미터 수를 계산해 봅시다:
| 층 | 계산 | 파라미터 수 |
|---|---|---|
| 첫 번째 컨볼루션층 | 5×5×48×192 + 192 | 230,592 |
| 중간 컨볼루션층 ×11 | (3×3×192×192 + 192) × 11 | 3,633,792 |
| 출력 컨볼루션층 | 1×1×192×1 + 1 | 193 |
| 총계 | ~3.9M |
약 390만 개의 파라미터로, 오늘날의 기준으로는 작은 네트워크입니다.
학습 목표와 방법
학습 데이터
Policy Network는 지도 학습을 사용하여 인간 기보에서 학습합니다.
데이터 출처:
- KGS Go Server: 아마추어와 프로 기사의 대국
- 약 3천만 국면: 16만 대국에서 샘플링
- 레이블: 각 국면에 대응하는 인간의 다음 수
교차 엔트로피 손실 함수
학습 목표는 인간 착수를 예측할 확률을 최대화하는 것입니다. 교차 엔트로피 손실 함수를 사용합니다:
L(θ) = -Σ log p_θ(a | s)
여기서:
s: 바둑판 상태a: 인간이 실제로 둔 위치p_θ(a | s): 모델이 해당 위치를 예측한 확률
직관적 이해
교차 엔트로피 손실은 간단한 의미를 가집니다:
모델이 정확한 위치를 예측할 확률이 높을수록, 손실이 낮다
만약 인간이 K10에 두었고, 모델이 K10에 준 확률이:
- 0.9 → 손실 = -log(0.9) ≈ 0.1 (매우 낮음, 좋음)
- 0.1 → 손실 = -log(0.1) ≈ 2.3 (높음, 나쁨)
- 0.01 → 손실 = -log(0.01) ≈ 4.6 (매우 높음, 매우 나쁨)
학습 과정
# 의사 코드
for epoch in range(num_epochs):
for batch in dataloader:
states, actions = batch
# 순전파
policy = network(states) # 361차원 확률 벡터
# 손실 계산 (교차 엔트로피)
loss = cross_entropy(policy, actions)
# 역전파
loss.backward()
optimizer.step()
학습 세부사항:
- 옵티마이저: SGD with momentum
- 학습률: 초기 0.003, 점진적 감소
- 배치 크기: 16
- 학습 시간: 약 3주 (50 GPUs)
데이터 증강
바둑판은 8중 대칭성(4개 회전 × 2개 거울 반사)을 가집니다. 각 학습 샘플은 8개의 등가 샘플로 변환될 수 있습니다:
원본 → 90° 회전 → 180° 회전 → 270° 회전
↓ ↓ ↓ ↓
수평 뒤집기 → ...
이렇게 하면 유효 학습 데이터가 8배 증가하고, 모델이 배운 패턴이 방향에 의존하지 않도록 보장합니다.
학습 결과
57% 정확도
학습 후, Policy Network는 57%의 top-1 정확도를 달성했습니다.
이것은 의미합니다: 어떤 국면이 주어져도, 모델이 인간 전문가가 실제로 둔 수를 예측할 확률이 57%입니다.
이 정확도가 높은가?
각 국면에서 평균 250개의 합법적인 착수가 있다는 점을 고려하면, 무작위 추측의 정확도는 0.4%에 불과합니다.
| 방법 | Top-1 정확도 |
|---|---|
| 무작위 추측 | 0.4% |
| 이전 최강 컴퓨터 바둑 | ~44% |
| AlphaGo Policy Network | 57% |
13 퍼센트 포인트 향상은 적어 보이지만, 의미가 큽니다.
기력 향상
순수하게 Policy Network만 사용하여(탐색 없이) 대국하면, 어느 정도 기력에 도달할 수 있을까요?
| 구성 | Elo 평점 | 대략적 등급 |
|---|---|---|
| 이전 최강 프로그램 (Pachi) | 2,500 | 아마추어 4-5단 |
| Policy Network 단독 | 2,800 | 아마추어 6-7단 |
| + MCTS 1600 시뮬레이션 | 3,200+ | 프로 수준 |
Policy Network 단독으로도 이미 아마추어 고단이고, MCTS를 더하면 프로 수준으로 도약합니다.
왜 57%밖에 안 되는가?
인간 기보에는 다음과 같은 특성이 있어 정확도를 제한합니다:
1. 여러 개의 좋은 수
많은 국면에서 여러 수가 모두 좋은 수입니다. 예를 들어 '화점 걸침'과 '화점 지킴'이 모두 올바른 선택일 수 있습니다. 모델이 다른 좋은 수를 선택하면, '오류'로 계산됩니다.
2. 스타일 차이
다른 기사들은 다른 스타일을 가집니다. 공격형 기사와 안정형 기사는 같은 국면에서 다른 수를 둘 수 있습니다. 모델이 배우는 것은 '평균' 스타일입니다.
3. 인간도 실수한다
KGS 데이터에는 아마추어 기사의 대국이 포함되어 있어, 그들의 선택이 반드시 최선은 아닙니다. 모델이 일부 '실수'를 배우는 것은 정상입니다.
MCTS에서의 역할
Policy Network는 AlphaGo의 MCTS에서 두 가지 핵심 역할을 합니다:
1. 탐색 방향 안내
MCTS의 Selection 단계에서, Policy Network의 출력은 UCB(Upper Confidence Bound) 계산에 사용됩니다:
UCB(s, a) = Q(s, a) + c_puct × P(s, a) × √(N(s)) / (1 + N(s, a))
여기서 P(s, a)가 바로 Policy Network가 제공한 확률입니다.
이것은 의미합니다:
- 높은 확률의 착수가 우선 탐색됨
- 낮은 확률의 착수도 탐색 기회가 있음 (탐색 항이 있기 때문)
2. 노드 확장 시 사전 확률
MCTS가 새 노드를 확장할 때, Policy Network는 모든 자식 노드의 사전 확률을 제공합니다.
노드 s 확장:
for each action a:
child = Node()
child.prior = policy_network(s)[a] # 사전 확률
child.value = 0
child.visits = 0
이러한 사전 확률은 MCTS가 어떤 자식 노드가 더 탐색할 가치가 있는지 '알 수' 있게 해줍니다, 그것들이 아직 방문되지 않았더라도.
경량 버전 vs 완전 버전
AlphaGo에는 실제로 두 개의 Policy Network가 있습니다:
완전 버전 (SL Policy Network)
- 아키텍처: 13층 CNN, 192 filters
- 정확도: 57%
- 추론 시간: 약 3 밀리초/국면
- 용도: MCTS에서 Selection과 Expansion
경량 버전 (Rollout Policy Network)
- 아키텍처: 선형 모델 + 수작업 특성
- 정확도: 24%
- 추론 시간: 약 2 마이크로초/국면 (1500배 빠름)
- 용도: 빠른 시뮬레이션 (rollout)
왜 경량 버전이 필요한가?
MCTS의 Simulation 단계에서, 현재 노드에서 게임 종료까지 계속 두어야 하며, 100수 이상이 필요할 수 있습니다. 매 수마다 완전 버전 Policy Network를 사용하면, 너무 느립니다.
경량 버전은 정확도가 24%밖에 안 되지만, 속도는 1500배 빠릅니다. rollout에서는 속도가 정밀도보다 중요합니다.
경량 버전의 특성
경량 버전은 수작업으로 설계된 특성을 사용하며, 다음을 포함합니다:
| 특성 유형 | 예시 |
|---|---|
| 국소 패턴 | 3×3 영역의 돌 배치 |
| 전역 특성 | 변, 귀인지, 대장 |
| 전술 특성 | 단수, 축머리, 연결 |
이러한 특성들은 선형 모델(은닉층 없음)에 입력되어, 계산 속도가 매우 빠릅니다.
AlphaGo Zero의 개선
이후의 AlphaGo Zero는 경량 버전과 rollout을 완전히 폐기했습니다. Value Network로 직접 리프 노드를 평가하며, 빠른 시뮬레이션이 필요 없습니다. 이것은 중대한 단순화입니다.
강화학습 미세조정 (RL Policy Network)
지도 학습의 한계
지도 학습으로 훈련된 Policy Network에는 근본적인 문제가 있습니다:
'인간 모방'을 배웠지, '승리'를 배우지 않았다
이것은 인간의 나쁜 습관을 배우게 되고, 인간이 한 번도 만나지 못한 국면에서 성능이 좋지 않다는 것을 의미합니다.
셀프 플레이 강화
DeepMind의 해결책은 정책 그래디언트(Policy Gradient) 방법으로 강화학습을 수행하는 것입니다:
1. Policy Network로 셀프 플레이
2. 각 대국의 모든 착수 기록
3. 승패에 따라 파라미터 조정:
- 이김 → 이 착수들의 확률 증가
- 짐 → 이 착수들의 확률 감소
REINFORCE 알고리즘
구체적으로 REINFORCE 알고리즘을 사용합니다:
∇J(θ) = E[Σ_t ∇log π_θ(a_t | s_t) × z]
여기서:
z: 이 대국의 결과 (+1 이김, -1 짐)π_θ(a_t | s_t): 상태s_t에서 행동a_t를 선택할 확률
결과
약 1일간의 셀프 플레이 훈련(128만 대국) 후, RL Policy Network:
| 지표 | SL Policy | RL Policy |
|---|---|---|
| SL Policy와 대전 | 50% | 80% |
| Elo 향상 | - | +100 |
정확도는 약간 하락할 수 있지만(더 이상 인간을 완전히 모방하지 않기 때문), 실제 대전 승률은 크게 향상됩니다.
'모방'에서 '혁신'으로
강화학습은 Policy Network가 인간이 생각하지 못한 착수를 배우게 합니다. 이러한 착수는 학습 데이터에 한 번도 나타나지 않았지만, 효과적입니다.
이것이 AlphaGo가 '신의 한 수'를 둘 수 있는 이유입니다 — 인간의 경험에 제한받지 않습니다.
시각화 분석
다른 국면의 확률 분포
다른 국면에서 Policy Network의 출력을 살펴봅시다:
초반 (포석 단계)
초반에 확률은 주로 다음에 집중됩니다:
- 귀 (화점 차지)
- 변 (화점 걸침, 화점 지킴)
- '대장' 위치
이것은 바둑의 기본 원리와 일치합니다: 금귀은변초복.
전투 중인 국면
전투 시 확률은 다음에 집중됩니다:
- 핵심 끊음점
- 단수, 연결
- 눈 만들기, 눈 부수기
이것은 모델이 국소 전술을 배웠음을 보여줍니다.
끝내기 단계
끝내기에서 확률은 각 끝내기 점에 분산되어, 정확한 집 계산이 필요합니다.
은닉층은 무엇을 배웠나?
컨볼루션층의 출력을 시각화하면, 모델이 배운 '특성'을 볼 수 있습니다:
- 낮은 층: 기본 형태 (눈, 끊음점)
- 중간 층: 전술 패턴 (단수, 축머리)
- 높은 층: 전역 개념 (세력, 두께)
이것은 인간이 바둑을 인지하는 계층 구조와 매우 유사합니다.
구현 포인트
PyTorch 구현
다음은 단순화된 Policy Network 구현입니다:
import torch
import torch.nn as nn
import torch.nn.functional as F
class PolicyNetwork(nn.Module):
def __init__(self, input_channels=48, 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)
])
# 출력 컨볼루션층 (1×1)
self.conv_out = nn.Conv2d(num_filters, 1, kernel_size=1)
def forward(self, x):
# x: (batch, 48, 19, 19)
# 첫 번째 층
x = F.relu(self.conv1(x))
# 중간 층
for conv in self.conv_layers:
x = F.relu(conv(x))
# 출력층
x = self.conv_out(x) # (batch, 1, 19, 19)
# 평탄화 + Softmax
x = x.view(x.size(0), -1) # (batch, 361)
x = F.softmax(x, dim=1)
return x
학습 루프
def train_step(model, optimizer, states, actions):
"""
states: (batch, 48, 19, 19) - 바둑판 특성
actions: (batch,) - 인간이 둔 위치 (0-360)
"""
# 순전파
policy = model(states) # (batch, 361)
# 교차 엔트로피 손실
loss = F.cross_entropy(
torch.log(policy + 1e-8), # log(0) 방지
actions
)
# 역전파
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 정확도 계산
predictions = policy.argmax(dim=1)
accuracy = (predictions == actions).float().mean()
return loss.item(), accuracy.item()
추론 시 주의사항
실제 대국에서 주의해야 할 점:
- 불법 착수 필터링: 불법 위치의 확률을 0으로 설정하고, 다시 정규화
- 온도 조절: 온도 파라미터로 확률 분포의 '날카로움' 제어 가능
- 배치 추론: MCTS에서 여러 국면을 배치 처리 가능
def get_move_probabilities(model, state, legal_moves, temperature=1.0):
"""합법적인 착수의 확률 분포 얻기"""
policy = model(state) # (361,)
# 합법적인 착수만 유지
mask = torch.zeros(361)
mask[legal_moves] = 1
policy = policy * mask
# 온도 조절
if temperature != 1.0:
policy = policy ** (1 / temperature)
# 다시 정규화
policy = policy / policy.sum()
return policy
애니메이션 대응
이 글에서 다루는 핵심 개념과 애니메이션 번호:
| 번호 | 개념 | 물리/수학 대응 |
|---|---|---|
| 🎬 E1 | Policy Network | 확률장 |
| 🎬 D9 | CNN 특성 추출 | 필터 응답 |
| 🎬 D3 | 지도 학습 | 최대 우도 추정 |
| 🎬 H4 | 정책 그래디언트 | 확률적 최적화 |
추가 읽기
- 다음 편: Value Network 상세 해설 — AlphaGo가 국면을 평가하는 방법
- 관련 주제: 입력 특성 설계 — 48개 특성 평면 상세
- 심층 원리: CNN과 바둑의 결합 — 왜 컨볼루션 신경망이 바둑판에 적합한가
핵심 포인트
- Policy Network는 확률 분포 생성기: 바둑판을 입력하면, 361개 위치의 확률 출력
- 13층 CNN + Softmax: 심층 컨볼루션으로 특성 추출, Softmax로 확률 출력
- 57% 정확도: 이전의 컴퓨터 바둑 프로그램을 훨씬 초과
- 두 버전: 완전 버전은 MCTS 의사결정에, 경량 버전은 빠른 시뮬레이션에 사용
- 강화학습 미세조정: '인간 모방'에서 '승리 추구'로 진화
Policy Network는 AlphaGo의 '직관'입니다 — AI가 인간처럼 고려할 가치가 있는 착수를 빠르게 식별할 수 있게 해줍니다.
참고 자료
- Silver, D., et al. (2016). "Mastering the game of Go with deep neural networks and tree search." Nature, 529, 484-489.
- Maddison, C. J., et al. (2014). "Move Evaluation in Go Using Deep Convolutional Neural Networks." arXiv:1412.6564.
- Sutton, R. S., & Barto, A. G. (2018). Reinforcement Learning: An Introduction. MIT Press.
- LeCun, Y., Bengio, Y., & Hinton, G. (2015). "Deep learning." Nature, 521, 436-444.