9

在观看了 Andrew Ng 教授关于 GLM 的讲座后,我正在尝试实现 Softmax 回归算法来解决 K 分类器问题。我以为我理解了他所说的一切,直到最终编写代码来实现 Softmax 回归的成本函数,如下所示:

具有权重衰减的 Softmax 回归的成本函数

我遇到的问题是试图找出一种将其矢量化的方法。我再次认为我了解如何对这样的方程进行矢量化,因为我能够为线性和逻辑回归做到这一点,但是在查看了该公式之后,我被卡住了。

虽然我很想为此找到一个矢量化解决方案(我意识到已经发布了一个类似的问题:Softmax Regression 的矢量化实现),但我更感兴趣的是你们中的任何人是否可以告诉我一种方式(你的方式)有条不紊地将这样的方程转换为矢量化形式。例如,对于那些是 ML 专家或经验丰富的老手,当您第一次阅读文献中的新算法,并看到它们以与上述等式相似的符号编写时,您如何将它们转换为矢量化形式?

我意识到我可能会像那个问莫扎特的学生一样,“你怎么弹得这么好?” 但我的问题只是出于对这种材料变得更好的渴望,并假设并非每个人都生来就知道如何向量化方程,所以肯定有人设计了他们自己的系统,如果是这样,请分享!提前谢谢了!

干杯

4

2 回答 2

2

Octave 附带的帮助文件有以下条目:

19.1 基本向量化

对于一个非常好的初步近似,向量化的目标是编写避免循环并使用整个数组操作的代码。作为一个简单的例子,考虑

 for i = 1:n
   for j = 1:m
     c(i,j) = a(i,j) + b(i,j);
   endfor
 endfor

相比更简单的

 c = a + b;

这不仅更容易编写;它在内部也更容易优化。Octave 将此操作委托给底层实现,除其他优化外,该实现可以使用特殊的向量硬件指令,或者甚至可以并行执行添加。一般来说,如果代码是矢量化的,则底层实现可以更自由地做出假设,以实现更快的执行。

这对于具有“廉价”主体的循环尤其重要。通常只需对最内层循环进行矢量化即可获得可接受的性能。一般的经验法则是矢量化主体的“顺序”应该大于或等于封闭循环的“顺序”。

作为一个不那么琐碎的例子,而不是

 for i = 1:n-1
   a(i) = b(i+1) - b(i);
 endfor

 a = b(2:n) - b(1:n-1);

这显示了一个重要的一般概念,即使用数组进行索引而不是循环索引变量。 索引表达式。还要慷慨地使用布尔索引。如果需要测试一个条件,这个条件也可以写成布尔索引。例如,而不是

 for i = 1:n
   if (a(i) > 5)
     a(i) -= 20
   endif
 endfor

 a(a>5) -= 20;

它利用了 'a > 5' 产生布尔索引的事实。

尽可能使用元素向量运算符以避免循环(运算符,如“.*”和“.^”)。 算术运算。对于简单的内联函数,“vectorize”函数可以自动执行此操作。

-- 内置函数:vectorize (FUN) 通过用 ' 替换所有出现的 ' '、'/' 等来创建内联函数 FUN 的矢量化版本。', '。/', ETC。

 This may be useful, for example, when using inline functions with
 numerical integration or optimization where a vector-valued
 function is expected.

      fcn = vectorize (inline ("x^2 - 1"))
         => fcn = f(x) = x.^2 - 1
      quadv (fcn, 0, 3)
         => 6

 See also:  inline,  formula,
  argnames.

还利用这些元素运算符中的广播来避免循环和不必要的中间内存分配。
广播。

如果可能,请使用内置函数和库函数。内置和编译功能非常快。即使使用 m 文件库函数,它也很有可能已经优化,或者将在未来的版本中进行更多优化。

例如,甚至比

 a = b(2:n) - b(1:n-1);

 a = diff (b);

大多数 Octave 函数在编写时都考虑了向量和数组参数。如果您发现自己编写了一个操作非常简单的循环,那么很可能这样的函数已经存在。以下函数在向量化代码中经常出现:

  • 索引操作

    * find
    
    * sub2ind
    
    * ind2sub
    
    * sort
    
    * unique
    
    * lookup
    
    * ifelse / merge
    
  • 重复

    * repmat
    
    * repelems
    
  • 向量化算术

    * sum
    
    * prod
    
    * cumsum
    
    * cumprod
    
    * sumsq
    
    * diff
    
    * dot
    
    * cummax
    
    * cummin
    
  • 高维数组的形状

    * reshape
    
    * resize
    
    * permute
    
    * squeeze
    
    * deal
    

另请查看来自斯坦福 ML wiki 的这些页面,以获取更多示例指导。

http://ufldl.stanford.edu/wiki/index.php/Vectorization

http://ufldl.stanford.edu/wiki/index.php/Logistic_Regression_Vectorization_Example

http://ufldl.stanford.edu/wiki/index.php/Neural_Network_Vectorization

于 2015-02-16T22:18:30.493 回答
2

这个看起来很难矢量化,因为你在求和中做指数。我假设您正在将 e 提高到任意权力。您可以向量化的是表达式 \sum \sum theta ^2 的第二项,只需确保在 matlab 中使用 .* 运算符在此处输入链接描述 到计算机 \theta ^2

对数的比率的内部项也是如此。\theta ' x^(i) 是可向量化的表达式。

您还可以从记忆化或动态编程技术中受益,并尝试重用 e^\theta' x^(i) 的计算结果。

一般来说,根据我的经验,矢量化的方法是首先让非矢量化实现工作。然后尝试向量化计算中最明显的部分。在每一步都很少调整你的函数,并且总是检查你是否得到与非向量化计算相同的结果。此外,拥有多个测试用例非常有帮助。

于 2012-02-29T16:52:06.183 回答