Converting for loop to GPU friendly code/ Cross Validation with GPU

7 visualizzazioni (ultimi 30 giorni)
Hi does anyone have an idea how to convert the following for loop to GPU friendly code? I have tried to do so with arrayfun, crossval and fitrlinear functions. But to no avail. I have converted the objects to gpu arrays but im not sure how to carry out cross validation using the GPU, specifically without invoking the for loop. Thanks.
function [output] = cross_val(featMatGPU,labelMatGPU,foldGrouping)
G1 = unique(foldGrouping(:));
G = gpuArray(G1);
estimate=[];
gpuestimate = gpuArray(estimate);
pooledTargets =[];
gpupooledTargets = gpuArray(pooledTargets);
g = [];
gpug = gpuArray(g);
testingOrder = [];
gputestingOrder = gpuArray(testingOrder);
for i=1:length(G)
fprintf('\t\tFold %d of %d\n',i,length(G));
idx1 = find(foldGrouping~=G(i)); % Training set
idx2 = find(foldGrouping==G(i)); % Test set
gputestingOrder = [gputestingOrder, idx2(:)];
% train
w = featMatGPU(idx1,:) \ labelMatGPU(idx1);
% test
estimateTemp = featMatGPU(idx2,:)*w;
pooledTargets = [pooledTargets,labelMatGPU(idx2)];
estimate = [estimate,estimateTemp(:)];
end
end
Or rather, the question can be simplified to how do you perform leave one out cross validation for the code below in a GPU friendly manner:
featMatGPU = gpuArray(featMat);
labelMatGPU = gpuArray(labelMat)
function [results] = test_script_crossval(x,y)
[results] = x \ y(:,1);
end
results = test_script_crossval(featMatGPU,labelMatGPU)
  10 Commenti
Walter Roberson
Walter Roberson il 5 Nov 2019
I do not think it should be involved in this step. If I were to involve it, I would take the results of the mldivide and multiply them by training(idx2,:) and compare against targets(idx2) in order to determine how well the training did.
Joss Knight
Joss Knight il 6 Nov 2019
Modificato: Joss Knight il 6 Nov 2019
So, it looks like each matrix sent to mldivide is the same rows of training but with a different row removed each time, and similarly for targets.
[~, IG] = unique(foldGrouping);
A_all = training(IG,:);
B_all = targets(IG);
% Create a version of A and B replicated along dim 3, but
% with a different row removed from each page
numSolves = numel(IG);
numCols = size(A_all,2);
A = repmat(A_all,1,1,numSolves);
B = repmat(B_all,1,1,numSolves);
selectorB = reshape(~eye(numSolves),numSolves,1,[]);
selectorA = repmat(selectorB,1,numCols);
A = reshape(A(selectorA),numSolves-1,numCols,[]);
B = reshape(b(selectorB),numSolves-1,1,[]);
% Solve the multiple systems
C = pagefun(@mldivide,A,B);
However, the problem is that pagefun mldivide doesn't support rectangular matrices yet. You can get round this for now by using a pseudo-inverse solution (solving the normal equations). For a well-conditioned problem this shouldn't be too bad.
function X = pagefunMldivide(A,B)
% Solve AX = B for an under-determined problem in batch,
% via the normal equations:
% X = ((AA')A) \ (AA')B
At = pagefun(@transpose,A);
AAt = pagefun(@mtimes,A,At);
AAtA = pagefun(@mtimes,AAt,A);
AAtB = pagefun(@mtimes,AAt,B);
X = pagefun(@mldivide,AAtA,AAtB);
end
I haven't checked any of this so no doubt there are bugs.

Accedi per commentare.

Risposte (0)

Categorie

Scopri di più su Arithmetic Operations in Help Center e File Exchange

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by