深度学习入门 基于python理论和实践读书笔记(七)

第四章 神经网络学习 第四节

第三节的内容是一些数学小知识,在高数课上老师讲过,这里我也不复习了。

梯度

由全部变量的偏导数汇总而成的向量称为梯度。
python实现代码

def numerical_gradient(f ,x):
    h = 1e-4
    grad = np.zeros_like(x)

    for idx in range(x.size):
        #计算f(x+h)
        tmp_val = x[idx]
        x[idx]=tmp_val+h
        fxh1 = f(x)
        # 计算f(x-h)
        x[idx] = tmp_val - h
        fxh2 = f(x)

        grad[idx] = (fxh1-fxh2)/(2*h)
        x[idx] = tmp_val
    return  grad

这个代码把每一个分量的偏导数都计算了,放在和x形状一样的gard中。np.zeros_like(x)表示grad的形状和x一样,只是其中的每一个值都为0.
     书中说到gradient_2d.py文件,我没有仔细看其中的代码,后面又有时间的时候再补充。

梯度法

      机器学习的主要任务就是在学习的时候寻找最优的参数(权重和偏置)。最优参数是就会让我们的损失函数达到最最小。可以通过梯度来寻找函数最小小值。梯度表示各点处的函数值减少最多的方向。因此无法保证梯度所值的方向就是函数的最小值或者真正应该前进的方向。在复杂的函数中,梯度指示的方向基本上不是函数的最小值。
下面还是把书上的那值的定义罗列一下,免得自己忘记。虽然这个高中的时候是学过的,呀呀呀,怀疑自己是不是应该把高中数学再看看了,嘻嘻。
函数极小值:就是在某个范围内最小值,局部最小
函数的最小值:就是整个函数的最小值
函数的鞍点:鞍点是从某个方向上看是极大值,从另一个方向上看则是
极小值的点。
梯度的方向并不一定(可能是极小值或者是鞍点)是指向最小值,但是沿着它的方向尽可能最大限度地减小函数的值。因此,在寻找函数函数的最小的位置的任务中,要以梯度的信息为线索,决定前进的方向。
梯度法要找梯度为0的地方。梯度法中,函数的取值从当前位置沿着梯度方向一定距离,然后在新的地方重新求梯度,在沿着梯度方向前进,反复这个动作。通过不断地沿梯度方向前进,逐渐减小函数值的过程就是梯度法。
寻找最小值的梯度法叫做梯度下降法,寻找最大值的梯度法叫做梯度上升法。不过在深度学习中,梯度法主要指梯度下降法。
用数学公式来表示梯度法
在这里插入图片描述
其中的η表示更新量,称为学习率。学习率决定了在一次学习中应该学习多少,以及在多大成都上更新参数。
在神经网络的学习中,一般会改变学习率的值,一边确认学习是否正确。
python代码

def gradient_descent(f,init_x,lr=0.01,step_num=100):
    x = init_x

    for i in range(step_num):
        grad = numerical_gradient(f,x)
        x -= lr*grad

    return  x

参数f是要进行最优化的函数,init_x是初始值,lr是学习率,step_num是梯度法的重复次数。numerical_gradient(f,x)会求函数的梯度,在前面写过这个函数,所以现在只用调用这个函数就可以了,用该梯度乘以学习率得到的值进行更新操作,由step_num指定重复的次数。画图的gradient_method.py文件里面的代码我就没有再去细看,只是跑了一下。以后等我python熟练一点,再看吧。
      学习率多大和过小都不好,我之前看过一个课程,他说学习率如果过大,第一你很有可能错过你的最值,第二是你的方向错误那么就相当于在错误的道路上越走越远。如果过小的话就会让我们学习的过程过久。像学习率这样子的参数成为超参数。它与权重和偏置这样的参数不一样。权重和偏置这样的参数是通过训练数据和学习算法自动获得的,学习率这样的参数是人工设定的。需要尝试多种值,去找到一种学习孙俪进行的设定。

神经网络的梯度

神经网络的学习也要求有梯度。指的是损失函数关于权重数的梯度。权重用W表示,损失
函数用L表示。此时,梯度可以用αL/αW表示。比如:
在这里插入图片描述
下面先建立一个神经网络,来实现梯度代码,该神经网络只有一层,激活输出层函数用的是softmax。先实现用一个类,计算出网络的的损失,用的是之前写的交叉熵误差函数,t为one-hot形式。
接下来求梯度

def f(W):
    return net.loss(x, t)
dW = numerical_gradient(f, net.W)
print(dW)

就是怎么短短的几句代码,我想了好久呀,嘤嘤嘤。首先它定义一个函数f(W),里面的参数W是一个伪参数,就是它没有在函数体里面使用。其实怎么会梯度呢就是损失函数算出的矩阵和权重矩阵每个位置对应算微分。然后损失函数矩阵的值是根据W变化而变化的,所以说可以看作W是函数f的因变量。终于看懂了,我这个小萌新真的太菜了。
Python中如果定义的是简单的函数,可以使用lambda表示法。使
用lambda的情况下,上述代码可以如下实现。感觉像iOS中的闭包。
f = lambda w: net.loss(x, t)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值