逻辑回归的向量化实现样例
From Ufldl
Line 1: | Line 1: | ||
- | |||
我们想用批量梯度上升法对logistic回归分析模型进行训练,其模型如下: | 我们想用批量梯度上升法对logistic回归分析模型进行训练,其模型如下: | ||
Line 20: | Line 19: | ||
以下是梯度运算代码的一种实现,非常恐怖,速度极慢: | 以下是梯度运算代码的一种实现,非常恐怖,速度极慢: | ||
- | <syntaxhighlight lang="matlab"> | + | :<syntaxhighlight lang="matlab"> |
% 代码1 | % 代码1 | ||
grad = zeros(n+1,1); | grad = zeros(n+1,1); | ||
Line 31: | Line 30: | ||
end; | end; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
嵌套的for循环语句使这段代码的运行非常缓慢。以下是更典型的实现方式,它对算法进行部分向量化,带来更优的执行效率: | 嵌套的for循环语句使这段代码的运行非常缓慢。以下是更典型的实现方式,它对算法进行部分向量化,带来更优的执行效率: | ||
Line 41: | Line 41: | ||
end; | end; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
但是,或许可以向量化得更彻底些。如果去除for循环,我们就可以显著地改善代码执行效率。特别的,假定b是一个列向量,A是一个矩阵,我们用以下两种方式来计算A*b: | 但是,或许可以向量化得更彻底些。如果去除for循环,我们就可以显著地改善代码执行效率。特别的,假定b是一个列向量,A是一个矩阵,我们用以下两种方式来计算A*b: | ||
- | <syntaxhighlight lang="matlab"> | + | :<syntaxhighlight lang="matlab"> |
% 矩阵-向量乘法运算的低效代码 | % 矩阵-向量乘法运算的低效代码 | ||
grad = zeros(n+1,1); | grad = zeros(n+1,1); | ||
Line 54: | Line 55: | ||
grad = A*b; | grad = A*b; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
我们看到,代码2是用了低效的for循环语句执行梯度上升(译者注:原文是下降)运算,将b(i)看成(y(i) - sigmoid(theta'*x(:,i))),A看成x,我们就可以使用以下高效率的代码: | 我们看到,代码2是用了低效的for循环语句执行梯度上升(译者注:原文是下降)运算,将b(i)看成(y(i) - sigmoid(theta'*x(:,i))),A看成x,我们就可以使用以下高效率的代码: | ||
- | <syntaxhighlight lang="matlab"> | + | :<syntaxhighlight lang="matlab"> |
% 代码3 | % 代码3 | ||
grad = x * (y- sigmoid(theta'*x)); | grad = x * (y- sigmoid(theta'*x)); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
这里我们假定Matlab/Octave的sigmoid(z)函数接受一个向量形式的输入z,依次对输入向量的每个元素施行sigmoid函数,最后返回运算结果,因此sigmoid(z)的输出结果是一个与z有相同维度的向量。 | 这里我们假定Matlab/Octave的sigmoid(z)函数接受一个向量形式的输入z,依次对输入向量的每个元素施行sigmoid函数,最后返回运算结果,因此sigmoid(z)的输出结果是一个与z有相同维度的向量。 |