在上一讲《Coursera自动驾驶课程第9讲:Visual Features Detection Description and Matching》中我们学习了如何进行图像特征检测
,特征匹配
以及如何构建视觉里程计
来估计相机的运动。
本讲我们将学习神经网络
模块,关于神经网络或深度学习网上有很多相关课程,这里推荐吴恩达老师的深度学习专项课程。由于篇幅所限,本讲介绍的不会很深入。
B站视频链接:https://www.bilibili.com/video/BV1PE411D72p。
文章目录
- 1. Feedforward Neural Networks
- 1.1 Overview
- 1.2 Applications
- 1.3 Mode of Action of Neural Networks
- 1) Hidden units
- 2) Activation functions
- 2.Output Layers and Loss Functions
- 2.1 Machine Learning Algorithm Design
- 2.2 Classification: Softmax Output Layers
- 2.3 Regression: Linear Output Layers
- 3. Neural Network Training with Gradient Descent
- 3.1 Overview
- 3.2 Batch Gradient Descent (重点)
- 3.3 Stochastic Gradient Descent (重点)
- 4. Data Splits and Neural Network Performance Evaluation
- 4.1 Data Splits
- 4.2 Underfitting & Overfitting
- 5. Neural Network Regularization
- 5.1 Overview
- 5.2 Parameter norm penalites
- 5.3 Dropout
- 5.4 Early Stopping
- 6. Convolutional Neural Networks
- 6.1 ConvNets
- 6.2 Cross Correlation
- 6.3 Output Volume Shape
1. Feedforward Neural Networks
1.1 Overview
本讲,我们将学习一个新的主题:深度学习
。我们将学习前馈神经网络
,前馈神经网络是一种非常有用的人工神经网络。
前馈神经网络本质上也是一种函数,定义了从输入xxx到输出yyy的映射,函数形式如下,θ\thetaθ是需要的参数。
y=f(x;θ)y=f(x ; \theta)y=f(x;θ)
下面来看一个神经网络的例子:这是一个四层前馈神经网络
。该神经网络具有输入层
,输入层为xxx。在这里,xxx可以是标量,向量,矩阵甚至是nnn维张量,例如图像。输入经过神经网络的第一层处理。我们将此层称为第一隐藏层
。类似地,第二隐藏层处理第一隐藏层的输出。我们可以根据需要添加任意数量的隐藏层,但是每个层都会添加其他要学习的参数。神经网络的最后一层称为输出层
。它获取最后一个隐藏层的输出并将其转换为所需的输出yyy。现在,我们应该对为什么将这些网络称为前馈具有直觉。这是因为信息从输入xxx经过一些中间计算,一直流到输出yyy,而没有任何反馈连接。
然后,我们将网络扩展到NNN层,函数形式为:
f(x;θ)=f(N)(f(N−1)(…f(2)(f(1)(x))))f(x ; \theta)=f^{(N)}\left(f^{(N-1)}\left(\ldots f^{(2)}\left(f^{(1)}(x)\right)\right)\right)f(x;θ)=f(N)(f(N−1)(…f(2)(f(1)(x))))
其中,xxx为输入层,f(N)f^{(N)}f(N)为输出层,函数f(1)f^{(1)}f(1)到f(N−1)f^{(N-1)}f(N−1)为隐藏层。
1.2 Applications
现在,我们看一下深度学习在自动驾驶中的应用实例,输入为图像。
- 最基本的感知任务是
分类任务
。在这里,我们需要神经网络告诉我们图像所属分类。 - 我们还可以对图像中的对象的进行定位,称之为
目标检测
。 - 另一组任务是
像素级任务
。举例来说,我们可能想估计图像中每个像素的深度值
。 - 我们可能要确定
每个像素属于哪个类
。此任务称为语义分割
。
1.3 Mode of Action of Neural Networks
现在我们了解一些关于神经网络训练
的知识。在称为神经网络训练的过程中,我们通过修改描述网络的参数θ\thetaθ来使神经网络fff以匹配真值f∗(x)f ^*(x)f∗(x),即:
f(x;θ)≅f∗(x)f(x ; \theta) \cong f^{*}(x)f(x;θ)≅f∗(x)
这里训练数据为xxx和其真值f∗(x)f ^*(x)f∗(x)。
1) Hidden units
现在我们来深入了解隐藏层
,隐藏层
由仿射变换
和一个非线性变换ggg组成。
- 其中非线性函数ggg称为
激活函数
。 - 第nnn个隐藏层的输入为n−1n-1n−1层的输出,在该层是第一隐藏层的情况下,其输入仅是输入图像xxx。
- 仿射变换由一个乘法权重矩阵WWW和一个偏差bbb组成。这些权重和偏差是神经网络需要学习的参数θ\thetaθ。
- 最后,转换后的输入通过激活函数ggg传递。
2) Activation functions
下面我们来介绍神经网络中常用的激活函数,ReLU是现在常用的激活函数,其形式为:
g(z)=max(0,z)g(z)=\max (0, z)g(z)=max(0,z)
ReLU将零和仿射变换的输出之间的最大值
作为其输出。
让我们来看一个ReLU隐藏层计算的示例。 已知前一个隐藏层输出hn−1h_{n-1}hn−1,权重矩阵WWW和偏差bbb。 首先进行仿射变换,仿射变换的最终结果是5×35\times35×3矩阵。
现在,让我们将此矩阵传递给ReLU函数。 我们可以看到ReLU防止了仿射变换的任何负输出传递到下一层。
实际上,隐藏单元的设计是深度学习中一个非常活跃的研究领域,并且还没有很多指导理论。 例如,某些神经网络体系结构使用sigmoid函数,双曲正切非线性tanh函数,ReLU的泛化,Maxout非线性作为其隐藏层激活函数,如果想深入了解可以查看相关教材和论文。
2.Output Layers and Loss Functions
2.1 Machine Learning Algorithm Design
包括神经网络在内的有监督机器学习
模型有两种工作模式:推理和训练
。
- 给定一组参数,将输入xxx传递到模型中,可以获得输出yyy,这种工作模式称为
推理
,网络及其参数是固定的。 - 第二种工作模式,涉及对网络参数进行优化,这种模式称为
训练
。
让我们看看通常如何进行训练。我们从与推理相同的工作流程开始。但是,在训练过程中,我们有训练数据。这样,我们知道xxx的真值是什么,即模型的预期输出。对于自动驾驶,训练数据常见的为人类标注的图像,这往往需要花费很长时间才能完成。我们通过损失函数
将预测的输出yyy和xxx的实际输出真值进行比较。
损失函数
将来自网络的预测输出yyy和x的实际输出作为输入,并提供了两者之间差异的度量。我们通常尝试通过修改参数来最小化此度量,以使网络的输出yyy与xxx的预期输出尽可能相似。我们通过优化函数
对参数进行修改。
在上一课中讨论了前馈神经网络,该神经网络将输入xxx传递给隐藏层函数,然后将隐藏层的输出传递给输出层。这是神经网络的推理阶段。为了进行训练,我们将预测的输出传递给损失函数,然后使用优化函数来生成一组新的参数。
人工神经网络的设计与传统机器学习算法的设计之间的主要区别
在于,神经网络仅通过输出层与损失函数进行交互
。然后通过优化函数进行参数调整。(这里课程说的不是很准确,其实神经网络会通过反向传播来调整每一层参数值
。)
2.2 Classification: Softmax Output Layers
自动驾驶感知的第一个常见任务就是分类任务
。分类可以描述为将输入xxx映射到kkk个类别中的其中一个类别,包括图像分类,语义分割,实体分割等。
自动驾驶感知的第二个任务是回归任务
。在回归中,我们将输入映射为一组实数。回归的示例包括深度估计
,估计图像中每个像素的真实深度值。我们也可以将两个任务混合在一起。例如,目标检测
通常包括一个回归任务和一个分类任务,在回归任务中我们估计目标的边界框
,在分类任务中我们确定边界框中的目标类型。
让我们先从分类任务开始。 通常,对于kkk个类别的分类任务,常用的分类函数为softmax函数。 Softmax函数能够表示kkk个类别上的概率分布
。 softmax输出层将神经网络最后一个隐藏层的输出作为输入hhh。 然后通过线性变换得到向量zzz。
z=WTh+bz=W^{T} h+bz=WTh+b
接下来,使用softmax函数将向量zzz转换为离散概率分布。 对于每个元素ziz_izi,此函数都会计算元素ziz_izi的指数与zzz的所有元素的指数之和之比。 结果为一个介于0和1之间的值,即其所属类别的概述,概率总和是1。
Softmax(zi)=exp(zi)∑jexp(zj)\operatorname{Softmax}\left(z_{i}\right)=\frac{\exp \left(z_{i}\right)}{\sum_{j} \exp \left(z_{j}\right)}Softmax(zi)=∑jexp(zj)exp(zi)
让我们看一个示例,以更好地解释softmax。 在此示例中,我们想对包含猫,狗或狐狸的图像进行分类。 首先,根据我们的网络,我们定义输出矢量的第一个元素以对应于图像是猫的概率。 类的顺序是任意的,对网络性能没有影响。 以线性变换的输出为例,我们通过将输出中每个元素的指数除以所有元素的指数总和来计算概率。我们得出该图像为猫的概率为88%,该图像为狐狸的概率为11.9%,而该图像为狗的概率非常低 。
现在,让我们看看如何设计一个损失函数
,该函数使用softmax输出层的输出向我们展示估计的准确性。 softmax输出层使用的损失函数是交叉熵损失
,它是通过取softmax函数的负对数
来形成的。交叉熵损失具有两项来控制网络输出与真实概率的接近程度,损失函数形式为:
L(θ)=−log(Softmax(zi))=−zi+(log∑jexp(zj))L(\theta)=-\log \left(\operatorname{Softmax}\left(z_{i}\right)\right)=-z_{i}+\left(\log \sum_{j} \exp \left(z_{j}\right)\right)L(θ)=−log(Softmax(zi))=−zi+(logj∑exp(zj))
要更好地了解这种损失。让我们看一个如何通过分类神经网络的输出来计算交叉熵损失的数值示例。回顾前面的示例,我们首先需要选择ziz_izi是什么。 ziz_izi是对应于真实输入类别的线性变换输出。在这种情况下,ziz_izi是对应于cat类的线性变换输出的元素。一旦确定了ziz_izi,就可以使用交叉熵来计算最终损失值。在这种情况下,网络可以正确地预测输入为猫,损失函数值为0.12。
现在让我们再次进行计算,但是网络输出错误。网络的输入仍然是猫的图像。网络仍将13的值分配给线性变换输出的cat条目。但是这一次fox条目的值为14。计算交叉熵损失,我们发现它的评估值为1.31,是前一张幻灯片的十倍。损失函数会严重惩罚错误的预测
,这种差异加快了学习过程。
2.3 Regression: Linear Output Layers
线性输出层
主要用于回归任务,线性输出层仅由一个线性变换组成,无任何非线性。 常见的损失函数为均方误差
函数。
L(θ)=∑i(zi−f∗(xi))2L(\theta)=\sum_{i}\left(z_{i}-f^{*}\left(x_{i}\right)\right)^{2}L(θ)=i∑(zi−f∗(xi))2
上面描述的线性和softmax是当今神经网络中最常用的输出层,可以与各种任务(特定的损失函数)结合使用,以执行用于自动驾驶的各种感知任务。
3. Neural Network Training with Gradient Descent
3.1 Overview
让我们首先回顾一下我们先前描述的前馈神经网络训练过程
。给定训练输入数据xxx和相应的标签f∗(x)f^*(x)f∗(x)。
我们首先将输入xxx传递给隐藏层,然后传递给输出层以获得最终输出yyy。我们在这里看到输出yyy是参数θ\thetaθ的函数。请记住,θ\thetaθ包含网络内部线性变换的权重和偏差
。
接下来,我们通过损失函数将xxx和θ\thetaθ的预测输出yyy与f∗(x)f^*(x)f∗(x)进行比较。请记住,损失函数衡量的是网络输出与真值之间的误差有多大。目标是使损失函数最小。我们通过使用损失函数作为指导来产生一组新的参数θ\thetaθ来达到预期的最小的损失值目的。具体来说,我们使用损失函数的梯度来修改参数θ\thetaθ。此优化过程称为梯度下降
。
3.2 Batch Gradient Descent (重点)
在详细介绍梯度下降之前,让我们再来看看神经网络的损失函数。通常,我们有数千对训练数据,xxx和f∗(x)f^*(x)f∗(x)。
我们可以计算所有训练样本的损失,作为单个训练样本损失的平均值
,公式为:
J(θ)=1N∑i=1NL[f(xi,θ),f∗(xi)]J(\theta)=\frac{1}{N} \sum_{i=1}^{N} L\left[f\left(x_{i}, \theta\right), f^{*}\left(x_{i}\right)\right]J(θ)=N1i=1∑NL[f(xi,θ),f∗(xi)]
然后我们可以计算训练损失相对于参数θ\thetaθ的梯度
,最终得到的梯度下降算法为:
∇θJ(θ)=∇θ[1N∑i=1NL[f(xi,θ),f∗(xi)]]=1N∑i=1N∇θL[f(xi,θ),f∗(xi)]\nabla_{\theta} J(\theta)=\nabla_{\theta}\left[\frac{1}{N} \sum_{i=1}^{N} L\left[f\left(x_{i}, \theta\right), f^{*}\left(x_{i}\right)\right]\right]=\frac{1}{N} \sum_{i=1}^{N} \nabla_{\theta} L\left[f\left(x_{i}, \theta\right), f^{*}\left(x_{i}\right)\right]∇θJ(θ)=∇θ[N1i=1∑NL[f(xi,θ),f∗(xi)]]=N1i=1∑N∇θL[f(xi,θ),f∗(xi)]
梯度下降是迭代一阶优化算法
。迭代意味着它从参数θ\thetaθ的初始值开始,迭代改进参数。一阶是指算法只利用一阶导数来改善参数θ\thetaθ。批量梯度下降过程如下:
- 首先,对神经网络的参数θ\thetaθ进行初始化。
- 其次,确定停止条件,终止迭代并返回最终的参数。一旦迭代过程开始,算法要做的第一件事就是计算损失函数相对于参数θ\thetaθ的梯度:∇θJ(θ)\nabla_{\theta} J(\theta)∇θJ(θ)。梯度可以用我们前面推导的方程来计算。最后,根据计算的梯度更新参数θ\thetaθ:θ←θ−ϵ∇θJ(θ)\theta \leftarrow \theta-\epsilon \nabla_{\theta} J(\theta)θ←θ−ϵ∇θJ(θ)。在这里,ϵ\epsilonϵ称为学习率,它控制着我们在每次迭代时,在负梯度方向上调整参数的程度。
让我们看一个二维情况下梯度下降的例子。在这里,我们试图找到使函数JJJ最小化的参数θ1\theta1θ1和θ2\theta2θ2。图中的等高线是相等的。梯度下降迭代地寻找新的参数θ\thetaθ,在每次迭代中,它会使我们向内前进一步。
- 算法的第一步是初始化参数θ\thetaθ。使用我们的初始参数,我们得到损失函数的初始值。
- 我们通过计算初始参数θ1\theta1θ1和θ2\theta2θ2处损失函数的梯度开始梯度下降。使用更新步骤,我们得到新的参数,以达到我们的损失函数的低点。
- 我们重复这个过程,直到满足终止条件。然后我们得到最后一组参数。该算法还缺少两个部分。
我们如何初始化参数
,以及如何决定何时停止算法
?
对于参数初始化
,我们通常使用标准正态分布初始化权重
,并将偏差设为0
。值得一提的是,还有一些特定于某些激活函数的启发式算法在文献中被广泛使用。
梯度下降的停止条件有点复杂。有三种方法可以确定何时停止训练算法。
- 当迭代次数超过多最大迭代次数时,终止迭代。
- 另一种启发式方法是基于参数θ\thetaθ在迭代之间的变化程度(即θnew −θold \boldsymbol{\theta}_{\text {new }}-\boldsymbol{\theta}_{\text {old }}θnew −θold )。微小的变化意味着算法不再有效地更新参数,这可能意味着已经达到最小值。
- 最后一个广泛使用的停止条件是迭代之间
损失函数值的变化
。同样,随着迭代之间损失函数的变化变小,优化很可能已经收敛到最小值。
3.3 Stochastic Gradient Descent (重点)
不幸的是,批梯度下降算法有严重的缺点。为了能够计算梯度,我们需要使用反向传播。而批梯度下降则对整个训练集的梯度进行评估。使执行单个更新步骤的速度非常慢
。为了解决这个问题,我们现在可以使用训练数据的一个小批量来计算我们的梯度。那么,如何使用小批量修改我们的批梯度下降算法?
对算法的唯一修改是在采样步骤
。这里我们选择训练数据的子样本作为我们的小批量,这种算法被称为随机或小批量梯度下降
,因为我们随机选择样本,但是,此算法会导致另一个要确定的参数,即我们要使用的minibatch大小N′N^{\prime}N′。
∇θJ(θ)=1N′∑iN′∇θL[fi(x,θ),fi∗(x)]\nabla_{\theta} J(\theta)=\frac{1}{N^{\prime}} \sum_{i}^{N^{\prime}} \nabla_{\theta} L\left[f_{i}(x, \theta), f_{i}^{*}(x)\right]∇θJ(θ)=N′1i∑N′∇θL[fi(x,θ),fi∗(x)]
在使用GPU时,我们可以将minibatch设置为2的nnn次方。要记住的最后一个问题是,在对minibatch进行采样之前,需要对数据集进行打乱
。
随机梯度下降法在文献中有许多变体,每种变体都有各自的优缺点。可能很难选择要使用哪种变体,有时其中一种变体比另一种变体更适用于某些问题。作为自动驾驶应用的简单经验法则,安全的选择是adam优化方法
。它对初始参数θ\thetaθ具有很强的鲁棒性,应用广泛。
4. Data Splits and Neural Network Performance Evaluation
4.1 Data Splits
让我们以一个现实问题为例。我们得到了一个包含10000张交通标志图像的数据集,其中包含相应的分类标签。我们想训练我们的神经网络来进行交通标志分类。如何处理这个问题?我们是否需要对所有数据进行训练,然后部署交通标志分类器?这种方法肯定会失败,原因如下。给定一个足够大的神经网络,我们几乎可以保证得到一个非常低的训练损失。这是因为在一个典型的深度神经网络中,参数数量会非常大,允许它在给定足够多的迭代次数的情况下,记忆训练数据。更好的方法是将这些数据分为三部分:训练集、验证集和测试集
。
- 训练集,顾名思义,在神经网络训练过程中,
模型在训练集上使损失函数最小化
。 - 当
超参数
发生变化时,使用验证集来验证神经网络的性能。超参数包括:学习率、网络层数、每层神经元数等
。 - 测试集用于测试网络性能的无偏估计。在开发神经网络结构时,测试集是禁止的,这样神经网络在训练或超参数优化过程中就不会看到这些数据。
现在让我们来确定不同数据集百分比划分。在大数据错误之前,当数据量小于10000时,默认数据百分比约为60%用于训练,20%用于验证,20%用于测试。然而,如今数据量可以达到上百万甚至更多,在验证和测试集中使用20%的数据是不必要的,因为验证和测试包含的样本将远远超过目的所需的样本。在这种情况下,我们会发现98%的训练集和1%的验证和测试集并不少见。
4.2 Underfitting & Overfitting
让我们回到我们的交通标志分类问题。我们假设我们的交通标志数据集由10000个标记的示例组成。我们可以根据6000、2000、2000的大小将数据集分成训练集、验证集和测试集。我们现在使用损失函数来评估我们的神经网络在每个数据集上的性能。
对于分类问题,损失函数定义为预测值与真值之间的交叉熵。交叉熵严格地大于零,所以它的值越高,分类器的性能就越差。记住,神经网络只直接观察训练集。所有开发人员都使用验证集来确定要使用的最佳超参数。训练的最终目标仍然是最小化测试集上的误差,因为它是对系统性能的无偏估计,并且数据从未被网络观察到。
- 让我们首先考虑以下场景。假设我们的估计器在训练集上的交叉熵损失为0.21,在验证集上的交叉熵损失为0.25,最后在测试集上的交叉熵损失为0.3。此外,由于数据集标签的错误,我们可以预期的最小交叉熵损失为0.18。在这种情况下,我们有一个相当好的分类器,因为三个集合上的损失是相当一致的。
- 让我们考虑第二个场景,其中训练损失现在是1.9,大约是最小损失的10倍。正如我们在上一课中所讨论的,我们期望任何大小合理的神经网络都能够在足够的训练时间内几乎完美地拟合数据。但在这种情况下,网络无法做到这一点。我们将这种情况称为神经网络无法降低训练损失的
欠拟合
。 - 我们可能面临的另一种情况是,训练集准确率较高,但验证和测试集准确率较低。这里验证损失大约是训练损失的十倍。这种情况被称为
过拟合
,是由于神经网络优化其参数,以精确地再现训练数据输出。当我们在验证集上部署时,网络不能很好地推广到新数据。训练和验证损失之间的差距称为泛化差距
。我们希望这个差距尽可能小,同时仍然有足够低的训练损失。
让我们看看如何改善欠拟合:
- 第一个选择是
延长训练时间
。即迭代次数越多,训练损失越小。 为神经网络添加更多层,或者为每层添加更多参数
。
现在,让我们讨论如何减少过拟合:
- 最简单的方法就是
收集更多的数据
。 - 另一个解决方案是
正则化
。
5. Neural Network Regularization
5.1 Overview
让我们在一个示例中逐步进行神经网络的迭代开发。我们将笛卡尔空间分成两个部分,橙色和蓝色
。属于蓝色空间的任何点都应标记为1,而属于橙色空间的任何点都应标记为2。但是,我们无法直接访问这些类或其边界。相反,我们只能访问传感器测量值,这些测量值为我们提供了点及其相应的类别。不幸的是,传感器存在噪音,这意味着它有时会提供错误的标签
。标签在蓝色空间中指向2,在橙色空间中指向1。
现在我们先使用一个简单的神经元网络,该网络具有二个隐藏层来对数据进行分类。使用这种设计选择,我们可以得到以下空间分类。训练集损失为0.264,验证集损失0.268。但是,它仍然远高于最小可实现的损失0.1。这是明显不合时宜的情况。当我们将网络分类的结果与真实空间分类的结果进行比较时,我们发现神经网络无法捕获当前问题的复杂性,并且没有按照要求将空间正确地划分为四个部分。
为了解决欠拟合问题,我们通过增加五个隐藏层来增加网络规模。我们的模型能够更好的学习数据特征,因此它应该能够更好地表示真实的分类。我们继续再次训练模型,然后进行测试以查看我们做得如何。我们注意到,我们的验证集损失为0.45,远远高于我们的训练集损失0.1。但是,训练集损失等于此任务上可实现的最小损失0.1。我们处于过拟合训练数据的状态
。为了解决过拟合现象,我们将介绍一种处理过拟合的方法:正则化
。
5.2 Parameter norm penalites
让我们看看神经网络常用的第一种正则化方法。适用于神经网络的最传统形式的正则化形式是参数范数惩罚
。常见的表达形式为:
J(θ)reg=J(θ)+αΩ(θ)J(\theta)_{r e g}=J(\theta)+\alpha \Omega(\theta)J(θ)reg=J(θ)+αΩ(θ)
α\alphaα是一个超参数, Ω(θ)\Omega(\theta)Ω(θ)是参数θ\thetaθ的惩罚项,常见的是LpLpLp正则化。此外,我们通常仅约束神经网络参数的权重值。
神经网络中最常用的规范惩罚是L2正则化。 其形式为:
Ω(W)=12WTW=12∥W∥22\Omega(W)=\frac{1}{2} W^{T} W=\frac{1}{2}\|W\|_{2}^{2}Ω(W)=21WTW=21∥W∥22
请记住,我们此前设计的网络导致对训练数据集的过拟合。加上L2范数惩罚后,验证集损失与训练集损失从0.1增加到0.176,验证集损失从0.45降为0.182。训练集损失与验证集损失与最小损失几乎相等。
5.3 Dropout
当前,研究人员已经开发出特定于神经网络的正则化机制:Dropout
。让我们看看在模型训练期间如何应用Dropout。Dropout的第一步是选择一个称为PkeepP_{keep}Pkeep的概率。在每次迭代训练中,此概率用于选择要保留在网络中的网络节点子集。这些节点可以是隐藏单元,输出单元或输入单元。然后,我们切断所有该神经节点的后续连接。
Dropout可以直观地解释为迫使模型在缺少输入和隐藏单元的情况下进行学习。它提供了一种在计算过程中不昂贵但功能强大的方法,可以在训练过程中对大量的神经网络模型进行正则化,从而大大减少过拟合的情况。此外,Dropout并没有明显限制可以使用的训练模型。它几乎适用于参数化表示形式上的任何模型,并且可以通过随机梯度下降进行训练。最后,所有神经网络库都已实现了Dropout层。
5.4 Early Stopping
最后一种正则化方法是Early Stopping
。为了从视觉上解释,我们查看了在训练集上的损失函数的变化,训练损失应该能够减少到接近零。但是,如果我们有独立的训练和验证集,则验证损失将先下降然后开始增加,这种现象在过拟合中很常见。
停止训练后,将返回验证损失最小的参数集。最后要说明的是,不应该将早期停止用作进行正则化的首选。由于它限制了训练时间,因此可能会影响整体模型性能。
6. Convolutional Neural Networks
6.1 ConvNets
卷积神经网络
是一种特殊的神经网络,用于处理具有网格状拓扑的数据。这样的数据的示例可以是以规则间隔采样的1D时间序列数据,2D图像甚至3D视频。卷积网主要由两种类型的层组成:卷积层和池化层
。 ConvNet
体系结构的一个简单示例是VGG 16
。该网络接收图像,并将其传递给卷积层,池化层,然后是池化层和卷积层等。现在,不必太担心VGG1 6
网络设计的细节,当我们了解目标检测时,我们将在后面的视频中详细讨论该网络。
让我们看看这两种类型的卷积层在实际中如何工作。到目前为止,我们描述的神经网络,隐藏层通常称为完全连接层
。顾名思义,上一层网络的每个节点与下一层网络的所有节点进行连接。这是通过矩阵乘法在软件中实现的。
尽管反直觉,但是卷积层对其线性算子使用互相关而不是卷积,不是通用矩阵乘法
。在卷积运算中仅使用了有限大小的内核。
6.2 Cross Correlation
让我们开始描述卷积层在实际中如何工作的。我们假设要对输入图像应用卷积层。我们将该图像称为输入量,因为我们将看到卷积层也将其他层的输出作为输入。输入宽度是其水平尺寸,高度是其垂直尺寸,深度是通道数
。在我们的案例中,所有三个特征的值均为三个。在卷积运算中通常我们也会进行填充操作
,这种情况下,在每一侧添加的像素数称为填充大小,填充对于保持执行卷积所需的形状至关重要。
我们通过一组内核执行卷积运算。每个内核由一组权重和一个偏差组成
。内核通道数对应于输入通道数。在这种情况下,每个内核有三个权重通道,分别对应于输入图像的红色,绿色和蓝色通道。
通常每个卷积层有多个卷积核。让我们看看如何应用二个卷积核从输入中获取输出。输入维度为(3,3,3)(3,3,3)(3,3,3),输出维度(2,2,2)(2,2,2)(2,2,2)
6.3 Output Volume Shape
假设卷积核大小是(m,m)(m,m)(m,m),并且我们有KKK个卷积核,步长为SSS,填充大小为PPP。则输出宽度为:
Wout=Win−m+2×Ps+1\boldsymbol{W}_{\boldsymbol{o u t}}=\frac{\boldsymbol{W}_{\boldsymbol{i n}}-m+2 \times P}{s}+1Wout=sWin−m+2×P+1
输出高度为:
Hout=Hin −m+2×PS+1\boldsymbol{H}_{\boldsymbol{o u t}}=\frac{\boldsymbol{H}_{\text {in }}-m+2 \times P}{S}+1Hout=SHin −m+2×P+1
通道数为:
Dout =K\boldsymbol{D}_{\text {out }}=KDout =K
现在让我们继续描述ConvNets
的第二个构建块,池化层
。让我们以最常用的池化层(最大池化)为例。下面是一个最大池化的示例。
同样,我们也可以给出最大池化输出的维度,假设池化卷积核大小为(n,n)(n,n)(n,n),步长为SSS。其输出宽度为:
Wout=Win−ns+1W_{o u t}=\frac{W_{i n}-n}{s}+1Wout=sWin−n+1
输出高度为:
Hout=Hin−nS+1H_{o u t}=\frac{H_{i n}-n}{S}+1Hout=SHin−n+1
输出高度为:
Dout =Din \boldsymbol{D}_{\text {out }}=\boldsymbol{D}_{\text {in }}Dout =Din
ConvNets
的有效性有两个重要原因。
- 首先,它们在卷积层中的参数通常比具有完全连接层的类似网络少得多。 这减少了通过参数共享而过拟合的机会,并允许
ConvNets
在较大的图像上运行。 - 也许更重要的是平移不变性。 通过使用相同的参数来处理图像的每个块,即使在图像平面上平移几个像素,
ConvNets
仍能够检测对象或对像素进行分类。 这意味着我们可以随时随地检测到汽车。