3

y = x ^ 2を推定するニューラルネットワークを作成しようとしました。そこで、フィッティングニューラルネットワークを作成し、入力と出力のサンプルをいくつか提供しました。このネットワークをC++で構築しようとしました。しかし、結果は私が予想したものとは異なります。

次の入力を使用します。

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71

および次の出力:

0 1 4 9 16 25 36 49 64 81100121144169196225256289324361400441484529576625676729 784 841 9009611024 1089 1156 1225 1296 1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2304 2401 2500 2601 2704 2809 2916 3025 3136 3249 3364 3481 3600 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041 1 4 9 16 25 36 49 64 81100121144169196225256289324361400441484529576625676729 784 841 900 961 1024 1089 1156 1225 1296 1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2304 2401 2500 2601 2704 2809 2916 3025 3136 3249 3364 3481 3600 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041

フィッティングツールネットワークを使用しました。行列行を使用します。トレーニングは70%、検証は15%、テストも15%です。隠れニューロンの数は2つです。次に、コマンドラインで次のように記述しました。

purelin(net.LW{2}*tansig(net.IW{1}*inputTest+net.b{1})+net.b{2})

その他の情報 :

私のnet.b[1]は次のとおりです:-1.16610230053776 1.16667147712026

私のnet.b[2]は51.3266249426358です。

そしてnet.IW(1)は次のとおりです:0.344272596370387 0.344111217766824

net.LW(2)は:31.7635369693519 -31.8082184881063

inputTestが3の場合、このコマンドの結果は16ですが、約9になるはずです。どこかでエラーが発生しましたか?

私の問題のような問題を含むMATLABのStackOverflowpost Neural networkを見つけましたが、少し違いがあり、その問題では入力と出力の範囲が同じですが、私の問題ではありません。その解決策は、結果をスケールアウトする必要があると言っていますが、どうすれば結果をスケールアウトできますか?

4

1 に答える 1

6

あなたはスケーリングについて正しいです。リンクされた回答で述べたように、ニューラルネットワークはデフォルトで入力と出力を範囲[-1,1]にスケーリングします。これは、ネットワーク処理機能の構成で確認できます。

>> net = fitnet(2);

>> net.inputs{1}.processFcns
ans =
    'removeconstantrows'    'mapminmax'

>> net.outputs{2}.processFcns
ans =
    'removeconstantrows'    'mapminmax'

入出力の両方に適用される2番目の前処理機能はmapminmax、次のパラメーターを使用します。

>> net.inputs{1}.processParams{2}
ans =
    ymin: -1
    ymax: 1

>> net.outputs{2}.processParams{2}
ans =
    ymin: -1
    ymax: 1

両方を[-1,1]の範囲にマッピングします(トレーニング前)。

これは、トレーニングされたネットワークがこの範囲の入力値を期待し、同じ範囲の値も出力することを意味します。入力をネットワークに手動でフィードし、出力を自分で計算する場合は、入力でデータをスケーリングし、出力でマッピングを逆にする必要があります。

最後に覚えておくべきことは、ANNをトレーニングするたびに、異なる重みが得られるということです。再現性のある結果が必要な場合は、乱数ジェネレーターの状態を修正する必要があります(毎回同じシードで初期化します)。rngおよびのような関数に関するドキュメントをお読みくださいRandStream

また、データをトレーニング/テスト/検証セットに分割する場合は、毎回同じ分割を使用する必要があることに注意する必要があります(おそらく、前述のランダム性の側面によっても影響を受けます)。


これは、アイデアを説明するための例です(私の別の投稿から採用):

%%# data
x = linspace(-71,71,200);            %# 1D input
y_model = x.^2;                      %# model
y = y_model + 10*randn(size(x)).*x;  %# add some noise

%%# create ANN, train, simulate
net = fitnet(2);                     %# one hidden layer with 2 nodes
net.divideFcn = 'dividerand';
net.trainParam.epochs = 50;
net = train(net,x,y);
y_hat = net(x);

%%# plot
plot(x, y, 'b.'), hold on
plot(x, x.^2, 'Color','g', 'LineWidth',2)
plot(x, y_hat, 'Color','r', 'LineWidth',2)
legend({'data (noisy)','model (x^2)','fitted'})
hold off, grid on

%%# manually simulate network
%# map input to [-1,1] range
[~,inMap] = mapminmax(x, -1, 1);
in = mapminmax('apply', x, inMap);

%# propagate values to get output (scaled to [-1,1])
hid = tansig( bsxfun(@plus, net.IW{1}*in, net.b{1}) ); %# hidden layer
outLayerOut = purelin( net.LW{2}*hid + net.b{2} );     %# output layer

%# reverse mapping from [-1,1] to original data scale
[~,outMap] = mapminmax(y, -1, 1);
out = mapminmax('reverse', outLayerOut, outMap);

%# compare against MATLAB output
max( abs(out - y_hat) )        %# this should be zero (or in the order of `eps`)

この関数を使用することを選択しましたmapminmaxが、手動で使用することもできます。式は非常に単純な線形マッピングです。

y = (ymax-ymin)*(x-xmin)/(xmax-xmin) + ymin;

スクリーンショット

于 2012-08-07T20:01:11.377 に答える