2016-08-04 2 views
2

쌍곡선 접선 (Sigmoid) 커널을 사용하여 두 이미지 사이의 유클리드 거리를 계산하고 싶습니다. this 링크를 따라 가면서 Gaussian Kernel을 사용하여 동일한 문제에 대해 자세히 논의했습니다. H(i,j) = tanh(alpha*(x'*y) + c)alphac 매개 변수이며, x'x의 전치 : & y=(i1,j1)x=(i,j)는 쌍곡선 탄젠트 커널 다음 우리의 이미지에서 두 픽셀이 경우큰 데이터를위한 루프 최적화 for matlab

, 내 H(x,y)는 다음과 같이 정의됩니다. 매개 변수 alpha은 1/N으로 취할 수 있습니다. 여기서 N은 내 이미지 크기 (8192 x 200)이며 문제에 따라 c 값을 취할 수 있습니다. 쌍곡선 탄젠트 커널에 대한 더 자세한 설명은 here입니다.

내 목표 인 &을 실행 시간을 유지하기 위해 아래 MATLAB 스크립트를 작성했습니다.

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); 

내 모든 노력에도 불구하고 실행 비용을 줄이기 위해 벡터화 할 수 없었습니다. 현재 완료까지는 약 29 시간이 걸리며, 여러 가지 다른 이미지로 실행하고 싶을 때 너무 많이 필요합니다. Gaussian Kernel의 경우 @ dan-man에 의해 수행 된 것처럼 내장 MATLAB 함수를 사용하여 완전히 벡터화 된 형식을 제공하고자합니다. 그의 도움으로 Gaussian Version은 1-2 초가 걸렸습니다. 이 경우에도 동일한 conv2fft 기능을 사용하기 위해 최선을 다했지만 그 방법을 찾기가 어려워 보입니다.

누군가가 알고리즘에 대한 실행 비용을 Gaussian 버전의 동일한 문제와 동일한 비율로 얻으려면 루프 용 extra for 루프를 제거 할 수 있습니까?

미리 감사드립니다.

+0

프로파일을 만들었습니까? –

+0

와우, 당신의 for 루프는'1638400'입니다. 많이 그렇습니다 –

+0

@Ander 예 .. 제가 프로파일 링했습니다. 단지 780 반복에 대해 약 50 초 걸립니다. 따라서 1638400 회 반복의 경우 약 29 시간이 소요됩니다. – nagarwal

답변

1

matrix-multiplication으로 불쾌한 루프를 제거하기 - 단 50 반복 내 PC에 내 시간이

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

죄송 합니다만,'perms * perms.''은 크기가 1638400 x 1638400 인 거대한 행렬을 생성 할 것이기 때문에 메모리 제약으로 인해 MATLAB이 생성 할 수 없습니다. – nagarwal

1

코드는 2.07s

그냥

bsxfun 라인을 변경한다
kernel = sum(bsxfun(@times,perms,perms1(i,:)),2)'; 

경고가 표시되면로 가져올 수 있음을 나타냅니다. 당신이 신경 네트워크 도구 상자를 사용하고 tansig에 의해 tanh을 대체 할 경우 989,257,643,210

는 시간은 작성하는 경우 1.44s

로 이동하여 시간이 1.28s

가는 자신의 tanh
kernel1= (2./(1+exp(-2.*((1/alpha)*kernel + 1)))-1)'; 

이러한 변경 사항은 개선을 의미합니다. 29h t o 18h


미리 할당하십시오!

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

그건 내가 원하는 개선은 아니지만 크게 좋아. 여러 다른 이미지 (~ 5000)에 대해 반복하고 싶기 때문에 가우스 커널의 경우 @ dan-man과 같이 실행 비용을 초 단위로 낮추고 싶다고 다시 말씀드립니다. – nagarwal

+0

무례하고 모욕적 인 코멘트 주셔서 감사합니다. 나는 이미 그것을보고했다. 인생 팁 : 가끔은 당신이 할 수있는 일들을 해결할 수 있습니다. 당신이 할 수 없다면 문제의 해결책을위한 '존재하지 않음'인증서를 제공 할 수 없습니다. 그 사이에 stackoverflow는 한때 불가능한 것 같았던 일을 토론하고 해결할 수있는 플랫폼으로, 일부이기 주의자와 함께 claptrap에 참여하지 않았습니다. – nagarwal

+0

@nagarwal 코멘트가 전혀 무례하다는 의미는 아니 었습니다. 이해하기 나는 할 일이 많고 나는이 일을 정말로 빨리 기록한다. 거기에서의 질문은 그들이 말하는 것과 팁이 실제로 무엇인지에 관해 말하는 것을 의미했다. –