読者です 読者をやめる 読者になる 読者になる

TadaoYamaokaの日記

山岡忠夫 Home で公開しているプログラムの開発ネタを中心に書いていきます。

強化学習の勉強

コンピュータ将棋の記事をちょっと書いたこともあり、強化学習について勉強を始めました。

教科書として用いるのは、

この本です。

この本で使用されているサンプルプログラムは、Octaveとg++が使用されいます。
Windowsで最新のOctaveとMSYS2で実行するのに少し苦労したので、実行方法を記しておきます。

環境

三目並べのコードの実行方法

Octaveのインストール

https://ftp.gnu.org/gnu/octave/windows/
から、「octave-4.2.1-w64-installer.exe」をダウンロードしてインストールする。

MSYS2のインストール

MSYS2 download | SourceForge.net
から、「msys2-x86_64-20161025.exe」をダウンロードしてインストールする。

MSYS2 homepage
の説明に従ってパッケージを最新にする。

g++インストール

スタートメニューから「MSYS2 MinGW 64bit」を起動する。

$ pacman -S mingw-w64-x86_64-toolchain
:: 17 のパッケージがグループ mingw-w64-x86_64-toolchain にあります:
:: リポジトリ mingw64
   1) mingw-w64-x86_64-binutils  2) mingw-w64-x86_64-crt-git  3) mingw-w64-x86_64-gcc  4) mingw-w64-x86_64-gcc-ada
   5) mingw-w64-x86_64-gcc-fortran  6) mingw-w64-x86_64-gcc-libgfortran  7) mingw-w64-x86_64-gcc-libs
   8) mingw-w64-x86_64-gcc-objc  9) mingw-w64-x86_64-gdb  10) mingw-w64-x86_64-headers-git
   11) mingw-w64-x86_64-libmangle-git  12) mingw-w64-x86_64-libwinpthread-git  13) mingw-w64-x86_64-make
   14) mingw-w64-x86_64-pkg-config  15) mingw-w64-x86_64-tools-git  16) mingw-w64-x86_64-winpthreads-git
   17) mingw-w64-x86_64-winstorecompat-git

選択して下さい (デフォルト=all): 1 2 3 7 9 10 11 12 13 14 15 16

makeコマンドのファイル名がmingw32-make.exeとなっているので、コマンドプロンプトでmake.exeへハードリンクを作成する。

cd /d C:\msys64\mingw64\bin
mklink /H make.exe mingw32-make.exe
FLTKのインストール

FLTKはパッケージマネージャからインストールできないので、
GitHub - Alexpux/MINGW-packages: Package scripts for MinGW-w64 targets to build under MSYS2.
のビルドスクリプトを使用して、自分でビルドしてインストールする。

「MSYS2 MinGW 64bit」を起動して、適当な作業ディレクトリに移動して、

$ git clone https://github.com/Alexpux/MINGW-packages.git
$ cd MINGW-packages
$ cd mingw-w64-fltk
$ MINGW_INSTALLS=mingw64 makepkg-mingw -sLf
$ pacman -U mingw-w64-x86_64-fltk*.pkg.tar.xz

三目並べサンプルプログラムのビルド

書籍に記載されているサポートページからサンプルプログラムをダウンロードして解凍する。
「MSYS2 MinGW 64bit」を起動して、解凍したディレクトリに移動して、

$ cd sanmoku
$ g++ -fpermissive sanmoku.cpp -o sanmoku.exe -lfltk

サンプルプログラムのコードは古いバージョンのg++でビルドされているためデフォルトオプションではエラーになるので「-fpermissive」オプションを付けている。

sanmoku.exeを実行すると、
f:id:TadaoYamaoka:20170415171548p:plain
このような画面が表示される。

学習の実行

学習のプログラムの実行方法は、書籍の4.9章に記載されている。

スタートメニューからOctave(GUI)を起動して、ファイルブラウザでサンプルプログラムを解凍したディレクトリの「sanmoku」ディレクトリを開く。
コマンドウィンドウで、書籍の通り入力していく。

options.pmode=2
options.epsilon=0.1
options.gamma=0.9
Q=MonteCarloPolicyIteration(10,1000,options)

このまま実行すると、大量に警告が出力されるので、以下の通り編集する。

action_train.mの49行目

if(val==2 & num==1)

if(val==2 && num==1)

に修正する。

MonteCarloPolicyIteration.mの97行目と99行目の日本語部分を

g=xlabel('games');

g=xlabel('rate');

に修正する。

Q=MonteCarloPolicyIteration(10,1000,options)

を実行すると、以下のように結果が表示され、

>> Q=MonteCarloPolicyIteration(10,1000,options)
1) Win=411/1000, Draw=83/1000, Lose=506/1000
2) Win=719/1000, Draw=63/1000, Lose=218/1000
3) Win=786/1000, Draw=45/1000, Lose=169/1000
4) Win=783/1000, Draw=61/1000, Lose=156/1000
5) Win=751/1000, Draw=50/1000, Lose=199/1000
6) Win=850/1000, Draw=38/1000, Lose=112/1000
7) Win=788/1000, Draw=36/1000, Lose=176/1000
8) Win=797/1000, Draw=29/1000, Lose=174/1000
9) Win=821/1000, Draw=52/1000, Lose=127/1000
10) Win=809/1000, Draw=26/1000, Lose=165/1000
Q =

Compressed Column Sparse (rows = 19683, cols = 9, nnz = 388 [0.22%])

  (1, 1) ->  4.9260
  (6, 2) -> -0.57000
  (12, 2) ->  3.1858
  (46, 2) ->  5.4000
  (84, 2) -> -2.6775
  (105, 2) -> -7.5000
  (129, 2) ->  5
  (748, 2) -> -6
  (781, 2) -> -5
  (831, 2) ->  6.3141
  (883, 2) -> -4.5000
  (937, 2) -> -5
  (968, 2) ->  10
  (993, 2) ->  4.0500
  (1158, 2) ->  9
  (1182, 2) ->  10
  (1245, 2) ->  4.5000
  (1344, 2) ->  20
  (1590, 2) -> -20
  (1713, 2) -> -7.5000
  (1717, 2) -> -5
  (1772, 2) -> -5
  (1806, 2) -> -10
  (1808, 2) -> -5
  (1856, 2) -> -5
  (1878, 2) ->  40
  (1896, 2) ->  12
  (1902, 2) -> -11.667
  (1906, 2) ->  10
  (1949, 2) -> -5
  (1988, 2) ->  9

グラフウィンドウが起動する。一度ウィンドウを切り替えないと描画されないので、他のウィンドウをアクティブにしてからグラフのウィンドウをアクティブにする。
f:id:TadaoYamaoka:20170415172533p:plain

対戦の実行

学習した関数を使用して対戦を実行できるが、Octaveで改行コードがCrLfだと、state.txtが正しく読めない。
observe_test.mの19行目を以下の通り編集する。

    [tok,rem]=strtok(rem,":\r\n");
    if (length(tok) == 0)
      break;
    endif

これで、書籍に記載している通りの実行方法で対戦ができる。

test(Q,options)

f:id:TadaoYamaoka:20170415182527p:plain