内容简介:在这节中,我们将学习有关向量化的内容。无论你是用Ocatve,还是别的语言,比如MATLAB或者你正在用Python、NumPy 或Java、C、C++,所有这些语言都具有内置的,容易阅读和获取的各种线性代数库,它们通常写得很好,已经经过高度优化,通常是数值计算方面的博士或者专业人士开发的。而让我们来看一些例子:这是一个常见的线性回归假设函数:h
在这节中,我们将学习有关向量化的内容。无论你是用Ocatve,还是别的语言,比如MATLAB或者你正在用 Python 、NumPy 或 Java 、C、C++,所有这些语言都具有内置的,容易阅读和获取的各种线性代数库,它们通常写得很好,已经经过高度优化,通常是数值计算方面的博士或者专业人士开发的。而 当你实现机器学习算法时,如果你能好好利用这些线性代数库,或者数值线性代数库,并联合调用它们 ,而不是自己去做那些函数库可以做的事情。如果是这样的话,那么通常你会发现:首先,这样更有效,也就是说运行速度更快,并且更好地利用你的计算机里可能有的一些并行硬件系统等等;其次,这也意味着你可以用更少的代码来实现你需要的功能。因此,实现的方式更简单,出错的可能性也就越小。举个具体的例子:与其自己写代码做矩阵乘法。如果你只在Octave中输入a乘以b,它会利用一个非常有效的做法,计算两个矩阵相乘。有很多例子可以说明,如果你用合适的向量化方法来实现,你的代码就会简单得多,也有效得多。
让我们来看一些例子:这是一个常见的线性回归假设函数:h θ (x) = Σθ j x j 。如果你想要计算h θ (x),注意到右边是求和,那么你可以自己计算 j=0 到 j=n 的和。但换另一种方式来想想, 把h θ (x)看作θ T X ,那么你就可以写成两个向量的内积,其中θ就是θ 0 ,θ 1 ,θ 2 。如果你有两个特征量,如果n=2,并且如果你把x看作x 0 、x 1 、x 2 ,这两种思考角度,会给你两种不同的实现方式。
下面是未向量化的代码。未向量化的意思是没有向量化。
首先,我们初始化变量prediction的值为0.0,而这个变量prediction的最终结果就是h θ (x),然后我要用一个for 循环,j 从1取值到n+1,变量prediction每次就通过自身加上θ j x j 的值,这个就是算法的代码实现。顺便我要提醒一下,之前的向量我用的下标是0,所以我有θ 0 ,θ 1 ,θ 2 ,但因为 MATLAB的下标从1开始 ,在MATLAB 中θ 0 可能会用θ 1 来表示,这些元素最后就会变成θ 1 ,θ 2 ,θ 3 表示,因为MATLAB中的下标从1开始,这就是为什么这里我的for循环,j从1取值到n+1,而不是从0取值到n。这是一个未向量化的代码实现方式,我们用一个for循环对n个元素进行加和。
作为比较,接下来是向量化的代码实现:
你把x和θ看作向量,而你只需要令变量prediction等于θ T X,你就可以这样计算。与其写所有这些for循环的代码,你只需要一行代码,这行代码就是利用Octave 的高度优化的数值线性代数算法来计算x和θ这两个向量的内积,这样会使代码更简单,运行起来也将更加高效。这就是Octave 所做的而向量化的方法,在其他编程语言中同样可以实现。
让我们来看一个C++ 的例子:
这是未向量化的代码。同样地,也是先初始化一个变量,然后再利用for循环。
下面是向量化的代码实现:
与此相反,使用较好的C++数值线性代数库,你可以写出像这样的代码,因此取决于你的数值线性代数库的内容。你或许有个C++对象:向量θ和一个C++对象:向量x。你只需要在C++中将两个向量相乘。根据你所使用的数值和线性代数库的使用细节的不同,你最终使用的代码表达方式可能会有些许不同,但是通过一个库来计算内积,你可以得到一段更简单、更有效的代码。
现在,让我们来看一个更为复杂的例子,这是线性回归算法梯度下降的更新规则:我只是用θ 0 ,θ 1 ,θ 2 来写方程,假设我们有两个特征量,所以n=2,这些都是我们需要对θ 0 ,θ 1 ,θ 2 来进行更新,这些都应该是同步更新。
实现这三个方程的方法就是使用一个for循环,让 j 等于0、1、2来更新对象θ j 。
但让我们用向量化的方式来实现,看看我们是否能够有一个更简单的方法,看看能不能一次实现这三个方程。让我们来看看怎样能压缩成一行向量化的代码来实现。 思路如下:我打算把θ看做一个向量,然后我用θ-α 乘以某个别的向量δ 来更新θ。这里的δ等于(1/m)Σ(h θ (x i )-y i )x i 。
让我解释一下是怎么回事:我要把θ看做一个n+1维向量,α是一个实数,δ是一个向量。
所以这个减法运算是一个向量减法,因为αδ是一个向量,所以θ更新为θ-αδ。那么向量δ是什么呢?
其实δ代表的就是红框框起来的内容。具体地说,δ是一个n+1维向量。向量δ的第一个元素就等于绿框框起来的内容。
认真看一下计算δ的正确方式。
前面是一个实数,后面是一个n+1维向量。然后再求和。
实际上,如果你要解下面这个方程,我们为了向量化这段代码,我们会令u = 2v +5w因此,我们说向量u等于2乘以向量v加上5乘以向量w。
用这个例子说明,如何对不同的向量进行相加,这里的求和是同样的道理。在这个求和公式中,只是一个实数乘以一个向量x 1 ,就像上面的2乘以向量v。然后再加上实数乘以一个向量x 2 ,就像上面的5乘以向量w。以此类推,再加上许多项实数乘以向量。这就是为什么这一整个是一个向量δ的原因。具体而言,如果n=2,那么δ就由三项相加而组成。这就是为什么根据θ-αδ更新θ的时候可以实现同步更新。
这就是为什么我们能够向量化地实现线性回归。所以,保证你确实能理解上面的步骤。如果你实在不能理解它们数学上等价的原因,你就直接实现这个算法,也是能得到正确答案的,你仍然能实现线性回归算法。如果你能弄清楚为什么这两个步骤是等价的,那我希望你可以对向量化有一个更好的理解。
如果你在实现线性回归的时候,使用一个或两个以上的特征量。有时我们使用几十或几百个特征量来计算线性回归,当你使用向量化地实现线性回归时,通常运行速度就会比你以前用你的for循环快的多。 因此使用向量化实现方式,你应该是能够得到一个高效得多的线性回归算法。 而当你向量化我们将在之后的课程里面学到的算法,这会是一个很好的技巧,无论是对于Octave 或者一些其他的语言,如C++、Java 来让你的代码运行得更高效。
最后附上有中文字幕视频的链接:https://www.bilibili.com/video/BV164411b7dx/?p=31
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 矢量语义(vector semantics)
- Android 矢量图详解
- 攻击云计算环境的8种攻击矢量
- 【译】了解 Android 的矢量图片格式:VectorDrawable
- Clojure – 从散列图矢量中提取值
- react中优雅使用svg矢量图
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
嵌入式系统开发之道
2011-12 / 69.00元
《嵌入式系统开发之道:菜鸟成长日志与项目经理的私房菜》用平易朴实的语言,以一个完整的嵌入式系统的开发流程为架构,通过一位“菜鸟”工程师与项目经理的诙谐对话,故事性地带出嵌入式系统概念及开发要素,并点出要成为一名称职的嵌入式系统工程师,在实际工作中所必须具备的各项知识及技能。 《嵌入式系统开发之道:菜鸟成长日志与项目经理的私房菜》可以分为三大部分:第1、3、4、17、18、19章和附录D为嵌入......一起来看看 《嵌入式系统开发之道》 这本书的介绍吧!