首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我要得到一个满是NaNs的重量矩阵?

为什么我要得到一个满是NaNs的重量矩阵?
EN

Stack Overflow用户
提问于 2011-10-23 20:32:10
回答 2查看 961关注 0票数 2

(Hebbian学习)

我的任务是在Matlab中编写Oja学习规则和Sanger学习规则,以训练一个神经网络。这个神经网络有6个输入和4个输出,我的训练集来自多元均匀分布,例如Xi ~ U(-ai,ai)和ai≠aj,对于所有的i≠j。

这些是最相关的文件(大多数评论和oja.m不包括在内)

main.m

代码语言:javascript
复制
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

代码语言:javascript
复制
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×6大小的矩阵。Wi是第一输出的权向量.Wij = (Wi)j.在这个例子中,TS是一个6x512大小的矩阵)

代码语言:javascript
复制
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也有同样的问题。

我试过:

用迭代次数的指数函数(->ok)代替eta ( 1/it --->NaN

  • Replacing eta ),但它不是I expected

  • Uncommenting W =1/范数(W)* W;的结果。这实际上是可行的,但它不应该是必要的,或者应该吗?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-25 19:54:31

你需要小的eta值。考虑一下您的更新规则:

代码语言:javascript
复制
DeltaW(i,j) = eta * V(i,1) * (trainingset(j,u) - sumatorias(i,j));

如果eta很大,DeltaW很可能有一个很大的绝对值(例如非常大,例如100000,或者非常小,例如-111111)。下一次循环sumatorias(i,j)会非常大,因为它是权值的函数。迭代次数越多,权重就越大,最终导致溢出。

票数 1
EN

Stack Overflow用户

发布于 2011-10-25 18:56:50

好的。在几次尝试之后,我让它成功了。

我选择一个相对较小的eta值: 0.00001。

代码语言:javascript
复制
W_sanger = sanger(W,TS,1000, 0.00001) 

由于没有充分利用矩阵乘法的优点,利用Matlab对矩阵乘法进行了优化,使得计算速度仍然很慢。

我希望它能帮助别人不要重复同样的错误。

致以问候!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7868984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档