KerasでXOR学習を色々試す

この前のANDの学習に引き続き、今回はxorの学習。


 
【参考】詳解ディープラーニング 3.6章
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~

 
xorの場合はandの時とは異なり、
xy座標に
a1(0,0)
a2(1,1)

b1(1,0)
b2(0,1)
をプロットするとわかるように、1本の線でaとbを分けることができない。
つまり線形分離不可能なので、2層のネットワークでは上手く学習させることができない。

前回のandを求めるコード(2層)の数字だけを変えてxorの教師データを与えると、


上のような結果になり、全く学習できていないことがわかる。

なので、入力層と出力層の間に隠れ層を入れることでこの問題を解決する。

 

xor.py

 

結果

せっかくなので、活性化関数や学習率、バッチ数、重み更新の仕方などを色々変えてどんなふうに結果が変わるのか比較してみた。

 

sigmoid/lr=0.1/batch_size=4/SGD


学習はできている。lossの遷移グラフを見てみると、単調減少の形になっているのでもっと強気でも行けるかなと思って学習率を上げてみた。

 

sigmoid/lr=0.3/batch_size=4/SGD


学習率を3倍にするとlossが3分の1になった。
まだ単調減少なのでもっと学習率をあげてみた。

 

sigmoid/lr=1/batch_size=4/SGD

学習率を上げれば上げるほどlossは下がるようだ。
次に、バッチサイズを変えてみる。

 

sigmoid/lr=0.1/batch_size=1/SGD


単純計算でさっきの4倍の時間がかかった。
しかし、バッチサイズが4のときよりもlossは下がった。

バッチサイズの話はここがわかりやすくかった。
ニューラルネットワークについて学んでみた。(その3) – いものやま。

要約すると、
・最急降下法⇒全部の訓練データを一気に重みを更新
・確率的勾配降下法⇒訓練データを1つずつ重みを更新
・ミニバッチ⇒訓練データを幾つかにまとめて重みを更新

 

ReLU/lr=0.1/batch_size=1/SGD

いつもは優秀なランプ関数だが、今回はなぜか全く更新されなかった。
どこかミスったかな・・。ミスったよね・・。

 

sigmoid/lr=0.1/batch_size=4/Adam

重みの更新の方法をadamに変えてみた。
今回試した中では最もlossが下がった。

 
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~

コメントを残す