网络知识 娱乐 读书笔记-深度学习入门-(16)

读书笔记-深度学习入门-(16)

我们尝试用数学式来表示梯度法,如下图所示:


读书笔记-深度学习入门-(16)

数学式来表示梯度法

式4.7 中表示更新量,在神经网络的学习中,称为学习率(learning rate).学习率决定在一次学习中,应该学习多少,以及在多大程度上更新参数。

式4.7式表示更新一次的式子,这个步骤会反复执行。也就是说,每一步都按式4.7更新变量的值,通过反复执行此步骤,逐渐减小函数值,虽然这里只展开了有两个变量时的更新过程,但是即使增加变量的数量,也可以通过类似的式子(各个变量的偏导数)进行更新。

学习率需要事先确定为某个值,比如0.01 或 0.001。一般而言,这个值过大或过小,都无法抵达一个“好的位置”。在神经网络的学习中,一般会一边改变学习率的值,一边确认学习是否正确进行了。


读书笔记-深度学习入门-(16)


下面,我们用python来实现梯度下降法。如下所示,这个实现很简单。

读书笔记-深度学习入门-(16)

参数f是要进行最优化的函数,init_x是初始值,lr是学习率(learning rate),step_num是梯度法的重复次数。numerical_gradient(f,x)会求函数的梯度,用该梯度乘以学习率得到的值进行更新操作,由step_num制定重复的次数。

使用这个函数可以求函数的极小值,顺利的话,还可以求函数的最小值,下面,我们就来尝试解决下面这个问题。

问题:请用梯度法求f(x0+x1) = x0^2+x1^2 的最小值。

读书笔记-深度学习入门-(16)

这里,设初始值为(-3.0,4.0),开始使用梯度法寻找最小值。最终的结果是

(-6.1e-10,8.1e-10),非常接近(0,0)。实际上,真的最小值就是(0,0),所以通过梯度法我们基本得到了正确结果。如果用图来表示梯度法的更新过程,则如下图所示。可以发现,原点处是最低的地方,函数的取值一点点在向其靠近。这个图的源代码在ch04/gradient_method.py中,(但gradient_method.py不显示表示等高线的虚线)

读书笔记-深度学习入门-(16)

f(x0,x1) = x0^2 + x1^2的梯度法的更新过程:虚线是函数的等高线

前面说过,学习率过大或者过小都无法得到好的结果,我们来做个实验验证一下。


读书笔记-深度学习入门-(16)

实验结果表明,学习率过大的话,会发散成一个很大的值;反过来,学习率过小的话,基本上没怎么更新就结束了。也就是说,设定合适的学习率是一个很重要的问题。

像学习率这样的参数成为超参数,这是一种和神经网络的参数(权重和偏置)性质不同的参数。相对于神经网络的权重参数是通过训练数据和学习算法自动获得的,学习率这样的超参数则是人工设定的,一般来说,超参数需要尝试多个值,以便找到一种可以使学习顺利进行的设定。

gradient_method.py

# coding: utf-8nimport numpy as npnimport matplotlib.pylab as pltnfrom gradient_2d import numerical_gradientnnndef gradient_descent(f, init_x, lr=0.01, step_num=100):n x = init_xn x_history = []nn for i in range(step_num):n x_history.append( x.copy() ) nn grad = numerical_gradient(f, x)n x -= lr * gradnn return x, np.array(x_history)nnndef function_2(x):n return x[0]**2 + x[1]**2nninit_x = np.array([-3.0, 4.0]) nnlr = 0.1nstep_num = 20nx, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)nnplt.plot( [-5, 5], [0,0], '--b')nplt.plot( [0,0], [-5, 5], '--b')nplt.plot(x_history[:,0], x_history[:,1], 'o')nnplt.xlim(-3.5, 3.5)nplt.ylim(-4.5, 4.5)nplt.xlabel("X0")nplt.ylabel("X1")nplt.show()

gradient_method.py 运行 效果图:


读书笔记-深度学习入门-(16)

plt.plot( [-5, 5], [0,0], '--b') 从(-5,0) 到(5,0) 画一条线,用"--"虚线相连,选择蓝色。

plt.plot( [0,0], [-5, 5], '--b') 从(0,-5) 到(0,5) 画一条线,用"--"虚线相连,选择蓝色。

plt.plot(x_history[:,0], x_history[:,1], 'o') ,打点,用圆圈做标识,去x_history[] 数组中的第一维和第二维

参考:https://blog.csdn.net/sinat_36219858/article/details/79800460

另外,X[:,0]是numpy中数组的一种写法,表示对一个二维数组,取该二维数组第一维中的所有数据,第二维中取第0个数据。X[0,:]使用类比前者。

x.copy() 把数组拷贝给某个队列中。

读书笔记-深度学习入门-(16)


gradient_2d.py

def _numerical_gradient_no_batch(f, x):nh = 1e-4 # 0.0001ngrad = np.zeros_like(x)nnfor idx in range(x.size):ntmp_val = x[idx]nx[idx] = float(tmp_val) + hnfxh1 = f(x) # f(x+h)nnx[idx] = tmp_val - h nfxh2 = f(x) # f(x-h)ngrad[idx] = (fxh1 - fxh2) / (2*h)nnx[idx] = tmp_val # 値を元に戻すnnreturn gradnnndef numerical_gradient(f, X):nif X.ndim == 1:nreturn _numerical_gradient_no_batch(f, X)nelse:ngrad = np.zeros_like(X)nnfor idx, x in enumerate(X):ngrad[idx] = _numerical_gradient_no_batch(f, x)nnreturn grad

看到page106