奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り...

101
( ) [email protected] TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Transcript of 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り...

Page 1: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

奥田 幸男(フリーランス)

[email protected]

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda ·

··

·

Page 2: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

奥田=コンピュータオタク

2

7 0 年 Fortran, PL/I, RPG 360/IBM8 0 年 Bliss, C, X11 VAX/DEC

(ADA, Objective-C)9 0 年 C++, Octave, Tcl Sparc/Sun0 0 年 CERN-Root    PC/Intel 1 0 年 JavaScript

1 8 年~ Python 加速器/Nvidia?DL(NN/AI)

●新技術の評価

·

··

·

はじめに

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 3: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

目的と背景

3

❶DLパッ ケージの選択 ❷Pythonの高速化

■ PythonのGIL縛り➡加速器=パラレル処理● CPU➡クロッ ク3 GHz限界➡マルチコア● GPU➡GP-GPU➡CUDA● Spark✈ , TPU,Phi✈ , Nervana✈ , Tegra✈ , ARM, QUALCOMM

■ Python: グルー言語➡他パッ ケージ親和性、 多種加速器

■パッ ケージ :●専用パッ ケージ: PyCUDA, OpenCL, PySpark

●既存パッ ケージの拡張: Pandas ➡Dask, Intel-Python

● List互換: Numba

● NumPy相当: TensorFlow(TF), PyTorch, CuPy比較

▼ TF:一番高機能、 しかし解説少➡ 要評価コード

·

··

·

はじめに

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 4: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

スト ーリー

4

❶はじめに

❷評価方法

❸解析

❹考察

❺まとめ

スピード比較

SG: Static Graph @session.runEG: Eager, not Graph

·

··

·

はじめに

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 5: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

H/W S/W

5

env-1, env-2,...env-nPython 3.5

Conda 4.3.30Mint Linux(Ubuntu 16.04)

CPU + GPU

SSH, NFS

CPU: i7-2630QM(Sandy Bridge’12ノ ート 用)

2.4 GHz 4コア 8スレッ ドL1=256K, L2=1M, L3=6MPCIe II 5GT/sDDR3 16G 21.3G/sQM77, NF9G(Jetway社)

GPU: GTX-1060(Pascal GP-106)

1.5 GHz 1280コアL2=1.5M(192bI/F)PCIe II 5GT/sDDR5 6G 8G/sCUDA-8 CC-6.1

·

··

·

評価方法

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 6: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

Env

6

$ conda create -n XXX python=3.5$ source activate XXX$ pip install YYYYY.whl

パッ ケージ CPU GPUバージョ ン1.1 TensorFlow-SG 〇 ー 1.41.2 TensorFlow-SG ー 〇 1.41.3 TensorFlow-EG 〇 ー 1.5-dev20171127

1.4 TensorFlow-EG ー 〇 1.5-dev20171127

1.5 TensorFlow-EG/SG〇 ー 1.5AVXコンパイル Python-2.7

2.1 PyTorch 〇 〇 0.2.0 43.1 CuPy ー 〇 2.2.04.1 Numba 〇 〇 0.36.15.1 Intel Python 〇 ー

·

··

·

評価方法

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 7: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

モンテカルロ円周率計算

7

■乱数[ 0, 1) shot、 半径1 円弧内にhit

r0

1

1■NumPy演算

● SIMD化容易

■変換容易:np. ➡tf.torch.cp.(CuPy)

π = 4 · hit/shotimport numpy as npdef get(size, shot, hit):

x = np.random.rand(size)y = np.random.rand(size)r = np.sqrt(np.add(np.multiply(x, x), np.multiply(y, y)))one = np.array([1.]*size)lss = np.less equal(r, one)hit one = np.count nonzero(lss)hit += hit oneshot += sizereturn shot, hit

·

··

·

評価方法

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 8: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

速度倍率

8

for size in [10**2, ..., 10**6]:shot, hit = 0, 0shot, hit = get(size, shot, hit)pi = 4 * hit/ shotrec( pi, shot, size)

����� ����� ��������

���

���

���

����� �

����

��

��

��

��������

����

for size in [10**2, ..., 10**6]:

for in range(1000):shot, hit = 0, 0shot, hit = get(size, shot, hit)

pi = 4 * hit/ shotrec( pi, shot, size)

倍率=直線近似傾きの比

����� ��� ��������

��

��

��

�������

����

����

������ ����

·

··

·

評価方法

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 9: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

TFスピード特徴

9

■CPUで 4~6倍!! ■CPU段差 ■GPUで 24~76倍■While高速

����� ����� ���� ����� ����� �����&%'

��

��

��

��

��

"$! ��#�

���������������� �������������������������������� ����

·

··

·

評価方法

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 10: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

NumPy変換

10

■np. ➡tf. torch.NumPy: np.xxx()

x = np . random . rand ( s i z e ) . a s t y p e ( np . f l o a t 3 2 )y = np . random . rand ( s i z e ) . a s t y p e ( np . f l o a t 3 2 )r s = np . s q r t ( np . add ( np . m u l t i p l y ( x , x ) ,

np . m u l t i p l y ( y , y ) ) )ones = np . a r r a y ( [ 1 . ] ∗ s i z e , d t y p e =np . f l o a t 3 2 )l s s = np . l e s s e q u a l ( r s , ones )h i t o n e = np . c o u n t n o n z e r o ( l s s )

1スレッ ド

TF-Eg: tf.xxx()x = t f . r andom uni fo rm ( shape =[ s i z e ] , minva l = 0 . ,

maxval = 1 . , d t y p e = t f . f l o a t 3 2 )y = t f . r andom uni fo rm ( shape =[ s i z e ] , minva l = 0 . ,

maxval = 1 . , d t y p e = t f . f l o a t 3 2 )r s = t f . s q r t ( t f . add ( t f . m u l t i p l y ( x , x ) ,

t f . m u l t i p l y ( y , y ) ) )ones = t f . ones ( [ s i z e ] , d t y p e = t f . f l o a t 3 2 )l s s = t f . l e s s e q u a l ( r s , ones )h i t o n e = t f . c o u n t n o n z e r o ( l s s , d t y p e = t f . i n t 6 4 )

8!スレッ ド完全パラレル?

PyTorch: torch.xxx()x = t f . r andom uni fo rm ( shape =[ s i z e ] , minva l = 0 . ,

maxval = 1 . , d t y p e = t f . f l o a t 3 2 )y = t f . r andom uni fo rm ( shape =[ s i z e ] , minva l = 0 . ,

maxval = 1 . , d t y p e = t f . f l o a t 3 2 )r s = t f . s q r t ( t f . add ( t f . m u l t i p l y ( x , x ) ,

t f . m u l t i p l y ( y , y ) ) )ones = t f . ones ( [ s i z e ] , d t y p e = t f . f l o a t 3 2 )l s s = t f . l e s s e q u a l ( r s , ones )h i t o n e = t f . c o u n t n o n z e r o ( l s s , d t y p e = t f . i n t 6 4 )

3+αスレッ ド

·

··

·

解析: EG

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 11: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

Np EG Pt@CPU比較

11

■PyTorch(Pt)無加速■EG加速

����� ����� �����! "

��

��

��

��������

�������������������������� �

■EG 2 速 原因は?● 0.5Mで段差● float32= 4byteで計算

● 2項演算要3 ベクター

● 4x3x0.5=6M=L3サイズ

■ AVXでは段差無

����� ����� ��������

��

��

��

�������

���

���

�����

��������

·

··

·

解析: EG

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 12: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

他のCPUで測定

12

■コア数倍●N3150 4.3倍1 速

(Braswell’15 Celeron/Atom)1.6-2GH, 4コアー、 ノ ー・ スレッ ドL1=224K L2=2M(1Mx2)

����� ��� �������

���

���

���

�������

��������������

●AVX 4.2倍●3.7~4.6倍 2速

1.6-2.4GH, 4 コアー、 8スレッ ドL1=256K, L2=1M, L3=6M

����� ����� �����"!#

��

��

��

� ������

���������������� ����������

·

··

·

解析: EG

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 13: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

EG,SGコードの違い

13

■ Eager コード ■ Static Graph コード

#定義#実行

def gen(a, loop):

for in range(loop):a = tf.add(a, 1)

return a

#定義#生成(マクロ )N = 3def gen(a):for in range(N):

a = tf.add(a, 1)return a

ap= tf.placeholder(··)ag = gen(ap)sess = tf.Session()

#実行a = tf.zeros(··)a = gen(a,3)

#実行sess.run(tf.··initializer())a = np.zeros(··)a = sess.run(ag,

feed dict=ap: a)

実行時決定

固定

〇 tf.Tensor

× tf.Variable

× tf.TensorArray

●閉じた関数

▼tf.Variable

▼tfe.Variable● tf.xxxのみ実行

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 14: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

EG,SG実行モデルの違い

14

for in range(N): a = tf.add(a, ・・ ) コード

●EG CPU 加速器

・ コンパイル a a 転送時間要実測

・ 機動 + + DDR➡M-Con.➡CPU➡PCIe➡GPU-M-Bus➡DDR

a1 プロト コール変換/ブロッ ク転送/キュー/コンテキスト 切り替え

●SG CPU 加速器

・ マクロ a a

・ コンパイル +1 +2 ● ● ● +N +1 +2 ・・ ・ +N

・ リ ンク a1 a2 aN

N回

N個グラフ

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 15: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

EG,SG速度の違い@GPU

15

■EG GPUで加速せず●転送量大:コード =9,アレー= (8 + 8)、スカラー=..

����� ����� ��������

��

��

��

������

� ���� ��

 

■SG GPUで 3.8倍●転送量小:グラフ =1 , アレー= 0, スカラー= (2, 2)

����� ����� ��������

��

�������

����������������

·

··

·

解析: EG

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 16: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

SG2種類のループ

16

■ Runループ コード

ap = tf.placeholder(...)aa = tf.add(ap, 1)sess = tf.Session()sess.run(tf.global variables initializer())a = np.zeros([10])

for in range(N):a = sess.run(aa,

feed dict=ap: a)

CPU 加速器

a ap

+ +

aa

■ While loopループap = tf.placeholder(...)i, a = tf.while loop(

lambda i, a: tf.less(i,N),lambda i, a: (tf.add(i, 1),

tf.add(a, 1)),[0, ap])

sess = tf.Session(); sess.run(tf.global variables initializer())

a = sess.run(a, feed dict=ap:..)

CPU 加速器

a0 ap

+ WL + WL

a i a

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 17: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

SGでのWhile loop

17

■GPU 3.2倍

����� ��� ������

��������

������� ��������������

■CPU 1.2 倍

����� ����� ��������

���

���

���

��

����

����

����� �

���������������������

·

··

·

解析: SG

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 18: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

EGでのWhile loop

18

■高速化無、 コード SG流用可能 (SGデバッ ク困難)

●GPU 0.9~1.3倍

����� ��� ����� �!

��

��

��������

���������� ������������������

●CPU 0.9~1.2倍

����� ��� ����� �!

��

��

��������

�� ��������������� ������������

·

··

·

解析: SG

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 19: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda ·

··

·

Page 20: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

転送時間推定(1/3)

20

■ EG処理時間: teg ≈ tsgw + N(ted + teu)●仮定: tf.xxx(..)処理時間, EG/SGで同じ● EG N回ループ時間: teg

CPU 加速器

a ap

+ +

aa

tedtecteu

teg =N(tec + ted + teu)

=Ntec + N(ted + teu)

● SG-While loop時間: tsgwCPU 加速器

a0 ap

+ WL + WL

a i a

twd

twc = Ntec

twu

tsgw = twc + twd + twu≈ twc

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 21: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

転送時間推定(2/3)

21

■転送1000回合計時間 tDU = 1000(ted + teu)CPU

for in range(1000):buf = np.empty(size)

ans = sess.run(ans get,feed dict= a: buf)注:np.emptyは負荷軽い

加速器a = tf.placeholder(...)

ans get = func(a)

def func(ain):return tf.add(ain, 1.)

■ばらつき大➡1 0 0 回の平均を採用

� ��� � ��� � ������

���

���

���

��������

��

����� ����� ��������

���

���

���� ��

��

��

ted

teu

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 22: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

転送時間推定(3/3)

22

■ teg = tsgw + 8tDU ➡GPU下一致, AVX全一致➡証明

● EG,SG内処理時間同じ ●転送時間で速度差

����� ����� ��������

��

��

��

���� ��

��

��tegtsgw

����� ����� ��������

��

��

��

��� ��

���

��tegavxtsgw

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 23: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

EGに適した加速器

23

■ GPUよりマルチコア (AVX)➡Phi/Intel要比較検討Wiki

� ��� � ��� � ������

��

��

��

�������

��������

☞4 コアで、 GPUと同速 ☞CPU間転送マルチコア早い  ☞Nコアで、 NumPyのN倍速 

Xeon:4~22コア (L3=20~60MB) Wiki

Atom:2~16コア (L3=2~16MB) Wiki

ARM/DynamIQ: 1~8コア

● GPU効果のない理由:

▼加速器で1 関数のみ実行 +関数粒度小➡GPUの多演算器不要

▼実行毎に入/出力データ移動 +少量データの頻繁な転送➡GPU不適

注:Google+Intel for Phi✈

Xeon(22コア ), AVX2に展開注:PyTorch, Chainer: マルチコア加速無

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 24: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

SG現実の速度要解析

24

■乱数を転送: feed dict={x: xs, y: ys... }

●GPU 25.8 ➡1.2倍●AVX 1.6倍

����� ����� ����$#%

��

��

�"������

!���

������� �������������������� �����

●乱数生成時間で補正●オーバーヘッ ド大

����� ����� ����! "

��

��

��������

������

����� ���������� �������tDU�������������� ������

}}}}

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 25: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

プラン (1/2):未評価

25

データー: a

n1 = fc1(a)

生成のみ➡自動化可能

n2 = fc2(a)

SIMD n = fc(a)

n[0 : 10] = fc(a[0 : 10])

n[10 : 20] = fc(a[10 : 20])

 並列グラフ

a

fc1 fc2

n1 n2

ループ条件分岐

a[i] = fu(m)

自動化不可能

ベクト ル演算 tf.while looptf.cond

Eager

Session.run

tf.Variabletfe.Variabletf.TensorArraytf.assign xxx()tf.scater xxx()tf.control dependencies

· ·

TF

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 26: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

プラン (2/2):実証と拡張

26

■TF: H/W,OS,方式..影響大➡要解析,対応▼要実用性の確認 ▼要DL演算への適応

Help: ト ライアル、 HW提供

●アプリ汎用数値計算

画像処理その他

●OS

 

LinuxWindows

EsxiAndroid

iOS

Web

●H/WマルチコアCUDAPhi/IntelAVX,Intel-Python

マルチノ ードGFX(AMD)?/ARM

●TF

 

Eager

Run-SIMD

I/O

●モデル化 ●測定 ●分析 ●解析DL演算

●モデル化 ●測定 ●分析 ●解析汎用数値計算

Model Based Data Analysis

·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 27: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

まとめ

27

■システム応答分析による ,TF基本機能の解析と考察●EG,SG共通

▼マルチコア、 GPUにより加速される

▼ tf.xxx()関数実行時間は、 両者で同じ

▼ CPU加速器間データ転送が重要(EGでの時間取得)

●EG

▼汎用数値計算器になりえる , (関数,用途別Libに依存)

▼デバッ クは通常のPythonと同じ

▼ EG開発、 SG運用の使い分けが有効か?●SG

▼制限の多い計算グラフのため、 用途は限定される

❙ループ不可 ❙スライス修正 ❙スタティッ ク

▼デバッ クは非常に困難

▼閉じた関数では非常に高速

■必要:「実証」「並列グラフ ,Variable,DL演算..モデル」·

··

·

考察

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 28: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

Q/Aor

コメント

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda ·

··

·

Page 29: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

補足

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda ·

··

·

Page 30: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

ループコード

30

■EG for ...

# −∗− co d in g : u t f −8 −∗−

i m p o r t t e n s o r f l o w as t f

i m p o r t t e n s o r f l o w . c o n t r i b . e a g e r a s t f e

t f e . e n a b l e e a g e r e x e c u t i o n ( )

d e f gen ( a , lo o p ) :

f o r i n r a n g e ( lo o p ) :

a = t f . add ( a , 1 )

r e t u r n a

a = t f . z e r o s ( [ 1 0 ] )

a = gen ( a , 3 )

p r i n t ( a )

■SG for ...

# −∗− co d in g : u t f −8 −∗−

i m p o r t t e n s o r f l o w as t f

i m p o r t numpy as np

N = 3

d e f gen ( a ) :

f o r i n r a n g e (N ) :

a = t f . add ( a , 1 )

r e t u r n a

ap = t f . p l a c e h o l d e r ( t f . i n t 3 2 , None , name= ’a ’ )

ag = gen ( ap )

s e s s = t f . S e s s i o n ( )

s e s s . r u n ( t f . g l o b a l v a r i a b l e s i n i t i a l i z e r ( ) )

a = np . z e r o s ( [ 1 0 ] )

a = s e s s . r u n ( ag , f e e d d i c t ={ap : a } )

p r i n t ( a )

■Runループ# −∗− co d in g : u t f −8 −∗−

i m p o r t t e n s o r f l o w as t f

i m p o r t numpy as np

ap = t f . p l a c e h o l d e r ( t f . i n t 3 2 , None , name= ’ap ’ )

aa = t f . add ( ap , 1 )

s e s s = t f . S e s s i o n ( )

s e s s . r u n ( t f . g l o b a l v a r i a b l e s i n i t i a l i z e r ( ) )

a = np . z e r o s ( [ 1 0 ] )

f o r i n r a n g e ( 3 ) :

a = s e s s . r u n ( aa , f e e d d i c t ={ap : a } )

p r i n t ( a )

■While loop

# −∗− co d in g : u t f −8 −∗−

i m p o r t t e n s o r f l o w as t f

i m p o r t numpy as np

ap = t f . p l a c e h o l d e r ( t f . i n t 3 2 , None , name= ’a ’ )

i , a = t f . w h i l e l o o p (

lambda i , a : t f . l e s s ( i , 3 ) ,

lambda i , a : ( t f . add ( i , 1 ) , t f . add ( a , 1 ) ) ,

[ 0 , ap ]

)

s e s s = t f . S e s s i o n ( )

s e s s . r u n ( t f . g l o b a l v a r i a b l e s i n i t i a l i z e r ( ) )

a = s e s s . r u n ( a , f e e d d i c t ={ap : np . z e r o s ( [ 1 0 ] ) } )

p r i n t ( a )

·

··

·

補足

TFUG-Tokyo#7-1 2018/1/29 Y. Okuda

Page 31: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

形態素解析を利用した江戸川乱歩風文書の生成

2018/1/29

石垣哲郎

TensorFlow User Group #7

1

Page 32: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

本プレゼンは、青空文庫の江戸川乱歩

作品を形態素解析し、これを入力とした、

KerasのLSTMレイヤーによる文書生成

の試みについてのご紹介です。

2

Page 33: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

発表者自己紹介

氏名:石垣 哲郎

1986年4月 日本電気株式会社入社2015年11月 日本インサイトテクノロジー株

式会社入社

TensorflowやKERASは仕事ではなく、もっぱらオフタイムに触っています。

3

Page 34: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

Kerasとは

Kerasは,Pythonで書かれた,TensorFlowまたはCNTK,Theano上で実行可能な高水準のニューラルネットワークライブラリです. Kerasは,迅速な実験を可能にすることに重点を置いて開発されました.アイデアから結果に到達するまでのリードタイムをできるだけ小さくすることが,良い研究をするための鍵になります.

次のような場合で深層学習ライブラリが必要なら,Kerasを使用してください:

• 容易に素早くプロトタイプの作成が可能(ユーザーフレンドリー,モジュール性,および拡張性による)

• CNNとRNNの両方,およびこれらの2つの組み合わせをサポート

• CPUとGPU上でシームレスな動作

(Kerasドキュメンテーションより) 4

Page 35: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

Kerasによるモデル構成

KerasのSequentialモデルを用い、各メソッドを積み上げて構成した。以下はKerasドキュメンテーションに掲載されていた、LSTMの例。

from keras.models import Sequentialfrom keras.layers import Dense, Dropoutfrom keras.layers import Embeddingfrom keras.layers import LSTM

model = Sequential()model.add(Embedding(max_features, output_dim=256))model.add(LSTM(128))model.add(Dropout(0.5))model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=16, epochs=10)score = model.evaluate(x_test, y_test, batch_size=16)

addメソッドを1行記述するだけで、簡単に層追加が出来る!

5

Page 36: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

6

コンセプト

• 基本的な考え方は、文書生成についてググると必ず出てくる、以下のgithub登録内容を参考にした

https://github.com/keras-team/keras/blob/master/examples/lstm_text_generation.py

• 上記のソースは英語をターゲットにしているが、今回は日本語の文書生成にチャレンジする

• 言うまでもなく、日本語は単語の分割が容易でない。この問題を避けるため、1文字ごとに処理する方法もあるが、今回は文書生

成の精度が上がることを期待して、形態素解析を利用することにした

• 形態素解析ソフトとして、京大黒橋・河原研究室のjuman++を採用した

http://nlp.ist.i.kyoto-u.ac.jp/index.php?JUMAN++

Page 37: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

7

GitHub「lstm_text_generation.py」(1/2)

• KerasのLSTMレイヤーを用い、入力の文字リスト(つまり入力文章)から次の文字を予測する

• 予測した文字を入力文字リストの最後尾に付け、今度はそれを入力に次の文字を予測する

• これを繰り返して文章を生成する

1 2 3 4 5 1LSTM

2 3 4 5 1 2LSTM

3 4 5 1 2 3LSTM

入力文字リスト(入力文章)

予測文字

1 2 3 4 5 n・・・・・・・

生成文章

Page 38: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

8

GitHub「lstm_text_generation.py」(2/2)

• 出力次元数は128、入力系列数は40

maxlen = 40model = Sequential()model.add(LSTM(128, input_shape=(maxlen, len(chars))))model.add(Dense(len(chars)))model.add(Activation('softmax'))

• LSTM出力ベクトルのargmaxから予測文字インデックスを決定する

のではなく、出力ベクトルを確率分布としたランダム抽出によるインデックス決定ロジックにより、予測結果に揺らぎを与えている

def sample(preds, temperature=1.0):# helper function to sample an index from a probability arraypreds = np.asarray(preds).astype('float64')preds = np.log(preds) / temperatureexp_preds = np.exp(preds)preds = exp_preds / np.sum(exp_preds)probas = np.random.multinomial(1, preds, 1)

return np.argmax(probas)

予測結果を確率的に決定

分散も変動させる

Page 39: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

9

予測結果のゆらぎについて

「lstm_text_generation.py」では予測結果に揺らぎを与えていたが、今回の事例では予測精度向上も目的としているので、普通にLSTM出力ベクトルのargmaxから予測文字インデックスを決定する

Page 40: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

10

形態素解析システムjuman++(1/2)

• 日本語を対象とした自然言語処理では、いわゆる「分かち書き」の問題は避けて通れない。分かち書きを実施せず、1文字ごとに

処理する方法もあるが、今回は文書生成の精度が上がることを期待して、形態素解析を利用することにした

• 形態素解析ソフトとして、京大黒橋・河原研究室のjuman++を採用した

http://nlp.ist.i.kyoto-u.ac.jp/index.php?JUMAN++

• juman++を採用した理由は、検索結果が上位だったためである

Page 41: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

11

形態素解析システムjuman++(2/2)

• 入力文字列と、解析結果は以下の通りである。情報量が豊富だが、今回は分かち書きの結果(一番左の列)のみ使用している

外国人参政権私もあさって日曜最終日

外国 がいこく 外国 名詞 6 普通名詞 1 * 0 * 0 "代表表記:外国/がいこく カテゴリ:場所-その他 ドメイン:政治"人 じん 人 名詞 6 普通名詞 1 * 0 * 0 "代表表記:人/じん 漢字読み:音 カテゴリ:人"@ 人 ひと 人 名詞 6 普通名詞 1 * 0 * 0 "代表表記:人/ひと 漢字読み:訓 カテゴリ:人"参政 さんせい 参政 名詞 6 サ変名詞 2 * 0 * 0 "代表表記:参政/さんせい カテゴリ:抽象物 ドメイン:政治"権 けん 権 名詞 6 普通名詞 1 * 0 * 0 "代表表記:権/けん 漢字読み:音 カテゴリ:抽象物"EOS私 わたし 私 名詞 6 普通名詞 1 * 0 * 0 "代表表記:私/わたし 漢字読み:訓 カテゴリ:人"も も も 助詞 9 副助詞 2 * 0 * 0 NILあさって あさって あさって 名詞 6 時相名詞 10 * 0 * 0 "代表表記:明後日/あさって カテゴリ:時間"日曜 にちよう 日曜 名詞 6 時相名詞 10 * 0 * 0 "代表表記:日曜/にちよう カテゴリ:時間"最終 さいしゅう 最終だ 形容詞 3 * 0 ナノ形容詞 22 語幹 1 "代表表記:最終だ/さいしゅうだ 反義:形容詞:最初だ/さいしょだ"日 ひ 日 名詞 6 時相名詞 10 * 0 * 0 "代表表記:日/ひ 漢字読み:訓 弱時相名詞 カテゴリ:時間"@ 日 にち 日 名詞 6 時相名詞 10 * 0 * 0 "代表表記:日/にち 漢字読み:音 カテゴリ:時間"EOS

入力文字列

解析結果

Page 42: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

12

なぜ江戸川乱歩か

• 文章のキャラクターがはっきりしている

• 口語かつ新仮名遣いで書かれている(文語や旧仮名遣いだと、形態素解析にかからない懸念があった)

• ある程度のボリュームの文書が容易に入手できる(江戸川乱歩の著作は青空文庫に収録されている)

Page 43: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

13

コーパスの作成方法(1/2)

① 青空文庫からテキストをダウンロードする

• ジュブナイルの「怪人20面相」ものは文体が違うので、使用しなかった

② ヘッダ部分を外して、juman++にかける

• ルビや見出しの指示記号は、削除せずそのまま使用した

人間椅子江戸川乱歩

-------------------------------------------------------【テキスト中に現れる記号について】

《》:ルビ(例)佳子《よしこ》

|:ルビの付く文字列の始まりを特定する記号(例)表題|丈《だけ》

[#]:入力者注 主に外字の説明や、傍点の位置の指定(数字は、JIS X 0213の面区点番号またはUnicode、底本のページと行数)

(例)※[#「骨+低のつくり」、第3水準1-94-21]-------------------------------------------------------

佳子《よしこ》は、毎朝、夫の登庁《とうちょう》を見送って了《しま》うと、それはいつも十時を過ぎるのだが、やっと自分のからだになって、洋館の方の、夫と共用の書斎へ、とじ籠《こも》るのが例になっていた。そこで、彼女は今、K雑誌のこの夏の増大号にのせる為の、長い創作にとりかかっているのだった。

この部分を外す

Page 44: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

14

コーパスの作成方法(2/2)

③ エクセルに取り込み、「@」で始まる行(別の読み方がある場合に出現)、および「EOS」の行を削除する

④ CSVファイルとして保存

⑤ Pythonプログラム上で、1列目を取り出す

⑥ 「sorted」および「dict」を使用して、単語-インデックス両引き辞書を生成する

chars = sorted(list(set(text)))print('total chars:', len(chars))char_indices = dict((c, i) for i, c in enumerate(chars))indices_char = dict((i, c) for i, c in enumerate(chars))

lstm_text_generation.pyでの実装例

上記の手順により、コーパス長約420千語、単語数役22千語のコーパスを生成した

Page 45: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

15

学習用データの絞り込み

• 単語数は分類数であり、これを減らすと学習コストが下がるので、出現頻度が3回以下の単語は、「UNK」文字列に置き換えた

• これにより、単語数は約7千語になった

Page 46: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

16

パラメータチューニング

• パラメータの値を変えながら1エポック分学習を実施して、accuracyの値を比較した

• 評価の結果、以下の値を採用することにした

• なお、input_length(入力系列数)はlstm_text_generation.pyに合わせて40固定とした

パラメータ 説明 値

units 出力の次元数 600

Input_dim 入力の次元数 400

Page 47: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

17

学習方式1:そのまま学習

• LSTMのニューラルネットワークに作成したコーパスをそのまま流

し込んで、学習の進行状況を見る。当初は、特に工夫せずとも収束するものと考えていた

• コーパスをセオリー通り訓練データ、評価データ、テストデータの3

つに分け、学習状況は評価データで測定し、最終状況はテストデータを使って評価した

• 過学習を防ぐため、評価データの損失関数val_lossに対するEarlyStoppingを設定した

• 結果:accuracyが4割を超えられなかった

全然収束しないため、汎化性能の獲得はあきらめて、すべてのデータを訓練用に投入することにした

学習の発散を防ぐため、訓練データの損失関数lossに対するEarlyStoppingを設定した

Page 48: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

18

学習方式2:カリキュラム学習

• 比較的容易な範囲で学習を進めて高い精度を得たところで、学習範囲を少しずつ広げて、精度を保ちながら学習を進めるカリキュラム学習という考え方があるので、それを適用してみた

• ラベルデータ(要は答え)の単語の出現頻度がある一定以上(例えば2000回以上)の学習データを集めて学習を実行し、その後出現頻度の閾値を下げて学習範囲を広げながら、学習を進めた

• 結果:閾値を下げていくと、それにつれてaccuracyの値も下がり、50%を切ってしまった

出現頻度2000回以上

1500回以上

1000回以上

500回以上

閾値を下げて学習対象を増やす

学習対象を徐々に広げることで、

accuracyの悪化を抑止

Page 49: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

19

学習方式3:訓練データのグループ分け(1/4)• 出現頻度でグループ分けをしてみると、個々のグループごとには学習が進む(正解率80%以上)。そこで、個々に学習、評価を実施

し、それぞれのグループごとの予測のうち、最も「最適」なものを採用する

• グループ分けは以下の7種類とする。各グループごとにニューラルネットワークを構築して、それぞれごとに学習を進める

• 最適解選択ロジックは、softmax結果ベクトルのmaxが最も大きい

グループの予測結果を採用するものとする。確率値が大きいほど、予測の精度が高くなると予想した

項番 出現頻度の範囲

0 10未満

1 10以上、28未満

2 28以上、100未満

3 100以上、300未満

4 300以上、2000未満

5 2000以上、15000未満

6 15000以上

Page 50: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

20

学習方式3:訓練データのグループ分け(2/4)処理イメージを以下に示す

max 0.812 0.962 0.959 0.978 0.985 0.949 0.968 0.894 0.993 0.861 ・・・ 0.986argmax 2973 620 6392 5690 3361 3797 4869 416 4471 2638 ・・・ 415

0 1 2 3 4 5 6 7 8 9 ・・・ n

max 0.821 0.899 0.803 0.883 0.896 0.886 0.943 0.841 0.827 0.932 ・・・ 0.855argmax 1829 1624 6995 628 3609 3214 3190 1600 5776 5217 ・・・ 4554

max 0.861 0.979 0.891 0.846 0.801 0.842 0.871 0.925 0.977 0.823 ・・・ 0.864argmax 5031 516 5554 1553 5252 1935 3156 2006 3381 2983 ・・・ 1414

max 0.821 0.827 0.823 0.849 0.815 0.872 0.883 0.947 0.85 0.944 ・・・ 0.909argmax 376 244 1083 5552 708 6980 1568 6315 5745 6924 ・・・ 4296

max 0.885 0.868 0.852 0.805 0.819 0.823 0.8 0.84 0.979 0.924 ・・・ 0.917argmax 5890 5528 6335 5065 4519 672 4413 3238 2628 383 ・・・ 6597

max 0.825 0.937 0.879 0.993 0.992 0.834 0.941 0.93 0.889 0.893 ・・・ 0.926argmax 6717 3163 799 7109 4480 546 6149 2349 141 518 ・・・ 1878

max 0.819 0.88 0.973 0.823 0.998 0.918 0.809 0.895 0.87 0.818 ・・・ 0.975argmax 3263 4505 5321 4536 5123 323 927 490 4047 666 ・・・ 525

5890 516 5321 7109 5123 3797 4869 2349 4471 6924 ・・・ 415

予測結果(グループ0)

予測結果(グループ1)

予測結果(グループ2)

予測結果(グループ3)

予測結果(グループ4)

予測結果(グループ5)

予測結果(グループ6)

評価用データの項番

出力ベクトルのmax値

が最大のグループの予測結果を採用

Page 51: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

21

学習方式3:訓練データのグループ分け(3/4)• 結果:正解率は49%程度に上昇した

• 出力ベクトルのmax値が大きいグループほど正解に近いという仮

定は必ずしも正しくなく、正解でないグループの予測結果がより「自信満々」である事例が往々にして見られた

Page 52: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

22

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい事柄が、行われているか、ほんとうに想像の外《ほか》で

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい事柄が、行われているか、ほんとうに想像の外《ほか》でございます。無論、UNKのUNKをしていた、UNKのUNK始めます。UNK、UNK、UNK、UNK、UNK、UNK、UNK、UNK、UNK、UNK、UNK、UNK《UNK》のUNK《UNKUNK》などより、UNKのUNKUNKのUNK、UNK《UNKUNK》のUNKのUNK《UNKUNK》のUNKのUNKなる様な、UNK《UNKUNK》のUNKのUNKのUNK、UNK《UNKUNK》のUNKのUNK

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい

事柄が、行われているか、ほんとうに想像の外《ほか》でございます。無論始めの予定では、盗みの目的を果しさえすれば、すぐにもホテルを逃げ出す積《つも》りでいたのですが、世にも奇怪な喜びに、夢中になった私は、逃げ出すどころか、いつまでもいつまでも、椅子の中をUNKのUNKにして、その生活を続けていたのでございます。UNK《UNK》の外出には、注意に注意を加えて、少しも物音を

立てず、又人目に触れない様にしていましたので、当然、危険はありませんでしたが、それにしても、数ヶ月という、長い

入力文章

生成文章

正解

文書生成結果

学習方式3:訓練データのグループ分け(4/4)

Page 53: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

23

学習方式4:事前分類(1/3)

• どのグループの予測結果を採用するかについての判断精度を上げるため、事前にグループを予測し、その結果に基づいてグループを選択する。

• 出力次元数が7000超からわずか7に減少するのだから、学習精度の向上が期待できると考えた

Page 54: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

24

事前分類(グループ予測)

グループ5内分

類 グループ6内分

類グループ1内分

類グループ0内分

類 グループ4内分

類グループ2内分

類 グループ3内分

グループ6グループ5

予測単語決定

学習方式4:事前分類(2/3)

処理イメージを以下に示す

入力系列

グループ4グループ3グループ2グループ1グループ0

Page 55: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

25

学習方式4:事前分類(3/3)

• 結果:正解率は56%程度に上昇した

• 事前分類の正解率は70%程度である

• しかしながら、この程度の正解率では、生成文書に不自然さはぬぐえない

Page 56: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

26

学習方式5:事前分類を2択にする(1/4)

• 予測結果をマトリックス表にまとめてみると、グループ0からグループ4までのかたまりと、グループ5及びグループ6のかたまりの

間での分類ミスが、全体の予測精度の悪化を引き起こしていることがわかる

• そこで、事前分類をグループ0からグループ4までと、グループ5及びグループ6の2択にすることで、事前分類精度を上げる

• 更に、グループ5及びグループ6にはもう1段、2択分類を追加する

0 1 2 3 4 5 6

0 53 0 2 1 2 7 4

1 2 57 2 1 0 9 6

2 1 4 100 2 4 18 17

3 4 3 9 173 20 42 34

4 9 11 16 14 291 67 65

5 15 21 24 15 21 250 55

6 44 60 76 21 55 136 267

正解グループ

予測グルー

0 1 2 3 4 5 6

128 156 229 227 393 529 448

53 56 100 173 291 249 266

0.41406 0.35897 0.43668 0.76211 0.74046 0.4707 0.59375

正解正解率

グループ総数

右表:学習パターン4の予測結果(一部)

この部分を減らすことで、予測精度の改善を図る

Page 57: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

27

事前分類(2択)グループ5~6

事前分類(2択)

グループ5

内分類

グループ6

内分類

グループ1

内分類

グループ0

内分類

グループ4

内分類

グループ2

内分類

グループ3

内分類

グループ0~4

グループ6グループ5

Softmax最大値からグループ選択

予測単語決定

学習方式5:事前分類を2択にする(2/4)

事前分類イメージ 入力系列

Page 58: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

28

• 結果:正解率は63%程度に上昇した。当然ながら、多値分類より2択分類のほうが精度が良い(正解率80%以上)。2段程度なら複数段重ねても、多値分類の精度を上回る

• 大分日本語らしくなった。しかし、てにをはが変なため、何か違和感のある文章である。また、全体としての意味は不明である

学習方式5:事前分類を2択にする(3/4)

Page 59: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

29

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい事柄が、行われているか、ほんとうに想像の外《ほか》で

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい

事柄が、行われているか、ほんとうに想像の外《ほか》でございます。無論始めは一寸した程の事業をするのでありましょう。この性質を以て、私は自分の部屋に入るのでありましょう。そして、丁度|二《た》目の間に、私の椅子が腰かけているばかりです。三造はこの部屋に一人の男を見ますと、河野は何かいい理由になって、彼をお話しかける声に、妙な事を気になれました。そうかといって、この事件を見たいと

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい

事柄が、行われているか、ほんとうに想像の外《ほか》でございます。無論始めの予定では、盗みの目的を果しさえすれば、すぐにもホテルを逃げ出す積《つも》りでいたのですが、世にも奇怪な喜びに、夢中になった私は、逃げ出すどころか、いつまでもいつまでも、椅子の中をUNKのUNKにして、その生活を続けていたのでございます。UNK《UNK》の外出には、注意に注意を加えて、少しも物音を

立てず、又人目に触れない様にしていましたので、当然、危険はありませんでしたが、それにしても、数ヶ月という、長い

入力文章

生成文章

正解

学習方式5:事前分類を2択にする(4/4)文書生成結果

Page 60: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

30

学習方式6:Stacked LSTMの採用(1/4)• もしかしたら予測精度が高まるのではないかと考え、Stacked

LSTMを使って学習してみた

• ただし、計算コストの観点から(ここまでで2万円以上をクラウドにつぎ込んでいる)、一部の分類には適用していない

• また、事前分類も増やした

• LSTMのスタック数は、第1段目分類のみ3段、他は2段である

Page 61: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

31

事前分類(2択)グループ5~6

事前分類(2択)

グループ5

内分類

グループ6

内分類

グループ1

内分類

グループ0

内分類

グループ4

内分類

グループ2

内分類

グループ3

内分類

グループ0~4

グループ6グループ5

ニューラルネットの構成

予測単語決定

事前分類(2択)グループ4グループ0~3

学習方式6:Stacked LSTMの採用(2/4) 入力系列

事前分類(2択)

事前分類(2択)

事前分類(2択)

グループ3グループ0~2

グループ2

グループ1グループ0

グループ0~1

Page 62: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

32

• 結果:全体の正解率は95%程度に上昇した。効果は圧倒的である。時間(と金)の関係上、途中で学習を打ち切ったNNもあるが、とことんやればさらなる高精度が期待できる

• 2択分類の正解率は、第1段目(3段スタック)が97%程度、2段目以降(2段スタック)は99.5%と、ほぼ100発100中のレベルに達した

• グループ内分類のほうも、正解率が99%以上になった

• 正解率向上の割に、文章の不自然さの改善はそれほどでもない

• 全体としての意味の不明さは、今回の対策でも解消しなかった

• 予測を誤ると、そこから別の文脈に飛んでしまうことが、意味不明になる原因である。予測精度向上とは別の対策が必要と考えられる

学習方式6:Stacked LSTMの採用(3/4)

Page 63: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

33

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい事柄が、行われているか、ほんとうに想像の外《ほか》で

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい

事柄が、行われているか、ほんとうに想像の外《ほか》でございます。無論始めの予定では、盗みの目的を果しさえすれば、すぐにもホテルを逃げ出す積《つも》りでいたのです。UNKの計画はまんまと成功したのを忘れて、舞台に立ったまま、流石《さすが》に烈UNKUNKを通っても、そとにUNK様に、電車が走り続け、やがて、ホテルの地に入っていた。クックックッとUNKに、例のトンネルの口が向って、トンネルの中を出ると、またしても

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい

事柄が、行われているか、ほんとうに想像の外《ほか》でございます。無論始めの予定では、盗みの目的を果しさえすれば、すぐにもホテルを逃げ出す積《つも》りでいたのですが、世にも奇怪な喜びに、夢中になった私は、逃げ出すどころか、いつまでもいつまでも、椅子の中をUNKのUNKにして、その生活を続けていたのでございます。UNK《UNK》の外出には、注意に注意を加えて、少しも物音を

立てず、又人目に触れない様にしていましたので、当然、危険はありませんでしたが、それにしても、数ヶ月という、長い

入力文章

生成文章

正解

文書生成結果

学習方式6:Stacked LSTMの採用(4/4)

Page 64: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

34

「UNK」の復元(1/3)

• 学習負荷を下げるため、最初のほうで低頻度単語を「UNK」文字列に置き換えたが、これを復元してみる

• 基本的な考え方は、低頻度単語のデータだけを集めてニューラルネットワークを訓練し、文書生成の過程で「UNK」が生成されたら、そのネットに通す、というものである

置いて 、 少しも 気 違い

低頻度

低頻度

低頻度

低頻度

訓練データ ラベルデータ

学習 学習済NN

の UNK

生成文書

永住

Page 65: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

35

「UNK」の復元(2/3)

• 訓練データ数は22千、分類数(=単語数)は15千程度である。データ数の割に、分類数が多い。半分以上の単語が、1つしか訓練データを持たない計算になる

• 最初はLSTMでやってみたが、正解率は7%程度にしかならなかった。LSTMをスタックしてみたが、14%程度までしか改善しなかった

• そこで、ニューラルネットワークをLSTMからFlatten+Denseに変えてみたところ、正解率は89%まで向上した

Embedding

LSTM

Dense

Activation

Embedding

Flatten

Dense

Activation

Dense

Page 66: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

36

UNK復元前

実行結果

「UNK」の復元(3/3)

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい

事柄が、行われているか、ほんとうに想像の外《ほか》でございます。無論始めの予定では、盗みの目的を果しさえすれば、すぐにもホテルを逃げ出す積《つも》りでいたのです。呟くの計画はまんまと成功したのを忘れて、舞台に立ったまま、流石《さすが》に烈かけつけ永住を通っても、そとに写った様に、電車が走り続け、やがて、ホテルの地に入っていた。クックックッと育ってに、例のトンネルの口が向って、トンネルの中を出ると、またしても

UNK復元後

はございますまいか。考えて見れば、この世界の、人目につかぬ隅々では、どの様にUNK、恐ろしい

事柄が、行われているか、ほんとうに想像の外《ほか》でございます。無論始めの予定では、盗みの目的を果しさえすれば、すぐにもホテルを逃げ出す積《つも》りでいたのです。UNKの計画はまんまと成功したのを忘れて、舞台に立ったまま、流石《さすが》に烈UNKUNKを通っても、そとにUNK様に、電車が走り続け、やがて、ホテルの地に入っていた。クックックッとUNKに、例のトンネルの口が向って、トンネルの中を出ると、またしても

Page 67: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

37

江戸川乱歩以外の文章を入力してみる

• 今回訓練したニューラルネットワークにどれくらいの汎用性があるか確認するため、江戸川乱歩以外の文章を入力文章として、文書生成を試みた

• 使用した入力文章は、川端康成「雪国」の冒頭である

• 結果は以下の通り

国境の長いトンネルを抜けると雪国であった。夜の底が白くなった。信号所に汽車が止まった。向側の座席から娘が立って来て、島村の前のガラス窓を落した。それから、あわただしいどこかできて、どこを探して見ていたが、急に言葉をあけて呉れないのでした。ところが、大分以前から、もう夜が巣食っているのだ。白きょうちょう机に墨汁半ばは、ふと立彼を案じと、その結果、ついにこの見せかけたをテレスコープ為に費かに思うのだがね。そして、唯一つ逆ぬの文明がこうしたたけて、却《かえ》って敷居云いつけひげまでして、自分の疑いを受けることもなく、ただ死刑積んでのお風俗頼みで、この怪しかった承諾した書棚にも拘らず、老婆のお茶苦はありません。それにきしょうから、ほんの仮りにいたのに、その真中には、それが始終十分敷いたいる訳ではありません。長吉が外からこの場へ圓というのは、順序を追ってい僕の推理には絶えず客の出入りがあります。ミュンスターベルヒにも申す心理は、

Page 68: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

まとめ

• LSTMを使って文書生成を行う場合、学習の収束をどのように図るかがポイントである。特に施策を講じず学習させても、正解率は4割に届かない

• 形態素解析後の単語の出現頻度をもとにグループ分けを行い、学習をグループ分類と、グループ単位に分けて実施することで、正解率は63%程度まで改善する

• 事前分類は、多値分類を1回実施するより、2択分類を複数組み合わせるほうが、精度が高まる

• 更にLSTMをスタックすることで、正解率は95%以上に改善する

• 正解率が改善しても、それに比例して生成文書の質が上がる感じはしない。また、全体として意味不明な文書になる

• 出現頻度が小さい(例えば1回しか現れない)単語向けには、LSTMよりFlatten+Denseのほうが良い結果を得られる

38

Page 69: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

ご清聴ありがとうございまし

39

Page 70: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

Tensorflowユーザから見たAlpha(Go)Zero, Ponanza

Katsuki Ohto 2018/1/29 @TFUG #7

Page 71: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

本日の目標

•事前知識なしで最強になった Alpha (Go) Zeroのメカニズムを伝える

•ゲームAIの流れと今後の未来についてイメージを膨らむようにする

Page 72: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

自己紹介

• 大渡 勝己(おおとかつき)

• 経歴~ 2014.3 大学生 (認知神経科学)~ 2015.3 無職~ 2015.8 事務職員~ 2017.9 大学院生 (ゲームAI)2017.10 ~

HEROZ株式会社 エンジニア

Machine Learning 15 minutes!発表時http://ainow.ai/2017/08/07/119456/

Page 73: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

自己紹介

• 「強い」ゲームAIについて研究

• 大富豪、カーリング(2年前のTensorflow勉強会で少し話しました)などのAIを作成

• 大富豪で「空場」(流れた後の自分から出せる場)でパスをした方がいい局面を解析する論文を出しました

Page 74: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

自己紹介

• 12種類のゲームのAI大会に参加

• 2017.6~2017.11将棋 Ponanzaのディープラーニング部分を担当

• 現在は囲碁ウォーズ「棋神」を開発

Page 75: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

本日の内容

• ゲームAIという分野の過去、今 (AlphaZeroなど)、未来について

• 自分が参加したPonanzaでTensorflowを使ってトライしたこと

• Ponanza … 2017春にプロ棋士のトップ(佐藤名人)を倒したプログラム

• AlphaZero ... 知識なしで囲碁、将棋、チェスで世界一になったAlpha Zeroの衝撃と技術的失業 (山本一成さんより)

Page 76: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

ゲームAIのこれまで(プログラマ視点)

• 過去の強いプログラムの成り立ち

• 「人手でのルールの記述」「機械学習モデル」がどちらも重要だった

• ルールの記述 … 将棋なら将棋盤、囲碁なら囲碁盤をどう実装するか

• 機械学習モデル … ある局面の勝ちやすさや最善手の予測など、ルールから自明でないので機械学習等で構築する評価モデル

Page 77: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

ゲームAIのこれまで(プログラマ視点)

• 「ルールの記述」が簡単ではないという例

• 将棋における右の局面(相手の手番)と金を動かして一手詰み(勝ち)

• 全ての手を調べれば一手詰みの手があるかわかるが、それでは遅いので一手詰み計算専用のアルゴリズムが書かれている

• 金で王手のパターン、離れた飛車で王手のパターン…などの羅列、プログラマが頑張る

Page 78: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

現在のゲームAIの流れ

• ① DQN (2013) とその後継モデルルールを記述することなくニューラルネットで一人ゲームをプレイ

Human-level control through deep reinforcement learning (Mnih et al., 2015)

Page 79: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

現在のゲームAIの流れ

• ②AlphaGoZero, AlphaZeroニューラルネットの最善手の予測と勝率の予測をベースに、モンテカルロ木探索を使って予備知識や上級者の棋譜なしで0から学習

Mastering Chess and Shogi by Self-Play with a General Reinforcement Learning Algorithm

(Silver et al., 2017a, arxiv)

Page 80: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

現在のゲームAIの流れ

• ③Libratus, DeepStack不完全情報ゲームのポーカーにおいても人間を圧倒両者全く違うアルゴリズムを使う (DeepStackはニューラルネットを利用)

DeepStackのアルゴリズムDeepStack: Expert-Level

Artificial Intelligence in

No-Limit Poker (Moravčík

et al., 2017)

Page 81: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

現在のゲームAIの流れ

• 人間がコーディングする部分が減っている

• ニューラルネットの表現能力が勝敗を分けることが増えている

Page 82: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

ボードゲームのニューラルネットへの入力

• 囲碁の盤面 ... 黒か白の2色石がある場所に1、それ以外が0

= +

Page 83: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

ボードゲームのニューラルネットへの入力

• 将棋の盤面 ... 色数が多い持ち駒などのスカラ値は1つの色全体に1を立てるなど

= + +…

Page 84: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

AlphaZeroの作り(ニューラルネット)

• 盤面の履歴 (8手分)を入力し、

最善手の予測 (policy)

勝率の予測 (value)

を同時に行うニューラルネット

• 複数の値を同時に出力するマルチタスク学習

Mastering the game of Go without human

knowledge (Silver et al., 2017b)

Page 85: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

AlphaZeroの作り(モンテカルロ木探索)

• サイコロを振って最後まで

https://en.wikipedia.org/wiki

/Monte_Carlo_tree_search

(クラシックな)モンテカルロ木探索

Page 86: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

AlphaZeroの作り(モンテカルロ木探索)

• ゲームのように閉じた環境においては、先の状態を考えることでより質の高い行動決定ができる

Silver et al. (2017b)

AlphaGo Zeroのモンテカルロ木探索

Page 87: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

AlphaZeroの強化学習アルゴリズム

• 前提①AlphaZero = 「ニューラルネット」「探索(先読み)アルゴリズム」

• 前提②ニューラルネット単体でもプレーしたり勝ち負けを予測したりできるが、先読みを行うともっと強くなる

• 前提③質の高いニューラルネットがあれば、より質の高い先読みが行えて強くなる

Page 88: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

AlphaZeroの強化学習アルゴリズム

• 学習手順探索ありで

試合棋譜を作成

棋譜の手/結果から教師あり学習で

ニューラルネットを学習

繰り返し

Silver et al. (2017b)

Page 89: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

AlphaZeroの強化学習アルゴリズム

• 強さの向上の概念図

• まずランダムの状態での勝ち負けを学び、それを使って探索すれば少し強くなる

• 探索の結果の手はニューラルネットそのままより強いので、それを教師とする

• 強くなれば勝ち負けの評価も妥当になり勝率予測も精度向上

棋譜から学習

Page 90: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

将棋PonanzaにおけるTensorflowの利用

• Ponanzaは大会出場する上位プログラムの中では最も早くニューラルネットを実用化(2017.5 世界コンピュータ将棋選手権でのPonanza Chainer)「手の予測」を行い、外部サーバで動かして通信

• その後ニューラルネット部分の担当が自分になり、使用ライブラリがTensorflowに変更

• 勝率予測も一緒に学習 (AlphaZero と同じ)

• Ponanza側のコードも書き換えて、C++から直接Tensorflowを呼び出す

Ponanza

Chainer のNN

Ponanza

(Tensoflow)

のNN

Page 91: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

将棋PonanzaにおけるTensorflowの利用

• AlphaZeroとの比較 (将棋ドメイン: 利用部分)

AlphaZero Ponanza with Tensorflow

ネットワーク入力 9 x 9 x 362

(7手前までの履歴)

9 x 9 x 86

(現局面のみ)

ネットワーク構成 ResNet20ブロック(40層)?

256フィルタCNN に工夫を加えたもの(PFNの方発案のアーキテクチャ)12層 256フィルタ

学習方法 ゼロから探索ありの強化学習 過去のPonanzaの着手・評価・勝敗1500万試合から教師あり学習(着手の一致率 56% 弱)

製作使用リソース TPUv1 5000枚(対戦)

v2 15枚(学習)

elmo 超えまで 2h 弱

これまでさくらインターネットさんからお借りしたCPU等最大数十台 (対戦)

GPU1枚 (学習) 1ヶ月

Page 92: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

将棋PonanzaにおけるTensorflowの利用

• AlphaZeroとの比較 (将棋ドメイン)

AlphaZero Ponanza with Tensorflow

利用法 ニューラルネットだけでモンテカルロ木探索

既存の評価関数によるアンサンブルミニマックス系探索

対戦利用リソース TPU v2 4枚 GPU GTX-1080 1枚(第5回将棋電王トーナメント本番)

探索速度 40,000 局面 / 秒(=ニューラルネットの計算回数)

6,000,000 局面 / 秒(ニューラルネットの計算は5,000 局面 / 秒)

Page 93: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

大人の知能と子どもの知能の融合

• 既存の探索部 (秒間 600万局面) … 理詰めで解決する

「大人の知能」

• ニューラルネット ... 計算局面数が少ないが、鋭い感性を持つ

「子供の知能」

• 大会に向けて、2つの「知能」をどう協調させるかを考えて製作した

• (子どもだけに絞った方がいいのかもしれなかったが…)

Page 94: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

大人は慎重。子どもは素直〜大人の知能と子どもの知能の融合〜

• 既存の探索は相対的な良し悪ししか見ていなかったり、慎重な評価を返したりする

• 一方ニューラルネットは絶対評価かつ大胆に評価する(その分ブレやポカも多い)

ニューラルネットの

予測勝率: 72 %

(既存の探索+評価関数:

深さ1で59%, 深さ32で61%)

Page 95: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

大人はあれもこれも気になる。子どもは大事なものが見える〜大人の知能と子どもの知能の融合〜

• 既存の探索では、人間から見て「盤上この一手」の状態でも丁寧に多くの手を調べていた

• ニューラルネットは手の予測もはっきり物を言うので、ニューラルネットの出した確率が低い手はそもそも探索しないようにできる

ニューラルネットの

予測最前手: 2四同歩

over 99.99 %

Page 96: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

Ponanza with Tensorflow の手法 (概略)

• Policyの確率で探索順序決定確率の和によって探索打ち切り判定

• 探索深さが増えると打ち切り閾値を大きくする

• Valueの予測勝率と探索の予測勝率を混ぜる(ただし元が相対評価なら相対評価として返す)

• 探索深さが深ければそちらの重みを大きくする

95% 2%

3%

95 + 3 = 98% > 閾値打ち切り!

探索 80 %

NN 60%

→70%

探索 < 80 %

NN 70%

→ < 75 %

Page 97: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

Tensorflowにおける学習

• Ponanzaのコードは現在非公開ですが、NN部分で元になったコードが自分のリポジトリにあります。https://github.com/YuriCat/apery/tree/nn/python

• ビッグデータからの学習…NNの入力画像を保存すると物凄い容量になる

①棋譜など最小の情報を持った状態で保存②C++側に入力画像行列作成コードを書く③pybind11でpythonから学習時に呼び出して入力画像・教師値を得る

のが良かった

Page 98: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

現在のゲームAI開発事情

• 計算資源をどう確保するかの問題

• 有志の計算資源を募ることが行われている

平岡拓也氏の Apery (将棋)https://github.com/HiraokaTakuya/apery-machine-learning

Gian-Carlo Pascutto 氏の LeelaZero (囲碁)https://github.com/gcp/leela-zero

Page 99: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

未来の(ゲームAI)アーティストに向けて

・勝ち負け以外の評価による学習 (好奇心だけで行動するマリオ) など、

人間のように「未知の事柄を知るためにどう行動するか」という側面から研究が進んでいる

Curiosity-driven

Exploration by

Self-supervised

Prediction (Pathak

et al., 2017)

Page 100: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

未来の(ゲームAI)アーティストに向けて

・「ゲームのAIを書く」ことがゲームAI開発のメインではなくなっていく

・できる限り人間はコードを書かない姿勢(「詰みを絶対に逃したくない」など書かざるを得ない場合もあるが、細かい最適化に留まらずに常に広い視野を持って欲しい)

・複数のドメインを扱う強化学習(マルチタスク)

・自然言語処理、画像や動画の自由な入力(マルチモーダル)

Page 101: 奥田 幸男目的と背景 3 DLパッケージの選択 Pythonの高速化 PythonのGIL縛り 加速器=パラレル処理 CPU クロック3GHz限界 マルチコア GPU GP-GPU

未来の(ゲームAI)アーティストに向けて

シンギュラリティを起こしましょう!

Alpha Zeroの衝撃と技術的失業 より