看 Andrew Ng 的机器学习课,听得懵懵懂懂,想着自己跑一把吧。没曾想跑出这么多道道来😱
思想很简单:有一坨便便,看起来像便便,闻起来像便便,我们就姑且当它便便吧。
这有 10 个点,看起来挺像在一条直线上的,我们就想知道到底该选哪一条。

选择标准是什么呢?要不就拿「数据点到直线的距离之和」来评判吧:

要是我们能找到这个判别函数J(theta_0, theta_1)
[1]的最小值点,那个点的坐标(theta_0, theta_1)
就是所求直线的待求参数。
接下来的问题是怎么找到它的最小值?我们先把这函数画出来看看吧:

这个函数会在点(-4.96154, 0.134615)
处取得最小值16.4973
[2]。

看起来还不错。但……
但,数学家们不喜欢绝对值函数☠️他们喜欢这款^maximum likelihood:

这函数长这样:

这个 2.0 版函数会在点(-8.64507, 0.161234)
处取得最小值22.3703
。

你能看出哪条直线更好吗?反正我是不能☹️
等等,我们是不是该回到正题——怎么求到判别函数的最小值点——了?!
很简单,我们找到「下山的方向」,跟着走就行了。直到「原地打转」(就是前后脚距离不超过某个预设的值ε
)为止。

至于 α 是什么,Andrew Ng 把它叫做 learning rate,也有的叫它「步长」。其实它还蛮重要的,因为它控制着下山的步子。步子大了,一不小心迈过最小值点了;步子小了,走太慢。
接下来,我们来验证一下这个算法好使不。拿x^2+y^2
来试试,因为它简单,够清楚。

目前看一切挺好,但是当我们把步长调到 1 的时候,它就开始原地打转了,调到 1.1 的时候,开始蹦跶出去了😱

好吧,我终于锲而不舍地画出来了👻

遇到特别陡峭的变态函数怎么办?
首先想到的是:要是新点的判别函数值比前一点的还高,那就调小步长,并且回退。试了下,效果不错。一旦跑反了,还知道回来。

下面的问题是如何让步长自适应变化。不过涉及到优化的问题就有点烦人了,先就这样吧。
最后做个有意思的吧:看看能不能用 linear regression 做个手写识别。
-
首先是去下一个「手写数字库」;
-
预处理下照片:缩小,压扁(拍成一个数组);
-
丢给现成的「线性回归库」做;
直接上代码吧:

毛都跑不出来!!!
网友评论