2

Je range un code de classification numérique. Donc je nourris une image d'un chiffre, disons "7" et je sors 10 probabilités (c'est-à-dire des sommes à 1). Si mon algorithme fonctionne bien, le 7ème élément devrait avoir la valeur la plus élevée.Échantillonnage binaire efficace à partir du vecteur des vecteurs de distribution de probabilité dans MatLab

Une complication supplémentaire est que je travaille avec des lots de 100 éléments. J'ai donc une MATRICE COLXROW = 100x10 où chaque ROW est égale à 1.

Maintenant, je souhaite échantillonner à partir de chacune de ces 100 distributions, c'est-à-dire que je dois produire un vecteur comme [0 0 0 1 0 0 0 0 0 0] (ce serait un 3) pour chaque lot en fonction de ma distribution de probabilité.

La mise en œuvre actuelle est:

samp = pd*0; 
layers = cumsum(pd, 2); 
randoms = rand(batchSize, 1); 
for k = 1:batchSize 
    index = find(randoms(k) <= layers(k,:), 1); 
    samp(k, index) = 1; 
end 

Cependant, je préférerais éviter les boucles explicitement (comme je l'ai lu est souvent cause de mauvaises performances).

L'efficacité est la clé, car cette routine est exécutée dans les boucles les plus serrées.

Comment accomplir cela efficacement? EDIT Je vais essayer de répondre à ma question, je poste au cas où quelqu'un pourrait améliorer la réponse (il y a presque toujours plus d'une façon de dépecer un chat dans MatLab) et aussi cela peut constituer un extrait de valeur à quelqu'un.

Répondre

0

Ce qui suit semble fonctionner:

function sample = sampleFromPDs(pd) 
    [batchSize_, nOutputs] = size(pd); 

    bools = cumsum(pd,2) > repmat(rand(batchSize_,1), 1, nOutputs); 

    % e.g. 001 111 gives (6+1) - 4 = 3 
    indexOfFirstONE = (nOutputs+1) - sum(bools, 2); 

    sample = 0 .* pd; 
    sample(... 
     sub2ind(size(pd), 1:batchSize_, indexOfFirstONE') ... 
     ) = 1;  
end 

Cependant, je suis un peu inquiet que MatLab pourrait être réaffecte mémoire chaque itération (alors qu'en réalité il est toujours appelée avec les mêmes dimensions d'argument).

1

est ici un moyen d'éviter la boucle:

% preparing some data: 
batchSize = 100; 
probs = [ones(1,9)*0.01 0.9]; 
pd = zeros(batchSize,10); 
for k = 1:batchSize 
    pd(k,:) = probs(randperm(10)); 
end 

% the actual answer: 
layers = cumsum(pd,2); 
randoms = rand(batchSize,1); 
index = 11-cumsum((layers-repmat(randoms,1,10))>0,2); 
samp = bsxfun(@eq,index(:,end),1:10);