前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CS231n:6 训练神经网络(二)

CS231n:6 训练神经网络(二)

作者头像
Here_SDUT
发布2022-08-08 14:14:31
3530
发布2022-08-08 14:14:31
举报
文章被收录于专栏:机器学习炼丹之旅

CS231n第六节:训练神经网络(二) 传送门:Parts 1, 2, 3 本系列文章基于CS231n课程,记录自己的学习过程,所用视频资料为 2017年版CS231n,阅读材料为CS231n官网2022年春季课程相关材料 在上一节中,我们介绍了一个神经元的模型,它将输入数据和自带的权值进行点击后进过一个非线性处理得到输出,同时还介绍了将神经元排列成层组成的神经网络。神经网络定义了一种新的评估函数,这也可以看做是线性分类器中简单地进行线性映射的一种拓展。特别是,神经网络执行的是一连串的线性映射,其中交织着非线性因素。在本节中,我们主要讨论训练一个神经网络的准备工作,包括数据预处理,权重初始化,批度归一化,正则化,以及损失函数的选取。

1. 数据预处理

对于一个数据矩阵 X ,假设数据的大小为 [N*D],N 表示数据的个数, D 表示数据的维度,一共有三种数据预处理的方法。

1.2 Mean subtraction 平均减法

这是一种最常见的预处理形式。它的做法是,对于数据的每个特征属性,减去这个属性的平均值。其集合解释是,沿着每个维度将数据云放在以原点为中心的周围,也就是将数据进行零中心化(zero-centered)。在numpy中,这个操作的实现方式为: X -= np.mean(X, axis = 0)。对于图片数据,为了方便,也可以对每个像素直接减去整个像素的均值(X -= np.mean(X)),或者也可以单独对每个颜色通道进行操作。

1.3 Normalization 归一化

归一化是指对数据维度进行归一化,使其具有大致相同的尺度。有两种常见的方法来实现这种归一化。一种是将每个维度除以其标准差:X /= np.std(X, axis = 0)。这种预处理的另一种形式是对每个维度进行归一化处理,使其在该维度下的取值为 [-1,1]。只有当你确信,不同的输入数据具有不同的尺度(或单位),但应该在模型学习时对这些尺度上的差异一视同仁时,应用这种预处理才有意义。在输入数据为图像时,像素的相对尺度已经大致相等(在0到255的范围内),所以严格来说,没有必要执行这个额外的预处理步骤。

如下图左是原始数据,中间是 Mean subtraction后的结果,数据呈现零中心化,右边是进行归一化的结果,在每个维度上,数据的尺度相同。

image-20220716202907338
image-20220716202907338

1.4 PCA和白化

这是另外一种形式的预处理。在这个过程中,首先如上所述对数据进行居中处理。然后,我们可以计算出协方差矩阵,告诉我们数据中的相关结构。

代码语言:javascript
复制
# Assume input data matrix X of size [N x D]
X -= np.mean(X, axis = 0) # zero-center the data (important)
cov = np.dot(X.T, X) / X.shape[0] # get the data covariance matrix

协方差矩阵 cov 的第(i,j)个元素包含输入数据的第 i 维和第 j 维之间的协方差。特别的,这个矩阵的对角线包含了某个维度的方差。此外,协方差矩阵是对称的和正半定的。我们可以计算出协方差矩阵的SVD因子。

代码语言:javascript
复制
U,S,V = np.linalg.svd(cov)

其中 U 的每列是一个特征向量,S 代表奇异值的一维向量。我们将原始(但经过零中心化处理后)数据投射到特征基中。

代码语言:javascript
复制
Xrot = np.dot(X, U) # decorrelate the data

请注意,U 的列是一组正态向量(范数为1,并且相互正交),所以它们可以被看作是基向量。因此,投影相当于对 X 中的数据进行旋转,这样新的轴就是特征向量。如果我们计算 Xrot 的协方差矩阵,我们会发现它现在是对角线的。np.linalg.svd 的一个很好的特性是,在其返回值 U 中,特征向量列是按其特征值排序的。我们可以利用这一点来降低数据的维度,只使用前几个特征向量,而放弃数据没有差异的维度。这有时也被称为PCA降维:

代码语言:javascript
复制
Xrot_reduced = np.dot(X, U[:,:100]) # Xrot_reduced becomes [N x 100]

经过这样的操作,我们将把大小为 [N x D] 的原始数据集减少到大小为 [N x 100] 的数据集,保留了包含差异最大的100个维度的数据。通常情况下,你可以通过在PCA减少的数据集上训练线性分类器或神经网络来获得非常好的性能的同时节约存储空间和训练时间。

你在实践中可能会看到的最后一种数据预处理是白化。白化操作是将投射到特征基后的数据的每个维度除以该维度对应的特征值,以实现每个维度尺度的归一化。这种预处理的几何解释是,如果输入数据是一个多变量的高斯分布,那么白化后的数据将是一个均值为零、协方差矩阵相同的高斯分布,即使PCA映射后的数据的每个维度尺度相同,代码如下:

代码语言:javascript
复制
# whiten the data:
# divide by the eigenvalues (which are square roots of the singular values)
Xwhite = Xrot / np.sqrt(S + 1e-5)

Warining:噪音的放大。请注意,在上述代码中加入了1e-5(或一个小常数)以防止被零除。这种做法的一个缺点是它会大大夸大数据中的噪声,因为它把所有的维度都拉长到相同大小。这在实践中可以通过更强的平滑化来缓解(即增加1e-5成为一个更大的数字)。

如下图,从左到右分别为原数据,PCA降维之后的数据,经过白化后的数据。

image-20220716204606968
image-20220716204606968

我们也可以尝试用CIFAR-10数据集将这些转换可视化。CIFAR-10的训练集大小为 50,000 x 3072,其中每个图像都被拉伸成 3072 维的行向量。然后我们可以计算[3072 x 3072] 大小的协方差矩阵并计算其SVD分解。计算出的特征向量可视化后效果如下图所示:

左图: 49张图片的示例。左起第二张图:3072个特征向量中的前144个。靠前的特征向量占了数据中的大部分差异,我们可以看到它们对应于图像中的低频率。右起第二张: 用PCA降维后的49幅图像,使用了前144个特征向量。也就是说,与其将每张图像表示为3072维向量,其中每个元素都是某个位置和通道上的特定像素的亮度,不如用144维的向量来表示上面的每张图像,其中向量中的每个元素衡量每个特征向量占据了图像的多少,从而构成了这个图像。为了直观地了解这144个数字中保留了哪些图像信息,我们必须将这144个数字重新转换回3072个像素值。这可以通过乘以 U.transpose()[:144,:] 来实现,然后将得到的3072个数字可视化为图像。你可以看到图像稍显模糊,反映了顶部特征向量捕捉了较低频率的事实。然而,大部分信息仍然被保留下来。最右边的图:白化后数据的可视化,其中144个维度中的每一个维度的方差都被压缩到同等长度。这里,通过乘以 U.transpose()[:144,:] ,将144个白化后的数据逆转回图像的像素。可以发现较低的频率(占大部分方差)现在可以忽略不计,而较高的频率(原来占相对较少的方差)则变得夸张了。

image-20220716205448956
image-20220716205448956

为了预处理方法介绍的完整性,我们在这提到了PCA和白化,但这些转换并不用于卷积网络。不过,对数据进行零中心化是非常重要的,对每个像素进行归一化也是很常见的。

常见的误区:关于预处理的一个重要观点是,任何预处理的统计数据(如数据平均值)必须只在训练数据上计算,然后再应用于验证/测试数据。例如,计算整个数据集的平均值并将整个数据集中的每个像素都减去它,然后将数据分割成训练集、验证集、测试集,这是一个错误的做法。相反,应当只计算训练集中数据的平均值,然后在使用到验证集和测试集时减去训练集的平均值。

2. 权重初始化

我们已经介绍了如何构建一个神经网络架构,以及如何对数据进行预处理。在我们开始训练网络之前,我们必须初始化其参数。

2.1 错误的做法

将所有权重初始化为0。虽然我们不知道训练后的网络中每个权重的最终值是什么,但是通过适当的数据归一化,我们可以合理地假设大约一半的权重是正的,一半是负的。那么,一个听起来合理的想法可能是将所有的初始权重设置为零,我们期望这将是 "最佳猜测"。事实证明这是一个错误,因为如果网络中的每个神经元权重初始化为0,那么它们将计算得到相同的输出,那么它们在反向传播过程中也都会计算得到相同的梯度,并经历完全相同的参数更新。换句话说,如果神经元的权重被初始化为相同,每个神经元将没有差异了,神经元将具有对称性。

2.2 小的随机数

因此,虽然我们希望权重非常接近于零,但正如我们上面所论证的,不能完全为零。作为一种解决方案,通常将神经元的权重初始化为小数字,并将这样做称为对称性的破坏。这个想法是,神经元在开始时都是随机和唯一的,所以它们将获得不同的更新,并将自己整合成为整个网络中的不同部分。一个权重矩阵的初始化可以实现为:W = 0.01* np.random.randn(D,H),其中 randn 从均值为零、单位标准差的高斯分布中获得。通过这种形式,每个神经元的权重向量都被初始化为一个从多维高斯分布中采样得到的随机向量,因此神经元在输入空间中指向随机方向。也可以使用从均匀分布中抽取的小数字,但在实践中,这对最终的性能影响相对较小。

Warning:严格说来,并不是数字越小效果就越好。例如,一个权重非常小的神经网络层在反向传播过程中会在其数据上计算出非常小的梯度(因为这个梯度与权重的值成正比)。这可能会大大减少通过网络向后流动的梯度强度,并可能成为深层网络的一个问题。

2.3 1/sqrt(n) 来改变方差

上述方法的一个问题是,随机初始化的神经元的输出分布有一个方差,这个方差随着输入的数量而增长。事实证明,我们可以通过将每个神经元的权重向量按其扇入 fan-in(即输入数量)的平方根缩放来将其输出方差归一。也就是说,推荐的启发式方法是将每个神经元的权重向量初始化为:w = np.random.randn(n) / sqrt(n),其中 n 是其输入的数量。这确保了网络中的所有神经元最初具有大致相同的输出分布,并提高了收敛率。

简单的推导如下:

设 权重 w 和 输入 x 的内积为 s=\sum_{i}^{n} w_{i} x_{i} ,这是神经元在经过非线性处理之前的输出值,我们可以计算方差:

在前两步中,我们使用了方差的特性。在第三步中,我们假设输入和权重的平均值为零,所以 E[x_i]=E[w_i]=0,注意,一般情况下不是这样的。例如,ReLU单元将有一个正的平均值。在最后一步中,我们假设所有的 w_i,x_i 是同分布的。从这个推导中我们可以看出,如果我们希望 s 的方差与它的所有输入 x 相同,那么在初始化过程中,我们应该确保每个权重 w 的方差是 1/n,由于对于一个随机变量 X 和一个标量 a 来说Var(aX)=a^2Var(X),这意味着我们应该从单位高斯中抽取,然后用 a=\sqrt{1 / n} 缩放,以使其方差为1/n。这就给出了初始化 w = np.random.randn(n) / sqrt(n)

2.4 稀疏的初始化

另一种解决未校准方差问题的方法是将所有权重矩阵设置为零,但为了打破对称性,每个神经元都随机连接(以一个从一个小的高斯分布中取样得到的权重)到它下面固定数量的神经元。连接的神经元的典型数量可能10个左右。

2.5 初始化偏置项

将偏差初始化为零是可能的,也是常见的,因为神经元的不对称性的打破依靠的是权重中的小随机数。对于ReLU的非线性,有些人喜欢对所有的偏置使用小的常数,如0.01,因为这可以确保所有的ReLU单元在开始时就生效,从而获得并传播一些梯度。然而,并不清楚这种改进结果的一致性(事实上,一些结果似乎表明,这表现得更糟),更常见的是简单地使用0初始化偏置项。

在实践中,目前的建议是使用 ReLU作为激活函数,并使用 w = np.random.randn(n) * sqrt(2.0/n) 进行权重初始化,正如 He et al. 中所讨论的。

3. 批度归一化

Ioffe 和Szegedy 最近发明了一项名为 "批度归一化 Batch Normalization" 的技术,通过明确地使整个网络的激活在训练开始时就符合高斯分布,缓解了许多关于如何正确地初始化神经网络的问题。这是可行的,因为归一化是一个简单的可微操作。在实施中,应用这种技术通常相当于在全连接层(或卷积层,我们很快就会看到)之后和非线性之前立即插入 BatchNorm 层。我们在此不对这一技术进行展开,因为它在 Batch Normalization 论文中得到了很好的描述,但请注意,在神经网络中使用批量归一化已经成为一种非常普遍的做法。此外,批量归一化可以解释为在网络的每一层做预处理,但以一种可区分的方式整合到网络本身。

4. 正则化

有几种方法可以控制神经网络的表达能力,以防止过度拟合。

4.1 L2 正则化

L2正则化可能是最常见的正则化形式。对于网络中的每一个权重 w,我们在损失函数中加入 \frac12λw^2 项,其中 λ 是正则化强度。通常会看到前面有 \frac12 ,因为这样使得这一项相对于参数 w 的梯度就只是 λw,而不是 2λw,使得求导方便。L2 正则化的直观解释是严重惩罚较大的权重向量,而倾向于使得权重向量的值比较均衡。正如我们在线性分类部分所讨论的,由于权重和输入之间以乘法的方式相互作用,所以L2正则化实际上是在鼓励网络将全部的输入作为输出的影响因素,而不是将某些输入作为输出的主要影响因素,这是非常吸引人的一个特性。最后,注意到在使用梯度下降更新参数期间,使用 L2 正则化意味着每个权重最终都是线性衰减到零的,其形式为 W += -lambda * W

4.2 L1 正则化

L1正则化是另一种比较常见的正则化形式,对于每个权重 w,我们在损失函数中加入 λ∣w∣ 这个项。同时,我们还可以将 L1 正则化与 L2 正则化相结合:λ_1∣w∣+λ_2w^2(这被称为 Elastic net regularization)。L1正则化有一个有趣的特性,它会导致权重向量在优化过程中变得稀疏(即非常接近于零)。换句话说,具有L1正则化的神经元最终只使用输入数据中最重要部分的稀疏子集,并变得对 "嘈杂 "的输入几乎没有变化。相比之下,来自 L2 正则化的最终权重向量通常是分散的、小数字。在实践中,如果你不关心明确的特征选择,可以预期L2正则化会比L1正则化有更好的性能。

4.3 Maxnorm 正则化

正则化的另一种形式是对每个神经元的权重向量的大小实施绝对的上限,并使用投影梯度下降法来实施该约束。在实践中,这相当于正常执行参数更新,然后通过限制每个神经元的权重向量 \vec{w} 来强制执行约束,以满足\|\vec{w}\|_{2}<c 的要求。c 的典型值是 3 或 4 的数量级。有些人说,使用这种形式的正则化会有改进。它的一个吸引人的特性是,即使学习率设置得太高,梯度也不会 "爆炸",因为更新总是有界限的。

4.4 Dropout

Dropout是Srivastava等人最近在 Dropout: A Simple Way to Prevent Neural Networks from Overfitting 中提出的一种极其有效、简单的正则化技术。在训练时,Dropout的实现方式是以某个概率 p(一个超参数)保留每个神经元,其余没被保留的就丢弃,即将其设置为零,不参与更新,示意图如下所示:

在训练过程中,Dropout可以被解释为在整个神经网络中对一个子神经网络进行采样,并且根据输入数据,只更新被采样网络的参数。(然而,大部分被采样的网络并不独立,因为它们共享参数)。在测试模型时,没有使用dropout,其解释是为了评估所有子网络的集合的平均效果。

在一个3层神经网络的例子中,原始的dropout将被实现如下:

代码语言:javascript
复制
""" Vanilla Dropout: Not recommended implementation (see notes below) """

p = 0.5 # probability of keeping a unit active. higher = less dropout

def train_step(X):
  """ X contains the data """
  
  # forward pass for example 3-layer neural network
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = np.random.rand(*H1.shape) < p # first dropout mask
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = np.random.rand(*H2.shape) < p # second dropout mask
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3
  
  # backward pass: compute gradients... (not shown)
  # perform parameter update... (not shown)
  
def predict(X):
  # ensembled forward pass
  H1 = np.maximum(0, np.dot(W1, X) + b1) * p # NOTE: scale the activations
  H2 = np.maximum(0, np.dot(W2, H1) + b2) * p # NOTE: scale the activations
  out = np.dot(W3, H2) + b3

在上面的代码中,在 train_step 函数中,我们进行了两次 dropout:在第一隐藏层和第二隐藏层。也可以在输入层上直接执行dropout,在这种情况下,我们也会为输入 X 创建一个二进制掩码。

最重要的是,注意在 predict 函数中,我们不使用 dropout,而是对两个隐藏层的输出进行 p 的缩放。这很重要,因为在测试模型时,所有的神经元都得到了它们的所有输入,所以我们希望测试时神经元的输出与训练时的预期输出相同。例如,在 p=0.5 的情况下,神经元在测试时必须将其输出减半,以获得与训练时相同的输出的期望值。为了看到这一点,考虑一个神经元 x 的输出(dropout前),在使用 dropout 后,该神经元的预期输出将变成 p*x+(1-p)*0,因为该神经元的输出将以 1-p 的概率被设置为零。在测试模型时,当我们保持该神经元始终处于活动状态时,我们必须调整 x→px 以保持相同的预期输出。

上面提出的方案的不理想之处在于,我们必须在测试时将输出按 p 进行调整。由于测试模型时的计算性能非常关键,这样的调整会耗费计算性能。所以最好是使用倒置的dropout,它在训练时进行缩放,而在测试时不调整前向传播。此外,这还有一个吸引人的特性,即当你决定调整应用dropout的位置时,预测模型的代码可以保持不动(实现了降耦)。其代码如下:

代码语言:javascript
复制
""" 
Inverted Dropout: Recommended implementation example.
We drop and scale at train time and don't do anything at test time.
"""

p = 0.5 # probability of keeping a unit active. higher = less dropout

def train_step(X):
  # forward pass for example 3-layer neural network
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = (np.random.rand(*H1.shape) < p) / p # first dropout mask. Notice /p!
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = (np.random.rand(*H2.shape) < p) / p # second dropout mask. Notice /p!
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3
  
  # backward pass: compute gradients... (not shown)
  # perform parameter update... (not shown)
  
def predict(X):
  # ensembled forward pass
  H1 = np.maximum(0, np.dot(W1, X) + b1) # no scaling necessary
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  out = np.dot(W3, H2) + b3

在首次引入dropout之后,有大量的研究试图了解它在实践中的力量来源,以及它与其他正则化技术的关系。推荐感兴趣的读者进一步阅读的内容包括:

前向传播中的噪声:

Dropout 以一个更普遍的方式在网络的前向传递中引入随机量。这些方法都是在训练的时候增加随机噪声,测试时通过分析法(在使用随机失活的本例中就是乘以 p )或数值法(例如通过抽样出很多子网络,随机选择不同子网络进行前向传播,最后对它们取平均)将噪音边缘化。这个方向的一个例子包括DropConnect,它在前向传递过程中,将一组随机的权重设置为零。作为预示,卷积神经网络也利用了这个方法,如随机池化、分数池化和数据增强。我们将在后面讨论这些方法的细节。

偏置项正则化:

正如我们在线性分类部分已经提到的,对偏置参数进行正则化并不常见,因为它们不通过乘法与数据进行交互,因此不具有控制数据维度从而对最终目标产生影响的能力。然而,在实际应用中(并且有适当的数据预处理),对偏置项进行正则化很少会导致性能明显下降。这可能是因为与所有的权重相比,偏置项非常少。

分层正则化:

对不同的层(也许输出层除外)采用不同的正则化并不是很常见。文献中发表的关于这一想法的结果相对较少。

在实践中:

最常见的是使用单一的、全局的、经过交叉验证的L2正则化。在所有层之后将其与 dropout 结合起来也很常见。p=0.5的值是一个合理的默认值,但这可以在验证集上进行调参。

5. 损失函数

我们已经讨论了损失函数中的正则化部分,它可以被看作是对模型的某种复杂性的惩罚。损失函数的第二部分是数据的损失值,在监督学习问题中,数据损失值用于衡量预测结构(如分类任务中的类别得分)和真实标签之间的差距。数据损失的形式是每一条数据的损失的平均值。也就是说,L=\frac{1}{N} \sum_{i} L_{i},其中 N 是训练集中数据的数量。让我们把 f=f(x_i;W) 简称为神经网络中输出层的激活值(即经过非线性处理后的输出)。在实践中,有几种类型的问题你可能想要解决:

5.1 分类问题

分类是我们到目前为止已经详细讨论过的情况。在这里,我们假设有一个数据集,数据集中的每一个样本都有唯一的正确的标签(标签取自一个固定的集合)。在这种情况下,两个最常见的成本函数之一是SVM(例如Weston Watkins公式):

正如我们简要提到的,有些人报告说使用平方铰链损失 (squared hinge loss ) 的性能更好(即改用max(0,f_j-f_{y_i}+1)^2)。第二个常见的选择是使用交叉熵损失的Softmax分类器:

类别很多时:

当标签集非常大时(如英语词典中的单词,或包含22,000个类别的ImageNet),计算完整的softmax概率变得非常慢。对于某些应用,近似的版本很受欢迎。例如,在自然语言处理任务中使用分层Softmax可能会有帮助(点击这里 here 跳转论文)。分层softmax将单词分解为树上的标签。然后,每个标签被表示为沿树的路径,在树的每个节点上训练一个Softmax分类器,以消除左、右分支之间的歧义(构造哈夫曼树)。树的结构对性能有很大影响,一般来说,树的结构取决于具体问题。

多属性的分类:

上述两种损失都假定有一个单一的正确答案 y_i。但是,如果 y_i 是一个二元向量,每个例子可能有也可能没有某个属性,而且这些属性并不具有排他性呢?例如,Instagram上的图片可以被认为是用一大堆标签中的某个标签子集标记的,而一张图片可能包含多个标签。在这种情况下,明智的做法是为每个单一的属性独立建立一个二元分类器。例如,每个类别独立的二元分类器将采取以下形式:

其中,总和表示对于所有类别 j 的总和,根据第 i 个样本是否被标记为第 j 个类别属性,y_{ij}为+1或-1,当预测该类别存在时,得分向量 f_j 为正,否则为负。请注意,如果一个正面的例子的得分小于+1,或者一个负面的例子的得分大于-1,那么损失就会累积。

这种损失函数的一种替代方法是为每个属性独立训练一个逻辑回归分类器。二元逻辑回归分类器只有两个类别(0,1),计算类别1的概率为:

由于1类和0类的概率之和为1,0类的概率为P(y=0∣x;w,b)=1-P(y=1∣x;w,b) 。因此,如果 σ(w^Tx+b)>0.5,或者等价于 w^Tx+b>0,则一个例子被归类为正面例子(y=1)。这可以简化为最小化负的对数似然函数:

其中标签 y_{ij} 被假定为 1(正)或 0(负),σ(⋅)是 sigmoid 函数。上面的表达式看起来很吓人,但实际上 f 的梯度是非常简单和直观的:∂L_i/∂f_j=σ(f_j)-y_{ij}(你可以通过求导数来反复检查)。

5.2 回归问题

回归是预测实值值的任务,例如预测房屋的价格或图像中某物的长度。对于这项任务,通常是计算预测值和真实值之间的损失,然后测量 L2 平方准则或 L1 准则的差异。L2规范的平方将计算出一个单一例子的损失为:

在损失函数中使用 L2 准则进行平方的原因是梯度变得更加简单的同时不会改变训练结果,因为平方是一个单调的操作。L1准则将通过沿每个维度的绝对值相加来得到:

其中 ∑_j 是所需预测的所有维度的总和。只看第 i 个例子的第 j 个维度,用 δ_{ij} 表示真实值和预测值之间的差异,这个维度的梯度(即∂L_i/∂f_j)很容易得出,如果使用L2作为损失函数,那么梯度就是2δ{ij},如果使用L1作为损失函数,那么梯度就是 sign(δ_{ij})。也就是说,损失值上的梯度要么与误差的差异成正比,要么是固定的,只继承差异的符号。

需要注意的是,L2损失比Softmax等更稳定的损失更难优化。直观地说,它要求网络具有非常脆弱和特殊的属性,即使得网络能够为每个输入(及其增强)准确输出一个正确的值。请注意,Softmax的情况并非如此,每个分数的精确值并不那么重要:重要的是它们的大小是合适的。此外,L2损失的稳健性较差,因为离群值会引入巨大的梯度。当面临回归问题时,首先要考虑的是是否绝对必要将输出量化为一个确切的数值。例如,如果你要预测一个产品的星级,使用5个独立的分类器来预测1-5星的评级,而不是使用回归,效果可能会好很多。分类有一个额外的好处,它可以给你一个回归输出的分布,而不仅仅是一个没有显示其置信度的单一输出。如果你确定分类不合适,可以使用L2,但要小心。例如,L2比较脆弱,在网络中应用dropout(尤其是在L2损失之前的那一层)并不是一个好主意。

When faced with a regression task, first consider if it is absolutely necessary. Instead, have a strong preference to discretizing your outputs to bins and perform classification over them whenever possible. 当面临回归任务时,首先要考虑它是否绝对必要。相反,强烈倾向于将你的输出离散化,并尽可能地对它们进行分类。

5.3 结构化预测

结构化损失指的是标签可以是任意结构的情况,如图、树或其他复杂对象。通常还假设结构的空间非常大,不容易列举。结构化SVM损失的基本思想是要求正确的结构 y_i 和得分最高的不正确结构之间有一个差值。将这个问题作为一个简单的无约束优化问题,并用梯度下降法解决并不常见。相反,通常会设计一些特殊的求解器,这样就可以利用特定的结构空间简化假设。具体细节不在本课的范围之内。

6. 总结

综上所述:

  • 推荐的预处理方法是将数据居中,使其平均值为零,并沿每个特征将其尺度归一化为[-1, 1]。
  • 通过从标准偏差为 \sqrt{2 / n} 的高斯分布中提取权重进行初始化,其中 n 是神经元的输入个数。例如,在numpy中:w = np.random.randn(n) * sqrt(2.0/n)。使
  • 用L2正则化 和 dropout(倒置版)。
  • 使用批量正则化 batch normalization
  • 我们讨论了你在实践中可能要执行的不同任务,以及每个任务最常见的损失函数。现在我们已经对数据进行了预处理,并建立和初始化了模型。在下一节中,我们将看看学习过程和它的动态变化。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-7-16 2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 数据预处理
    • 1.2 Mean subtraction 平均减法
      • 1.3 Normalization 归一化
        • 1.4 PCA和白化
        • 2. 权重初始化
          • 2.1 错误的做法
            • 2.2 小的随机数
              • 2.3 用 1/sqrt(n) 来改变方差
                • 2.4 稀疏的初始化
                  • 2.5 初始化偏置项
                  • 3. 批度归一化
                  • 4. 正则化
                    • 4.1 L2 正则化
                      • 4.2 L1 正则化
                        • 4.3 Maxnorm 正则化
                          • 4.4 Dropout
                          • 5. 损失函数
                            • 5.1 分类问题
                              • 5.2 回归问题
                                • 5.3 结构化预测
                                • 6. 总结
                                相关产品与服务
                                NLP 服务
                                NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档