创建智能自动编码器有什么问题?的方法有哪些?

入门

考虑到涉及的许多参数,设计深度神经网络可能是一项痛苦的任务,并且没有适用于所有用例的万能公式。我们可以使用卷积神经网络 (CNN) 进行图像分类,使用 LSTM 进行 NLP 相关任务,但特征数量、特征大小、神经元数量、隐藏层数量、激活函数的选择、权重的初始化等。在不同的用例中会有所不同。

图像数据集:与相邻像素的相关性

参数的这些变化可归因于不同类型的数据,并且需要独立于其他数据集进行分析。像图像数据集将具有不同的属性,因为相邻位置的像素是相关的,但在关系数据库条目中可以是随机的,没有关系。因此,需要一种不同的方法。

我们能够为它们泛化数据类型和合适的神经网络结构类型,例如用于图像、音频、视频的 CNN 和用于 NLP 相关任务的 RNN/LSTM 等。但是,为了获得最大性能,我们应该让它们变得更智能。

暗淡(h) 暗淡(h) ≥ 暗淡(xi)

为简单起见,我们将讨论限制在自动编码器上,这是一种特殊类型的前馈神经网络,它在隐藏层中对输入进行编码,并从该隐藏表示中对其进行解码。每个神经网络架构都有一个自动编码器作为其基本块。因此,通过讨论它们,我们可以扩展不同深度学习架构的思想。

在本文中,我们将探索微调网络以获得更好的验证准确性和更好的预测的技术。此外,我们将查看这些技术背后的一些数学知识,以了解这些技术的幕后情况。

创建智能自动编码器有什么问题?

我们真正想要的神经网络是从可用数据中泛化而不是记忆它。死记硬背的问题在于模型最终可能会过度拟合。由于深度学习模型很复杂,它们往往会超出目标函数。考虑一些非常基本的情况,其中模型在训练数据集上进行了广泛的训练,使得训练数据集上的误差最小化并接近于零。神经网络可以不捕捉数据中的趋势,而只是记住使用复杂函数再现整个数据的方法。

让我们使用偏差与方差权衡的概念更清楚地理解这一点。看下图,x 轴代表模型复杂度,y 轴代表误差。随着复杂度的增加,训练误差趋于减小,但方差增加,显示出较高的验证误差。

蓝色:训练错误,红色:验证错误

该模型最初将具有高偏差,并且随着训练误差接近零,模型将过度拟合导致高方差。

我们希望模型更敏感地捕捉稀疏但重要特征的细微细节。因此,不拟合数据根本不是一种选择。因为更复杂的模型对变化更敏感。关于过拟合的讨论只有在深度学习的背景下才有意义。

以过完备编码器为例,它们可以通过复制粘贴整个网络的值来学习简单的编码。这就像将输入 (xi) 复制到隐藏层 (h),然后从 h 复制到输出层 (x hat)。显然,错误将是最小的,但没有学习

它也是一种过度拟合的形式,因为自动编码器捕获了训练数据中权重映射的所有变化。

让我们在上述讨论的基础上,为了让深度学习自动编码器成功,必须消除过拟合。当然,仍然存在数据不足、参数量大、相关特征是否掌握、何时停止训练等问题。可以说,智能自动编码器概括了我们可以观察和学习重要趋势的信息,并从中进行预测。让我们开始探索这些技术,目的是培养直觉、使用它们的理由和合适的例子来增强我们的学习。

数据集增强 Early Stop l2 正则化避免 Vanilla Autoencoders:噪声和稀疏参数共享和绑定 DropOut 和 DropConnect 数据集增强的集成方法

在计算机视觉分类任务中,训练数据越多,模型的学习效果就越好。但海量数据的问题在于它增加了训练时间。

在深度学习模型中,参数的数量是巨大的(大约数百万)。如果一开始没有足够的数据可用,这显然会有所帮助。但是,如果您已经有足够的数据,这有帮助吗?是的,因为它会增加数据集中的相关特征,这将有助于自动编码器学习重要的稀疏特征,而不是不相关的丰富特征。

数据增强是一种技术,我们从现有数据中创建新数据,目的是增强原始数据中的相关特征。请参阅下图以了解数据增强的概念。

不变性:根据平移、旋转、大小、视点和光照的差异对数据进行稳健分类

通过这种方式,最明显的分类特征被添加成为最相关的特征。在 ML 管道中在哪里扩充数据?第一个是离线增强以应用转换并将图像添加到数据集。但是,它会根据应用的转换次数增加大小。其次,在进入我们的学习模型之前,将在线增强应用于小批量。在这里,假设我们不关心图像边界之外的内容,请查看一些用于此类转换的 Tensorflow 脚本。

这是什么意思?假设图像的某些部分什么都没有,即它是未知空间,那么我们需要不同的变换如下。例如,一些带有黑色背景的旋转图像。

从左侧开始,应用了常量、边缘、反射、对称和环绕变换

Tensorflow 脚本基于上述关于在小批量上应用简单数据转换的假设。Python示例代码如下:

# 1. Flip: 'x' = A placeholder for an image.
shape = [height, width, channels]
x = tf.placeholder(dtype = tf.float32, shape = shape)
flip_2 = tf.image.flip_up_down(x)
flip_5 = tf.image.random_flip_left_right(x)
# 2. Rotate: 'y' = A batch of images
# To rotate in any angle. In the example below, 'angles' is in radians
shape = [batch, height, width, 3]
y = tf.placeholder(dtype = tf.float32, shape = shape)
rot_tf_180 = tf.contrib.image.rotate(y, angles=3.1415)
# 3. Noise: 'x' = A placeholder for an image.
shape = [height, width, channels]
x = tf.placeholder(dtype = tf.float32, shape = shape)
# Adding Gaussian noise
noise = tf.random_normal(shape=tf.shape(x), mean=0.0, stddev=0.5,
dtype=tf.float32)
output = tf.add(x, noise)

对于随机裁剪、包装、颜色通道转换等,可以类似地编写其他增强功能。

早点停止

正如名称(Early Stopping)所暗示的那样,它确实为我们提供了一些我们在训练时提前停止以避免拟合的信息。但是如何提前停止呢?基本上,我们的目标是在训练错误被推向零并且验证错误即将爆发之前停止。

参数P:如果你在第k步并且验证错误在前面的步骤中没有改善,停止训练并返回到第kp步存储的模型。

这些早期停止规则通过将原始训练集拆分为新的训练集和验证集来发挥作用。验证集上的误差用于替换原始训练误差,以确定何时开始过度拟合。使用 Keras,您可以通过以下方法做到这一点。Python示例如下:

keras.callbacks.EarlyStopping(monitor='val_loss',
 min_delta=0,
 patience=0,
 verbose=0, mode='auto')

min_delta 是否将某个时期的损失量化为改进的阈值。如果 loss 的差异低于 min_delta,则量化为没有改善。耐心参数表示一旦损失开始增加(停止改进),在停止之前的 epoch 数。mode参数取决于你监控数量的方向(应该减少还是增加),因为我们监控损失,我们可以使用min。

现在,如果我说 Early Stopping 也是一种正则化技术。你能证明这个说法是正确的吗?让我们看一个小数学。请记住,正则化是指向学习神经网络添加一些权重和偏差约束的技术。

更新随机梯度下降的规则。让’τ’是delta(wi)的最大梯度。将不等式应用于上述等式,我们得到:

t 控制从 wt 到初始 w0 的距离

提前停止只允许参数更新。更重要的是,维度越大,与之相关的损失也越大,如上式所示,我们控制学习率和 t,只有与梯度相关的损失是主导因素,这实际上意味着只有越大的损失是。重要参数将占更多。

在那里,不太重要的将无法成长。因此,重要的参数被放大,这将导致更好的准确性。这类似于 L2 正则化,见下文。

L2 正则化

正则化是学习过程中对模型的约束。L2正则化是权重衰减正则化,它使权重更接近原点,减少了不太重要的特征。

让我们以直观的方式理解真正错误的概念。这个误差可以用下面给出的形式表示,其中添加到经验误差的项是基于估计过程的神经网络 参数初始化,因为我们不知道 f(x)。

其中 yi = f(xi) + ε, ε 是小值

主要目的是将模型复杂性对真实误差的影响联系起来。显然,它增加了训练误差。这是什么?在斯坦因引理和一些数学的帮助下,我们可以证明这一点

当观察值的微小变化导致估计值(fhat(xi))发生较大变化时神经网络 参数初始化,误差会更大。

这与复杂模型有关吗?是的,上述观察与模型越复杂,对观察到的变化越敏感这一事实有关。所以我们可以说真实误差 = 经验训练误差 + 小常数 + Ω(模型复杂度)。Ω 是正则化的基础。因此,在正则化中,我们的目标是最小化由于模型复杂性引起的误差,而这又与偏差-方差权衡有关。

添加这个术语的直觉是训练误差永远不会达到零。w 影响上述方程的梯度和更新规则。

上面添加到更新规则和SGD公式是什么意思。上面提到的等式2运算在数学上表示了权重矩阵在重要方向上的缩放,即具有主次特征值的那个被缩放了,但是不太重要的特征被进一步缩小了。这种正则化操作首先有效地旋转了权重矩阵,然后将其对角化,然后再次旋转。在这里,查看这些等效的等高线图操作。

权重向量 (w*) 旋转到 (w̃)。在几何上,所有特征都在缩小,但有些缩小得更多。可以为重要特征分配更多权重。

这是基于上述公式在神经网络模型中使用正则化的 Tensorflow 脚本。第一个例子是只在一个层上使用它,第二个是在所有层上使用它。Python代码如下:

# Code 1:
# Loss function using L2 Regularization
regularizer = tf.nn.l2_loss(weights)
loss = tf.reduce_mean(loss + beta * regularizer)
# Optimizer.
 optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
# Code 2:
# Loss for all trainable variables, 0.001 is beta above
vars = tf.trainable_variables() 
regularizer = tf.add_n([ tf.nn.l2_loss(v) for v in vars ]) * 0.001
# Let's say you wan't to regularize biases
regularizer = tf.add_n([ tf.nn.l2_loss(v) for v in vars
 if 'bias' not in v.name ]) * 0.001
# More descriptive code
regularizers = tf.nn.l2_loss(weights_1) + tf.nn.l2_loss(weights_2) + tf.nn.l2_loss(weights_3) + tf.nn.l2_loss(weights_4) + tf.nn.l2_loss(weights_5) + tf.nn.l2_loss(weights_6)
loss = tf.reduce_mean(loss + beta * regularizers)

避免香草自动编码器:噪声和稀疏性

考虑如上所述的过度完整的香草自动编码器的情况。显然,它们容易过度拟合和琐碎的学习。所以在这些情况下使用这些普通的自动编码器不会有太大的好处。通过向输入添加噪声来解决此问题的一种方法是强制神经网络不要学习琐碎的编码,而是专注于更多的泛化。

去噪编码器在将输入数据馈送到网络之前使用概率过程 (P(x(tilda)ij|xij)) 简单地破坏输入数据。这些被称为去噪自动编码器。Python代码如下:

# Generate corrupted MNIST images by adding noise with normal dist # centered at 0.618 and std=0.618 
noise = np.random.normal(loc=0.618, scale=0.618, size=x_train.shape)
x_train_noisy = x_train + noise
noise = np.random.normal(loc=0.618, scale=0.618, size=x_test.shape)
x_test_noisy = x_test + noise
# np.clip to move out of bound values inside given interval
x_train_noisy = np.clip(x_train_noisy, 0., 1.) x_test_noisy = np.clip(x_test_noisy, 0., 1.)

图描述了针对不同特征(例如,MNIST 数据集中的笔画、数字边缘)激发的神经元。显然,与普通 AE 相比,我们可以看到去噪 AE 捕获的更有意义的模式。

随着高斯噪声的加入,这些隐藏的神经元变成了边缘检测器,这是 PCA 无法提供的。此外,噪声可以应用于目标类,这将导致具有随机分析的软目标而不是硬目标。

稀疏自动编码器也被用来解决这个参数稀疏的问题,这将导致在特征相关的极少数情况下观察神经元。它可以写为 L^(θ) = L(θ) + Ω(θ),其中 L(θ) 是平方误差损失或交叉熵损失,Ω(θ) 是稀疏约束力触发的一个重要特征神经元。

好处:对于收缩自动编码器,正则化项 Ω(θ) = ||J x(h)||^2 是编码器的雅可比行列式。Jacobian 的 (j, l) 项捕捉到了第 l 个神经元输出的变化,而第 j 个输入的变化很小。L(θ) – 捕捉重要的变化数据 & Ω(θ) – 不捕捉变化的数据,雅可比矩阵使神经元对变化不敏感。通过这种权衡,我们只能捕获最重要的特征。可以对稀疏 AE 进行类似的讨论。

参数共享和绑定

共享权重仅仅意味着使用相同的权重向量进行计算。这样做的主要动机是限制参数的数量。

ℎ1 = · [1:3], ℎ2 = · [3:5], ℎ3 = · [5:7]

我们可以通过做一个直观的假设来显着减少我们的参数,即如果一个特征在某一点计算上很重要,那么它在另一点也很重要。示例:如果在特定位置检测边缘很重要。因此,由于图像的平移不变结构,所有边缘都重复它们的位置。这将导致更快的收敛。此外,我们限制了灵活性,这也可以作为一种正则化机制来避免过度拟合。考虑一种情况,我们希望并行处理两组图像,但也希望列共享参数。

def function(x, reuse):
 with tf.variable_scope(layer_name) as s:
 output = tf.contrib.layers.convolution2d(inputs = x, num_outputs = 10, kernel_size = [3, 3], stride = [1, 1], padding = 'VALID', reuse = reuse, scope = s)
 return output
 
output1 = function(image1, False)
output2 = function(image2, True)

权重绑定概念基于与上述相同的思想,具有相同的参数减少动机,但应用于自动编码器单元,其中编码器权重和解码器权重被绑定和使用。它降低了自编码器的容量并充当正则化器。

绑定encoder和decoder的权重,即W* = W T。

DropOut 和 DropConnect 集成

集成组合不同模型的输出以减少泛化误差,并且模型可以是不同的分类器。在这里,它们是在不同超参数、特征和不同训练数据样本上训练的同一神经网络的不同实例。Bagging 是一种跨整个数据集的方法,用于在训练数据的子集上训练模型。因此,给定模型中没有显示一些训练示例。它允许不同的神经元使用不同的训练数据收集不同的相关特征。所有模型的平均预测误差如何?

期望平方误差由下式给出: 从每个模型的平均预测中获得的误差期望

从上面看,模型彼此之间的独立性越小,误差只会减少到 (V/k)。非常好,因为理想情况下,当神经网络的架构变化很大时,误差会非常小。然而,随着单个模型数量的增加,训练参数的数量急剧增加。随着训练变得计算成本高昂。

如果我们可以减少这些参数,那不是很好。此外,不同的架构将帮助我们增加模型之间的差异。Dropout 解决了这两个问题。它给出了组合许多不同网络的近似值,并在没有任何显着开销的情况下训练多个网络。它在所有网络之间共享权重,并为每个训练实例采样不同的训练网络。只有有效参数从前向和反向传播中更新。不是聚合 2^n 稀疏网络,而是每个节点的输出按训练周期的一小部分进行缩放。

辍学是指辍学单位。即一个节点及其所有传入/传出连接都被暂时删除,从而导致网络变薄。

它适用于每个训练示例中的特征,导致某些特征对网络不可用。因为神经元不能完全依赖于一个输入,这些网络中的表示往往更加分散,网络不太可能过度拟合。这是因为 dropout 会将掩蔽噪声放入隐藏单元中,从而阻止协同适应,并且本质上隐藏单元不依赖于其他单元来检测特定特征,因为这些单元可能会丢失。这使得隐藏单元更加健壮。

Python代码如下:

# Simple keras implementation of MNIST for dropout
import tensorflow as tf
mnist = tf.keras.datasets.mnist
 
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
 
model = tf.keras.models.Sequential([
 tf.keras.layers.Flatten(),
 tf.keras.layers.Dense(512, activation=tf.nn.relu),
 tf.keras.layers.Dropout(0.2),
 tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
 loss='sparse_categorical_crossentropy',
 metrics=['accuracy'])
 
model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

什么是dropconnect?好吧,假设我们不删除节点而是随机子集。它的行为与 dropout 类似。将从伯努利分布中提取的二进制掩码应用于原始权重矩阵。

由于输入数据类或连接对更深层的贡献,不是在每个训练会话中随机丢弃连接,而是丢弃并保留连接。

tf.nn.dropout(W, keep_prob=p) * p 
OR
tf.layers.dropout(W, rate=1-p) * p

综上所述

根据何时使用这些技术的直觉,我们可以创建高效的深度神经网络,在学习任何特定任务的同时,其核心更智能。

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论