深度学习基础
目录一、什么是深度学习1 人工智能、机器学习与深度学习1.1人工智能1.2 机器学习1.3 从数据中学习表示1.4 深度学习之“深度”1.5 用三张图理解深度学习的工作原理2 深度学习之前:机器学习简史2.1 概率建模2.2 早期神经网络2.3 核方法2.4 决策树、随机森林与梯度提升机二、神经网络的数学基础1 初识神经网络2 神经网络...
目录
一、什么是深度学习
1 人工智能、机器学习与深度学习
1.1 人工智能
人工智能的简洁定义如下:努力将通常由人类完成的智力任务自动化。因此,人工智能是一个综合性的领域,不仅包括机器
学习与深度学习,还包括更多不涉及学习的方法。在相当长的时间内,许多专家相信,只要程序员精心编写足够多的明确规则来处理知识,就可以实现与人类水平相当的人工智能。这一方法被称为符号主义人工智能(symbolic AI)。虽然符号主义人工智能适合用来解决定义明确的逻辑问题,比如下国际象棋,但它难以给出明确的规则来解决更加复杂、模糊的问题,比如图像分类、语音识别和语言翻译。于是出现了一种新的方法来替代符号主义人工智能,这就是机器学习(machine learning)。
1.2 机器学习
机器学习系统是训练出来的,而不是明确地用程序编写出来的。将与某个任务相关的许多示例输入机器学习系统,它会在这些示例中找到统计结构,从而最终找到规则将任务自动化。
机器学习与数理统计密切相关,但二者在几个重要方面有所不同。不同于统计学,机器学习经常用于处理复杂的大型数据集(比如包含数百万张图像的数据集,每张图像又包含数万个像素),用经典的统计分析(比如贝叶斯分析)来处理这种数据集是不切实际的。因此,机器学习(尤其是深度学习)呈现出相对较少的数学理论(可能太少了),并且是以工程为导向的。这是一门需要上手实践的学科,想法更多地是靠实践来证明,而不是靠理论推导。
1.3 从数据中学习表示
需要以下三个要素来进行机器学习:
- 输入数据点;
- 预期输出的示例;
- 衡量算法效果好坏的方法。衡量结果是一种反馈信号,用于调节算法的工作方式。这个调节步骤就是我们所说的学习。
机器学习模型将输入数据变换为有意义的输出,这是一个从已知的输入和输出示例中进行“学习”的过程。因此,机器学习和深度学习的核心问题在于有意义地变换数据,换句话说,在于学习输入数据的有用表示(representation)——这种表示可以让数据更接近预期输出。
机器学习中的学习指的是,寻找更好数据表示的自动搜索过程。
机器学习的技术定义:在预先定义好的可能性空间中,利用反馈信号的指引来寻找输入数据的有用表示。
1.4 深度学习之“深度”
深度学习是机器学习的一个分支领域:它是从数据中学习表示的一种新方法,强调从连续的层(layer)中进行学习,这些层对应于越来越有意义的表示。“深度学习”中的“深度”指的并不是利用这种方法所获取的更深层次的理解,而是指一系列连续的表示层。数据模型中包含多少层,这被称为模型的深度(depth)。这一领域的其他名称包括分层表示学习(layered representations learning)和层级表示学习(hierarchical representations learning)。
深度学习的技术定义:学习数据表示的多级方法。
1.5 用三张图理解深度学习的工作原理
神经网络中每层对输入数据所做的具体操作保存在该层的权重(weight)中,其本质是一串数字。用术语来说,每层实现的变换由其权重来参数化(parameterize)。权重有时也被称为该层的参数(parameter)。在这种语境下,学习的意思是为神经网络的所有层找到一组权重值,使得该网络能够将每个示例输入与其目标正确地一一对应。
想要控制神经网络的输出,就需要能够衡量该输出与预期值之间的距离。这是神经网络损失函数(loss function)的任务,该函数也叫目标函数(objective function)。损失函数的输入是网络预测值与真实目标值(即你希望网络输出的结果),然后计算一个距离值,衡量该网络在这个示例上的效果好坏。
深度学习的基本技巧是利用这个距离值作为反馈信号来对权重值进行微调,以降低当前示例对应的损失值。这种调节由优化器(optimizer)来完成,它实现了所谓的反向传播(backpropagation)算法,这是深度学习的核心算法。
一开始对神经网络的权重随机赋值,因此网络只是实现了一系列随机变换。其输出结果自然也和理想值相去甚远,相应地,损失值也很高。但随着网络处理的示例越来越多,权重值也在向正确的方向逐步微调,损失值也逐渐降低。这就是训练循环(training loop),将这种循环重复足够多的次数(通常对数千个示例进行数十次迭代),得到的权重值可以使损失函数最小。具有最小损失的网络,其输出值与目标值尽可能地接近,这就是训练好的网络。
2 深度学习之前:机器学习简史
2.1 概率建模
概率建模(probabilistic modeling)是统计学原理在数据分析中的应用。它是最早的机器学习形式之一,至今仍在广泛使用。其中最有名的算法之一就是朴素贝叶斯算法。朴素贝叶斯是一类基于应用贝叶斯定理的机器学习分类器,它假设输入数据的特征都是独立的。这是一个很强的假设,或者说“朴素的”假设,其名称正来源于此。
另一个密切相关的模型是logistic 回归(logistic regression,简称logreg)。
2.2 早期神经网络
贝尔实验室于1989 年第一次成功实现了神经网络的实践应用,当时Yann LeCun 将卷积神经网络的早期思想与反向传播算法相结合,并将其应用于手写数字分类问题,由此得到名为LeNet 的网络,在20 世纪90 年代被美国邮政署采用,用于自动读取信封上的邮政编码。
2.3 核方法
核方法是一组分类算法,其中最有名的就是支持向量机(SVM,support vector machine)。
SVM 的目标是通过在属于两个不同类别的两组数据点之间找到良好决策边界(decisionboundary,见图1-10)来解决分类问题。
SVM 通过两步来寻找决策边界:
(1) 将数据映射到一个新的高维表示,这时决策边界可以用一个超平面来表示(如果数据像图1-10 那样是二维的,那么超平面就是一条直线)。
(2) 尽量让超平面与每个类别最近的数据点之间的距离最大化,从而计算出良好决策边界(分割超平面),这一步叫作间隔最大化(maximizing the margin)。这样决策边界可以很好地推广到训练数据集之外的新样本。
核技巧基本思想是:要想在新的表示空间中找到良好的决策超平面,你不需要在新空间中直接计算点的坐标,只需要在新空间中计算点对之间的距离,而利用核函数(kernel function)可以高效地完成这种计算。核函数是一个在计算上能够实现的操作,将原始空间中的任意两点映射为这两点在目标表示空间中的距离,完全避免了对新表示进行直接计算。核函数通常是人为选择的,而不是从数据中学到的——对于SVM 来说,只有分割超平面是通过学习得到的。
2.4 决策树、随机森林与梯度提升机
决策树(decision tree)是类似于流程图的结构,可以对输入数据点进行分类或根据给定输入来预测输出值(见图1-11)。
随机森林(random forest)算法,它引入了一种健壮且实用的决策树学习方法,即首先构建许多决策树,然后将它们的输出集成在一起。
与随机森林类似,梯度提升机(gradient boosting machine)也是将弱预测模型(通常是决策树)集成的机器学习技术。它使用了梯度提升方法,通过迭代地训练新模型来专门解决之前模型的弱点,从而改进任何机器学习模型的效果。将梯度提升技术应用于决策树时,得到
的模型与随机森林具有相似的性质,但在绝大多数情况下效果都比随机森林要好。
二、神经网络的数学基础
1 初识神经网络
神经网络的核心组件是层(layer),它是一种数据处理模块,你可以将它看成数据过滤器。具体来说,层从输入数据中提取表示。大多数深度学习都是将简单的层链接起来,从而实现渐进式的数据蒸馏(data distillation)。深度学习模型就像是数据处理的筛子,包含一系列越来越精细的数据过滤器(即层)。
要想训练网络,我们还需要选择编译(compile)步骤的三个参数:
- 损失函数(loss function):网络如何衡量在训练数据上的性能,即网络如何朝着正确的方向前进。
- 优化器(optimizer):基于训练数据和损失函数来更新网络的机制。
- 在训练和测试过程中需要监控的指标(metric):eg:精度
2 神经网络的数据表示
一般来说,当前所有机器学习系统都使用张量作为基本数据结构。张量这一概念的核心在于,它是一个数据容器。它包含的数据几乎总是数值数据,因此它是数字的容器。张量是矩阵向任意维度的推广[注意,张量的维度(dimension)通常叫作轴(axis)]。
2.1 标量(0D 张量)
仅包含一个数字的张量叫作标量(scalar,也叫标量张量、零维张量、0D 张量)。在Numpy中,一个float32 或float64 的数字就是一个标量张量(或标量数组)。你可以用ndim 属性来查看一个Numpy 张量的轴的个数。标量张量有0 个轴(ndim == 0)。张量轴的个数也叫作
阶(rank)。下面是一个Numpy 标量。
>>> import numpy as np
>>> x = np.array(12)
>>> x
array(12)
>>> x.ndim
0
2.2 向量(1D 张量)
数字组成的数组叫作向量(vector)或一维张量(1D 张量)。一维张量只有一个轴。下面是一个Numpy 向量。
>>> x = np.array([12, 3, 6, 14, 7])
>>> x
array([12, 3, 6, 14, 7])
>>> x.ndim
1
这个向量有5 个元素,所以被称为5D 向量。不要把5D 向量和5D 张量弄混! 5D 向量只有一个轴,沿着轴有5 个维度,而5D 张量有5 个轴(沿着每个轴可能有任意个维度)。维度(dimensionality)可以表示沿着某个轴上的元素个数(比如5D 向量),也可以表示张量中轴的个数(比如5D 张量),这有时会令人感到混乱。对于后一种情况,技术上更准确的说法是5 阶张量(张量的阶数即轴的个数),但5D 张量这种模糊的写法更常见。
2.3 矩阵(2D 张量)
向量组成的数组叫作矩阵(matrix)或二维张量(2D 张量)。矩阵有2 个轴(通常叫作行和列)。你可以将矩阵直观地理解为数字组成的矩形网格。下面是一个Numpy 矩阵。
>>> x = np.array([[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]])
>>> x.ndim
2
第一个轴上的元素叫作行(row),第二个轴上的元素叫作列(column)。在上面的例子中,[5, 78, 2, 34, 0] 是x 的第一行,[5, 6, 7] 是第一列。
2.4 3D 张量与更高维张量
将多个矩阵组合成一个新的数组,可以得到一个3D 张量,你可以将其直观地理解为数字组成的立方体。下面是一个Numpy 的3D 张量。
>>> x = np.array([[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]],
[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]],
[[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]]])
>>> x.ndim
3
将多个3D 张量组合成一个数组,可以创建一个4D 张量,以此类推。深度学习处理的一般是0D 到4D 的张量,但处理视频数据时可能会遇到5D 张量。
2.5 关键属性
张量是由以下三个关键属性来定义的。
- 轴的个数(阶)。例如,3D 张量有 3 个轴,矩阵有 2 个轴。这在 Numpy 等 Python 库中也叫张量的ndim。
- 形状。这是一个整数元组,表示张量沿每个轴的维度大小(元素个数)。例如,前面矩阵示例的形状为(3, 5),3D 张量示例的形状为(3, 3, 5)。向量的形状只包含一个元素,比如(5,),而标量的形状为空,即()。
- 数据类型(在 Python 库中通常叫作 dtype)。这是张量中所包含数据的类型,例如,张量的类型可以是float32、uint8、float64 等。在极少数情况下,你可能会遇到字符(char)张量。注意,Numpy(以及大多数其他库)中不存在字符串张量,因为张量存储在预先分配的连续内存段中,而字符串的长度是可变的,无法用这种方式存储。
2.6 数据批量的概念
通常来说,深度学习中所有数据张量的第一个轴(0 轴,因为索引从0 开始)都是样本轴(samples axis,有时也叫样本维度)。
具体来看,下面是MNIST 数据集的一个批量,批量大小为128。
batch = train_images[:128]
然后是下一个批量。
batch = train_images[128:256]
然后是第n 个批量。
batch = train_images[128 * n:128 * (n + 1)]
对于这种批量张量,第一个轴(0 轴)叫作批量轴(batch axis)或批量维度(batch dimension)。
2.7 现实世界中的数据张量
我们用几个你未来会遇到的示例来具体介绍数据张量。你需要处理的数据几乎总是以下类
别之一。
- 向量数据:2D 张量,形状为 (samples, features)。
- 时间序列数据或序列数据:3D 张量,形状为 (samples, timesteps, features)。
- 图像:4D张量,形状为(samples, height, width, channels)或(samples, channels,height, width)。
- 视频:5D张量,形状为(samples, frames, height, width, channels)或(samples,frames, channels, height, width)。
2.8 向量数据
对于这种数据集,每个数据点都被编码为一个向量,因此一个数据批量就被编码为2D 张量(即向量组成的数组),其中第一个轴是样本轴,第二个轴是特征轴。
我们来看两个例子。
- 人口统计数据集,其中包括每个人的年龄、邮编和收入。每个人可以表示为包含 3 个值的向量,而整个数据集包含100 000 个人,因此可以存储在形状为(100000, 3) 的2D张量中。
- 文本文档数据集,我们将每个文档表示为每个单词在其中出现的次数(字典中包含20 000 个常见单词)。每个文档可以被编码为包含20 000 个值的向量(每个值对应于字典中每个单词的出现次数),整个数据集包含500 个文档,因此可以存储在形状为(500, 20000) 的张量中。
2.9 时间序列数据或序列数据
当时间(或序列顺序)对于数据很重要时,应该将数据存储在带有时间轴的3D 张量中。每个样本可以被编码为一个向量序列(即2D 张量),因此一个数据批量就被编码为一个3D 张量(见图2-3)。
根据惯例,时间轴始终是第2 个轴(索引为1 的轴)。我们来看几个例子。
- 股票价格数据集。每一分钟,我们将股票的当前价格、前一分钟的最高价格和前一分钟的最低价格保存下来。因此每分钟被编码为一个3D 向量,整个交易日被编码为一个形状为(390, 3) 的2D 张量(一个交易日有390 分钟),而250 天的数据则可以保存在一个形状为(250, 390, 3) 的3D 张量中。这里每个样本是一天的股票数据。
- 推文数据集。我们将每条推文编码为 280 个字符组成的序列,而每个字符又来自于 128个字符组成的字母表。在这种情况下,每个字符可以被编码为大小为128 的二进制向量(只有在该字符对应的索引位置取值为1,其他元素都为0)。那么每条推文可以被编码为一个形状为(280, 128) 的2D 张量,而包含100 万条推文的数据集则可以存储在一个形状为(1000000, 280, 128) 的张量中。
2.10 图像数据
图像通常具有三个维度:高度、宽度和颜色深度。虽然灰度图像(比如MNIST 数字图像)只有一个颜色通道,因此可以保存在2D 张量中,但按照惯例,图像张量始终都是3D 张量,灰度图像的彩色通道只有一维。因此,如果图像大小为256×256,那么128 张灰度图像组成的批量可以保存在一个形状为(128, 256, 256, 1) 的张量中,而128 张彩色图像组成的批量则可以保存在一个形状为(128, 256, 256, 3) 的张量中(见图2-4)。
图像张量的形状有两种约定:通道在后(channels-last)的约定(在TensorFlow 中使用)和通道在前(channels-first)的约定(在Theano 中使用)。Google 的TensorFlow 机器学习框架将颜色深度轴放在最后:(samples, height, width, color_depth)。与此相反,Theano将图像深度轴放在批量轴之后:(samples, color_depth, height, width)。如果采用Theano 约定,前面的两个例子将变成(128, 1, 256, 256) 和(128, 3, 256, 256)。Keras 框架同时支持这两种格式。
2.11 视频数据
视频数据是现实生活中需要用到5D 张量的少数数据类型之一。视频可以看作一系列帧,每一帧都是一张彩色图像。由于每一帧都可以保存在一个形状为(height, width, color_depth) 的3D 张量中,因此一系列帧可以保存在一个形状为(frames, height, width,color_depth) 的4D 张量中,而不同视频组成的批量则可以保存在一个5D 张量中,其形状为(samples, frames, height, width, color_depth)。
举个例子,一个以每秒4 帧采样的60 秒YouTube 视频片段,视频尺寸为144×256,这个视频共有240 帧。4 个这样的视频片段组成的批量将保存在形状为(4, 240, 144, 256, 3)的张量中。总共有106 168 320 个值!如果张量的数据类型(dtype)是float32,每个值都是32 位,那么这个张量共有405MB。好大!你在现实生活中遇到的视频要小得多,因为它们不以float32 格式存储,而且通常被大大压缩,比如MPEG 格式。
3 神经网络的“齿轮”:张量运算
深度神经网络学到的所有变换也都可以简化为数值数据张量上的一些张量运算(tensor operation),例如加上张量、乘以张量等。
3.1 逐元素运算
relu 运算和加法都是逐元素(element-wise)的运算,即该运算独立地应用于张量中的每个元素,也就是说,这些运算非常适合大规模并行实现(向量化实现,这一术语来自于1970—1990 年间向量处理器超级计算机架构)。
3.2 广播
我们将一个2D 张量与一个向量相加。如果将两个形状不同的张量相加,会发生什么?
如果没有歧义的话,较小的张量会被广播(broadcast),以匹配较大张量的形状。广播包含以下两步。
- (1) 向较小的张量添加轴(叫作广播轴),使其ndim 与较大的张量相同。
- (2) 将较小的张量沿着新轴重复,使其形状与较大的张量相同。
3.3 张量点积
点积运算,也叫张量积(tensor product,不要与逐元素的乘积弄混),是最常见也最有用的张量运算。与逐元素的运算不同,它将输入张量的元素合并在一起。
注意,两个向量之间的点积是一个标量,而且只有元素个数相同的向量之间才能做点积。
注意,如果两个张量中有一个的ndim 大于1,那么dot 运算就不再是对称的,也就是说,dot(x, y) 不等于dot(y, x)。
当然,点积可以推广到具有任意个轴的张量。最常见的应用可能就是两个矩阵之间的点积。对于两个矩阵x 和y,当且仅当x.shape[1] == y.shape[0] 时,你才可以对它们做点积(dot(x, y))。得到的结果是一个形状为(x.shape[0], y.shape[1]) 的矩阵,其元素为x的行与y 的列之间的点积。
3.4 张量变形
张量变形是指改变张量的行和列,以得到想要的形状。变形后的张量的元素总个数与初始张量相同。
经常遇到的一种特殊的张量变形是转置(transposition)。对矩阵做转置是指将行和列互换,使x[i, :] 变为x[:, i]。
3.5 张量运算的几何解释
对于张量运算所操作的张量,其元素可以被解释为某种几何空间内点的坐标,因此所有的张量运算都有几何解释。
4 机器学习基础
4.1 机器学习的四个分支
4.1.1 监督学习
监督学习是目前最常见的机器学习类型。给定一组样本(通常由人工标注),它可以学会将输入数据映射到已知目标[也叫标注(annotation)]。
虽然监督学习主要包括分类和回归,但还有更多的奇特变体,主要包括如下几种。
- 序列生成(sequence generation)。给定一张图像,预测描述图像的文字。序列生成有时可以被重新表示为一系列分类问题,比如反复预测序列中的单词或标记。
- 语法树预测(syntax tree prediction)。给定一个句子,预测其分解生成的语法树。
- 目标检测(object detection)。给定一张图像,在图中特定目标的周围画一个边界框。这个问题也可以表示为分类问题(给定多个候选边界框,对每个框内的目标进行分类)或分类与回归联合问题(用向量回归来预测边界框的坐标)。
- 图像分割(image segmentation)。给定一张图像,在特定物体上画一个像素级的掩模(mask)。
4.1.2 无监督学习
无监督学习是指在没有目标的情况下寻找输入数据的有趣变换,其目的在于数据可视化、数据压缩、数据去噪或更好地理解数据中的相关性。无监督学习是数据分析的必备技能,在解决监督学习问题之前,为了更好地了解数据集,它通常是一个必要步骤。降维(dimensionality reduction)和聚类(clustering)都是众所周知的无监督学习方法。
4.1.3 自监督学习
自监督学习是监督学习的一个特例,它与众不同,值得单独归为一类。自监督学习是没有人工标注的标签的监督学习,你可以将它看作没有人类参与的监督学习。标签仍然存在(因为总要有什么东西来监督学习过程),但它们是从输入数据中生成的,通常是使用启发式算法生成的。
4.1.4 强化学习
在强化学习中,智能体(agent)接收有关其环境的信息,并学会选择使某种奖励最大化的行动。
例如,神经网络会“观察”视频游戏的屏幕并输出游戏操作,目的是尽可能得高分,这种神经网络可以通过强化学习来训练。
4.2 评估机器学习模型
机器学习的目的是得到可以泛化(generalize)的模型,即在前所未见的数据上表现很好的模型,而过拟合则是核心难点。能够可靠地衡量模型的泛化能力非常重要。
4.2.1 训练集、验证集和测试集
为什么不是两个集合:一个训练集和一个测试集?
原因在于开发模型时总是需要调节模型配置,比如选择层数或每层大小[这叫作模型的超参数(hyperparameter),以便与模型参数(即权重)区分开]。这个调节过程需要使用模型在验证数据上的性能作为反馈信号。这个调节过程本质上就是一种学习:在某个参数空间中寻找良好的模型配置。因此,如果基于模型在验证集上的性能来调节模型配置,会很快导致模型在验证集上过拟合,即使你并没有在验证集上直接训练模型也会如此。
造成这一现象的关键在于信息泄露(information leak)。每次基于模型在验证集上的性能来调节模型超参数,都会有一些关于验证数据的信息泄露到模型中。如果对每个参数只调节一次,那么泄露的信息很少,验证集仍然可以可靠地评估模型。但如果你多次重复这一过程(运行一次实验,在验证集上评估,然后据此修改模型),那么将会有越来越多的关于验证集的信息泄露到模型中。
最后,你得到的模型在验证集上的性能非常好(人为造成的),因为这正是你优化的目的。你关心的是模型在全新数据上的性能,而不是在验证数据上的性能,因此你需要使用一个完全不同的、前所未见的数据集来评估模型,它就是测试集。你的模型一定不能读取与测试集有关的任何信息,既使间接读取也不行。如果基于测试集性能来调节模型,那么对泛化能力的衡量是不准确的。
三种经典的评估方法:简单的留出验证、K 折验证,以及带有打乱数据的重复K 折验证。
1. 简单的留出验证
留出一定比例的数据作为测试集。在剩余的数据上训练模型,然后在测试集上评估模型。如前所述,为了防止信息泄露,你不能基于测试集来调节模型,所以还应该保留一个验证集。
这是最简单的评估方法,但有一个缺点:如果可用的数据很少,那么可能验证集和测试集包含的样本就太少,从而无法在统计学上代表数据。这个问题很容易发现:如果在划分数据前进行不同的随机打乱,最终得到的模型性能差别很大,那么就存在这个问题。接下来会介绍K 折验证与重复的K 折验证,它们是解决这一问题的两种方法。
2. K 折验证
K 折验证(K-fold validation)将数据划分为大小相同的K 个分区。对于每个分区i,在剩余的K-1 个分区上训练模型,然后在分区i 上评估模型。最终分数等于K 个分数的平均值。对于不同的训练集- 测试集划分,如果模型性能的变化很大,那么这种方法很有用。与留出验证一样,这种方法也需要独立的验证集进行模型校正。
3. 带有打乱数据的重复K 折验证
如果可用的数据相对较少,而你又需要尽可能精确地评估模型,那么可以选择带有打乱数据的重复K 折验证(iterated K-fold validation with shuffling)。具体做法是多次使用K 折验证,在每次将数据划分为K 个分区之前都先将数据打乱。最终分数是每次K 折验证分数的平均值。注意,这种方法一共要训练和评估P×K 个模型(P是重复次数),计算代价很大。
4.2.2 评估模型的注意事项
- 数据代表性(data representativeness)。你希望训练集和测试集都能够代表当前数据。例如,你想要对数字图像进行分类,而图像样本是按类别排序的,如果你将前80% 作为训练集,剩余20% 作为测试集,那么会导致训练集中只包含类别0~7,而测试集中只包含类别8~9。这个错误看起来很可笑,却很常见。因此,在将数据划分为训练集和测试集之前,通常应该随机打乱数据。
- 时间箭头(the arrow of time)。如果想要根据过去预测未来(比如明天的天气、股票走势等),那么在划分数据前你不应该随机打乱数据,因为这么做会造成时间泄露(temporalleak):你的模型将在未来数据上得到有效训练。在这种情况下,你应该始终确保测试集中所有数据的时间都晚于训练集数据。
- 数据冗余(redundancy in your data)。如果数据中的某些数据点出现了两次(这在现实中的数据里十分常见),那么打乱数据并划分成训练集和验证集会导致训练集和验证集之间的数据冗余。从效果上来看,你是在部分训练数据上评估模型,这是极其糟糕的!一定要确保训练集和验证集之间没有交集。
4.3 数据预处理、特征工程和特征学习
4.3.1 神经网络的数据预处理
数据预处理的目的是使原始数据更适于用神经网络处理,包括向量化、标准化、处理缺失值和特征提取。
1. 向量化
神经网络的所有输入和目标都必须是浮点数张量(在特定情况下可以是整数张量)。无论处理什么数据(声音、图像还是文本),都必须首先将其转换为张量,这一步叫作数据向量化(data vectorization)。
2. 值标准化
一般来说,将取值相对较大的数据(比如多位整数,比网络权重的初始值大很多)或异质数据(heterogeneous data,比如数据的一个特征在0~1 范围内,另一个特征在100~200 范围内)输入到神经网络中是不安全的。这么做可能导致较大的梯度更新,进而导致网络无法收敛。为了让网络的学习变得更容易,输入数据应该具有以下特征。
- 取值较小:大部分值都应该在 0~1 范围内。
- 同质性(homogenous):所有特征的取值都应该在大致相同的范围内。
3. 处理缺失值
一般来说,对于神经网络,将缺失值设置为0 是安全的,只要0 不是一个有意义的值。网络能够从数据中学到0 意味着缺失数据,并且会忽略这个值。
注意,如果测试数据中可能有缺失值,而网络是在没有缺失值的数据上训练的,那么网络不可能学会忽略缺失值。在这种情况下,你应该人为生成一些有缺失项的训练样本:多次复制一些训练样本,然后删除测试数据中可能缺失的某些特征。
4.3.2 特征工程
特征工程(feature engineering)是指将数据输入模型之前,利用你自己关于数据和机器学习算法(这里指神经网络)的知识对数据进行硬编码的变换(不是模型学到的),以改善模型的效果。多数情况下,一个机器学习模型无法从完全任意的数据中进行学习。呈现给模型的数据应该便于模型进行学习。
4.4 过拟合与欠拟合
机器学习的根本问题是优化和泛化之间的对立。优化(optimization)是指调节模型以在训练数据上得到最佳性能(即机器学习中的学习),而泛化(generalization)是指训练好的模型在前所未见的数据上的性能好坏。机器学习的目的当然是得到良好的泛化,但你无法控制泛化,只能基于训练数据调节模型。
训练开始时,优化和泛化是相关的:训练数据上的损失越小,测试数据上的损失也越小。这时的模型是欠拟合(underfit)的,即仍有改进的空间,网络还没有对训练数据中所有相关模式建模。但在训练数据上迭代一定次数之后,泛化不再提高,验证指标先是不变,然后开始变差,即模型开始过拟合。这时模型开始学习仅和训练数据有关的模式,但这种模式对新数据来说是错误的或无关紧要的。
为了防止模型从训练数据中学到错误或无关紧要的模式,最优解决方法是获取更多的训练数据。模型的训练数据越多,泛化能力自然也越好。如果无法获取更多数据,次优解决方法是调节模型允许存储的信息量,或对模型允许存储的信息加以约束。如果一个网络只能记住几个模式,那么优化过程会迫使模型集中学习最重要的模式,这样更可能得到良好的泛化。
这种降低过拟合的方法叫作正则化(regularization)。
4.4.1 减小网络大小
防止过拟合的最简单的方法就是减小模型大小,即减少模型中可学习参数的个数(这由层数和每层的单元个数决定)。在深度学习中,模型中可学习参数的个数通常被称为模型的容量(capacity)。直观上来看,参数更多的模型拥有更大的记忆容量(memorization capacity),因此能够在训练样本和目标之间轻松地学会完美的字典式映射,这种映射没有任何泛化能力。
不幸的是,没有一个魔法公式能够确定最佳层数或每层的最佳大小。你必须评估一系列不同的网络架构(当然是在验证集上评估,而不是在测试集上),以便为数据找到最佳的模型大小。要找到合适的模型大小,一般的工作流程是开始时选择相对较少的层和参数,然后逐渐增加层的大小或增加新层,直到这种增加对验证损失的影响变得很小。
4.4.2 添加权重正则化
给定一些训练数据和一种网络架构,很多组权重值(即很多模型)都可以解释这些数据。简单模型比复杂模型更不容易过拟合。
这里的简单模型(simple model)是指参数值分布的熵更小的模型(或参数更少的模型,比如上一节的例子)。因此,一种常见的降低过拟合的方法就是强制让模型权重只能取较小的值,从而限制模型的复杂度,这使得权重值的分布更加规则(regular)。这种方法叫作权重正则化(weight regularization),其实现方法是向网络损失函数中添加与较大权重值相关的成本(cost)。这个成本有两种形式。
- L1 正则化(L1 regularization):添加的成本与权重系数的绝对值[权重的 L1 范数(norm)]成正比。
- L2 正则化(L2 regularization):添加的成本与权重系数的平方(权重的L2 范数)成正比。神经网络的L2 正则化也叫权重衰减(weight decay)。不要被不同的名称搞混,权重衰减与L2 正则化在数学上是完全相同的。
4.4.3 添加dropout 正则化
dropout 是神经网络最有效也最常用的正则化方法之一,它是由多伦多大学的Geoffrey Hinton和他的学生开发的。对某一层使用dropout,就是在训练过程中随机将该层的一些输出特征舍弃(设置为0)。
dropout 比率(dropout rate)是被设为0 的特征所占的比例,通常在0.2~0.5范围内。测试时没有单元被舍弃,而该层的输出值需要按dropout 比率缩小,因为这时比训练时有更多的单元被激活,需要加以平衡。
参考:《Python 深度学习》
更多推荐
所有评论(0)