Search code examples
matlabparallel-processingmachine-learningneural-networkparfor

Neural network train matlab parfor problems


I'm trying to find where are make mistakes. Be very glad if you could help me.

Here is my problem:

In serial the train, from neural network toolbox, function behave in one way but when I put it in a parfor loop everything goes crazy.

>> version

ans =

8.3.0.532 (R2014a)

Here is a function

function per = neuralTr(tSet,Y,CrossVal,Ycv)

hiddenLayerSize = 94;
redeT = patternnet(hiddenLayerSize);
redeT.input.processFcns = {'removeconstantrows','mapminmax'};
redeT.output.processFcns = {'removeconstantrows','mapminmax'};
redeT.divideFcn = 'dividerand';  % Divide data randomly
redeT.divideMode = 'sample';  % Divide up every sample
redeT.divideParam.trainRatio = 80/100;
redeT.divideParam.valRatio = 10/100;
redeT.divideParam.testRatio = 10/100;
redeT.trainFcn = 'trainscg';  % Scaled conjugate gradient
redeT.performFcn = 'crossentropy';  % Cross-entropy
redeT.trainParam.showWindow=0; %default is 1)
redeT = train(redeT,tSet,Y);    
outputs = sim(redeT,CrossVal);
per = perform(redeT,Ycv,outputs);

end

And here is the code I'm typing:

Data loaded in workspace
whos
        Name            Size              Bytes  Class     Attributes

        CrossVal      282x157            354192  double
        Y               2x363              5808  double
        Ycv             2x157              2512  double
        per             1x1                   8  double
        tSet          282x363            818928  double

Function executing in Serial

per = neuralTr(tSet,Y,CrossVal,Ycv)

        per =

        0.90

Starting parallel

>> parpool local
Starting parallel pool (parpool) using the 'local' profile ... connected to 12 workers.

ans = 

 Pool with properties: 

            Connected: true
           NumWorkers: 12
              Cluster: local
        AttachedFiles: {}
          IdleTimeout: Inf (no automatic shut down)
          SpmdEnabled: true

Initializing and executing the function 12 times in parallel

per = cell(12,1);
parfor ii = 1 : 12
per{ii} = neuralTr(tSet,Y,CrossVal,Ycv);
end        

per

per = 

    [0.96]
    [0.83]
    [0.92]
    [1.08]
    [0.85]
    [0.89]
    [1.06]
    [0.83]
    [0.90]
    [0.93]
    [0.95]
    [0.81]

Executing again to see if random initialization brings different values

per = cell(12,1);
parfor ii = 1 : 12
per{ii} = neuralTr(tSet,Y,CrossVal,Ycv);
end
per

per = 

    [0.96]
    [0.83]
    [0.92]
    [1.08]
    [0.85]
    [0.89]
    [1.06]
    [0.83]
    [0.90]
    [0.93]
    [0.95]
    [0.81]

EDIT 1: Running the function only with for

per = cell(12,1);
for ii = 1 : 12
    per{ii} = neuralTr(tSet,Y,CrossVal,Ycv);
end
    per

    per =

    [0.90]
    [0.90]
    [0.90]
    [0.90]
    [0.90]
    [0.90]
    [0.90]
    [0.90]
    [0.90]
    [0.90]
    [0.90]
    [0.90]

EDIT 2: I modified my function now everything works great. Maybe the problem is when data is divided in parallel. So i divided the data before send to parallel. Tks a lot

function per = neuralTr(tSet,Y,CrossVal,Ycv)
indt = 1:round(size(tSet,2) * 0.8) ;
indv = round(size(tSet,2) * 0.8):round(size(tSet,2) * 0.9);
indte = round(size(tSet,2) * 0.9):size(tSet,2);
hiddenLayerSize = 94;
redeT = patternnet(hiddenLayerSize);
redeT.input.processFcns = {'removeconstantrows','mapminmax'};
redeT.output.processFcns = {'removeconstantrows','mapminmax'};
redeT.divideFcn = 'dividerand';  % Divide data randomly
redeT.divideMode = 'sample';  % Divide up every sample
redeT.divideParam.trainRatio = 80/100;
redeT.divideParam.valRatio =  10/100;
redeT.divideParam.testRatio = 10/100;

redeT.trainFcn = 'trainscg';  % Scaled conjugate gradient
redeT.performFcn = 'crossentropy';  % Cross-entropy
redeT.trainParam.showWindow=0; %default is 1)
redeT = train(redeT,tSet,Y);    
outputs = sim(redeT,CrossVal);
per = zeros(12,1);
parfor ii = 1 : 12
    redes = train(redeT,tSet,Y);
    per(ii) = perform(redes,Ycv,outputs);
end
end

Result:

>> per = neuralTr(tSet,Y,CrossVal,Ycv)

per =

          0.90
          0.90
          0.90
          0.90
          0.90
          0.90
          0.90
          0.90
          0.90
          0.90
          0.90
          0.90

Solution

  • Oh! I think I found it, but cant test it.

    you have in your code:

    redeT.divideFcn = 'dividerand';  % Divide data randomly
    

    If each of the workers chooses the data randomly, then its expected for them to have different results, aren't they?

    Try the next:

    per = cell(12,1);
    parfor ii = 1 : 12
       rng(1); % set the seed for random number generation, so every time the number generated will be the same
       per{ii} = neuralTr(tSet,Y,CrossVal,Ycv);
    end
    per
    

    Not sure if neuralTr does set the seed inside, but give it a go.