Почему я получаю весовую матрицу, полную NaNs? - PullRequest
2 голосов
/ 24 октября 2011

(изучение иврита)

Мне было поручено программировать правило обучения Оджи и правило обучения Сэнгера в Matlab для обучения нейронной сети. Этот NN имеет 6 входов и 4 выхода, и мой обучающий набор происходит из многомерного равномерного распределения, такого как Xi ~ U (-ai, ai) и ai ≠ aj, для всех i ≠ j

Это наиболее важные файлы (большинство комментариев и 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

Я пробовал:

  • Замена эта на 1 / it ---> NaN
  • Замена эта экспоненциальной функцией числа итераций ---> хорошо, но это не то, что я ожидал
  • Не комментирует W = 1 / норма (W) * W; . Это на самом деле работает, но это не должно быть необходимо, или это должно быть?

Ответы [ 2 ]

1 голос
/ 25 октября 2011

Вам нужны небольшие значения эта.Рассмотрим правило обновления:

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

Если eta велико, DeltaW может иметь большое абсолютное значение (то есть очень большое, например, 100000, или очень маленькое, например, -111111).В следующий раз цикл sumatorias(i,j) будет довольно большим, потому что это функция весов.Чем больше у вас итераций, тем больше будет ваш вес, что в конечном итоге приведет к переполнению.

0 голосов
/ 25 октября 2011

Хорошо. После нескольких попыток я заработал.

Я выбираю сравнительно небольшое значение Эта : 0,00001

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

Это все еще медленно, потому что не использует преимущества умножения матриц, которое оптимизировано Matlab.

Надеюсь, это поможет кому-то другому не повторить ту же ошибку.

Привет!

...