Оптимизация формулы Matlab: радиальная базисная функция - PullRequest
6 голосов
/ 09 августа 2011
  • z - матрица пар, размер Nx2;
  • x - матрица пар, размер Nx2;

sup = x(i, :);

phi(1, i) = {@(z) exp(-g * sum((z - sup(ones([size(z, 1) 1]),:)) .^ 2, 2))};

это функция радиального базиса (RBF) для логистической регрессии.Вот формула:

enter image description here

Мне нужен ваш совет, могу ли я оптимизировать эту формулу?потому что это вызывает миллионы раз, и это занимает много времени ...

Ответы [ 2 ]

6 голосов
/ 09 августа 2011

Кажется, в ваших последних изменениях вы ввели некоторые синтаксические ошибки, но я думаю, что я понял, что вы пытались сделать (из первой версии).

Вместо использования REPMAT или индексирование для повторения вектора x(i,:) для соответствия строкам z, рассмотрите возможность использования эффективной функции BSXFUN :

rbf(:,i) = exp( -g .* sum(bsxfun(@minus,z,x(i,:)).^2,2) );

Очевидно, что вышеприведенное зацикливается на каждой строке x


Вы можете пойти еще дальше и использовать PDIST2 для вычисления евклидова расстояния между каждой парой строк в z и x:

%# some random data
X = rand(10,2);
Z = rand(10,2);
g = 0.5;

%# one-line solution
rbf = exp(-g .* pdist2(Z,X,'euclidean').^2);

Теперь каждое значение в матрице: rbf(i,j) соответствует значению функции между z(i,:) и x(j,:)


РЕДАКТИРОВАТЬ:

Я рассчитал различные методы, здесьэто код, который я использовал:

%# some random data
N = 5000;
X = rand(N,2);
Z = rand(N,2);
g = 0.5;

%# PDIST2
tic
rbf1 = exp(-g .* pdist2(Z,X,'euclidean').^2);
toc

%# BSXFUN+loop
tic
rbf2 = zeros(N,N);
for j=1:N
    rbf2(:,j) = exp( -g .* sum(bsxfun(@minus,Z,X(j,:)).^2,2) );
end
toc

%# REPMAT+loop
tic
rbf3 = zeros(N,N);
for j=1:N
    rbf3(:,j) = exp( -g .* sum((Z-repmat(X(j,:),[N 1])).^2,2) );
end
toc

%# check if results are equal
all( abs(rbf1(:)-rbf2(:)) < 1e-15 )
all( abs(rbf2(:)-rbf3(:)) < 1e-15 )

Результаты:

Elapsed time is 2.108313 seconds.     # PDIST2
Elapsed time is 1.975865 seconds.     # BSXFUN
Elapsed time is 2.706201 seconds.     # REPMAT
3 голосов
/ 09 августа 2011

Амро упомянул несколько действительно хороших методов.Но bsxfun может быть дополнительно использован путем изменения формы одной из матриц.

>> type r.m

N = 5000;
X = rand(N,2);
Z = rand(N,2);
g = 0.5;

%BSXFUN+loop
tic
rbf2 = zeros(N,N);
for j=1:N
    rbf2(:,j) = exp( -g .* sum(bsxfun(@minus,Z,X(j,:)).^2,2) );
end
toc

tic
diffs = bsxfun(@minus, reshape(X', [1, 2, N]), Z);
dist = reshape(sum(diffs.^2, 2), [N, N]);
rbf3 = exp(-g .* dist);
toc

>> r
Elapsed time is 2.235527 seconds.
Elapsed time is 0.877833 seconds.
>> r
Elapsed time is 2.253943 seconds.
Elapsed time is 1.047295 seconds.
>> r
Elapsed time is 2.234132 seconds.
Elapsed time is 0.856302 seconds.
>> max(abs(rbf2(:) - rbf3(:)))

ans =

     0

Вы хотите вычесть каждую строку X из каждой строки Z. Обычно это просто, когда один из них является вектором, а другой - матрицей.Но если они оба являются матрицами, мы можем сделать это, убедившись, что каждая матрица в объеме содержит только один вектор.Здесь я выбрал X, но Z можно использовать взаимозаменяемо с X.

...