梯度下降算法可以求极值,它将逼近极值的过程变成了一个可操作的step by step的过程。这是最重要的。本文不谈梯度下降算法的细节,这些随便百度,谷歌,知乎一下就知道了,最好的办法是看一本教科书。本文谈一下我对这种算法的认知和态度。
以一元函数 f(x) 为例,画图它的曲线,下图展示了梯度下降的过程:
从初始点 x0 开始,逐步的迭代求 x1,x2,x3... ,进而求出 y0,y1,y3... ,当 yn−yn−1 小于某个很小的值的时候,意味着曲线变水平了,那么这里就可能是一个极值。但并不意味着这个极值是全局的,可能是局部的,也可能是个马鞍点…
如果换成 f(x,y) 呢?如果是 f(x,y,z) 呢?导数变偏导数,斜率还是很容易求出来的,梯度的定义呗,很简单。
这些都不是重要的,重要的一点是,你看到上面的过程完全是线性的,这就让计算机实现变得简单了很多。
曾经,有一个问题,很简单的问题,就是编程解一个一元二次方程:
3x2+4x−4=0
在中学时,我们就学过求根公式:
x=−b±b2−4ac−−−−−−−√2a
那么让计算机做这个不是很简单吗:
int a = 3, b = 4, c = -4;
int tmp;
tmp = pow(b, 2);
tmp = tmp - 4*a*c;
tmp = sqrt(tmp);
tmp = (0 - b) + tmp;
tmp = tmp/(2*a);
printf("结果:%d\n", tmp);
这解法有点抖机灵了。但确实有效。
但是,计算机的工作方式不是这样的,那个求根公式是人总结出来的,计算机并不知道这个。计算机会做的就是step by step地线性做事。
计算机需要一步一步的做事,它就是一部机器,假设它对事物没有任何认知是正确的。如果我们拥有数据,那就需要有一种方法对数据进行加工处理,以得到某种规律。问题的关键在于,用怎样一种方法。
这种方法一定要是线性的,简单的,这是计算机的傻逼性质决定的。这种方法包括但不限于,贝叶斯公式,梯度下降算法…
先到这里,未完待续。