Numpy Gradient - 神经网络的下降优化器
在微分学中,函数的导数告诉我们输出变量在输入变量中的微小微调有多少变化。这个想法也可以扩展到多变量函数。本文展示了使用 NumPy 实现梯度下降算法。这个想法很简单——从一个任意的起点开始,向最小值(即梯度值的 -ve)移动,然后返回一个接近最小值的点。
GD() 是用于此目的的用户定义函数。它采用以下参数:
- 梯度是一个函数,它也可以是一个Python可调用对象,它接受一个向量并返回我们试图最小化的函数的梯度。
- start是我们赋予函数的任意起点,它是一个独立的变量。它也可以是一个列表,用于多变量的 Numpy 数组。
- learn_rate控制向量更新的幅度。
- n_iter是操作应该运行的迭代次数。
- tol是指定每次迭代中最小移动的公差级别。
下面给出了产生所需功能的实现。
例子:
Python3
import numpy as np
def GD(f, start, lr, n_iter=50, tol=1e-05):
res = start
for _ in range(n_iter):
# graident is calculated using the np.gradient
# function.
new_val = -lr * np.gradient(f)
if np.all(np.abs(new_val) <= tol):
break
res += new_val
# we return a vector as the gradient can be
# multivariable function. if the function has 1
# dependent variable then it returns a scalar value.
return res
# Example 1
f = np.array([1, 2, 4, 7, 11, 16], dtype=float)
print(f"The vector notation of global minima:{GD(f,10,0.01)}")
# Example 2
f = np.array([2, 4], dtype=float)
print(f'The vector notation of global minima: {GD(f,10,0.1)}')
Python3
if np.all(np.abs(new_val) <= tol):
break
Python3
import numpy as np
def GD(f, start, lr, n_iter=50, tol=1e-05):
res = start
for _ in range(n_iter):
# gradient is calculated using the np.gradient function.
new_val = -lr * np.gradient(f)
if np.all(np.abs(new_val) <= tol):
break
res += new_val
# we return a vector as the gradient can be multivariable function.
# if the function has 1 dependent variable then it returns a scalar value.
return res
f = np.array([2, 4], dtype=float)
# low learing rate doesn't allow to converge at global minima
print(f'The vector notation of global minima: {GD(f,10,0.001)}')
输出:
The vector notation of global minima:[9.5 9.25 8.75 8.25 7.75 7.5 ]
The vector notation of global minima: [2.0539126e-15 2.0539126e-15]
让我们详细看看这个函数中使用的相关概念。
公差等级应用
下面的代码行使 GD() 能够提前终止并在 n_iter 完成之前返回,如果更新小于或等于容差水平,当我们达到局部最小值或增量运动的鞍点时,这特别加快了过程由于非常低的梯度而非常慢,因此它加快了收敛速度。
蟒蛇3
if np.all(np.abs(new_val) <= tol):
break
学习率使用(超参数)
- 学习率是一个非常重要的超参数,因为它会影响梯度下降算法的行为。例如,如果我们将学习率从 0.2 更改为 0.7,我们会得到另一个非常接近 0 的解,但是由于学习率很高,x 的变化很大,即它多次通过最小值,因此它振荡在归零之前。这种振荡增加了整个算法的收敛时间。
- 小的学习率会导致收敛缓慢,并且如果迭代次数限制很小,则情况会更糟,那么算法甚至可能在找到最小值之前就返回。
下面给出了一个例子来说明学习率如何影响结果。
例子:
蟒蛇3
import numpy as np
def GD(f, start, lr, n_iter=50, tol=1e-05):
res = start
for _ in range(n_iter):
# gradient is calculated using the np.gradient function.
new_val = -lr * np.gradient(f)
if np.all(np.abs(new_val) <= tol):
break
res += new_val
# we return a vector as the gradient can be multivariable function.
# if the function has 1 dependent variable then it returns a scalar value.
return res
f = np.array([2, 4], dtype=float)
# low learing rate doesn't allow to converge at global minima
print(f'The vector notation of global minima: {GD(f,10,0.001)}')
输出:
[9.9 9.9]
算法返回的值甚至不接近 0。这表明我们的算法在收敛到全局最小值之前返回。