【问题标题】:Matlab formula optimization: Radial Basis FunctionMatlab公式优化:径向基函数
【发布时间】:2011-10-22 19:09:22
【问题描述】:
  • z - 双精度矩阵,大小 Nx2;
  • x - 双精度矩阵,大小为 Nx2;

sup = x(i, :);

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

这是逻辑回归的径向基函数 (RBF)。这是公式:

我需要你的建议,我可以优化这个公式吗?因为它调用了数百万次,而且需要很多时间......

【问题讨论】:

  • repmat 调用中的表达式中缺少逗号。
  • @Yekver 您的公式有语法错误。我用$ 标记了它们。 x(i,:)$(ones([size(z,1) 1]),$:))。如果您告诉我们N 有多大,也会有所帮助。
  • @yoda 这个公式对我来说很好。我使用附加变量sup = x(i, :);。 N 可以是[100..5000]
  • @yoda:实际上,尺寸现在确实匹配(实际上是 Nx2,因为 sup 是),但我同意公式会更清晰。
  • @MikaelÖhman 你是对的sup。我把它误读为x(:,i)。我回去看了他的第一个版本,那是最清楚的。我想知道他为什么一直试图修改表达式。

标签: matlab math optimization euclidean-distance


【解决方案1】:

Amro 提到了一些非常好的方法。但是可以通过重塑其中一个矩阵来进一步利用 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

您想从 Z 的每一行中减去 X 的每一行。当其中一个是向量而另一个是矩阵时,这通常是直截了当的。但是如果它们都是矩阵,我们可以通过确保卷中的每个矩阵只包含一个向量来做到这一点。这里我选择了X,但是Z可以和X互换使用。

【讨论】:

  • +1 不错的 BSXFUN 矢量化。我应该提到,我们比较时间的方式有点不公平。在 PDIST2 的情况下,调用函数会产生开销,而其他内联方法则不存在这种开销。所以我将每个都包装在一个函数中,并使用TIMEIT 重新进行了实验,结果发现 PDIST2 是最快的:1.4369 (PDIST2), 1.816 (BSXFUN+loop), 2.2238 (REPMAT+loop), 2.2306 (BXSFUN/RESHAPE)
【解决方案2】:

在您最近的编辑中,您似乎引入了一些语法错误,但我想我理解您想要做什么(从第一个版本开始)。

考虑使用高效的BSXFUN 函数,而不是使用REPMAT 或索引来重复向量x(i,:) 以匹配z 的行:

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

上面显然循环了 x 的每一行


您可以更进一步,使用PDIST2 计算zx 中每对行之间的欧几里得距离:

%# 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

【讨论】:

  • @Yekver:我还是不明白你在做什么;发布几乎没有解释的sn-ps代码势必会让读者感到困惑...请编辑您的问题并更清楚地描述问题
  • Amro,没有测试完整的 bsxfun 有什么特别的原因吗?这有点棘手,但可以实现。
  • @Yekver,在您的实现中,每个单元格将包含 N 个元素,并且由于有 1xN 单元格数组,因此 Amro 得到的输出与您的相同,除了他使用矩阵表示而不是细胞。
猜你喜欢
  • 2012-10-15
  • 2016-03-06
  • 2015-01-13
  • 2015-01-27
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
相关资源
最近更新 更多