我想使用双曲正切(Sigmoid(核计算两个图像之间的欧几里得距离。请点击此链接,我详细讨论了使用高斯内核的相同问题。
如果x=(i,j)
和y=(i1,j1)
是我们图像中的任何两个像素,那么对于双曲切线核,我的H(x,y)
将被定义为: H(i,j) = tanh(alpha*(x'*y) + c)
其中alpha
和c
是参数,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 循环,以便获得与同一问题的高斯版本相同的算法运行成本。
提前谢谢。
用matrix-multiplication
摆脱讨厌的循环 -
g_temp = img_diff(:).'*tanh((1/alpha)*(perms*perms.')+1)
我在PC上的时间只有50次迭代,代码需要2.07s
只需将bsxfun
行更改为
kernel = sum(bsxfun(@times,perms,perms1(i,:)),2)';
正如警告所暗示的那样,您可以将其1.65s
如果使用神经网络工具箱并将tanh
替换为 tansig
,则时间会变为1.44s
如果您将自己的tanh
写为
kernel1= (2./(1+exp(-2.*((1/alpha)*kernel + 1)))-1)';
时间流逝1.28s
这些变化意味着从29h
到18h
的改进
并记得预先分配!
g_temp=zeros(length(perms1),1);