可分离卷积没有加速
No speed up in Separable Convolution
我正在实施可分离卷积以加速 2D 高斯卷积。
clear all;
close all;
im = randi([0,255],1024,1024);
win = 7;
window = fspecial('gaussian',win,win/6);
[U, S, V] = svd(window);
v = U(:,1) * sqrt(S(1,1));
h = V(:,1)' * sqrt(S(1,1));
out1 = filter2(window, im);
out2 = filter2(h, filter2(v, im));
norm(out1 - out2)
tic
for i = 1:1000
out1 = filter2(window, im);
end
toc
tic
for i = 1:1000
out2 = filter2(h, filter2(v, im));
end
toc
分离版应该快win*win/(win + win) = 2.5倍,但实际上更慢:
ans =
2.6250e-12
Elapsed time is 5.486270 seconds.
Elapsed time is 8.769868 seconds.
filter2里面有没有隐藏的实现?
首先,如果您查看 filter2
的源代码,您会发现它已经使用相同的可分离 SVD 方法实现。这是 filter2
在你的案例中所做的要点(但你真的应该单步执行代码):
[U, S, V] = svd(window,'econ');
v = U(:,1) * sqrt(S(1,1));
h = V(:,1)' * sqrt(S(1,1));
out2 = conv2(v, h, im, 'same');
你做的是一样的,但不是使用更有效的单一调用 conv2(v, h, im, 'same')
,你最终会进行递归调用 conv2(conv2(im, v, 'same'), h, 'same')
,这显然是它变慢的原因。
Matlab 对内置 conv
函数集(包括 conv2
)的实现不是最优的。您可以在此处阅读有关它(和解决方法)的信息:http://undocumentedmatlab.com/blog/convolution-performance。
基本思想是使用卷积定理或基于 C++ 的 MEX 实现,或者最好同时使用两者,如 Bruno Luong 所使用的 convfft实用程序。
我正在实施可分离卷积以加速 2D 高斯卷积。
clear all;
close all;
im = randi([0,255],1024,1024);
win = 7;
window = fspecial('gaussian',win,win/6);
[U, S, V] = svd(window);
v = U(:,1) * sqrt(S(1,1));
h = V(:,1)' * sqrt(S(1,1));
out1 = filter2(window, im);
out2 = filter2(h, filter2(v, im));
norm(out1 - out2)
tic
for i = 1:1000
out1 = filter2(window, im);
end
toc
tic
for i = 1:1000
out2 = filter2(h, filter2(v, im));
end
toc
分离版应该快win*win/(win + win) = 2.5倍,但实际上更慢:
ans =
2.6250e-12
Elapsed time is 5.486270 seconds.
Elapsed time is 8.769868 seconds.
filter2里面有没有隐藏的实现?
首先,如果您查看 filter2
的源代码,您会发现它已经使用相同的可分离 SVD 方法实现。这是 filter2
在你的案例中所做的要点(但你真的应该单步执行代码):
[U, S, V] = svd(window,'econ');
v = U(:,1) * sqrt(S(1,1));
h = V(:,1)' * sqrt(S(1,1));
out2 = conv2(v, h, im, 'same');
你做的是一样的,但不是使用更有效的单一调用 conv2(v, h, im, 'same')
,你最终会进行递归调用 conv2(conv2(im, v, 'same'), h, 'same')
,这显然是它变慢的原因。
Matlab 对内置 conv
函数集(包括 conv2
)的实现不是最优的。您可以在此处阅读有关它(和解决方法)的信息:http://undocumentedmatlab.com/blog/convolution-performance。
基本思想是使用卷积定理或基于 C++ 的 MEX 实现,或者最好同时使用两者,如 Bruno Luong 所使用的 convfft实用程序。