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

小鸡
阅读692 喜欢3 算法 更新2019-5-20

这里所说的“学习”是指从训练数据中自动获取最优权重参数的过程。为了使神经网络能进行学习,将导入损失函数这一指标。而学习的目的就是以该损失函数为基准,找出能使它的值达到最小的权重参数。为了找出尽可能小的损失函数的值,将使用函数倾斜的梯度法

对于线性可分问题,感知机是可以利用数据自动学习的。 根据“感知机收敛定理”,通过有限次数的学习,线性可分问题是可 解的。但是,非线性可分问题则无法通过(自动)学习来解决

机器学习和深度学习

机器学习先从数据集中提取特征量,再用机器学习技术学习这些特征量模式,这里所说的“特征量”是指可以 从输入数据(输入图像)中准确地提取本质数据(重要的数据)的转换器。图像的特征量通常表示为向量的形式。在计算机视觉领域,常用的特征量包括SIFT、SURF和HOG等。使用这些特征量将图像数据转换为向量,然后对转换后的向量使用机器学习中的SVM、KNN等分类器进行学习。

但是 需要注意的是,将图像转换为向量时使用的特征量仍是由人设计的。对于不同的问题,必须使用合适的特征量(必须设计专门的特征量)。比如,为了区分狗的脸部,人们需要考虑与用于识别5的特征量不同的其他特征量。也就是说,即使使用特征量和机器学习的方法,也需要针对 不同的问题人工考虑合适的特征量。

神经网络直接学习图像本身。在利用特征量和机器学习的方法中,特征量仍是由人工设计的,而在神经网络中,连图像中包含的重要特征量也都是由机器来学习的。


训练数据集和测试数据集

机器学习中,一般将数据分为训练数据和测试数据两部分来进行学习和 实验等。首先,使用训练数据进行学习,寻找最优的参数;然后,使用测试 数据评价训练得到的模型的实际能力。

为什么需要将数据分为训练数据和测试数据呢?

因为机器学习追求的是模型的泛化能力为了正确评价模型的泛化能力,就必须划分训练数据和测试数据。**另外,训练数据也可以称为监督数据。 **

什么是泛化能力?

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

比如,在识别手写数字的问题 中,泛化能力可能会被用在自动读取明信片的邮政编码的系统上。此时,手 写数字识别就必须具备较高的识别“某个人”写的字的能力。注意这里不是“特定的某个人写的特定的文字”,而是“任意一个人写的任意文字”。如果系统 只能正确识别已有的训练数据,那有可能是只学习到了训练数据中的个人的 习惯写法。

过拟合

仅仅用一个数据集去学习和评价参数,是无法进行正确评价的。 这样会导致可以顺利地处理某个数据集,但无法处理其他数据集的情况。只对某个数据集过度拟合的状态称为过拟合(over fitting)。避免 过拟合也是机器学习的一个重要课题。

损失函数

例子:生活中对于幸福感的衡量,一般的人可能会给出诸 如“还可以吧”或者“不是那么幸福”等笼统的回答,如果有人说幸福感为9.8,可能就无法理解了。因为他用一个数值指标来 评判自己的幸福程度。

实际上神经网络的学习也在做同样的事情。神经网络的学习通过某个指标表示现在的状态。然后,以这个指标为基准,寻找最优权重参数。和刚刚那位以幸福指数为指引寻找“最优人生”的人一样,神经网络以某个指标为线索寻找最优权重参数。神经网络的学习中所用的指标称为损失函数(lossfunction)。这个损失函数可以使用任意函数, 但一般用均方误差交叉熵误差等。

均方误差


y数组表示该数字为0~9的可能性,t为监督数据,将正确解标签设为1,其他均设为0。这里,标签“2”为1, 表示正确解是“2”。将正确解标签表示为1,其他标签表示为0的表示方法称one-hot表示

用python计算上述均方误差

def mean_squared_error(y, t): 
return 0.5 * np.sum((y-t)**2)

下面使用两组测试用例,可以看出第二组的均方误差比较大




交叉熵误差

交叉熵误差也经常被用来做损失函数,它的方程如下



def cross_entropy_error(y, t):
mini= 1e-7
return -np.sum(t * np.log(y + mini))

这里的 log()函数里面加了个极小值 mini 是为了避免出现 log(0) 影响后续计算


Mini-batch 学习

机器学习使用训练数据集进行学习,就是针对训练数据计算损失函数,找出该值尽可能小的参数。而前面的损失函数考虑的都是单个数据,但是实际项目中的训练数据集可能上万或者上千万,这时就要求所有训练数据的损失函数的总和。

比如交叉熵的方程就要改写为


但是,如果以全部数据为对象 求损失函数的和,则计算过程需要花费较长的时间。再者,如果遇到大数据, 数据量会有几百万、几千万之多,这种情况下以全部数据为对象计算损失函 数是不现实的。

解决方法:从全部数据中选出一批数据(称为mini-batch,小批量)然后对每个mini-batch进行学习。这种学习方式称为 mini-batch学习

随机抽取n笔数据的方法——使用NumPynp.random.choice()函数
使用np.random.choice()可以从指定的数字中随机选择想要的数字。比如, np.random.choice(60000, 10)会从0到59999之间随机选择10个数字


那么从训练数据集中随机选取10个数据,可以写为


上面可以看出,numpy数组可以使用另一个“下标数组”将其相应位置元素提取出来作为一个新数组x_batch =x_train[batch_mask]

使用mini-batch学习计算出来值的并不等于整体的输出值,但是可以作为近似值来作为参考

有点像迭代

mini-batch版交叉熵误差的实现

import numpy as np
def cross_entropy_error(y, t):
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
batch_size = y.shape[0]
return -np.sum(t * np.log(y + 1e-7)) / batch_size

如果输入维度是一维的话需要改变形状,当输入为mini-batch时,用除于batch的个数进行正规化,计算单个数据的平均交叉熵。

如果监督数据时标签形式(非one-hot表示,而是像“2”“7”这样的 标签)时,交叉熵误差可通过如下代码实现。

def cross_entropy_error(y, t): 
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
batch_size = y.shape[0]
return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size

np.arange(batch_size) 会生成一个长度为batch_size的内容为数字0~batch-size的数组,
所以y[ np.arange(batch_size), t ]是数组y[0,t[0]]y[1,t[1]]y[2,t[2]]. . .而 y 是个batch_size维数组,y[k,t[k]] 对应着输出层的第k个神经元的正确值标签的概率

比如有输出层的 y[5] = [0.01, 0.9, 0.5, 0.05, 0.05, 0.1, 0.1, 0.03, 0.07, 0.1]
该神经元对应的正确值为2,即t[5] = 2

那么,y[5,2] = 0.5,也就是该正确值的概率为0.5

设定损失函数的意义

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

此时,对该权重参数的损失函数求导,如果导数的值为负,通过使该权 重参数向正方向改变,可以减小损失函数的值;反过来,如果导数的值为正, 则通过使该权重参数向负方向改变,可以减小损失函数的值。

在进行神经网络的学习时,不能将识别精度作为指标。因为如果以 识别精度为指标,则参数的导数在绝大多数地方都会变为0

例子:假设某个神经网络正 确识别出了100笔训练数据中的32笔,此时识别精度为32%。如果以识别精 度为指标,即使稍微改变权重参数的值,识别精度也仍将保持在32%,即微小的改动没有让识别精度发生变化。那么这个点的导数将会为0,而导数为0会停止神经网络的学习。

而如果把损失函数作为指标,则当前损 失函数的值可以表示为0.92543 … 这样的值。并且,如果稍微改变一下参数 的值,对应的损失函数也会像0.93432 … 这样发生连续性的变化。便可以使参数往导数相反方向梯度下降

作为激活函数的阶跃函数也有同样的情况。如果使用阶跃函数作为激活函数,神经网络的学习将无法进行。阶跃函数的导数在绝大多数地方(除了0以外的地方)均为0。 也就是说,如果使用了阶跃函数,那么即便将损失函数作为指标,参数的微小变化也会被阶跃函数抹杀,导致损失函数的值不会产生任何变化。而sigmoid函数,不仅函数的输出(竖轴的值)是连续变化的,曲线的斜率(导数)也是连续变化的。也就是说,sigmoid函数的导数在任何地方都不为0。这对神经网络的学习非常重要。得益于这个斜率不会为0的性质,神经网络的学 习得以正确进行。


:本文为斋藤康毅的《深度学习入门:基于Python的理论与实现》片段摘抄与学习笔记