본 논문에서는 2016년 AlphaGo, 2017년 AlphaGo Zero를 통해 바둑(Go)에 대한 성공을 경험한 후, AlphaGo Zero의 more generic version 인 AlphaZero를 소개하고 있음.

(https://www.deepmind.com/blog/muzero-mastering-go-chess-shogi-and-atari-without-rules)
Game 의 복잡도를 보았을 때, Go가 가장 복잡하고, shogi (일본식 장기) 와 chess 순으로 복잡도를 가지고 있는데, AlphaZero는 동일한 알고리즘을 이용하여 Go, Chess, Shogi 모두에 대응하는 generic algorithm을 제안함.

(https://www.researchgate.net/publication/337871637_Application_of_Q-Learning_and_RBF_Network_in_Chinese_Chess_Game_System)
Alpha Go는 실제 전문가의 기보 데이터를 기반으로 모델을 학습하고 해당 모델을 활용하여 MCTS(Monte Carlo Tree Search) 를 진행하는 방법론임.
💡 Alpha Go 학습 방법실제 전문가의 기보 데이터가 있으면, 이를 통해 Rollout Policy 나 SL Policy / Rollout Policy 를 학습.
RL policy network 에서는 SL policy로 weight initialization 하여 self-play 를 진행하고, network를 업데이트 함.

Inference 시에는 앞선 train 단계에서 학습 시켰던 모델을 활용하여 MCTS 를 진행함.


AlphaGo Zero는 사람의 지식을 제거하면서도, 좋은 성능을 낼 수 있다는 점에서 AlphaGo 보다 진보한 알고리즘이라고 함.
[AlphGo 와의 차이점]



AlphaZero는 AlphaGo Zero의 generic version 알고리즘임. 학습 방법은 자체는 거의 동일하며, 대상 게임에서 차이가 존재함.
그럼에도 존재하는 차이는 아래와 ‘차이점’과 같음.
for i in range(10):
print('Train', i, '====================')
# 셀프 플레이 파트
**self_play()**
# 파라미터 변경 파트
**train_network()**
# 신규 파라미터 평가 파트
**evaluate_network()**
Self play를 통해 학습 데이터를 모으고 저장함.
def self_play():
# 학습 데이터
history = []
# 베스트 플레이어 모델 로드
model = load_model('./model/best.h5')
# 여러 차례 게임 실행
for i in range(SP_GAME_COUNT):
# 1ゲームの実行
h = play(model)
history.extend(h)
# 출력
print('\rSelfPlay {}/{}'.format(i + 1, SP_GAME_COUNT), end='')
print('')
# 학습 데이터 저장
write_data(history)
# 모델 파기
K.clear_session()
del model
모은 학습 데이터를 이용하여 network를 학습함.
# 듀얼 네트워크 학습
def train_network():
# 학습 데이터 로드
history = load_data()
xs, y_policies, y_values = zip(*history)
# 학습을 위한 입력 데이터 셰이프로 변환
a, b, c = DN_INPUT_SHAPE
xs = np.array(xs)
xs = xs.reshape(len(xs), c, a, b).transpose(0, 2, 3, 1)
y_policies = np.array(y_policies)
y_values = np.array(y_values)
# 베스트 플레이어 모델 로드
model = load_model('./model/best.h5')
# 모델 컴파일
model.compile(loss=['categorical_crossentropy', 'mse'], optimizer='adam')
# 학습률
def step_decay(epoch):
x = 0.001
if epoch >= 50: x = 0.0005
if epoch >= 80: x = 0.00025
return x
lr_decay = LearningRateScheduler(step_decay)
# 출력
print_callback = LambdaCallback(
on_epoch_begin=lambda epoch, logs:
print('\rTrain {}/{}'.format(epoch + 1, RN_EPOCHS), end=''))
# 학습 실행
model.fit(xs, [y_policies, y_values], batch_size=128, epochs=RN_EPOCHS,
verbose=0, callbacks=[lr_decay, print_callback])
print('')
# 최신 플레이어 모델 저장
model.save('./model/latest.h5')
# 모델 파기
K.clear_session()
del model
학습한 network를 평가함.
# 네트워크 평가
def evaluate_network():
# 최신 플레이어 모델 로드
model0 = load_model('./model/latest.h5')
# 베스트 플레이어 모델 로드
model1 = load_model('./model/best.h5')
# PV MCTS를 활용해 행동 선택을 수행하는 함수 생성
next_action0 = pv_mcts_action(model0, EN_TEMPERATURE)
next_action1 = pv_mcts_action(model1, EN_TEMPERATURE)
next_actions = (next_action0, next_action1)
# 여러 차례 대전을 반복
total_point = 0
for i in range(EN_GAME_COUNT):
# 1 게임 실행
if i % 2 == 0:
total_point += play(next_actions)
else:
total_point += 1 - play(list(reversed(next_actions)))
# 출력
print('\rEvaluate {}/{}'.format(i + 1, EN_GAME_COUNT), end='')
print('')
# 평균 포인트 계산
average_point = total_point / EN_GAME_COUNT
print('AveragePoint', average_point)
# 모델 파기
K.clear_session()
del model0
del model1
# 베스트 플레이어 교대
if average_point > 0.5:
update_best_player()
return True
else:
return False
결과적으로 실험을 진행했을 때, AlphaZero를 이용하는 경우 Chess, Shogi, Go 모두에서 높은 승률을 볼 수 있었다고 함.

