Оптимизировать 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);
Другие вопросы по тегам