在这节中,咱们将学习有关向量化的内容。不管你是用Ocatve,仍是别的语言,好比MATLAB或者你正在用Python、NumPy 或Java、C、C++,全部这些语言都具备内置的,容易阅读和获取的各类线性代数库,它们一般写得很好,已经通过高度优化,一般是数值计算方面的博士或者专业人士开发的。而当你实现机器学习算法时,若是你能好好利用这些线性代数库,或者数值线性代数库,并联合调用它们,而不是本身去作那些函数库能够作的事情。若是是这样的话,那么一般你会发现:首先,这样更有效,也就是说运行速度更快,而且更好地利用你的计算机里可能有的一些并行硬件系统等等;其次,这也意味着你能够用更少的代码来实现你须要的功能。所以,实现的方式更简单,出错的可能性也就越小。举个具体的例子:与其本身写代码作矩阵乘法。若是你只在Octave中输入a乘以b,它会利用一个很是有效的作法,计算两个矩阵相乘。有不少例子能够说明,若是你用合适的向量化方法来实现,你的代码就会简单得多,也有效得多。算法
让咱们来看一些例子:这是一个常见的线性回归假设函数:hθ(x) = Σθjxj。若是你想要计算hθ(x),注意到右边是求和,那么你能够本身计算 j=0 到 j=n 的和。但换另外一种方式来想一想,把hθ(x)看做θTX,那么你就能够写成两个向量的内积,其中θ就是θ0,θ1,θ2。若是你有两个特征量,若是n=2,而且若是你把x看做x0、x1、x2,这两种思考角度,会给你两种不一样的实现方式。编程
下面是未向量化的代码。未向量化的意思是没有向量化。机器学习
首先,咱们初始化变量prediction的值为0.0,而这个变量prediction的最终结果就是hθ(x),而后我要用一个for 循环,j 从1取值到n+1,变量prediction每次就经过自身加上θjxj的值,这个就是算法的代码实现。顺便我要提醒一下,以前的向量我用的下标是0,因此我有θ0,θ1,θ2,但由于MATLAB的下标从1开始,在MATLAB 中θ0可能会用θ1 来表示,这些元素最后就会变成θ1,θ2,θ3表示,由于MATLAB中的下标从1开始,这就是为何这里个人for循环,j从1取值到n+1,而不是从0取值到n。这是一个未向量化的代码实现方式,咱们用一个for循环对n个元素进行加和。编程语言
做为比较,接下来是向量化的代码实现:ide
你把x和θ看做向量,而你只须要令变量prediction等于θTX,你就能够这样计算。与其写全部这些for循环的代码,你只须要一行代码,这行代码就是利用Octave 的高度优化的数值线性代数算法来计算x和θ这两个向量的内积,这样会使代码更简单,运行起来也将更加高效。这就是Octave 所作的而向量化的方法,在其余编程语言中一样能够实现。函数
让咱们来看一个C++ 的例子:学习
这是未向量化的代码。一样地,也是先初始化一个变量,而后再利用for循环。优化
下面是向量化的代码实现:spa
与此相反,使用较好的C++数值线性代数库,你能够写出像这样的代码,所以取决于你的数值线性代数库的内容。你或许有个C++对象:向量θ和一个C++对象:向量x。你只须要在C++中将两个向量相乘。根据你所使用的数值和线性代数库的使用细节的不一样,你最终使用的代码表达方式可能会有些许不一样,可是经过一个库来计算内积,你能够获得一段更简单、更有效的代码。
如今,让咱们来看一个更为复杂的例子,这是线性回归算法梯度降低的更新规则: 我只是用θ0,θ1,θ2来写方程,假设咱们有两个特征量,因此n=2,这些都是咱们须要对θ0,θ1,θ2来进行更新,这些都应该是同步更新。 3d
实现这三个方程的方法就是使用一个for循环,让 j 等于0、一、2来更新对象θj。
但让咱们用向量化的方式来实现,看看咱们是否可以有一个更简单的方法,看看能不能一次实现这三个方程。让咱们来看看怎样能压缩成一行向量化的代码来实现。思路以下:我打算把θ看作一个向量,而后我用θ-α 乘以某个别的向量δ 来更新θ。这里的δ等于(1/m)Σ(hθ(xi)-yi)xi。
让我解释一下是怎么回事:我要把θ看作一个n+1维向量,α是一个实数,δ是一个向量。
因此这个减法运算是一个向量减法,由于αδ是一个向量,因此θ更新为θ-αδ。那么向量δ是什么呢?
其实δ表明的就是红框框起来的内容。具体地说,δ是一个n+1维向量。向量δ的第一个元素就等于绿框框起来的内容。
认真看一下计算δ的正确方式。
前面是一个实数,后面是一个n+1维向量。而后再求和。
实际上,若是你要解下面这个方程,咱们为了向量化这段代码,咱们会令u = 2v +5w所以,咱们说向量u等于2乘以向量v加上5乘以向量w。
用这个例子说明,如何对不一样的向量进行相加,这里的求和是一样的道理。在这个求和公式中,只是一个实数乘以一个向量x1,就像上面的2乘以向量v。而后再加上实数乘以一个向量x2,就像上面的5乘以向量w。以此类推,再加上许多项实数乘以向量。这就是为何这一整个是一个向量δ的缘由。具体而言,若是n=2,那么δ就由三项相加而组成。这就是为何根据θ-αδ更新θ的时候能够实现同步更新。
这就是为何咱们可以向量化地实现线性回归。因此,保证你确实能理解上面的步骤。若是你实在不能理解它们数学上等价的缘由,你就直接实现这个算法,也是能获得正确答案的,你仍然能实现线性回归算法。若是你能弄清楚为何这两个步骤是等价的,那我但愿你能够对向量化有一个更好的理解。
若是你在实现线性回归的时候,使用一个或两个以上的特征量。有时咱们使用几十或几百个特征量来计算线性回归,当你使用向量化地实现线性回归时,一般运行速度就会比你之前用你的for循环快的多。所以使用向量化实现方式,你应该是可以获得一个高效得多的线性回归算法。而当你向量化咱们将在以后的课程里面学到的算法,这会是一个很好的技巧,不管是对于Octave 或者一些其余的语言,如C++、Java 来让你的代码运行得更高效。
最后附上有中文字幕视频的连接:https://www.bilibili.com/video/BV164411b7dx/?p=31