2

我想使用双曲正切(Sigmoid)内核计算两个图像之间的欧几里得距离。请点击这个链接,我已经详细讨论了使用高斯内核的相同问题。

如果x=(i,j)&y=(i1,j1)是我们图像中的任意两个像素,那么对于双曲正切核,myH(x,y)将被定义为: H(i,j) = tanh(alpha*(x'*y) + c) 其中alphac是参数,并且x'是 的转置x。参数alpha可以取为 1/N,其中 N 是我的图像尺寸(在我的情况下为 8192 x 200),c 可以根据问题取任何值。有关双曲正切核的更详细说明,请参见此处

为了实现我的目标并考虑运行时间,我编写了以下 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 小时才能完成,这对我来说太多了,因为我想为各种不同的图像运行它。我想使用内部 MATLAB 函数给它一个完全矢量化的形式,就像 @dan-man 在高斯内核的情况下所做的那样。在他的帮助下,高斯版本需要 1-2 秒才能完成。在这种情况下,我也尽力使用相同的conv2fft功能,但似乎很难找到实现这一目标的方法。

有人可以帮我删除一个额外的 for 循环,以使算法的运行成本与同一问题的高斯版本的运行成本相同。

提前致谢。

4

2 回答 2

1

我在 PC 上的时间只有 50 次迭代,代码需要2.07s

只需将bsxfun行更改为

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

正如警告所暗示的,你可以得到它1.65s

如果您使用神经网络工具箱并替换tanhtansig,则时间转到1.44s

如果你写你自己tanh

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

时间到了 1.28s

只是这些变化将意味着29h改进18h


并记得预先分配!

g_temp=zeros(length(perms1),1);
于 2016-08-05T08:52:08.113 回答
1

摆脱讨厌的循环matrix-multiplication-

g_temp = img_diff(:).'*tanh((1/alpha)*(perms*perms.')+1)
于 2016-08-04T14:56:37.573 回答