(33) ニューラルネットでsin関数を近似

投稿者: | 2014/09/20

4,642 views

この記事は最終更新から 1615日 が経過しています。

octaveには MATLABの Neural Network Toolbox に似せた nnet package がある。
http://octave.sourceforge.net/nnet/overview.html
注意:nnet packageは、Octave-Forgeで Unmaintained packages に分類されている。

これを使ってニューラルネットワークによる sin関数の近似 を試してみたい。
まずは nnet packageの簡単な使い方を調べながら実際に動かしてみた。

nnet_sin

(1) 学習データを作る

入力データは、-π x 2 ~ π x 2 までの範囲を 0.1刻みとする。
出力期待値データは、sin( 入力データ ) とする。

pkg load nnet
data_IN  = [ -pi*2 : 0.1 : pi*2 ];
data_OUT = sin(data_IN);

(2) ニューラルネットワークを作成

ネットワーク構成は隠れ層(ニューロン数3個)を1層のみとする。
学習時のエポック数は100回とする。
結合荷重、バイアスの初期値をどうしているかは未調査。
※初期値によってはうまく収束しない場合もある。

Rx2 = [min(data_IN), max(data_IN)];
S   = [3 1];
rand('state', 0)
randn('state', 0)
NNet = newff( Rx2, S );
NNet.trainParam.epochs = 100;

(3) 学習を実行

戻り値 net には、学習済みのニューラルネットが出力される。

VV.P = data_IN;
VV.T = data_OUT;
net = train( NNet, data_IN, data_OUT, [], [], VV );

誤差は順調に収束しているようだ。
20140920_01

(4) 学習に使用したデータの出力を確認

学習済みのニューラルネットに、学習に使用したデータを入力してみる。
学習に使用したデータに対して、ニューラルネットが sin関数をどれだけ近似できているか?を見たい。

res = sim( net, data_IN );
plot(data_IN, data_OUT, 'r', data_IN, res, 'b')

本物のsin関数の出力値を赤線、ニューラルネットの出力値を青線で表示した。
グラフ表示した結果はほぼ重なっているため、下側に表示した赤線がほとんど見えない。
20140920_02

両者の差を数値(最大値、最小値、標準偏差)で見てみる。

> diff = data_OUT - res;
> max(diff)
ans =  0.021823
> min(diff)
ans = -0.018701
> std(diff)
ans =  0.0057264

(5) 未学習の入力データの出力を確認

学習に使用していないデータを入力した場合に対応できているか?を見たい。

test_IN = rand(1,100) * 12 - 6;
res = sim( net, test_IN );
figure;
plot(data_IN, data_OUT, 'r', 'LineWidth',2', test_IN, res, 'b+');
grid on;
ylim([-1.2 1.2]);

本物のsin関数の出力値を赤線、ニューラルネットの出力値を青十字で表示した。
結果をグラフ表示すると、両者はほぼ重なっている。
20140920_06


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です