《Python深度学习》第四章笔记

《Python深度学习》第四章笔记

  • 1.机器学习的四个分支
  • 2.评估机器学习模型
    • 2.1简单的留出验证
    • 2.2 K折验证
    • 2.3带有打乱数据的重复K折验证
  • 3.数据预处理、特征工程、特征学习
    • 3.1神经网络的数据预处理
    • 3.2特征工程
  • 4.降低过拟合以及将泛化能力最大化
    • 4.1减小网络大小
    • 4.2添加权重正则化
    • 4.3添加 dropout 正则化

这里将介绍一种可用于解决任何机器学习问题的通用模板。这一模板将下面说到的概念串在一起:问题定义、评估、特征工程和解决过拟合。

  • 定义问题,收集数据集:你的输入数据是什么?你要预测什么?你面对的是什么类型的问题?
  • 选择衡量成功的指标:对于平衡分类问题(每个类别的可能性相同),精度和接收者操作特征曲线下面积(ROC AUC)是常用的指标。对于类别不平衡的问题,你可以使用准确率和召回率。对于排序问题或多标签分类,你可以使用平均准确率均值(mean average precision)。自定义衡量成功的指标也很常见。
  • 确定评估方法:确定如何衡量当前的进展。
  • 准备数据:该将数据格式化(标准化、特征工程),使其可以输入到机器学习模型中。
  • 开发比基准更好的模型
  • 模型正则化与调节超参数:不断地调节模型、训练、在验证数据上评估(不是测试数据)、再次调节模型,然后重复这一过程,直到模型达到最佳性能。

1.机器学习的四个分支

  • 监督学习,其目标是学习训练输入与训练目标之间的关系。给定一组样本(由人工标注好标签),它可以学会将输入数据映射到已知目标。监督学习主要包括分类和回归。近年来广受关注的深度学习应用几乎都属于监督学习,比如光学字符识别、语音识别、图像分类和语言翻译等。在第三章笔记中提到的二分类、多分类、回归问题都属于监督学习的例子。
  • 无监督学习是指在没有目标的情况下寻找输入数据的有趣变换,其目的在于数据可视化、数据压缩、数据去噪或更好地理解数据中的相关性。在进行监督学习之前,为了更好地了解数据集,对数据进行分析,无监督学习通常是一个必要步骤。无监督学习方法主要包括降维和聚类
  • 自监督学习是监督学习的一个特例,是没有人工标注的标签的监督学习,可以将它看作没有人类参与的监督学习。标签仍然存在,但它们是从输入数据中生成的,通常是使用启发式算法生成的。给定视频中过去的帧来预测下一帧,或者给定文本中前面的词来预测下一个词,都是自监督学习的例子。

无监督学习、监督学习、自监督学习之间的区别有时很模糊,这三个类别更像是没有明确界限的连续体。

  • 强化学习是指智能体接收有关其环境的信息,并学会选择使某种奖励最大化的行动。例如,神经网络会“观察”视频游戏的屏幕并输出游戏操作,目的是尽可能得高分,这种神经网络可以通过强化学习来训练。

分类和回归术语表
样本(sample)或输入(input):进入模型的数据点。
预测(prediction)或输出(output):从模型出来的结果。
目标(target):真实值。对于外部数据源,理想情况下,模型应该能够预测出目标。
预测误差(prediction error)或损失值(loss value):模型预测与目标之间的距离。
类别(class):分类问题中供选择的一组标签。例如,对猫狗图像进行分类时,“狗”和“猫”就是两个类别。
标签(label):分类问题中类别标注的具体例子。比如,如果 1234 号图像被标注为包含类别“狗”,那么“狗”就是 1234 号图像的标签。
真值(ground-truth)或标注(annotation):数据集的所有目标,通常由人工收集。
二分类(binary classification):一种分类任务,每个输入样本都应被划分到两个互斥的类别中。
多分类(multiclass classification):一种分类任务,每个输入样本都应被划分到两个以上的类别中,比如手写数字分类。
多标签分类(multilabel classification):一种分类任务,每个输入样本都可以分配多个标签。举个例子,如果一幅图像里可能既有猫又有狗,那么应该同时标注“猫”标签和“狗”标签。每幅图像的标签个数通常是可变的。
标量回归(scalar regression):目标是连续标量值的任务。预测房价就是一个很好的例子,不同的目标价格形成一个连续的空间。
向量回归(vector regression):目标是一组连续值(比如一个连续向量)的任务。如果对多个值(比如图像边界框的坐标)进行回归,那就是向量回归。
小批量(mini-batch)或批量(batch):模型同时处理的一小部分样本(样本数通常为 8~128)。样本数通常取 2 的幂,这样便于 GPU 上的内存分配。训练时,小批量用来为模型权重计算一次梯度下降更新。

2.评估机器学习模型

机器学习的目的是得到可以泛化(generalize)的模型,即在前所未见的数据上表现很好的模型,而过拟合则是核心难点。首先介绍如何衡量泛化能力,即如何评估机器学习模型。

评估模型的重点是将数据划分为三个集合:训练集、验证集和测试集。在训练数据上训练模型,在验证数据上评估模型。一旦找到了最佳参数,就在测试数据上最后测试一次。为什么不是两个集合:一个训练集和一个测试集?因为,如果基于模型在验证集上的性能来调节模型配置,会很快导致模型在验证集上过拟合,但你关心的是模型在全新数据上的性能,而不是在验证数据上的性能,因此你需要使用一个完全不同的、前所未见的数据集来评估模型,它就是测试集。

选择模型评估方法时,需要注意以下几点。

  • 数据代表性。你希望训练集和测试集都能够代表当前数据。例如,你想要对数字图像进行分类,而图像样本是按类别排序的,如果你将前 80% 作为训练集,剩余 20% 作为测试集,那么会导致训练集中只包含类别 0~7,而测试集中只包含类别 8~9。因此,在将数据划分为训练集和测试集之前,通常应该随机打乱数据
  • 时间箭头。如果想要根据过去预测未来(比如明天的天气、股票走势等),那么在划分数据前你不应该随机打乱数据,因为这么做会造成时间泄露(temporal leak):你的模型将在未来数据上得到有效训练。在这种情况下,你应该始终确保测试集中所有数据的时间都晚于训练集数据
  • 数据冗余。如果数据中的某些数据点出现了两次(这在现实中的数据里十分常见),那么打乱数据并划分成训练集和验证集会导致训练集和验证集之间的数据冗余。从效果上来看,你是在部分训练数据上评估模型,这是极其糟糕的!一定要确保训练集和验证集之间没有交集

2.1简单的留出验证

简单的留出验证是指留出一定比例的数据作为测试集。在剩余的数据上划分训练集和验证集,训练模型后在测试集上评估模型。
《Python深度学习》第四章笔记_第1张图片

这是最简单的评估方法,但有一个缺点:如果可用的数据很少,那么可能验证集和测试集包含的样本就太少,从而无法在统计学上代表数据。如果在划分数据前进行不同的随机打乱,最终得到的模型性能差别很大。

2.2 K折验证

K 折验证(K-fold validation)将数据划分为大小相同的 K 个分区。对于每个分区 i,在剩余的 K-1 个分区上训练模型,然后在分区 i 上评估模型。最终分数等于 K 个分数的平均值。对于不同的训练集 - 测试集划分,如果模型性能的变化很大,那么这种方法很有用。与留出验证一样,这种方法也需要独立的验证集进行模型校正。
《Python深度学习》第四章笔记_第2张图片

2.3带有打乱数据的重复K折验证

如果可用的数据相对较少,而你又需要尽可能精确地评估模型,那么可以选择带有打乱数据的重复 K 折验证(iterated K-fold validation with shuffling)。具体做法是多次使用 K 折验证,在每次将数据划分为 K 个分区之前都先将数据打乱。最终分数是每次 K 折验证分数的平均值。

注意,这种方法一共要训练和评估 P×K 个模型(P是重复次数),计算代价很大。

3.数据预处理、特征工程、特征学习

除模型评估之外,在深入研究模型开发之前,我们还必须解决另一个重要问题:将数据输
入神经网络之前,如何准备输入数据和目标?

现在介绍所有数据领域通用的基本方法。

3.1神经网络的数据预处理

数据预处理的目的是使原始数据更适于用神经网络处理,包括向量化、标准化、处理缺失
值和特征提取。

  • 向量化
    神经网络的所有输入和目标都必须是浮点数张量(在特定情况下可以是整数张量)。无论处理什么数据(声音、图像还是文本),都必须首先将其转换为张量,这一步叫作数据向量化(data vectorization)。例如,在前面文本分类的例子中,开始时文本都表示为整数列表(代表单词序列),然后我们用 one-hot 编码将其转换为 float32 格式的张量。在手写数字分类和预测房价的例子中,数据已经是向量形式,所以可以跳过这一步。
  • 值标准化
    在手写数字分类的例子中,开始时图像数据被编码为 0~255 范围内的整数,表示灰度值。将这一数据输入网络之前,你需要将其转换为 float32 格式并除以 255,这样就得到 0~1 范围内的浮点数。同样,预测房价时,开始时特征有各种不同的取值范围,有些特征是较小的浮点数,有些特征是相对较大的整数。将这一数据输入网络之前,你需要对每个特征分别做标准化,使其均值为 0、标准差为 1。数值相差比较大的数据需要进行归一化
  • 处理缺失值
    你的数据中有时可能会有缺失值。例如在房价的例子中,第一个特征是人均犯罪率。如果不是所有样本都具有这个特征的话,那样你的训练数据或测试数据将会有缺失值。
    一般来说,对于神经网络,将缺失值设置为 0 是安全的,只要 0 不是一个有意义的值。网络能够从数据中学到 0 意味着缺失数据,并且会忽略这个值。
    注意,如果测试数据中可能有缺失值,而网络是在没有缺失值的数据上训练的,那么网络不可能学会忽略缺失值。在这种情况下,你应该人为生成一些有缺失项的训练样本:多次复制一些训练样本,然后删除测试数据中可能缺失的某些特征

3.2特征工程

特征工程(feature engineering)是指将数据输入模型之前,利用你自己关于数据和机器学习算法(这里指神经网络)的知识对数据进行硬编码的变换(不是模型学到的),以改善模型的效果。多数情况下,一个机器学习模型无法从完全任意的数据中进行学习。呈现给模型的数据应该便于模型进行学习。
《Python深度学习》第四章笔记_第3张图片

良好的特征可以让你用更少的数据解决问题。深度学习模型自主学习特征的能力依赖于大量的训练数据。如果只有很少的样本,那么特征的信息价值就变得非常重要。

4.降低过拟合以及将泛化能力最大化

训练数据上的损失越小,测试数据上的损失也越小。这时的模型是欠拟合的,即仍有改进的空间,网络还没有对训练数据中所有相关模式建模。但在训练数据上迭代一定次数之后,泛化不再提高,验证指标先是不变,然后开始变差,即模型开始过拟合。这时模型开始学习仅和训练数据有关的模式,但这种模式对新数据来说是错误的或无关紧要的。

降低过拟合的方法叫作正则化(regularization)。我们先介绍几种最常见的正则化方法。

4.1减小网络大小

防止过拟合的最简单的方法就是减小模型大小,即减少模型中可学习参数的个数(这由层
数和每层的单元个数决定)。

深度学习模型通常都很擅长拟合训练数据,但真正的挑战在于泛化,而不是拟合。使用的模型应该具有足够多的参数,以防欠拟合。在容量过大与容量不足之间要找到一个折中。不幸的是,没有一个魔法公式能够确定最佳层数或每层的最佳大小。你必须评估一系列不同的网络架构(当然是在验证集上评估,而不是在测试集上),以便为数据找到最佳的模型大小。

要找到合适的模型大小,一般的工作流程是开始时选择相对较少的层和参数,然后逐渐增加层的大小或增加新层,直到这种增加对验证损失的影响变得很小

我们在电影评论分类的网络上试一下。
《Python深度学习》第四章笔记_第4张图片如你所见,更小的网络开始过拟合的时间要晚于参考网络(前者 6 轮后开始过拟合,而后
者 4 轮后开始)。
我们再向这个基准中添加一个容量更大的网络。
《Python深度学习》第四章笔记_第5张图片更大的网络只过了一轮就开始过拟合,过拟合也更严重。
更大网络的训练损失很快就接近于零。网络的容量越大,它拟合训练数据(即得到很小的训练损失)的速度就越快,但也更容易过拟合(导致训练损失和验证损失有很大差异)。

4.2添加权重正则化

奥卡姆剃刀原理:如果一件事情有两种解释,那么最可能正确的解释就是最简单的那个,即假设更少的那个。这个原理也适用于神经网络学到的模型:给定一些训练数据和一种网络架构,很多组权重值(即很多模型)都可以解释这些数据。简单模型比复杂模型更不容易过拟合

这里的简单模型是指参数值分布的熵更小的模型(或参数更少的模型)。因此,一种常见的降低过拟合的方法就是强制让模型权重只能取较小的值,从而限制模型的复杂度。这种方法叫作权重正则化(weight regularization),其实现方法是向网络损失函数中添加与较大权重值相关的成本(惩罚)。

这个成本有两种形式:

  • L1 正则化:添加的成本与权重系数的绝对值成正比。
  • L2 正则化(权重衰减):添加的成本与权重系数的平方成正比。

例如向电影评论分类网络中添加 L2 权重正则化:

from keras import regularizers
model = models.Sequential()
model.add(layers.Dense(16, 
#.l2(0.001)该层权重矩阵的每个系数都会使网络总损失增加 0.001 * weight_coefficient_value
						kernel_regularizer=regularizers.l2(0.001),
						activation='relu', 
						input_shape=(10000,)))
model.add(layers.Dense(16, 
						kernel_regularizer=regularizers.l2(0.001),
						activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

《Python深度学习》第四章笔记_第6张图片
如图所示,即使两个模型的参数个数相同,具有 L2正则化的模型(圆点)比参考模型(十字)更不容易过拟合。

4.3添加 dropout 正则化

dropout 是神经网络最有效也最常用的正则化方法之一,对某一层使用 dropout,就是在训练过程中随机将该层的一些输出特征舍弃(设置为 0)。假设在训练过程中,某一层对给定输入样本的返回值应该是向量 [0.2, 0.5, 1.3, 0.8, 1.1]。使用 dropout 后,这个向量会有几个随机的元素变成 0,比如 [0, 0.5, 1.3, 0, 1.1]。

dropout 比率(dropout rate)是被设为 0 的特征所占的比例,通常在 0.2~0.5范围内。测试时该层的输出值需要按 dropout 比率缩小,因为这时比训练时有更多的单元被激活,需要加以平衡。

假设有一个包含某层输出的 Numpy 矩阵 layer_output,其形状为 (batch_size, features)。
训练时,我们随机将矩阵中一部分值设为 0。

layer_output *= np.random.randint(0, high=2, size=layer_output.shape)

测试时,我们将输出按 dropout 比率缩小。这里我们乘以 0.5(因为前面舍弃了一半的单元)。

layer_output *= 0.5

我们向 IMDB 网络中添加两个 Dropout 层,来看一下它们降低过拟合的效果。

model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))

《Python深度学习》第四章笔记_第7张图片

结果如图示,这种方法的性能相比参考网络有明显提高。

你可能感兴趣的:(深度学习,python,人工智能)