目录标题
- 一、概念
- 二、代码实现
- 三、代码测试
- 四、超参影响
一、概念
梯度下降法(Gradient Descent) 是一种用于最小化目标函数的迭代优化算法。核心是沿着目标函数(如损失函数)的负梯度方向逐步调整参数,从而逼近函数的最小值。梯度方向指示了函数增长最快的方向,因此负梯度方向是函数下降最快的方向
具体来说,我们初始找到函数f ( x 1 , x 2 ) f(x_1, x_2)f(x1,x2)的一个点( x 1 , x 2 ) (x_1, x_2)(x1,x2),按下式进行更新:
x 1 ′ = x 1 − η ∂ f ∂ x 1 x_1' = x_1 - \eta \frac{\partial f}{\partial x_1}x1′=x1−η∂x1∂f
x 2 ′ = x 2 − η ∂ f ∂ x 2 x_2' = x_2 - \eta \frac{\partial f}{\partial x_2}x2′=x2−η∂x2∂f
这样就可以沿着负梯度方向,找到一个新的点( x 1 ′ , x 2 ′ ) (x_1', x_2')(x1′,x2′),让函数值更小。
这里的η \etaη表示每次的更新量,在神经网络的学习过程中,就代表了一次学习的步长(一次学习多少、多大程度去更新参数),称为学习率(learning rate)。学习率需要预先设定好,过大或过小都会导致学习效果不佳。
二、代码实现
引用梯度方法numerical_gradient在blog: 深度学习5:神经网络学习2:数值微分,偏导,梯度
importnumpyasnpimportmatplotlib.pyplotaspltfromcommon.gradientimportnumerical_gradient# 定义梯度下降法的函数defgradient_descent(f,init_x,lr=0.01,num_iter=100):x=init_x# 定义列表保存x的变化x_history=[]# 循环迭代foriinrange(num_iter):# 这里是值传递,不能引用传递,不然引用修改,这个历史记录list全都跟着改了x_history.append(x.copy())# 计算梯度 目标函数取一点,计算梯度下降grad=numerical_gradient(f,x)# 更新参数x-=lr*gradreturnx,np.array(x_history)三、代码测试
importnumpyasnpimportmatplotlib.pyplotaspltfromcommon.gradientimportnumerical_gradient# 定义梯度下降法的函数defgradient_descent(f,init_x,lr=0.01,num_iter=100):x=init_x# 定义列表保存x的变化x_history=[]# 循环迭代foriinrange(num_iter):# 这里是值传递,不能引用传递,不然引用修改,这个历史记录list全都跟着改了x_history.append(x.copy())# 计算梯度 目标函数取一点,计算梯度下降grad=numerical_gradient(f,x)# 更新参数x-=lr*gradreturnx,np.array(x_history)# 定义目标函数 f(x1, x2) = x1^2 + x2^2deff(x):returnx[0]**2+x[1]**2if__name__=='__main__':# 1. 定义初始值init_x=np.array([-3.0,4.0])# 2. 定义超参数lr=0.1# 定义过大会左右来回震荡,定义正好临界,竟然不变,下面刚好来回不变num_iter=20# 3. 使用梯度下降法,计算最小值点x,x_history=gradient_descent(f,init_x,lr,num_iter)print("最小值点为:",x)# 画图plt.plot([-5,5],[0,0],'--b')plt.plot([0,0],[-5,5],'--b')plt.scatter(x_history[:,0],x_history[:,1])plt.xlim([-3.5,3.5])plt.ylim([-4.5,4.5])plt.xlabel('x[0]')plt.ylabel('x[1]')#plt.show()plt.savefig('gradient_descent_result.png')四、超参影响
上面测试:当学习率为1,效果如下