Deeplearning とか 人工知能とか

情報学を勉強してる人

オセロの教師データ公開【ディープラーニング】

学部の実験で作ったディープラーニングを使ったオセロのプログラムで教師データを作ったので(およそ23万対局分)

オセロの棋譜データが欲しい人のために公開します、ご自由にお使いください

オリジナル kihuFixed.txt - Google ドライブ

800MBほどあるのでメモ帳などの軽いソフトでないと見れないと思います

軽量版 kihuFixedのコピー.txt - Google ドライブ

中身の説明

1 1 1 1 1 1 1 1 1 1 2 1 2 2 2 1 1 1 1 2 1 1 2 1 1 2 1 1 1 1 2 1 1 2 1 1 1 1 2 1 1 2 1 2 1 2 2 1 1 1 1 1 2 2 2 1 1 1 1 2 2 2 0 0 7 8 W 2

こんな感じのデータが大量に入っていると思います

八文字ごとに改行します

1 1 1 1 1 1 1 1
1 1 2 1 2 2 2 1
1 1 1 2 1 1 2 1
1 2 1 1 1 1 2 1
1 2 1 1 1 1 2 1
1 2 1 2 1 2 2 1
1 1 1 1 2 2 2 1
1 1 1 2 2 2 0 0

7 8 W 2

するとこのようになると思います 上の8 x 8の数字は現在の盤面です また黒が2、白が1です0は空白を表しています

この盤面に対して白が打った次の手が7 8(一番左上のマス目は(0,0)です)となります

最後の2はあと何個空白スペースがあるかを表しています

自分は勝った方のデータのみを用いて学習を行ったため

テキストに入っているデータは全て勝利した人の手が書かれています

またこの棋譜

https://www.skatgame.net/mburo/ggs/game-archive/Othello/

を元に作成しました、オンラインオセロ対局のデータのようです

DeepLearning for Java (DL4J)の始め方(一発で動く!!!!)

んにちは、今回はQiitaとかにいっぱい書いてあると思いますけど
Java機械学習用ライブラリ
DeepLearning4Jのインストールについて書きたいと思います
具体的にはインストール、ND4Jのライブラリを使ってコードを実行するところまで書きます
自分はコードを実行するまでいろんなサイトを見て回ってとても苦労したので
このブログではこのページだけ見れば一発で導入が終わる丁寧な解説をしたいと思います
まず使うツールについて説明します

IntelliJ IDEA
コードを書くことから実行ファイルの出力まで、なんでもこなしてくれます
コミュニティー版で良いのでインストールしてください
f:id:meipuru_344:20170713044143p:plain

インストールするものはこれだけです
他は必要ありません
ただし、Java DevelopmentKitはもちろん必要です(笑)
(ちなみに自分はJDK1.8を使用しています)
またIntelliJはUIがWindowsMacほとんど一緒なので分けた説明はしません

新規プロジェクトの作成
それでは新規プロジェクトの作成をしましょう
f:id:meipuru_344:20170713044708p:plain
f:id:meipuru_344:20170713045118p:plain

新しいプロジェクトに入ると最初に必要なものがダウンロードされ
右下に何か出ると思いますので"Enable-Auto-Import"を押してください
そうするとmainディレクトリの中のApp.javaが実行できるようになるはずです
(App.javaが実行可能であればとりあえずここは大丈夫です!)

f:id:meipuru_344:20170713045409p:plain
緑色の三角が実行可能の証です

f:id:meipuru_344:20170713045501p:plain

Runで実行してください、HelloWorldが出てくるはずです。


pom.xmlについて
はい、これです
実はIntelliJMavenを使って自動ダウンロードをするためにこれは避けて通れません!
とは言ってもとても簡単です

f:id:meipuru_344:20170713045838p:plain

このpom.xmlMavenにどのライブラリをダウンロードして欲しいか伝えるために必要です!
今回はCPU環境のnd4jを使うことにしましょう
そのためには
f:id:meipuru_344:20170713050302p:plain

<dependency>
 <groupId>org.nd4j</groupId>
 <artifactId>nd4j-native</artifactId>
 <version>${nd4j.version}</version>
</dependency>

とコピーします
そして${nd4j.version}を 0.8.0  に書き換えてください
f:id:meipuru_344:20170713050725p:plain
すると外部ライブラリに大量のライブラリがダウンロードされるはずです
これらはnd4jを実行するために必要なのです


Hello ND4J!
実は自分の環境ではこのまま進めるとエラーに遭遇します(笑)
もちろん今からその対処方法を書きます
f:id:meipuru_344:20170713051344p:plain
行列を宣言してから標準出力にするとエラーが出ます。
これの対処方法は機械的ですが、、、、
pom.xml

   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.3</version>
    </dependency>

と追加してください
f:id:meipuru_344:20170713051726p:plain

バージョンは1.7.3にしてください、最新バージョンだとなぜかうまくいきませんでした

終わりに
以上で導入終わりです、導入できましたか?
大見得切っておいてできなかったらごめんなさい;w;
以上で説明を終わります
最後まで見ていただきありがとうございました

f:id:meipuru_344:20170713052257p:plain

活性化関数

ディープラーニングで必須の活性化関数についてまとめます
リファレンスを見ていてSoftmax関数を探したんですが
見つからなくて。。。
どなたかわかる人教えてくださいorz

ReLU

max(0,x)

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.ops.transforms.Transforms;

INDArray matrixA = Nd4j.create(new float[]{-3,-2,-1,0,1,2,3,4},new int[]{1,8});
matrixA = Transforms.relu(matrixA);
System.out.println("matrixA\n"+matrixA);
出力
matrixA
[0.00, 0.00, 0.00, 0.00, 1.00, 2.00, 3.00, 4.00]

Softmax
出力層への各ノードへの入力に対して同じ個数の出力を計算する
ソフトマックス関数です
ライブラリの中に配列のソフトマックス関数が見当たらなかったので
合計を計算したのちに各成分に割り算を行うことにしました

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.ops.transforms.Transforms;

INDArray matrixA = Nd4j.create(new float[]{2,3,4,3,1,2,3,4},new int[]{1,8});
float sum = Transforms.exp(matrixA).sumNumber().floatValue();
matrixA = Transforms.exp(matrixA).div(sum);
System.out.println("Softmax:\n"+matrixA);

出力
Softmax:
[0.04, 0.11, 0.29, 0.11, 0.01, 0.04, 0.11, 0.29]

ND4J 行列の定義

m × n行列を定義したいとき Nd4j.createは一次元の行列を引数としますので それがどのような順番で行列に変換されるのか気になったので動かしてみました

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;

        INDArray matrixA = Nd4j.create(new float[]{1,2,3,4,5,6,7,8},new int[]{2,4});
        System.out.println("matrixA:\n"+matrixA);

出力
matrixA:
[[1.00, 2.00, 3.00, 4.00],
 [5.00, 6.00, 7.00, 8.00]]

一次元配列は行列に 行方向に一番上からfillされていくようです

列方向の一番左からfillしていくためには

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;

        INDArray matrixA = Nd4j.create(new float[]{1,2,3,4,5,6,7,8},new int[]{2,4},'f');
        System.out.println("matrixA:\n"+matrixA);

出力
matrixA:
[[1.00, 3.00, 5.00, 7.00],
 [2.00, 4.00, 6.00, 8.00]]

orderingの小文字'f'を引数にすると使えます

ND4J 行列計算

ND4Jの勉強をしている時に 同じ形をした行列の要素ごとの計算が必要になったので まとめてみようとおもいます INDArrayクラス Nd4jクラス

行列の要素毎の積

INDArray mul(INDArray);

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;

INDArray matrixA = Nd4j.create(new float[]{1,2,3,4},new int[]{1,4});
INDArray matrixB = Nd4j.create(new float[]{1,2,3,4},new int[]{1,4});
INDArray returnMatrix = matrixA.mul(matrixB);
System.out.println("returnMatrix:\n"+returnMatrix);


出力
returnMatrix:
[1.00, 4.00, 9.00, 16.00]

行列の要素毎の商(割り算)

INDArray div(INDArray);

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;

INDArray matrixA = Nd4j.create(new float[]{1,2,3,4},new int[]{1,4});
INDArray matrixB = Nd4j.create(new float[]{1,2,3,4},new int[]{1,4});
INDArray returnMatrix = matrixA.div(matrixB);
System.out.println("returnMatrix:\n"+returnMatrix);

出力
returnMatrix:
[1.00, 1.00, 1.00, 1.00]

行列の要素毎の和

INDArray addi(INDArray);

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;

INDArray matrixA = Nd4j.create(new float[]{1,2,3,4},new int[]{1,4});
INDArray matrixB = Nd4j.create(new float[]{1,2,3,4},new int[]{1,4});
INDArray returnMatrix = matrixA.addi(matrixB);
System.out.println("returnMatrix:\n"+returnMatrix);


出力
returnMatrix:
[2.00, 4.00, 6.00, 8.00]

行列の要素毎の差

INDArray sub(INDArray);

import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;

INDArray matrixA = Nd4j.create(new float[]{1,2,3,4},new int[]{1,4});
INDArray matrixB = Nd4j.create(new float[]{1,2,3,4},new int[]{1,4}); INDArray returnMatrix = matrixA.sub(matrixB);
System.out.println("returnMatrix:\n"+returnMatrix);


出力
returnMatrix:
[0.00, 0.00, 0.00, 0.00]