2016-08-04 3 views
2

Je veux calculer la distance euclidienne entre deux images en utilisant le noyau de Tangente hyperbolique (Sigmoïde). S'il vous plaît suivez this lien où j'ai discuté du même problème en utilisant Gaussian Kernel en détail.Optimiser matlab pour la boucle pour le Big Data

Si x=(i,j) & y=(i1,j1) sont tous deux pixels dans notre image puis pour le noyau tangente hyperbolique, mon H(x,y) sera défini comme: H(i,j) = tanh(alpha*(x'*y) + c)alpha et c sont des paramètres et x' est la transposition de x. Le paramètre alpha peut être pris comme 1/N où N est ma dimension d'image (8192 x 200 dans mon cas) et c peut prendre n'importe quelle valeur en fonction du problème. Une description plus détaillée du noyau Tangent hyperbolique peut être trouvée here.

Pour atteindre mon objectif & en tenant compte du temps d'exécution, j'ai écrit le script MATLAB ci-dessous.

gray1=zeros(8192,200); 
gray2=zeros(8192,200); 

s1 = 8192; 
s2 = 200; 

alpha = s1*s2; 

perms = combvec(1:s2,1:s1); 
perms = [perms(2,:);perms(1,:)]'; 
perms1 = perms; 

gray1(4096,100) = 10; 
gray2(10,100) = 10; 
img_diff = gray1 - gray2; 

display('Calculation of Sigmoid Kernel started'); 

for i = 1:length(perms1) 
    kernel = sum(bsxfun(@times,perms,perms1(i,:))'); 
    kernel1 = tanh((1/alpha)*kernel + 1)'; 
    g_temp(i) = img_diff(:)'*kernel1; 
end 

temp = g_temp*img_diff(:); 
ans = sqrt(temp); 

Malgré tous mes efforts, je n'ai pas pu le vectoriser davantage afin de réduire son coût de fonctionnement. Actuellement, cela prend environ 29 heures à compléter ce qui est trop pour moi car je veux l'exécuter pour différentes images. Je veux lui donner une forme complètement vectorisée en utilisant des fonctions MATLAB intrinsèques comme cela a été fait par @ dan-man dans le cas de Gaussian Kernel. Avec son aide, la version gaussienne prenait 1-2 secondes pour terminer. J'ai essayé de mon mieux d'utiliser la même fonction conv2fft dans ce cas aussi, mais il semble difficile de trouver un moyen d'y parvenir.

Quelqu'un peut-il m'aider s'il vous plaît à enlever ce un supplémentaire pour la boucle afin d'obtenir le coût de fonctionnement de l'algorithme dans la même proportion que celle de la version gaussienne du même problème.

Merci d'avance.

+0

l'avez-vous profilé? –

+0

Wow, votre boucle for est '1638400', c'est beaucoup eh –

+0

@Ander Yeah..J'ai profilé. Cela prend environ 50 secondes pour seulement 780 itérations. Par conséquent, pour 1638400 itérations, cela prendra environ 29 heures. – nagarwal

Répondre

1

Débarrassez-vous de la méchante boucle avec matrix-multiplication -

g_temp = img_diff(:).'*tanh((1/alpha)*(perms*perms.')+1) 
+0

Je suis désolé mais cela ne peut pas être fait car 'perms * perms.'' va créer une énorme matrice de taille 1638400 x 1638400 qui n'est pas possible pour MATLAB de créer en raison des contraintes de mémoire. – nagarwal

1

Avec mon temps dans mon PC pour seulement 50 itérations, le code prend 2.07s

changer juste la ligne bsxfun à

kernel = sum(bsxfun(@times,perms,perms1(i,:)),2)'; 

comme l'avertissement suggère que vous pouvez l'obtenir à 1.65s

Si vous utilisez la boîte à outils Neural Network et le remplacer par tanh par tansig, le temps va à 1.44s

Si vous écrivez votre propre tanh comme

kernel1= (2./(1+exp(-2.*((1/alpha)*kernel + 1)))-1)'; 

le temps passe à 1.28s

Juste ces changements signifieraient une amélioration de 29h t o 18h


Et n'oubliez pas de préallouer!

g_temp=zeros(length(perms1),1); 
+0

C'est appréciable mais pas l'amélioration que je veux. Je voudrais vous répéter que je veux l'itérer pour plusieurs images différentes (~ 5000) et que je veux ainsi réduire le coût de fonctionnement à quelques secondes, comme celui fait par @ dan-man dans le cas du noyau gaussien. – nagarwal

+0

Merci pour ce commentaire grossier et offensant. Je l'ai déjà signalé. Conseil de vie: Parfois, vous pouvez résoudre les choses, parfois vous ne pouvez pas. Vous ne pouvez pas fournir de certificat d'absence d'existence pour la solution du problème si vous ne pouvez pas le faire. Pendant ce temps, stackoverflow est une plate-forme pour discuter et résoudre des choses qui semblaient autrefois impossibles, ne pas impliquer dans le claptrap avec des gars égoïstes. – nagarwal

+0

@ nagarwal le commentaire n'était pas méchant du tout. Comprenez que j'ai beaucoup de choses à faire et j'écris ces choses très rapidement. Les questions étaient là pour dire exactement ce qu'ils disent et le pourboire était réel. –