2

(ヘッブの学習)

ニューラルネットワークをトレーニングするために、MatlabでOjaの学習ルールとSangerの学習ルールをプログラミングするタスクが与えられました。このNNには6つの入力と4つの出力があり、私のトレーニングセットは、すべてのi≠jについて、Xi〜U(-ai、ai)やai≠ajなどの多変量一様分布から取得されます。

これらは最も関連性の高いファイルです(ほとんどのコメントとoja.mは含まれていませんでした)


main.m

TS = generarVectoresUnif(6, [1, 4, 9, 36, 25, 16], 512);
TS = TS';
W = unifrnd(0,1,[4,6]);
% it not very fast. That's why I put 500 iterations
W_sanger = sanger(W,TS,500, 0.05)


generarVectoresUnif.m

function [ TS ] = generarVectoresUnif( dim, rangos, n )
dimensiones = int8(dim);
tamanio = int32(n);
TS = [];

for i = 1:dimensiones
   TS = [TS, unifrnd(-rangos(i), rangos(i), [tamanio, 1]) ];
end


sanger.m

(注: Wは4 x 6サイズの行列です 。Wiはi番目の出力 の重みベクトルです。Wij = (Wi)j。この例では、TSは6 x 512サイズの行列です)

function [ W ] = sanger( W_init, trainingset, iteraciones , eta)

W = W_init;

% obtiene los tamaños desde los parametros de entrada
size_input = size(W,2);
size_output = size(W,1);
n_patterns = size(trainingset, 2);


% one-tenth part
diezmo = iteraciones/10;


for it = 1:iteraciones

   if 0 == mod(it, diezmo)
      disp(horzcat('Iteracion numero ', num2str(it), ' de ',num2str(iteraciones)));
   end

   % for each pattern
   for u = 1:n_patrones

      DeltaW = zeros(size(W));

      % Vi = sum{j=1...N} Wij * Xj
      V = W * trainingset(:,u);

      % sumatorias(i,j) is going to replace sum{k=1..i} Vk*Wkj
      sumatorias = zeros(size_output,size_input);
      for j = 1:size_input
         for k = 1:size_output
             % sumar de 1 hasta i, sin hacer otro ciclo
             sumatorias(k,j) = (V' .* [ones(1,k), zeros(1,size_output-k)]) * W(:,j);
         end
      end

       % calcula la variacion
       for i = 1:size_output
          for j=1:size_input
             % Delta Wij = eta * Vi * ( xj - sum{k=1..i} Vk*Wkj )
              DeltaW(i,j) = eta * V(i,1) * (trainingset(j,u) - sumatorias(i,j));
          end
       end

       W = W + DeltaW;      
       %W = 1/norm(W) * W; %<---is it necessary? [Hertz] doesn't mention it

  end

end

私が間違っていることを教えていただけますか?マトリックスの値は非常に速く成長します。oja.mでも同じ問題があります

私はもう試した:

  • eta1/it --->NaNに置き換える
  • etaを反復回数の指数関数に置き換える--->ok、しかしそれは私が期待したものではありません
  • コメント解除W=1 / norm(W)* W; 。これは実際には機能しますが、必要ではないはずですか、それとも必要ですか?
4

2 に答える 2

1

etaの値を小さくする必要があります。更新ルールを検討してください。

DeltaW(i,j) = eta * V(i,1) * (trainingset(j,u) - sumatorias(i,j));

etaが大きい場合、DeltaW絶対値が大きくなる可能性があります(つまり、非常に大きい、たとえば100000、または非常に小さい、たとえば-111111)。次回のループsumatorias(i,j)は、重みの関数であるため、かなり大きくなります。反復回数が多いほど、重みが大きくなり、最終的にオーバーフローが発生します。

于 2011-10-25T19:54:31.837 に答える
0

Ok。何度か試した後、私はそれを機能させました。

etaの比較的小さい値を選択します:0.00001

W_sanger = sanger(W,TS,1000, 0.00001) 

Matlabによって最適化された行列乗算を利用していないため、まだ低速です。

他の誰かが同じ過ちを繰り返さないようにするのに役立つことを願っています。

よろしく!

于 2011-10-25T18:56:50.193 に答える