火炬,StochasticGradient功能训练中的“大小不匹配”

时间:2015-05-20 21:48:49

标签: lua neural-network deep-learning torch

我正在使用由两个torch.Tensor()对象组成的数据集在Torch7中实现深度神经网络。 第一个由12个元素(completeTable)组成,另一个由1个元素(presentValue)组成。 每个数据集行都是这两个张量的数组:

dataset[p] = {torch.Tensor(completeTable[p]), torch.Tensor(presentValue)};

一切都适用于神经网络训练和测试。 但是现在我想切换并使用completeTable的12个元素中的一半,即只有6个元素(firstChromRegionProfile)。

dataset_firstChromRegion[p] = {torch.Tensor(firstChromRegionProfile), torch.Tensor(presentValue)};

如果我使用这个新数据集运行相同的神经网络架构,它就不起作用。 它表示由于“尺寸不匹配”,培训师:train(dataset_firstChromRegion)功能无法正常工作。

这是我的神经网络功能:

-- Neural network application
function neuralNetworkApplication(input_number, output_number, datasetTrain, datasetTest, dropOutFlag, hiddenUnits, hiddenLayers)

      require "nn"
    -- act_function = nn.Sigmoid();
    act_function = nn.Tanh();

    print('input_number '.. input_number);
    print('output_number '.. output_number);

      -- NEURAL NETWORK CREATION - <START>

      perceptron=nn.Sequential();  -- make a multi-layer perceptron
      perceptron:add(nn.Linear(input_number, hiddenUnits));
      perceptron:add(act_function);
      if dropOutFlag==TRUE then perceptron:add(nn.Dropout()) end  -- DROPOUT

        -- we add w layers DEEP LEARNING
      for w=0, hiddenLayers do
          perceptron:add(nn.Linear(hiddenUnits,hiddenUnits)) -- DEEP LEARNING layer
          perceptron:add(act_function); -- DEEP LEARNING 
          if dropOutFlag==TRUE then 
        perceptron:add(nn.Dropout())  -- DROPOUT
          end
      end

    print('\n#datasetTrain '.. #datasetTrain);
    print('#datasetTrain[1] '.. #datasetTrain[1]);
    print('(#datasetTrain[1][1])[1] '..(#datasetTrain[1][1])[1]);
    print('\n#datasetTest '.. #datasetTest);
    print('#datasetTest[1] '.. #datasetTest[1]);
    print('(#datasetTest[1][1])[1] '..(#datasetTest[1][1])[1]);

      perceptron:add(nn.Linear(hiddenUnits, output_number));
      perceptron:add(act_function);

      criterion = nn.MSECriterion();  -- MSE: Mean Square Error
      trainer = nn.StochasticGradient(perceptron, criterion)
      trainer.learningRate = LEARNING_RATE_CONST;
      trainer:train(datasetTrain);

      idp=3;
      predValueVector={}
      for i=1,(#datasetTest) do
        pred=perceptron:forward(datasetTest[i][1]);  -- get the prediction of the perceptron 
        predValueVector[i]=pred[1];     
      end

      -- NEURAL NETWORK CREATION - <END>

    return predValueVector;

end

这是错误日志:

input_number 6  
output_number 1 

#datasetTrain 13416 
#datasetTrain[1] 2  
(#datasetTrain[1][1])[1] 6  

#datasetTest 3354   
#datasetTest[1] 2   
(#datasetTest[1][1])[1] 6   
# StochasticGradient: training  
/mnt/work1/software/torch/7/bin/luajit: /mnt/work1/software/torch/7/share/lua/5.1/nn/Linear.lua:71: size mismatch
stack traceback:
    [C]: in function 'addmv'
    /mnt/work1/software/torch/7/share/lua/5.1/nn/Linear.lua:71: in function 'updateGradInput'
    /mnt/work1/software/torch/7/share/lua/5.1/nn/Sequential.lua:36: in function 'updateGradInput'
    ...software/torch/7/share/lua/5.1/nn/StochasticGradient.lua:37: in function 'train'
    siamese_neural_network.lua:278: in function 'neuralNetworkApplication'
    siamese_neural_network.lua:223: in function 'kfold_cross_validation_separate'
    siamese_neural_network.lua:753: in main chunk
    [C]: in function 'dofile'
    ...1/software/torch/7/lib/luarocks/rocks/trepl/scm-1/bin/th:131: in main chunk
    [C]: at 0x004057d0

2 个答案:

答案 0 :(得分:1)

所有激活图层共享相同的nn.Tanh()对象。那就是问题所在。尝试这样的事情:

act_function = nn.Tanh
perceptron:add( act_function() )

为什么?

要执行向后传播步骤,我们必须计算w.r.t层的渐变。它的输入。在我们的案例中:

  

tanh&#39;(输入)= 1 - tanh(输入) ^ 2

可以注意到图层前进步骤的 tanh(输入) = 输出。您可以将此输出存储在图层中,并在向后传递期间使用它以加速训练。这正是nn库中发生的事情:

// torch/nn/generic/Tanh.c/Tanh_updateGradInput:

for(i = 0; i < THTensor_(nElement)(gradInput); i++)
    {
        real z = ptr_output[i];
        ptr_gradInput[i] = ptr_gradOutput[i] * (1. - z*z);
    }

激活图层的输出尺寸不匹配,因此会发生错误。即使他们这样做,也会导致错误的结果。

抱歉我的英文。

答案 1 :(得分:0)

通过消除这条线,我出乎意料地能够解决我的问题:

act_function = nn.Tanh();

并因此将act_function替换为nn.Tanh()

我不知道为什么,但知道一切正常...... 所以教训是:永远不要将激活函数分配给变量(!?)。