1

MATLAB でこのバックプロパゲーションを実装していますが、トレーニングに問題があります。トレーニング フェーズの早い段階で、すべての出力が 1 になります。入力データ (バイナリ ターゲット ベクトルの生成に使用される目的のクラスを除く) を間隔 [0, 1] に正規化しました。私は、Artificial Intelligence: A Modern Approach、Norvig et al. での実装について言及してきました。

私のコードに対して疑似コードをチェックした(そしてしばらくの間アルゴリズムを研究した)が、エラーを見つけることができません。私は MATLAB をそれほど長く使用していないので、必要に応じてドキュメントを使用しようとしています。

また、隠れ層のさまざまな量のノードとさまざまな学習率も試しました ( ALPHA)。

ターゲット データのエンコーディングは次のとおりです。ターゲットがたとえば として分類される場合2、ターゲット ベクトルは[0,1,0]、それが1だっ[1, 0, 0]たとします。1また、(たとえばクラスの場合)など、ターゲットにさまざまな値を使用してみました[0.5, 0, 0]

体重の一部が を超え1、正味の値が大きくなっていることに気付きました。

%Topological constants
NUM_HIDDEN = 8+1;%written as n+1 so is clear bias is used
NUM_OUT = 3;

%Training constants
ALPHA = 0.01;
TARG_ERR = 0.01;
MAX_EPOCH = 50000;

%Read and normalize data file.
X = normdata(dlmread('iris.data'));
X = shuffle(X);
%X_test = normdata(dlmread('iris2.data'));
%epocherrors = fopen('epocherrors.txt', 'w');

%Weight matrices.
%Features constitute size(X, 2)-1, however size is (X, 2) to allow for
%appending bias.
w_IH = rand(size(X, 2), NUM_HIDDEN)-(0.5*rand(size(X, 2), NUM_HIDDEN)); 
w_HO = rand(NUM_HIDDEN+1, NUM_OUT)-(0.5*rand(NUM_HIDDEN+1, NUM_OUT));%+1 for bias

%Layer nets
net_H = zeros(NUM_HIDDEN, 1);
net_O = zeros(NUM_OUT, 1);

%Layer outputs
out_H = zeros(NUM_HIDDEN, 1);
out_O = zeros(NUM_OUT, 1);

%Layer deltas
d_H = zeros(NUM_HIDDEN, 1);
d_O = zeros(NUM_OUT, 1);

%Control variables
error = inf;
epoch = 0;

%Run the algorithm.
while error > TARG_ERR && epoch < MAX_EPOCH
    for n=1:size(X, 1)
        x = [X(n, 1:size(X, 2)-1) 1]';%Add bias for hiddens & transpose to column vector.
        o = X(n, size(X, 2));

        %Forward propagate.
        net_H = w_IH'*x;%Transposed w.
        out_H = [sigmoid(net_H); 1]; %Append 1 for bias to outputs
        net_O = w_HO'*out_H;
        out_O = sigmoid(net_O); %Again, transposed w.

        %Calculate output deltas.
        d_O = ((targetVec(o, NUM_OUT)-out_O) .* (out_O .* (1-out_O)));

        %Calculate hidden deltas.
        for i=1:size(w_HO, 1);
            delta_weight = 0;
            for j=1:size(w_HO, 2)
                delta_weight = delta_weight + d_O(j)*w_HO(i, j);
            end
            d_H(i) = (out_H(i)*(1-out_H(i)))*delta_weight;
        end

        %Update hidden-output weights
        for i=1:size(w_HO, 1)
            for j=1:size(w_HO, 2)
                w_HO(i, j) = w_HO(i, j) + (ALPHA*out_H(i)*d_O(j));
            end
        end

        %Update input-hidden weights.
        for i=1:size(w_IH, 1)
            for j=1:size(w_IH, 2)
                w_IH(i, j) = w_IH(i, j) + (ALPHA*x(i)*d_H(j));
            end
        end
        out_O
        o
        %out_H
        %w_IH
        %w_HO
        %d_O
        %d_H
    end  
end

function outs = sigmoid(nets)
    outs = zeros(size(nets, 1), 1);
    for i=1:size(nets, 1)
        if nets(i) < -45
            outs(i) = 0;
        elseif nets(i) > 45
            outs(i) = 1;
        else
            outs(i) = 1/1+exp(-nets(i));
        end
    end
end
4

2 に答える 2

2

コメントで確立したことから、私の心に浮かぶ唯一のことは、この素晴らしいNNアーカイブにまとめて書き留められたすべてのレシピです。

ftp://ftp.sas.com/pub/neural/FAQ2.html#質問

最初に試すことができるのは次のとおりです。

1)ロジスティック関数のオーバーフローを回避するには? おそらくそれが問題です - 私が NN を実装したことが何度もありましたが、問題はそのようなオーバーフローにありました。

2)カテゴリはどのようにエンコードする必要がありますか?

そしてより一般的に:

3)体調不良は NN トレーニングにどのように影響しますか?

4)助けて! 私のNNは学習しません!私は何をすべきか?

于 2013-08-05T11:40:02.837 に答える
1

議論の後、問題はシグモイド関数内にあることが判明しました。

function outs = sigmoid(nets)
%...
            outs(i) = 1/1+exp(-nets(i)); % parenthesis missing!!!!!!
%...
end

そのはず:

function outs = sigmoid(nets)
%...
            outs(i) = 1/(1+exp(-nets(i)));
%...
end

括弧がないため、シグモイド出力が 1 より大きい場合がありました。これにより、勾配の計算が正しくなくなりました (この関数の勾配ではないため)。これにより、勾配が負になりました。これにより、ほとんどの場合、出力レイヤーのデルタが間違った方向に向いていました。修正後 (エラー変数を正しく維持した後 - これはコードに欠落しているようです)、すべて正常に動作しているようです。


それに加えて、このコードには他に 2 つの主な問題があります。

1) 偏見がない。偏りがなければ、各ニューロンは原点を横切る線しか表現できません。データが正規化されている (つまり、値が 0 から 1 の間である) 場合、一部の構成は分離できません。

2)高い勾配値に対する保護の欠如(私の以前の回答のポイント1)。

于 2013-08-07T12:19:51.810 に答える