さて、今回は番外編ということで”Courcera Machine Learning Week 4”より、非常に難解だったニューラルネットワークを少し応用して遊んでみたいと思います。
今回やりたいことは、
- 与えられたデータをトレーニング/テストセットに分けてモデルの精度確認
- 予測の結果、学習させたモデルによって間違えて予測した数字の表示
- ペイントで書いた数字を入力して予測!
というようなことをOctaveを使って行いたいと思います。
※前提として、Courcera Machine Learning Week 4の課題が終わっていることとします。もし終わっていない方はこっそり参考にしてください。
1.トレーニングセット、テストセットを用いたモデルの精度確認
Week4の課題を順調に進めるにあたって、ダウンロードしたファイルの中に”ex4data1.mat”という名前のファイルがあります。
load(‘ex4data1.mat’);
によってデータを読み込むと自動でXの値とyの値が読み込まれます。
このファイルの中には下図のように5000枚(下図は100枚のみ表示)の手書きの数字データが含まれています。各画像は20ピクセル×20ピクセルの解像度を持つ粗めの画像で、グレースケールとなっています。
図 0~9の手書きの画像データ(10×10枚)
画像データの構造は次のように1つ画像データ(20ピクセル×20ピクセル)を一行に繋げて並べ、400列の数値を持つデータとしています。
画像は全部で5000個あるので5000×400の行列として圧縮加工されているようです。
(未確認ですが、各数値は単なる0~255の階調を持つグレースケールではないようです。なんらかの正規化処理が行われているっぽい…)
今回はこの5000個のサンプルをシャッフルして次のように分けます。
・4000個 トレーニング用
・1000個 テスト用
※初期状態では0から順番にデータが並んでいますのでデータのシャッフルが必要となります。
Octaveのプログラム例
5000個のデータをシャッフルして新たにX、yとして代入します。
m=size(X,1);
rand_num=randperm(m);
X=X(rand_num,:);
y=y(rand_num);
続いて5000個のデータをトレーニング用とテスト用と分けます。
num_train=4000;
X_train=X(1:num_train,:);
y_train=y(1:num_train);
X_test=X(num_train+1:end,:);
y_test=y(num_train+1:end);
それでは、実際に4000個のテストセットをfmincg関数に入れてシータを学習していきましょう。
costFunction = @(p) nnCostFunction(p, input_layer_size,... hidden_layer_size, num_labels, X_train, y_train, lambda);
fmincgを使うためにcostFunctionにおけるp=シータを指定します。
options = optimset('MaxIter', 200);
optionsによってfmincgの繰り返し回数を指定でき、今回は200回に設定してより予測精度を高めていきたいと思います。
[nn_params, cost] = fmincg(costFunction, initial_nn_params, options);
fmincgによってnn_params(シータ)を求めていきます。
Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)),
hidden_layer_size, (input_layer_size + 1));
Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), num_labels, (hidden_layer_size + 1));
最後に、nn_paramsをシータ1、シータ2に展開していきます。
さて、次に上で求めたシータ1,2を用いて実際にテストをしてみましょう。
用意されているpredict関数を用いて、次のようにトレーニング用のデータを用いて予測を行います。
pred = predict(Theta1, Theta2, X_train);
fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y_train)) * 100);
気になる予測の正答率は…98.63%!!!
かなりの高確率で予測を当てることができました。
それもそのはずです。トレーニングで用いたデータを入力しているので予測する上では都合の良いデータとなります。
一度解いた過去問をテストしているようなものですね!
次に、まだ見ぬデータを用いて予測を行ってみます。
先ほどのpred関数にX_testを入れ、予測結果をy_testと比較してみましょう。
pred = predict(Theta1, Theta2, X_test);
fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y_test)) * 100);
さて、予測の正答率は…91.8%!!!
さすがニューラルネットワークですね。まだ見ぬデータに対して高確率で予測を当てていきました。
ーーーーーーーーーーーーーーーーーーーーー
それでは、間違えてしまった画像データはいったいどのようなデータなのでしょうか?きったない字なのでしょうか?
間違えてしまった画像データを表示させるコードを作ってみましょう。
コメント