【发布时间】:2018-11-20 10:39:16
【问题描述】:
我正在尝试使用'valid' 参数实现conv2(MATLAB 中的二维卷积函数),该参数仅返回在没有零填充边缘的情况下计算的卷积部分,这意味着内核不会扫描超出输入。
到目前为止,我有这段代码,但它似乎是不必要的复杂,如您所见,我计划稍后转换为定点并在硬件上实现它,SampleWindow 变量一直给我带来麻烦,因为编码器为其分配一个动态矩阵。
所以我正在寻找更简单和/或有效的功能实现。
function outConvAcc = convn(input, kernel, S)
% Get the input size in terms of rows and cols. The weights should have
% same depth as the input volume(image)
[rowsIn, colsIn, depthInput] = size(input);
% Get the kernel size, considering a square kernel always
F = size(kernel,1);
kernelf=rot90(squeeze(kernel),2);
%% Initialize outputs
sizeRowsOut = ((rowsIn-F)/S) + 1;
sizeColsOut = ((colsIn-F)/S) + 1;
outConvAcc = zeros(sizeRowsOut , sizeColsOut, depthInput);
%% Do the convolution
% Convolve each channel on the input with it's respective kernel channel,
% at the end sum all the channel results.
for r=1:S:(rowsIn-1)
for c=1:S:(colsIn-1)
% Avoid sampling out of the image.
if (((c+F)-1) <= colsIn) && (((r+F)-1) <= rowsIn)
% Select window on input volume (patch)
sampleWindow = input(r:(r+F)-1,c:(c+F)-1);
% Do the dot product
dotProd =(sampleWindow(:) .* kernelf(:));
n=size(dotProd,1);
dotProdc=0;
for km=1:n % Replace function Sum for code generation
dotProdc=dotProd(km)+dotProdc;
end
% Store result
outConvAcc(ceil(r/S),ceil(c/S),depthInput) = dotProdc;
end
end
end
end
【问题讨论】:
-
那么,你的问题是什么?
-
高效卷积通常涉及 FFT,避免使用您拥有的双嵌套循环。
-
@SembeiNorimaki 尽管我同意在这种情况下有效卷积通常涉及
fft或fft2,但它不会删除双嵌套循环,它只是将它们隐藏在fft.主要好处是其中一个循环更小,因为fft比dft快(我猜这在 MATLAB 中不存在)。 -
为什么不在
r=1:S:min(rowsIn-1,rowsIn+1-F)上循环(或假设F>=2,r=1:S:rowsIn+1-F),而不是先循环然后在计数器值上以if开始迭代?除此之外,如果最终目的是将该代码转换为 C 或其他低级语言,我认为没有太多不必要的复杂性。 -
@NickyMattsson 另外,将循环隐藏在
fft中意味着循环在内部完成(可能在 C 中),这比在 Matlab 中显式执行要快
标签: matlab convolution hardware-programming