深度学习入门——神经网络的学习

目录

1.从数据中学习

   训练数据与测试数据

2.损失函数

(1)损失函数的定义

(2)为何要设定损失函数

3.数值微分——利用微小的差分求导数的过程(用数值方法近似求解函数的导数的过程)

(1)导数——表示某个瞬间的变化量

(2)偏导数——有多个变量的函数的导数

4.梯度——由全部变量的偏导数汇总而成的向量


1.从数据中学习

   训练数据与测试数据

       机器学习中,一般将数据分为训练数据测试数据两部分来进行学习和实验等。首先,使用训练数据进行学习,寻找最优的参数(神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数);然后,使用测试数据评价训练得到的模型的实际能力,评价模型的泛化能力。

泛化能力是指处理未被观察过的数据(不包含在训练数据中的数据)的能力。获得泛化能力是机器学习的最终目标。


2.损失函数

(1)损失函数的定义

       损失函数是神经网络中寻找最优权重参数的指标,是表示神经网络性能的“恶劣程度”的指标,即当前的神经网络对监督数据在多大程度上不拟合,在多大程度上不一致。

(2)为何要设定损失函数

       在神经网络的学习中,寻找最优参数(权重和偏置)时,要寻找使损失函数的值尽可能小的参数。为了找到使损失函数的值尽可能小的地方,需要计算参数的导数(确切地讲是梯度),然后以这个导数为指引, 逐步更新参数的值。

       在进行神经网络的学习时,不能将识别精度作为指标。因为如果以识别精度为指标,则参数的导数在绝大多数地方都会变为0。 识别精度对微小的参数变化基本上没有什么反应,即便有反应,它的值也是不连续地、突然地变化。


3.数值微分——利用微小的差分求导数的过程(用数值方法近似求解函数的导数的过程)

(1)导数——表示某个瞬间的变化量

def numerical_diff(f, x):

    h = 1e-4 # 0.0001

    return (f(x+h) - f(x-h)) / (2*h)


例:f(x)=0.01x² + 0.1x

def function_1(x):
    return 0.01*x**2 + 0.1*x
 
import numpy as np
import matplotlib.pylab as plt
 
x = np.arange(0.0,20.0,0.1)
y = function_1(x)
plt. xlabel("x")
plt.ylabel("f(x)")
plt.plot(x,y)
plt.show()
>>> numerical_diff(function_1, 5)
0.1999999999990898
>>> numerical_diff(function_1, 10)
0.2999999999986347

这里计算的导数是f(x)相对于x的变化量,对应函数的斜率。另外, f(x) = 0.01+ 0.1的解析解是0.02x+0.1。因 此,在 = 5 和 = 10处,“真的导数”分别为0.2和0.3。和上面的结果相比,我们发现虽然严格意义上它们并不一致,但误差非常小。实际上,误差小到基本上可以认为它们是相等的。


(2)偏导数——有多个变量的函数的导数

 这个式子可以用Python来实现,如下所示。

def function_2(x):  
     return x[0]**2 + x[1]**2

结果如图4-8所示, 是一个三维图像。

 偏导数和单变量的导数一样,都是求某个地方的斜率。不过,偏导数需要将多个变量中的某一个变量定为目标变量,并将其他变量固定为某个值。

为了将目标变量以外的变量固定到某些特定的值上,我们定义了新函数。然后,对新定义的函数应用了之前的求数值微分的函数,得到偏导数。


4.梯度——由全部变量的偏导数汇总而成的向量

梯度指示的方向是各点处的函数值减小最多的方向。

梯度可以像下面这样来实现。

def numerical_gradient(f, x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x) # 生成和x形状相同的数组
 
    for idx in range(x.size):
        tmp_val = x[idx]
        # f(x+h)的计算
        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

 现在,我们用这个函数实际计算一下梯度。这里我们求点(34)、(02)、(30)处的梯度。

>>> numerical_gradient(function_2, np.array([3.0, 4.0]))
array([ 6., 8.])
>>> numerical_gradient(function_2, np.array([0.0, 2.0]))
array([ 0., 4.])
>>> numerical_gradient(function_2, np.array([3.0, 0.0]))
array([ 6., 0.])

这个梯度意味着什么呢?为了更好地理解,我们把的梯度画在图上。

如图,f(x₀,x₁) = x₀² +x₁²的梯度呈现为有向向量(箭头)。观察图像,我们发现梯度指向函数f(x₀,x₁)的“最低处”(最小值),就像指南针一样,所有的箭头都指向同一点。其次,我们发现离“最低处”越远,箭头越大。

虽然图 4-9 中的梯度指向了最低处,但并非任何时候都这样。实际上,梯度会指向各点处的函数值降低的方向。更严格地讲,梯度指示的方向是各点处的函数值减小最多的方向 。

梯度法

机器学习的主要任务是在学习时寻找最优参数。同样地,神经网络也必须在学习时找到最优参数(权重和偏置)。这里所说的最优参数是指损失函数取最小值时的参数。但是,一般而言,损失函数很复杂,参数空间庞大,我们不知道它在何处能取得最小值。而通过巧妙地使用梯度来寻找函数最小值(或者尽可能小的值)的方法就是梯度法。

 在梯度法中,函数的取值从当前位置沿着梯度方向前进一定距离,然后在新的地方重新求梯度,再沿着新梯度方向前进,如此反复,不断地沿梯度方向前进。像这样,通过不断地沿梯度方向前进,逐渐减小函数值的过程就是梯度法。梯度法是解决机器学习中最优化问题的常用方法,特别是在神经网络的学习中经常被使用。


学习算法的实现

步骤1(mini-batch)

从训练数据中随机选出一部分数据,这部分数据称为mini-batch。我们的目标是减小mini-batch的损失函数的值。

步骤2(计算梯度)

为了减小mini-batch的损失函数的值,需要求出各个权重参数的梯度。

步骤3(更新参数)

将权重参数沿梯度方向进行微小更新。

步骤4(重复)

重复步骤1、步骤2、步骤3。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值