Оптимизировать Matlab для цикла для больших данных
Я хочу вычислить евклидово расстояние между двумя изображениями, используя ядро Гиперболический тангент (сигмоид). Пожалуйста, перейдите по этой ссылке, где я подробно обсудил ту же проблему с использованием Gaussian Kernel.
Если 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 в случае ядра Gaussian. С его помощью гауссовская версия заняла 1-2 секунды. Я старался изо всех сил, чтобы использовать тот же conv2fft
функция в этом случае также, но кажется, что трудно найти способ достичь этого.
Может кто-нибудь, пожалуйста, помогите мне удалить этот дополнительный цикл for, чтобы получить текущую стоимость алгоритма в той же пропорции, что и в гауссовой версии той же задачи.
Заранее спасибо.
2 ответа
Избавьтесь от неприятной петли с matrix-multiplication
-
g_temp = img_diff(:).'*tanh((1/alpha)*(perms*perms.')+1)
С моим временем в моем компьютере всего за 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);