什么是梯度下降:
官方的意思:
- 梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。
这里没有数学公式,没有推导过程,我只是从物理的角度,来说明梯度下降的意思和怎么去用它解决问题。
科学家们发现或者发明了任何东西,肯定都是有意义的,我们要做的不是去问科学家怎么发现它的,而是利用他们的发现去解决我们现在的难题。至于怎么推导,怎么一步一步研究出来,如果都纠结这些东西,我们不就成了科学家,还用敲代码吗?
所以说,我就是一个搬运工。哈哈哈哈~
来说说梯度下降,其实就是下楼梯,下山,等等一样的概念,我们要下山哪一条路是最近的,当然是把自己当成一个球,滚下去是最近的。
当一个二维空间开口向上的曲线,或者三维空间,那么这条路又是在哪呢。
那就是导数,也就是斜率。高中都学过的,所以很简单。
现有来求一个抛物线的最小值。
有这样一个函数:
def f(x):
return 2*x**2-6*x+8
plt.title("f(x)函数的图形:",loc="left")
x = np.linspace(-3,6,num=50)
plt.plot(x,f(x))
假如 我们都不会用公式求最小值了。
那我们用梯度下降试一试
如果要求最小值,那我先给他一个值,然后让他沿着这个点切线的方向往前(或往后)走一小步,这个值会更加接近我们的最小值。无线的走下去吗?当然,不是!
当这个值和之前一步的值之间存在的这个差值无线接近于0(一般会给一个阈值0.0001或者自己定义),我们就不让他往前走了,这个值就是我们定义的最小值。
好了,那么为什么他们的差值会越来越小了?
一般:a = a - f’(x)*step
如果我给的这个点a是在最小值的左边,那么他的导数是个负数(不要问为什么)。a减去一个负数,a会忘右走。
如果这个点a是在最小值的右边,那么他的导数是个正数。a减去一个正数,a会忘左走
他们都是越来越接近最小值。所以每一步(step)不能设置太大(跨越山川了),也不能太小(举步维艰了)
当越接近最小值时,他的斜率就会越平行于x轴。那么相近的两个点在斜率上的y轴差值就会越来越小。所以当这个值小于我们定义的一个值时,我们就认为这个斜率平行于x轴,也就是最低点。
下面用Python来构建一下代码,思想就是我上面的一大段了。
先求导函数:
#f的导函数
def g(x):
return 4*x-6
#计算次数,停止的条件之一
num = 0
#先定义一个随机数为最小值
f_min = np.random.randint(-10,15,size=(1))[0]
#定义一个上一次的最小值
f_last = f_min+0.5
#放置每一次计算的最小值
list_min=[]
list_min.append(f_min)
while True:
if np.abs(f_last-f_min)<0.0001:#第一个退出条件,精度达到
print('最后精度:{:.8f}'.format(np.abs(f_last-f_min)))
break
if num >=3000:#第二个退出条件,次数
print(num)
break
f_last = f_min
f_min = f_min - g(f_min