《深度学习入门——基于python的理论与实现》读书笔记(四)

上一章介绍神经网络的组成。神经网络是由神经元连接而成(形成输入层、隐藏层、输出层的层结构),神经元是使用了sigmoid(或ReLU)的感知机。

这一章介绍神经网路的学习。神经网络学习,其主要思想是,先为各层参数(模仿生物概念说,轴突强度(边权重,一层当中每个神经元的各个边权重组成该层的边权重矩阵W)和敏感度(激活阈值,由该层各神经元的阈值组成))设置一个随机的初始值,称之为初始网络。让初始网络对输入数据给出一个预测,因为是随机产生的网络,它的初始预测结果和标准答案(目标,监督,标记)相比一般相差较大,即,准确度很低。

如何提高准确度呢?数据驱动的方法的思路是,一边调节网络参数,一边观察预测结果和正确结果的差距,使参数向着能使差距减小的方向移动。要使这种调节参数的过程自动化,我们计算损失函数(一个自定义的,反映预测值与正确值差距的函数,常用的有均方误差和交叉熵误差)对每个参数的导数,并据此迭代地调节各个参数。

从数据中学习

如何识别数字‘5’,即,如何设计一种算法,输入数字‘5’的图像(比如,用灰度格式保存,读入内存的就是一个(也许是一维的)浮点数数组。你也许会认为,由于图像是方形的,所以必须以灰度矩阵的形式输入。但是,可能是由于展平操作没有造成关键信息的丢失,我们的神经网络可以适应这种变化),输出一个整型数字表示预测结果?

第一种方法

非数据驱动方法

第二种方法

上图展示了三种方案。其中,第二种和第三种是数据驱动的机器学习方法。第二种方法,为了利用分类器,需要把输入的图像映射到一个样本空间中,这个映射操作依赖于‘人想到的特征量’。也就是说,为了顺利使用分类器(笔记(一)中的感知机就是一种简单的线性分类器,它把二维坐标平面分成两块)分类,我们要先把图像映射为某维度样本空间中的一个点。能不能直接把每一像素点的灰度值当作一维(这时的映射就是恒等映射),在全灰度图像空间中分类呢?不好,那样牵扯的维度太多,其中很多维度不含有关键信息,分类效果不好。换句话说,这样直接使用恒等映射,相当于(算法)认为每个像素点都是同等重要的。结合生活体验,我们知道这是不正确的,因为我们甚至可以在模糊或者残破的字迹中辨认数字,不是所有的像素点都同样重要。

所以我们需要某种特征量,反映待学习事物的关键特征,去除无关(甚至干扰)信息。这种特征量是宝贵的,往往需要专家结合数学、物理知识才能发明出来。有了(优质的、反映与待解决问题最为相关信息的)特征量之后,我们使用分类器就可以获得优质的结果。

第三种方法

深度学习有时也称为端到端学习。所谓端到端,是从原始数据到目标结果的意思。神经网络在理论上可以拟合任意函数,其出色的适应能力让它可以从任意形式的数据中学习。通过参数迭代,重要信息的连接会被加强,无关信息的连接会被减弱,就像生物的神经网络一样。

训练数据和测试数据

机器学习中,一般将数据分为训练数据和测试数据。神经网络拟合训练数据,如果在训练数据上表现好,在测试数据上表现不好,则很可能出现了过拟合的现象。但从根本上说,模型的泛化能力依赖于训练数据的量(基本上越多越好),以及所选取的训练数据能不能反映真实世界中的总体(样本的代表性越强越好)。将手头上的数据分为训练数据和测试数据,只是抵御过拟合的有效实践。

损失函数

典型损失函数

损失函数反映预测值与正确值之间的差距。符合要求的函数很多,例如,

均方误差

                                                 E=\frac{1}{2}\sum_k(y_k-t_k)^2

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

交叉熵误差(来自信息论)

                                                 E=-\sum_kt_klogy_k

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

delta防止出现log(0): 未定义

损失函数的关键

由于我们的方法是利用损失函数对每个参数的导数调节参数,损失函数必须对每个参数的调节有指导作用。有一些函数就没有指导作用,例如,阶跃函数对它的所有参数的导数要么是零要么是无穷,即,参数的微小改变对阶跃函数的值要么根本没有影响,要么使其瞬间跳跃——导数值对调参起不到指导作用,不知道哪个方向是使损失函数减小的方向。

利用梯度更新参数的代码,梯度下降算法,

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

学习算法的实现

import numpy as np
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet

(x_train, t_train), (x_test, t_test) = \ load_mnist(normalize=True, one_hot_
laobel = True)

train_loss_list = []

# 超参数
iters_num = 10000
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1

network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)

for i in range(iters_num):
    # 获取mini-batch
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]

    # 计算梯度
    grad = network.numerical_gradient(x_batch, t_batch)

    # 更新参数
    for key in ('W1', 'b1', 'W2', 'b2'):
        network.params[key] -= learning_rate * grad[key]

    # 记录学习过程
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)

小结

首先,为了能顺利进行神经网络的学习,我们导入了损失函数这个指标。以这个损失函数为基准,找出使它的值达到最小的权重参数,就是神经网络学习的目标。为了找到尽可能小的损失函数值,我们介绍了使用函数斜率的梯度法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值