Machine Learning Mastery Keras 深度学习教程(十)
在 Python 和 Keras 中对深度学习模型使用学习率调度
原文:
machinelearningmastery.com/using-learning-rate-schedules-deep-learning-models-python-keras/
训练神经网络或大型深度学习模型是一项困难的优化任务。
训练神经网络的经典算法称为随机梯度下降。已经确定,通过使用在训练期间发生变化的学习率,您可以在某些问题上实现更高的表现和更快的训练。
在这篇文章中,您将了解如何使用 Keras 深度学习库在 Python 中为神经网络模型使用不同的学习率调度。
阅读这篇文章后你会知道:
- 如何配置和评估基于时间的学习率调度。
- 如何配置和评估基于丢弃的学习率调度。
让我们开始吧。
- 2017 年 3 月更新:更新了 Keras 2.0.2,TensorFlow 1.0.1 和 Theano 0.9.0 的示例。
使用 Keras 在 Python 中使用深度学习模型的学习率调度哥伦比亚 GSAPP ,保留一些权利。
训练模型的学习率表
调整随机梯度下降优化程序的学习率可以提高表现并缩短训练时间。
有时这称为学习率退火或自适应学习率。在这里,我们将此方法称为学习率调度,默认计划是使用恒定学习率来更新每个训练时期的网络权重。
在训练期间最简单且可能最常用的学习率调整是随时间降低学习率的技术。当使用较大的学习率值时,这些具有在训练过程开始时进行大的改变的益处,并且降低学习率,使得在训练过程中稍后对权重进行较小的速率并因此进行较小的训练更新。
这具有早期快速学习良好权重并稍后对其进行微调的效果。
两个流行且易于使用的学习率表如下:
- 根据时代逐渐降低学习率。
- 在特定时期使用间断大滴,降低学习率。
接下来,我们将看看如何使用 Keras 依次使用这些学习率调度。
基于时间的学习费率表
Keras 内置了基于时间的学习率调度。
SGD 类中的随机梯度下降优化算法实现具有称为衰减的参数。该参数用于基于时间的学习率衰减调度方程如下:
LearningRate = LearningRate * 1/(1 + decay * epoch)
当衰减参数为零(默认值)时,这对学习率没有影响。
LearningRate = 0.1 * 1/(1 + 0.0 * 1)
LearningRate = 0.1
当指定衰减参数时,它将使学习率从前一个迭代减少给定的固定量。
例如,如果我们使用 0.1 的初始学习率值和 0.001 的衰减,前 5 个时期将调整学习率如下:
Epoch Learning Rate
1 0.1
2 0.0999000999
3 0.0997006985
4 0.09940249103
5 0.09900646517
将其延伸到 100 个时期将产生以下学习率(y 轴)与时期(x 轴)的关系图:
基于时间的学习费率表
您可以通过设置衰减值来创建一个不错的默认计划,如下所示:
Decay = LearningRate / Epochs
Decay = 0.1 / 100
Decay = 0.001
以下示例演示了在 Keras 中使用基于时间的学习率适应计划。
它在电离层二分类问题上得到证实。这是一个小型数据集,您可以从 UCI 机器学习库下载。使用文件名 ionosphere.csv 将数据文件放在工作目录中。
电离层数据集适用于使用神经网络进行实践,因为所有输入值都是相同比例的小数值。
构建一个小型神经网络模型,其中一个隐藏层具有 34 个神经元并使用整流器激活函数。输出层具有单个神经元并使用 S 形激活函数以输出类似概率的值。
随机梯度下降的学习率已设定为 0.1 的较高值。模型训练 50 个时期,衰减参数设置为 0.002,计算为 0.1 / 50。此外,在使用自适应学习率时使用动量可能是个好主意。在这种情况下,我们使用动量值 0.8。
下面列出了完整的示例。
# Time Based Learning Rate Decay
from pandas import read_csv
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
from sklearn.preprocessing import LabelEncoder
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load dataset
dataframe = read_csv("ionosphere.csv", header=None)
dataset = dataframe.values
# split into input (X) and output (Y) variables
X = dataset[:,0:34].astype(float)
Y = dataset[:,34]
# encode class values as integers
encoder = LabelEncoder()
encoder.fit(Y)
Y = encoder.transform(Y)
# create model
model = Sequential()
model.add(Dense(34, input_dim=34, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal', activation='sigmoid'))
# Compile model
epochs = 50
learning_rate = 0.1
decay_rate = learning_rate / epochs
momentum = 0.8
sgd = SGD(lr=learning_rate, momentum=momentum, decay=decay_rate, nesterov=False)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
# Fit the model
model.fit(X, Y, validation_split=0.33, epochs=epochs, batch_size=28, verbose=2)
该模型在 67%的数据集上进行训练,并使用 33%的验证数据集进行评估。
运行该示例显示分类准确度为 99.14%。如果没有学习率下降或动量,这高于 95.69%的基线。
...
Epoch 45/50
0s - loss: 0.0622 - acc: 0.9830 - val_loss: 0.0929 - val_acc: 0.9914
Epoch 46/50
0s - loss: 0.0695 - acc: 0.9830 - val_loss: 0.0693 - val_acc: 0.9828
Epoch 47/50
0s - loss: 0.0669 - acc: 0.9872 - val_loss: 0.0616 - val_acc: 0.9828
Epoch 48/50
0s - loss: 0.0632 - acc: 0.9830 - val_loss: 0.0824 - val_acc: 0.9914
Epoch 49/50
0s - loss: 0.0590 - acc: 0.9830 - val_loss: 0.0772 - val_acc: 0.9828
Epoch 50/50
0s - loss: 0.0592 - acc: 0.9872 - val_loss: 0.0639 - val_acc: 0.9828
基于丢弃的学习率调度
与深度学习模型一起使用的另一种流行的学习率调度是在训练期间的特定时间系统地降低学习率。
通常,通过将学习率降低每个固定数量的迭代的一半来实现该方法。例如,我们可能具有 0.1 的初始学习率并且每 10 个时期将其降低 0.5。前 10 个训练时期将使用 0.1 的值,在接下来的 10 个时期中将使用 0.05 的学习率,依此类推。
如果我们将此示例的学习率绘制到 100 个时期,您将得到下图,显示学习率(y 轴)与时期(x 轴)。
基于丢弃的学习率调度
在拟合模型时,我们可以使用 LearningRateScheduler 回调在 Keras 中实现此功能。
LearningRateScheduler 回调允许我们定义一个调用函数,该函数将迭代号作为参数,并返回用于随机梯度下降的学习率。使用时,忽略随机梯度下降指定的学习率。
在下面的代码中,我们在 Ionosphere 数据集上的单个隐藏层网络之前使用相同的示例。定义了一个新的 step_decay()函数来实现等式:
LearningRate = InitialLearningRate * DropRate^floor(Epoch / EpochDrop)
其中,InitialLearningRate 是初始学习率,例如 0.1,DropRate 是每次更改学习率时修改的量,例如 0.5,Epoch 是当前的迭代号,EpochDrop 是改变学习率的频率,例如 10 。
请注意,我们将 SGD 类中的学习率设置为 0,以清楚地表明它未被使用。不过,如果您想在此学习率调度中使用动量,则可以设置新元的动量项。
# Drop-Based Learning Rate Decay
import pandas
from pandas import read_csv
import numpy
import math
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
from sklearn.preprocessing import LabelEncoder
from keras.callbacks import LearningRateScheduler
# learning rate schedule
def step_decay(epoch):
initial_lrate = 0.1
drop = 0.5
epochs_drop = 10.0
lrate = initial_lrate * math.pow(drop, math.floor((1+epoch)/epochs_drop))
return lrate
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load dataset
dataframe = read_csv("ionosphere.csv", header=None)
dataset = dataframe.values
# split into input (X) and output (Y) variables
X = dataset[:,0:34].astype(float)
Y = dataset[:,34]
# encode class values as integers
encoder = LabelEncoder()
encoder.fit(Y)
Y = encoder.transform(Y)
# create model
model = Sequential()
model.add(Dense(34, input_dim=34, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal', activation='sigmoid'))
# Compile model
sgd = SGD(lr=0.0, momentum=0.9, decay=0.0, nesterov=False)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
# learning schedule callback
lrate = LearningRateScheduler(step_decay)
callbacks_list = [lrate]
# Fit the model
model.fit(X, Y, validation_split=0.33, epochs=50, batch_size=28, callbacks=callbacks_list, verbose=2)
运行该示例会导致验证数据集的分类准确率达到 99.14%,这也是问题模型基线的改进。
...
Epoch 45/50
0s - loss: 0.0546 - acc: 0.9830 - val_loss: 0.0634 - val_acc: 0.9914
Epoch 46/50
0s - loss: 0.0544 - acc: 0.9872 - val_loss: 0.0638 - val_acc: 0.9914
Epoch 47/50
0s - loss: 0.0553 - acc: 0.9872 - val_loss: 0.0696 - val_acc: 0.9914
Epoch 48/50
0s - loss: 0.0537 - acc: 0.9872 - val_loss: 0.0675 - val_acc: 0.9914
Epoch 49/50
0s - loss: 0.0537 - acc: 0.9872 - val_loss: 0.0636 - val_acc: 0.9914
Epoch 50/50
0s - loss: 0.0534 - acc: 0.9872 - val_loss: 0.0679 - val_acc: 0.9914
使用学习率调度的提示
本节列出了在使用神经网络学习率调度时要考虑的一些提示和技巧。
- 提高初始学习率。因为学习率很可能会降低,所以从较大的值开始减少。较大的学习率将导致权重的更大变化,至少在开始时,允许您稍后从微调中受益。
- 使用大动量。当您的学习率缩小到较小值时,使用较大的动量值将有助于优化算法继续在正确的方向上进行更新。
- 尝试不同的时间表。目前还不清楚使用哪种学习率调度,因此请尝试使用不同的配置选项,看看哪种方法最适合您的问题。还可以尝试以指数方式更改的计划,甚至可以计划响应模型在训练或测试数据集上的准确率的计划。
摘要
在这篇文章中,您发现了用于训练神经网络模型的学习率调度。
阅读这篇文章后,您了解到:
- 如何在 Keras 中配置和使用基于时间的学习费率表。
- 如何在 Keras 开发自己的基于 drop 的学习率调度。
您对神经网络或此帖子的学习率表有任何疑问吗?在评论中提出您的问题,我会尽力回答。
如何在 Keras 中可视化深度学习神经网络模型
原文:
machinelearningmastery.com/visualize-deep-learning-neural-network-model-keras/
Keras Python 深度学习库提供了可视化和更好地理解您的神经网络模型的工具。
在本教程中,您将发现如何在 Keras 中总结和可视化您的深度学习模型。
完成本教程后,您将了解:
- 如何创建深度学习模型的文本摘要。
- 如何创建深度学习模型的图形图。
- 在 Keras 开发深度学习模型时的最佳实践技巧。
让我们开始吧。
如何在 Keras 中可视化深度学习神经网络模型 照片由 Ed Dunens ,保留一些权利。
教程概述
本教程分为 4 个部分;他们是:
- 示例模型
- 总结模型
- 可视化模型
- 最佳实践技巧
示例模型
我们可以从 Keras 中定义一个简单的多层感知机模型开始,我们可以将其用作摘要和可视化的主题。
我们将定义的模型有一个输入变量,一个带有两个神经元的隐藏层,以及一个带有一个二进制输出的输出层。
例如:
[1 input] -> [2 neurons] -> [1 output]
下面提供了该网络的代码清单。
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(2, input_dim=1, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
总结模型
Keras 提供了一种总结模型的方法。
摘要是文本性的,包括以下信息:
- 层和它们在模型中的顺序。
- 每层的输出形状。
- 每层中的参数(权重)数。
- 模型中的参数(权重)总数。
可以通过调用模型上的summary()函数来创建摘要,该函数返回可以打印的字符串。
下面是打印已创建模型摘要的更新示例。
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(2, input_dim=1, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
print(model.summary())
运行此示例将打印下表。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 2) 4
_________________________________________________________________
dense_2 (Dense) (None, 1) 3
=================================================================
Total params: 7
Trainable params: 7
Non-trainable params: 0
_________________________________________________________________
我们可以清楚地看到每层的输出形状和权重数量。
可视化模型
摘要对于简单模型很有用,但对于具有多个输入或输出的模型可能会造成混淆。
Keras 还提供了创建网络神经网络图的功能,可以使更复杂的模型更容易理解。
Keras 中的plot_model()功能将创建您的网络图。这个函数有一些有用的参数:
- _ 型号 _ :(必填)您想要绘制的模型。
to_file:(必需)要保存绘图的文件的名称。show_shapes:(可选,默认为False)是否显示每个层的输出形状。show_layer_names:(可选,默认为True)是否显示每个层的名称。
下面是绘制创建模型的更新示例。
注意,该示例假设您已安装 graphviz 图形库和 Python 接口。
from keras.models import Sequential
from keras.layers import Dense
from keras.utils.vis_utils import plot_model
model = Sequential()
model.add(Dense(2, input_dim=1, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
plot_model(model, to_file='model_plot.png', show_shapes=True, show_layer_names=True)
运行该示例将创建文件model_plot.png,其中包含已创建模型的图。
神经网络模型图的绘制
最佳实践技巧
我通常建议始终在 Keras 中创建神经网络模型的摘要和图表。
我推荐这个有几个原因:
- 确认层顺序。使用顺序 API 以错误的顺序添加层或使用功能 API 错误地将它们连接在一起很容易。图表图可以帮助您确认模型是否按照您预期的方式连接。
- 确认每层的输出形状。在定义复杂网络(如卷积和递归神经网络)的输入数据形状时,常常会遇到问题。摘要和图表可以帮助您确认网络的输入形状是否符合您的预期。
- 确认参数。一些网络配置可以使用更少的参数,例如在编解码器递归神经网络中使用
TimeDistributed包裹的密集层。查看摘要可以帮助发现使用远远超出预期的参数的情况。
进一步阅读
如果您希望深入了解,本节将提供有关该主题的更多资源。
摘要
在本教程中,您了解了如何在 Keras 中总结和可视化您的深度学习模型。
具体来说,你学到了:
- 如何创建深度学习模型的文本摘要。
- 如何创建深度学习模型的图形图。
- 在 Keras 开发深度学习模型时的最佳实践技巧。
你有任何问题吗? 在下面的评论中提出您的问题,我会尽力回答。
深度学习神经网络的权重初始化
最后更新于 2021 年 2 月 8 日
权重初始化是开发深度学习神经网络模型时的重要设计选择。
历史上,权重初始化涉及使用小随机数,尽管在过去十年中,已经开发了使用信息的更具体的试探法,例如正在使用的激活函数的类型和节点的输入数量。
这些更定制的试探法可以导致使用随机梯度下降优化算法更有效地训练神经网络模型。
在本教程中,您将发现如何为深度学习神经网络实现权重初始化技术。
完成本教程后,您将知道:
- 权重初始化用于在数据集上训练模型之前定义神经网络模型中参数的初始值。
- 如何实现用于使用 Sigmoid 或 Tanh 激活函数的节点的 xavier 和规范化 xavier 权重初始化试探法。
- 如何实现用于使用 ReLU 激活函数的节点的权重初始化启发式算法。
我们开始吧。
- 2020 年 2 月更新:修正了归一化泽维尔公式中的错别字。
深度学习神经网络的权重初始化 图片由安德烈斯·阿尔瓦拉多提供,保留部分权利。
教程概述
本教程分为三个部分;它们是:
- 神经网络的权值初始化
- Sigmoid 和 Tanh 的权重初始化
- 泽维尔权重初始化
- 归一化泽维尔权重初始化
- ReLU 的权重初始化
- 何权重初始化
神经网络的权值初始化
权重初始化是设计神经网络模型的重要考虑因素。
神经网络中的节点由被称为权重的参数组成,用于计算输入的加权和。
神经网络模型使用一种称为随机梯度下降的优化算法进行拟合,该算法递增地改变网络权重以最小化损失函数,有望产生一组能够做出有用预测的模式权重。
该优化算法要求在可能的权重值空间中有一个起始点,从该点开始优化过程。权重初始化是将神经网络的权重设置为小的随机值的过程,该随机值定义了神经网络模型优化(学习或训练)的起点。
……训练深度模型是一项非常困难的任务,大多数算法都会受到初始化选择的强烈影响。初始点可以决定算法是否收敛,一些初始点非常不稳定,以至于算法遇到数值困难并完全失败。
—第 301 页,深度学习,2016。
每次,用不同的权重集初始化神经网络,导致优化过程的不同起点,并潜在地导致具有不同表现特征的不同最终权重集。
有关每次在同一数据集上训练相同算法时不同结果的预期的更多信息,请参见教程:
我们无法将所有权重初始化为值 0.0,因为优化算法会导致误差梯度出现一些不对称,从而开始有效搜索。
有关为什么用随机权重初始化神经网络的更多信息,请参见教程:
历史上,权重初始化遵循简单的试探法,例如:
- 范围[-0.3,0.3]内的小随机值
- 范围[0,1]内的小随机值
- [-1,1]范围内的小随机值
总的来说,这些试探法继续有效。
我们几乎总是将模型中的所有权重初始化为从高斯或均匀分布中随机抽取的值。高斯分布或均匀分布的选择似乎不太重要,但尚未进行详尽的研究。然而,初始分布的规模对优化过程的结果和网络的泛化能力都有很大的影响。
—第 302 页,深度学习,2016。
尽管如此,在过去的十年中,已经开发出了更多定制的方法,这些方法已经成为事实上的标准,因为它们可能导致稍微更有效的优化(模型训练)过程。
这些现代权重初始化技术根据正在初始化的节点中使用的激活函数类型进行划分,例如“ Sigmoid 和 Tanh ”和“ ReLU ”
接下来,让我们仔细看看这些针对具有 Sigmoid 和 Tanh 激活函数的节点的现代权重初始化试探法。
Sigmoid 和 Tanh 的权重初始化
使用 Sigmoid 或 TanH 激活函数初始化神经网络层和节点权重的当前标准方法称为“ glorot 或“ xavier ”初始化。
它以Xavier glrot命名,Xavier glrot 目前是 Google DeepMind 的研究科学家,Xavier 和 Yoshua Bengio 在 2010 年发表的题为“理解训练深度前馈神经网络的难度的论文中对此进行了描述。”
这个权重初始化方法有两个版本,我们称之为“ xavier ”和“归一化 xavier ”
格洛特和本吉奥建议采用适当比例的均匀分布进行初始化。这被称为“泽维尔”初始化[……]它的推导是基于激活是线性的假设。这个假设对 ReLU 和 PReLU 无效。
——深入探究整流器:在 ImageNet 分类上超越人类水平的表现,2015。
这两种方法都是在假设激活函数是线性的情况下推导出来的,然而,它们已经成为像 Sigmoid 和 Tanh 这样的非线性激活函数的标准,而不是 ReLU。
让我们依次仔细看看每一个。
泽维尔权重初始化
xavier 初始化方法被计算为在范围-(1/sqrt(n))和 1/sqrt(n)之间具有均匀概率分布(U)的随机数,其中 n 是节点的输入数。
- weight = u[(1/sqrt(n)),1/sqrt(n)]
我们可以直接在 Python 中实现。
下面的示例假设一个节点有 10 个输入,然后计算范围的下限和上限,并计算 1000 个初始权重值,这些值可用于使用 sigmoid 或 tanh 激活函数的层或网络中的节点。
计算权重后,打印下限和上限,以及生成的权重的最小、最大、平均和标准偏差。
下面列出了完整的示例。
# example of the xavier weight initialization
from math import sqrt
from numpy import mean
from numpy.random import rand
# number of nodes in the previous layer
n = 10
# calculate the range for the weights
lower, upper = -(1.0 / sqrt(n)), (1.0 / sqrt(n))
# generate random numbers
numbers = rand(1000)
# scale to the desired range
scaled = lower + numbers * (upper - lower)
# summarize
print(lower, upper)
print(scaled.min(), scaled.max())
print(scaled.mean(), scaled.std())
运行该示例会生成权重并打印汇总统计数据。
我们可以看到权重值的界限大约是-0.316 和 0.316。输入越少,这些界限越宽,输入越多,界限越窄。
我们可以看到,生成的权重遵守这些界限,平均权重值接近零,标准偏差接近 0.17。
-0.31622776601683794 0.31622776601683794
-0.3157663248679193 0.3160839282916222
0.006806069733149146 0.17777128902976705
它还有助于了解权重的分布如何随着输入数量而变化。
为此,我们可以用从 1 到 100 的不同输入数计算权重初始化的界限,并绘制结果。
下面列出了完整的示例。
# plot of the bounds on xavier weight initialization for different numbers of inputs
from math import sqrt
from matplotlib import pyplot
# define the number of inputs from 1 to 100
values = [i for i in range(1, 101)]
# calculate the range for each number of inputs
results = [1.0 / sqrt(n) for n in values]
# create an error bar plot centered on 0 for each number of inputs
pyplot.errorbar(values, [0.0 for _ in values], yerr=results)
pyplot.show()
运行该示例会创建一个图表,允许我们比较不同数量输入值的权重范围。
我们可以看到,在输入很少的情况下,范围很大,例如-1 到 1 或-0.7 到-7 之间。然后我们可以看到,我们的范围迅速下降到大约 20 个权重,接近-0.1 和 0.1,在这里它保持合理的恒定。
输入从 1 到 100 的泽维尔重量初始化范围图
归一化泽维尔权重初始化
归一化 xavier 初始化方法被计算为在范围-(sqrt(6)/sqrt(n + m))和 sqrt(6)/sqrt(n + m)之间具有均匀概率分布(U)的随机数,其中 n 表示节点的输入数量(例如前一层中的节点数量) m 表示该层的输出数量(例如当前层中的节点数量)。
- weight = u[(sqrt(6)/sqrt(n+m))、sqrt(6)/sqrt(n + m)]
我们可以像上一节一样直接在 Python 中实现这一点,并总结 1000 个生成权重的统计摘要。
下面列出了完整的示例。
# example of the normalized xavier weight initialization
from math import sqrt
from numpy import mean
from numpy.random import rand
# number of nodes in the previous layer
n = 10
# number of nodes in the next layer
m = 20
# calculate the range for the weights
lower, upper = -(sqrt(6.0) / sqrt(n + m)), (sqrt(6.0) / sqrt(n + m))
# generate random numbers
numbers = rand(1000)
# scale to the desired range
scaled = lower + numbers * (upper - lower)
# summarize
print(lower, upper)
print(scaled.min(), scaled.max())
print(scaled.mean(), scaled.std())
运行该示例会生成权重并打印汇总统计数据。
我们可以看到权重值的界限大约是-0.447 和 0.447。输入越少,这些界限越宽,输入越多,界限越窄。
我们可以看到,生成的权重遵守这些界限,平均权重值接近零,标准偏差接近 0.17。
-0.44721359549995787 0.44721359549995787
-0.4447861894315135 0.4463641245392874
-0.01135636099916006 0.2581340352889168
它还有助于了解权重的分布如何随着输入数量而变化。
为此,我们可以用从 1 到 100 的不同输入数和 10 个固定输出数计算权重初始化的界限,并绘制结果。
下面列出了完整的示例。
# plot of the bounds of normalized xavier weight initialization for different numbers of inputs
from math import sqrt
from matplotlib import pyplot
# define the number of inputs from 1 to 100
values = [i for i in range(1, 101)]
# define the number of outputs
m = 10
# calculate the range for each number of inputs
results = [1.0 / sqrt(n + m) for n in values]
# create an error bar plot centered on 0 for each number of inputs
pyplot.errorbar(values, [0.0 for _ in values], yerr=results)
pyplot.show()
运行该示例会创建一个图表,允许我们比较不同数量输入值的权重范围。
我们可以看到,在输入较少的情况下,范围从-0.3 到 0.3 左右开始变宽,随着输入数量的增加,范围减小到-0.1 到 0.1 左右。
与上一节中的非标准化版本相比,范围最初较小,尽管以类似的速率过渡到紧凑范围。
输入从 1 到 100 的归一化泽维尔权重初始化范围图
ReLU 的权重初始化
当用于初始化使用整流线性( ReLU )激活函数的网络时,发现“ xavier ”权重初始化有问题。
因此,该方法的修改版本是专门为使用 ReLU 激活的节点和层开发的,在大多数多层感知机和卷积神经网络模型的隐藏层中很流行。
当前使用校正线性(ReLU)激活函数初始化神经网络层和节点权重的标准方法被称为“T0”初始化。
它以的研究科学家何命名,在何等人 2015 年的论文《深入研究整流器:在 ImageNet 分类中超越人类水平的表现》中有描述
何权重初始化
该初始化方法被计算为具有高斯概率分布(G)的随机数,平均值为 0.0,标准偏差为 sqrt(2/n),其中 n 是节点的输入数。
- 重量=克(0.0,平方英尺(2/n))
我们可以直接在 Python 中实现。
下面的示例假设节点有 10 个输入,然后计算高斯分布的标准偏差,并计算 1000 个初始权重值,这些值可用于使用 ReLU 激活函数的层或网络中的节点。
计算权重后,将打印计算的标准偏差以及生成权重的最小、最大、平均和标准偏差。
下面列出了完整的示例。
# example of the he weight initialization
from math import sqrt
from numpy.random import randn
# number of nodes in the previous layer
n = 10
# calculate the range for the weights
std = sqrt(2.0 / n)
# generate random numbers
numbers = randn(1000)
# scale to the desired range
scaled = numbers * std
# summarize
print(std)
print(scaled.min(), scaled.max())
print(scaled.mean(), scaled.std())
运行该示例会生成权重并打印汇总统计数据。
我们可以看到,权重的计算标准偏差的界限约为 0.447。输入越少,标准偏差越大,输入越多,标准偏差越小。
我们可以看到权重的范围约为-1.573 到 1.433,接近理论范围约为-1.788 和 1.788,是标准偏差的 4 倍,在高斯分布中捕获了 99.7%的观测值。我们还可以看到,生成权重的均值和标准差分别接近规定的 0.0 和 0.447。
0.4472135954999579
-1.5736761136523203 1.433348584081719
-0.00023406487278826836 0.4522609460629265
它还有助于了解权重的分布如何随着输入数量而变化。
为此,我们可以用从 1 到 100 的不同输入数计算权重初始化的界限,并绘制结果。
下面列出了完整的示例。
# plot of the bounds on he weight initialization for different numbers of inputs
from math import sqrt
from matplotlib import pyplot
# define the number of inputs from 1 to 100
values = [i for i in range(1, 101)]
# calculate the range for each number of inputs
results = [sqrt(2.0 / n) for n in values]
# create an error bar plot centered on 0 for each number of inputs
pyplot.errorbar(values, [0.0 for _ in values], yerr=results)
pyplot.show()
运行该示例会创建一个图表,允许我们比较不同数量输入值的权重范围。
我们可以看到,在输入很少的情况下,范围很大,接近-1.5 和 1.5 或-1.0 到-1.0。然后我们可以看到,我们的范围迅速下降到大约 20 个权重,接近-0.1 和 0.1,在这里它保持合理的恒定。
输入从 1 到 100 的重量初始化范围图
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
教程
报纸
- 理解深度前馈神经网络的训练难度,2010。
- 深究整流器:在 ImageNet 分类上超越人类水平的表现,2015。
书
- 深度学习,2016 年。
摘要
在本教程中,您发现了如何为深度学习神经网络实现权重初始化技术。
具体来说,您了解到:
- 权重初始化用于在数据集上训练模型之前定义神经网络模型中参数的初始值。
- 如何实现用于使用 Sigmoid 或 Tanh 激活函数的节点的 xavier 和规范化 xavier 权重初始化试探法。
- 如何实现用于使用 ReLU 激活函数的节点的权重初始化启发式算法。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
什么是深度学习?
校对:linmeishang
深度学习(Deep Learning)是机器学习的一个子领域,涉及受大脑结构和功能激发的算法,这些算法被称为人工神经网络 (Artificial Neural Networks)。
如果你刚刚接触深度学习,或者你有过一些有关神经网络的经验,你可能会感到困惑。我记得我刚开始学习时也很困惑,许多同事和朋友在 90 年代和 21 世纪初学习和使用神经网络时也是如此。
该领域的领军人物和专家对深度学习有些了解,这些具体而细微的观点会为你了解什么是深度学习提供很多启发。
在这篇文章中,你将看到一系列该领域的专家和领军人物的观点,从而来了解什么是深度学习。
让我们开始吧!
什么是深度学习? Kiran Foster 的图片。保留部分权利。
深度学习是大型神经网络
来自百度研究院 Coursera 和首席科学家的 Andrew Ng 正式成立了谷歌大脑 (Google Brain) ,最终促成了大量谷歌服务中深度学习技术的产品化。
他谈论过也写过很多关于深度学习的内容,这些都是了解深度学习很好的起点。
在深度学习的早期讨论中,Andrew 描述了传统人工神经网络背景下的深度学习。在 2013 年题为“深度学习,自学习和非监督特征学习”的演讲中,他将深度学习的理念描述为:
使用大脑模拟,希望:
使学习算法更好,更容易使用。
在机器学习和人工智能方面取得革命性进展。
我相信这是我们迈向真正人工智能的最好机会。
后来他的评论变得更加细致入微了。
根据 Andrew 的观点,深度学习的核心是我们现在拥有足够快的计算机和足够多的数据来真正训练大型神经网络。关于为什么深度学习是在现在开始迅猛发展,他在 2015 年的 ExtractConf 上一个标题为“为什么数据科学家需要了解深度学习”的演讲中评论道:
我们现在可以开发非常大的神经网络......而且我们可以访问大量的数据。
他还强调了规模(scale)的重要性。当我们构建更大的神经网络,并用越来越多的数据训练它们时,它们的表现(performance)会不断提高。这通常与其他机器学习方法不同, 因为那些机器学习方法的表现会在某个时候趋于稳定。
大多数老一代学习算法的表现在某个时候会趋于稳定。深度学习是可扩展的第一类算法。提供更多数据会使模型的表现不断提高。
他在幻灯片中提供了一个很好的图片:
为什么是深度学习? Andrew Ng的幻灯片。保留所有权利。
最后,他清楚地指出,我们在实践中看到的深度学习的好处来自监督学习(supervised learning)。在 2015 年 的 ExtractConf 演讲中,他评论道:
如今深度学习的所有价值几乎都是通过监督学习或从已标记的数据中学习而得到的。
早在 2014 年,他在斯坦福大学的一次题为“深度学习”的演讲中作了类似的评论:
深度学习突飞猛进的一个原因是它在监督学习中的表现十分惊人。
Andrew 经常说,我们应该,也将会看到更多的来自深度学习中非监督学习的好处,因为该领域在处理大量未标记的数据方面正在渐渐成熟。
Jeff Dean 是谷歌的系统和基础设施组的向导和高级研究员。他参与并可能部分负责谷歌内部深度学习的扩展和应用。Jeff 参与了谷歌大脑(Google Brain)项目以及大型深度学习软件 DistBelief 和后来的 TensorFlow 的开发。
在 2016 年题为“深度学习: 用于建立智能计算机系统”的演讲中,他也评论说,深度学习实际上就是大型神经网络。
当你听到深度学习这个词的时候,就想想一个大的深度神经网络(deep neural net)。深度(deep)通常指神经网络的层数,书籍出版时就采用这种流行的术语。我通常就把它们想成深度神经网络。
他曾多次做过这个演讲,在同一演讲的修正版的幻灯片中,他强调了神经网络的可扩展性,表明更多数据和更大的模型会使模型的结果变得更好,这反过来也需要更多的运算能力去训练模型。
更多数据、更大模型、更多运算,带来更好的结果, Jeff Dean的幻灯片。保留所有权利。
深度学习是层次特征学习 (Hierarchical Feature Learning)
除了可扩展性之外,深度学习模型的另一个经常被引用的好处是,它们能够从原始数据中自动提取特征(feature),也称为特征学习 (feature learning)。
Yoshua Bengio 是深度学习领域的另一个领军人物,尽管他刚开始时感兴趣的领域是自动特征学习(automatic feature learning),这种学习是通过大型神经网络实现的。
他从深度学习算法利用特征学习从数据中发现并学习表征(representation)的能力方面描述了深度学习。在 2012 年题为“非监督和转移学习之表征深度学习”的论文中,他评论道:
深度学习算法试图开发输入(input)数据分布中的未知结构,以便发现良好的表征。良好的表征(representation)通常是在多个级别上的,即用较低级别的特征(feature)定义更高级别的特征。
他在 2009 年的技术报告“为 AI 学习深度结构 ”中详细阐述了深度学习,其中强调了特征学习中层次(hierarchy)的重要性。
深度学习方法旨在学习特征层次(feature hierarchies),它们是由来自较高级别的层次(higher levels of the hierarchy)中的特征组成的,而这些较高级别的层次则是由较低级别的特征(lower level features)所组成的。自动学习在多个抽象级别的特征允许一个系统能够学习到数据背后复杂的函数,这些函数直接从数据中将输入映射到输出,而不完全依赖于人工设计的特征(feature)。
在即将出版的与 Ian Goodfellow 和 Aaron Courville 合著的名为“深度学习”的书中,他们根据模型的架构(architecture )深度来定义深度学习。
概念的层次结构(the hierarchy of concepts)允许计算机去学习复杂的概念(concepts)。这些复杂的概念是由计算机从简单的概念中建立起来的。如果我们可以画一个图来表示这些概念是如何在各自的基础上互相构建的,那么这个图会很深(deep),有很多层(layers)。出于这个原因,我们将这种方法称为 AI 深度学习。
这是一本重要的书,有可能在一段时间内成为该领域的权威资源。本书继续描述深度学习领域使用的算法 —— 多层感知机(multilayer perceptrons, MLP),因为深度学习已经被归入人工神经网络这一更大的领域中。
深度学习模型的一个典型例子就是前馈深度网络(feedforward deep network)或多层感知机(multilayer perceptrons,MLP)。
Peter Norvig 是谷歌研究部主任,因其题为“人工智能:现代方法”的人工智能教科书而闻名。
在 2016 年的一次题为“深度学习及其可理解性 VS 软件工程和验证”的演讲中,他以和 Yoshua 非常相似的方式定义了深度学习,重点强调更深层网络结构所激发的抽象能力。
深度学习通过由很多抽象层次所形成的表征来学习,而不是从直接输入和输出中学习。
为什么称它为“深度学习”?
为什么不只是“人工神经网络”?
Geoffrey Hinton 是人工神经网络领域的先驱,并与他人合著了第一篇用于训练多层感知机网络的反向传播算法的论文。
他可能是第一个用“deep”(深度)这个词来描述大型人工神经网络发展的人。
他在 2006 年与他人合著了一篇题为“深度信念网的快速学习算法”的论文,其中描述了一种训练“深度”(如在多层网络中)受限玻尔兹曼机(Restricted Boltzmann Machine) 的方法。
使用互补先验,我们推导出一种快速、贪婪(greedy)的算法,它可以一次学习一层深层有向信念网络(Directed Belief Networks),前提是前两层形成一个无向联想记忆。
这篇文章和 Geoff 的另一篇与他人合著的关于无向深度网络(Undirected Deep Network)的题为“ 深度玻尔兹曼机 ”的论文得到了社区的好评(现已引用数百次),因为它们是贪婪按层训练网络的成功例子。在前馈网络中,这种方法允许更多的层。
在科学杂志上的一篇题为“用神经网络降低数据维度”的合著的文章中,同样按照之前对“深度”的定义,他们描述了他们开发网络的方法,这些网络的层数比以前典型网络的层数更多。
我们阐述了一种有效的初始化权重的方法,它允许深度自编码器(Auto-encoder)网络学习低维度代码(low-dimensional codes)。作为减少数据维度的工具,这些代码比主成分分析(Principal Components Analysis)更好。
在同一篇文章中,他们还有一个有趣的评论。这个评论与 Andrew Ng 关于最近计算能力的提高以及对大型数据集的访问的评论不谋而合。他们都认为大规模使用这些数据集可以激发神经网络的潜能。
自 20 世纪 80 年代以来,显而易见的是,深度自编码器的反向传播(backpropagation)对于非线性降维是非常有效的,只要计算机足够快,数据集足够大,并且初始权重足够接近良好解就可以。如今,这三个条件都满足了。
在 2016 年皇家学会题为“深度学习”的演讲中,Geoff 评论说深度信念网络是 2006 年深度学习的开始,这一新的深度学习浪潮的首次成功应用是 2009 年的语音识别,这个文章的标题为“基于深度信念网络的声学建模”,他们达到了最先进的水平。
这个结果使语音识别和神经网络社区注意到,可能是因为使用“深度”来与先前的神经网络进行区分而造成了这个领域名称的改变。
在皇家学会的谈话中,大概正如您所期望的那样,他们对深度学习的描述非常专注于反向传播。有趣的是,他提出了为什么反向传播(应读作“深度学习”)在上世纪 90 年代没有起飞的 4 个原因。前两点与 Andrew Ng 的评论相符,即数据集太小而且计算机太慢。
1986 年的反向传播到底错在哪里? Geoff Hinton 的幻灯片。保留所有权利。
深度学习作为跨领域的可扩展学习
深度学习在相似输入(甚至输出)的问题上表现优异。意思是,它们不是少量的表格数据,而是像素数据的图像、文本文档或音频数据。
Yann LeCun 是脸书研究部(Facebook Research)的主管,也是卷积神经网络(CNN) 架构之父,这种网络擅长图像数据中的对象(object)识别。这种技术非常成功,因为像多层感知机(MLP)前馈神经网络一样,该技术可以根据数据和模型大小进行扩展,并且可以通过反向传播进行训练。
这使他对深度学习的定义更专注于大型 CNN ,这些 CNN 在照片中的对象识别方面取得了巨大成功。
在劳伦斯利弗莫尔国家实验室 (Lawrence Livermore National Laboratory) 2016 年的一次题为“加速理解:深度学习,智能应用和 GPU ”的演讲中,他将深度学习描述为层次表征(hierarchical representations)的学习,并将其定义为一种为了构建对象识别系统的可扩展的学习方法:
深度学习[是] ...所有可训练模块组成的流水线(pipeline)。 ......“深”是因为识别对象的过程有多个阶段,所有这些阶段都是训练的一部分。
深度学习=层次表征的学习 Yann LeCun的幻灯片。保留所有权利。
Jurgen Schmidhuber 是另一种流行的深度学习算法之父。这种算法像 MLP 和 CNN 一样也可以根据模型大小和数据集大小进行扩展,并且可以通过反向传播进行训练,但是它是为序列数据(sequence data)量身定制的,称为 长短期记忆网络(LSTM),是一种递归神经网络(Recurrent Neural Network)。
我们确实看到了“深度学习”这个命名引起的混淆。在 2014 年题为“神经网络中的深度学习:概述”的论文中,他对该领域命名的问题以及区分深度学习与浅层学习(shallow learning)进行了评论。他还有趣地解释了“深度”是问题复杂程度的深度,而不是用于解决问题的模型的深度。
深度学习在何种问题复杂程度上真正开始优于浅层学习?深度学习专家的讨论尚未给这一问题作出结论性的回应。 [...],让我来下个定义,不过这个定义只是为了让你们有个大致的总览:问题深度大于 10 就需要非常深度的学习。
Demis Hassabis 是 DeepMind 的创始人,后来被谷歌收购。 DeepMind 在深度学习与强化学习相结合的方面取得了突破,这种学习方法可以处理复杂的学习问题,如玩游戏。在此方面,十分出名的例证是 Atari 游戏和游戏 Go 中的 Alpha Go 。
为了与深度学习命名保持一致,他们将他们的新技术称为深度 Q 网络(Deep Q-Network),将深度学习与 Q-Learning 结合起来。他们还将这个广泛的研究领域命名为“深层强化学习(Deep Reinforcement Learning)”。
在他们 2015 年发表在自然(Nature)杂志上的题为“通过深度强化学习实现人类控制”的论文中,他们评论了深度神经网络在这些突破中的重要作用,并强调了层次抽象(hierarchical abstraction)的必要性。
为了实现这一目标,我们开发了一种新型的代理(agent),一种深度 Q 网络(Deep Q-Network,DQN),它能够将强化学习与一类称为深度神经网络的人工神经网络相结合。值得注意的是,深度神经网络的最新进展使得人工神经网络可以直接从原始传感数据中学习诸如对象类别之类的概念。这些深度神经网路使用若干层节点来逐渐建立数据的抽象表征。
最后,这篇可能是被认为最初定义该领域的论文,即 Yann LeCun,Yoshua Bengio 和 Geoffrey Hinton 在自然(Nature)杂志上发表的题为“深度学习”的论文。他们在文中对深度学习作了清晰的定义,这个定义强调多层方法(multi-layered approach)。
深度学习允许由多个神经网络层组成的模型通过多层抽象来学习数据的表征。
后来,他们从表征学习(representation learning)和抽象(abstraction)的角度描述了多层方法(multi-layered approach)。
深度学习方法是具有多个级别表征的表征学习方法。这些表征可以通过简单但非线性的模块而形成,每个模块将一个级别(从原始输入开始)上的表征转换为更高级别上的表征,即稍微更抽象一点的级别。 [...]深度学习的关键方面是这些特征层次(layers of features)不是由人类工程师设计的:它们是使用学习程序从数据中学习的。
这个定义很好而且很通用,可以很简单地描述大多数的人工神经网络算法。这也可以作为本文的结尾。
总结
在这篇文章中,你学习到了深度学习其实就是用于更大数据的大型神经网络,因此需要更强的计算能力。
虽然 Hinton 和其合作者发表的早期的方法侧重于贪婪的分层训练(greedy layerwise training)和无监督方法,如自编码器,但现代最先进的深度学习主要集中在使用反向传播算法训练深层(多层)神经网络模型。最流行的技术有:
- 多层感知机网络(MLP)。
- 卷积神经网络(CNN)。
- 长短期记忆递归神经网络(LSTM)。
我希望本文清晰地解释了什么是深层学习,以及深度学习的各种主流定义是如何融会贯通的。
如果你对深度学习或本文有任何疑问,请在下面的评论中提问,我会尽力回答。
何时使用 MLP,CNN 和 RNN 神经网络
原文:
machinelearningmastery.com/when-to-use-mlp-cnn-and-rnn-neural-networks/校对:linmeishang
什么神经网络适合您的预测性建模问题?
对于初学者来说,深度学习领域很难知道要使用什么类型的网络。有许多类型的网络可供选择,每天都会发布和讨论新的方法。
更糟糕的是,大多数神经网络足够灵活,即使在使用错误类型的数据或预测问题时也可以工作(做出预测)。
在这篇文章中,您将发现三种主要类型的人工神经网络的建议用法。
阅读这篇文章后,您会知道:
- 在处理预测性建模问题时要关注哪种类型的神经网络。
- 何时使用,不使用,并可能尝试在项目中使用 MLP,CNN 和 RNN。
- 在选择模型之前,要考虑使用混合模型并清楚了解项目目标。
让我们开始吧。
何时使用 MLP,CNN 和 RNN 神经网络 照片由 PRODAVID S. FERRY III,DDS ,保留一些权利。
概观
这篇文章分为五个部分;他们是:
- 什么神经网络要关注?
- 何时使用多层感知机?
- 何时使用卷积神经网络?
- 何时使用递归神经网络?
- 混合网络模型
什么神经网络要关注?
深度学习是使用现代硬件的人工神经网络的应用。
它允许开发,训练和使用比以前认为可能更大(更多层)的神经网络。
研究人员提出了数千种类型的特定神经网络,作为对现有模型的修改或调整。有时是全新的方法。
作为一名从业者,我建议您等到模型出现后普遍适用。很难从每天或每周发布的大量出版物的噪音中梳理出一般效果良好的信号。
有三类人工神经网络我建议您一般关注。他们是:
- 多层感知机(Multilayer Perceptron,MLP)
- 卷积神经网络(Convolutional Neural Network,CNN)
- 递归神经网络(Recurrent Neural Network,RNN)
这三类网络提供了很大的灵活性,并且经过数十年的证明,它们在各种各样的问题中都是有用和可靠的。他们还有许多子类型来帮助他们专注于预测问题和不同数据集的不同框架的怪癖。
现在我们知道要关注哪些网络,让我们看看何时可以使用每一类神经网络。
何时使用多层感知机?
多层感知机(简称 MLP)是经典类型的神经网络。
它们由一层或多层神经元(neuron)组成。数据被馈送到输入层(input layer),之后可能有一个或多个隐藏层(hidden layer)来提供更高水平的抽象(abstraction)关系,并且在输出层(output layer)(也称为可见层(visiable layer))上做出预测。
有关 MLP 的更多详细信息,请参阅帖子:
MLP 适用于分类预测(classification prediction)问题,其中输入(input)被指定给一定的类(class)或标签(label)。
它们也适用于回归预测(regression prediction)问题,其中在给定一组输入的情况下预测实际值。数据通常以表格格式提供,例如 CSV 文件或电子表格。
MLP 可用于:
- 表格数据集
- 分类预测问题
- 回归预测问题
它们非常灵活,通常可用于学习输入和输出之间的关系。
这种灵活性允许它们应用于其他类型的数据。例如,图像的像素可以缩减为一行长数据并馈送到 MLP 中。文档的单词也可以缩减为一行长数据并馈送到 MLP。甚至对时间序列预测问题的滞后观察也可以减少为长行数据并馈送到 MLP。
因此,如果您的数据采用的不是表格数据集,例如图像、文档或时间序列,我建议至少测试一个 MLP 来解决您的问题。MLP 的结果可用作比较的基准,以确定那些可能看起来更适合的模型确实比 MLP 更好。
可用 MLP 尝试如下问题:
- 图像数据
- 文本数据
- 时间序列数据
- 其他类型的数据
何时使用卷积神经网络?
卷积神经网络(Convolutional Neural Network,CNN)用于将图像数据映射到一定的输出变量。
事实证明它们非常有效,如果您遇到涉及图像数据作为输入的任何类型的预测问题,它们是首选方法。
有关 CNN 的更多详细信息,请参阅帖子:
使用 CNN 的好处是它们能够开发二维图像的内部表征(representation)。这允许模型在各种不同的数据结构中学习图像中物体的位置和比例,这在处理图像时很重要。
CNN 可用于:
- 图像数据
- 分类预测问题
- 回归预测问题
更一般地,CNN 在具有空间关系的数据上表现良好。
CNN 的输入传统上是二维的,场或矩阵,但也可以改变为一维的,允许它学习一维序列的内部表征。
这允许 CNN 更普遍地用于具有空间关系的其他类型的数据。例如,文本文档中的单词之间存在顺序关系,时间序列的步长(time step)中存在有序关系。
虽然不是专门为非图像数据开发的,但 CNN 在诸如情绪分析中使用的文档分类和相关问题上实现了最先进的结果。
可用 CNN 尝试如下问题:
- 文字数据
- 时间序列数据
- 序列输入数据
何时使用递归神经网络?
递归神经网络(Recurrent Neural Network,RNN)用于处理序列预测问题。
序列预测问题有多种形式,我们最好用模型可支持的输入和输出的类型来描述这些预测问题的类型。
序列预测问题的一些例子包括:
- 一对多:一个观测点(observation)作为输入映射到多步(multiple steps)序列输出。
- 多对一:多步序列输入映射到一个类或数值的输出。
- 多对多:多步序列输入映射到多步序列输出。
多对多问题通常被称为序列到序列(sequence-to-sequence),或简称为 seq2seq。
有关序列预测问题类型的更多详细信息,请参阅帖子:
递归神经网络通常难以训练。
长短期记忆( Long Short-Term Memory, LSTM) 网络可能是最成功的 RNN,因为它克服了递归神经网络训练的难题,已经被广泛的应用了。
有关 RNN 的更多详细信息,请参阅帖子:
一般而言,RNNs 和 LSTM 在处理单词和段落序列时最为成功,通常称为自然语言处理(natural language processing,NLP)。
这包括以时间序列表示的文本序列语音序列。它们还用作生成模型(generative model),需要生成一定的序列。可生成的序列不仅包括文本,还包括手写字迹等。
RNN 可用于:
- 文字数据
- 语音数据
- 分类预测问题
- 回归预测问题
- 生成模型
正如您在 CSV 文件或电子表格中看到的那样,递归神经网络不适用于表格数据集。它们也不适合图像数据输入。
请勿使用 RNN 于:
- 表格数据
- 图像数据
RNN 和 LSTM 已经被用在时间序列预测问题上进行了测试,但结果却很差。自回归方法,甚至线性方法通常表现得更好。 在同样的数据集上,甚至简单的 MLP 都比 LSTM 效果更好。
有关此主题的更多信息,请参阅帖子:
然而,它仍然是一个活跃的研究领域。
也许可以用 RNN 尝试如下问题 :
- 时间序列数据
混合网络模型(Hybrid Network Models)
CNN 或 RNN 模型很少单独使用。
这些类型的网络可包括在更广泛的模型中作为 CNN 或 RNN 层,这种模型也可具有一个或多个 MLP 层。从技术上讲,这些是混合类型的神经网络架构。
也许最有趣的是将来自不同类型的网络混合在一起成为混合模型。
例如,设想这样一个模型:它使用堆叠的 CNN 作为输入层,中间为 LSTM 层,输出为 MLP 层。像这样的模型可以读取一系列图像输入,例如视频,并生成预测。这种模型被称为 CNN LSTM 架构。
网络类型也可以堆叠在特定的结构中,以此来解锁新功能。例如可重复使用的图像识别模型,这些模型使用非常深的 CNN 和 MLP 网络,它可以被添加到新的 LSTM 模型并用于给照片加标题。此外,编码器-解码器 LSTM 网络*(encoder-decoder LSTM networks)可用于具有不同长度的输入和输出序列。
重要的是要先了解您和利益相关者对项目的要求,然后寻找(或开发一个)满足特定项目需求的网络架构。
如果您需要一个鉴别数据和预测问题的框架,请参阅帖子:
进一步阅读
如果您希望深入了解此话题,可参见有关该主题的更多资源:
总结
在这篇文章中,您发现了三种主流人工神经网络的推荐用法。
具体来说,您学到了:
- 在处理预测性建模问题时要关注哪种类型的神经网络。
- 何时使用、不使用或可以尝试在项目中使用 MLP,CNN 和 RNN。
- 在选择模型之前,可以考虑使用混合模型并清楚了解项目目标。
您有任何问题吗? 请在评论中区中提出您的问题,我会尽力解答。
神经网络的权重为什么要随机初始化?
原文:
machinelearningmastery.com/why-initialize-a-neural-network-with-random-weights/
人工神经网络的权重(weights)必须初始化为小的随机数。
因为用于训练模型的随机优化算法(stochastic optimization algorithm)要求如此,这种算法称为随机梯度下降(stochastic gradient descent)。
要理解这种解决问题的方法,您首先必须了解非确定性和随机算法(nondeterministic and randomized algorithms)的作用,以及为什么随机优化算法在参数搜索过程中需要利用随机数。
在这篇文章中,您将学习为什么神经网络的权重必须随机初始化(randomly initialized)。
阅读这篇文章后,您会知道:
- 处理具有挑战性的问题时我们有时需要非确定性和随机算法。
- 在随机优化算法中,使用随机数来进行初始化和参数的搜索。
- 随机梯度下降是随机优化算法,它需要对神经网络的权重进行随机初始化。
让我们开始吧!
神经网络的权重为什么要随机初始化? lwtt93 的照片,保留一些权利。
概要
这篇文章分为以下 4 个部分:
- 确定性和非确定性算法
- 随机搜索算法
- 神经网络中的随机初始化
- 初始化方法
确定性和非确定性算法
经典算法是确定性的(deterministic),例如对列表进行排序的算法。
假设给定一个未排序的列表,排序算法(比如冒泡排序(bubble sort)或快速排序(quick sort))将系统地对列表进行排序,直到有一个有序的结果。"确定性"意味着每次给定相同的列表时,它将以完全相同的方式执行。它将在程序的每个步骤都进行相同的操作。
确定性算法很棒,因为它们可以保证最佳、最差和平均运行时间。问题是,它们并不适合所有问题。
有些问题对计算机来说很难。也许是因为组合的数量,也许是因为数据的大小。它们非常难,因为确定性算法不能有效率地解决它们。该算法可能会运行,但会继续运行直至宇宙因过热而死亡。
另一种解决方案是使用非确定性算法。这些是在算法执行期间做决策时使用随机性元素的算法。这意味着当在相同数据上重新运行相同的算法时,将遵循不同的步骤顺序。
他们可以大大加快获得解决方案的过程,但解决方案将是近似的,或者说是“_ 好的 ”, 但往往不是 “ 最佳的 _”。 不确定性算法往往不能很好地保证运行时间或其解决方案的质量。
不过这不是问题。因为这类算法想要解决的问题通常非常难,所以任何好的解决方案都已经可以使人满意了。
随机搜索算法
搜索问题通常非常具有挑战性,这类问题需要使用非确定性算法,而非确定性算法则往往很大程度上依赖随机性。
这类算法本身并不是随机的,而是他们谨慎地使用随机性。它们在一定边界内是随机的,被称为随机算法。
搜索算法的逐步搜索(incremental or step-wise search)的性质通常意味着搜索过程和搜索算法是一种从初始状态或位置到最终状态或位置的优化(optimization)过程。例如,随机优化问题或随机优化算法,这其中的例子是遗传算法(genetic algorithm),模拟退火(simulated annealing)和随机梯度下降(stochastic gradient descent)。
搜索过程是从可行域中的一个起点到一些足够好的解决方案的一个逐步的过程。
它们在使用随机性方面具有共同特征,例如:
- 在初始化期间使用随机性。
- 在搜索过程中使用随机性。
我们对搜索空间(search space)的结构一无所知。因此,为了消除搜索过程中的偏差,我们从随机选择的一个起点开始。
随着搜索过程的展开,我们有可能陷入搜索空间的不利区域。在搜索过程中使用随机性可能会使我们避免陷入不利区域,并找到更好的候选解决方案。
陷入不利区域并找到次优的解决方案,这种情况被称为陷入局部最优(local optima)。
在搜索过程中使用随机性和在初始化中使用随机性是齐头并进的。
如果我们将搜索找到的任何解决方案视为临时或候选方案,并且搜索过程可以多次执行,那么这两个随机过程就可以更好地协同工作。
这为随机搜索过程提供了多个机会来启动和遍历候选解决方案的空间,以寻找更好的候选解决方案 - 即所谓的全局最优解(global optima)。
我们通常用山脉和山谷景观的类比(例如适应度景观)来描述在候选解决方案空间的搜索过程。如果我们想要寻找最大解,我们可以将景观中的小山丘视为局部的最大解,将最大的山丘视为全局最大解。
这是一个吸引人的研究领域,我在这个领域有一些研究。您可以参见我的书:
神经网络中的随机初始化
人工神经网络是使用随机梯度下降的随机优化算法训练的。
该算法使用随机性,以便为正在学习的数据中的输入到输出的特定映射函数(mapping function)找到足够好的权重集。这意味着每次使用这样的训练算法时,特定训练数据的特定网络将会被训练成具有不同模型技能的不同网络。
这是该算法的一个特征,而不是一个 bug。
我在下面的帖子中更详细地描述了这个问题:
如前一节所述,诸如随机梯度下降的随机优化算法在选择搜索的起始点和搜索的过程中使用随机性。
具体而言,随机梯度下降要求将网络的权重初始化为小的随机数(随机,但接近零,例如[0.0, 0.1])。在每个时期(epoch)之前,训练数据集也使用随机性来进行混合(shuffling),这反过来导致每个批次 (batch) 的梯度估计(gradient estimate)也会不同。
您可以在这篇文章中了解更多关于随机梯度下降的信息:
神经网络在搜索或学习上的进展称为收敛(convergence)。发现次优解或局部最优被称为早熟收敛(premature convergence)。
深度学习的训练算法在本质上通常是迭代的(iterative),因此需要用户指定开始迭代的初始点。此外,训练深度模型是一项非常困难的任务,大多数算法都会被不同的初始化而强烈影响。
- 第 301 页,深度学习,2016 年。
如果想要评估一个神经网络架构的表现,最有效方法是多次重复搜索的过程,并总结模型的平均表现。这为网络架构提供了从多个不同初始条件集搜索空间的最佳机会,称为多次重启(multiple restart)或多次重启搜索(multiple-restart search)。
您可以在这篇文章中了解有关神经网络有效评估的更多信息:
为什么不将权重设置为零?
每次训练网络时,我们都可以使用相同的权重集。例如,您可以对所有权重使用 0.0 的值。
在这种情况下,学习算法(learning algorithm)的方程将无法对网络权重进行任何更改,模型将被卡住。重要的是要注意,每个神经元中的偏差权重(bias weight)默认设置为零,而不是一个小的随机值。
具体地,连接到相同输入(input)的隐藏层中并排的神经元(nodes)必须用不同权重,这样学习算法才可以更新权重。
这通常被称为“在训练期间打破对称性的需要”(the need to break symmetry)。
关于神经网络的学习算法,也许我们只知道一个完全确定的属性,即初始参数需要在不同神经元之间“打破对称性”。如果具有相同激活函数(activation function)的两个隐藏神经元连接到相同的输入(input),则这些神经元必须具有不同的初始参数。如果它们具有相同的初始参数,那么确定性学习算法(这些算法用于确定性成本和模型)将以相同方式不断更新这两个神经元。
- 第 301 页,深度学习,2016 年。
何时初始化为相同权重?
每次训练网络时,我们都可以使用相同的随机数。
在评估网络架构时,这没有用。
但这在生产环境中使用模型的情况下,给定训练数据集,训练相同的最终网络权重集时可能是有帮助的。
您可以在如下这篇文章中了解有关由 Keras 开发的使用固定随机种子(random seed) 来训练神经网络的更多信息:
- 如何用 Keras 得到可重现的结果
初始化方法
传统上,神经网络的权重被设置为小的随机数。
神经网络权重的初始化是一个完整的研究领域,因为精心地初始化一个网络可以加速学习过程。
现代深度学习库,例如 Keras,提供了许多网络初始化方法,所有这些都是用小随机数初始化权重的变体。
例如,目前 Keras 为所有类型的网络编写提供了如下方法:
- Zeros :使张量(tensor)初始化为 0 的初始化器(initializer) 。
- Ones :使张量初始化为 1 的初始化器。
- Constant:使张量初始化为某个常数的初始化器。
- RandomNormal :使张量符合正态分布的初始化器。
- RandomUniform :使张量符合均匀分布的初始化器。
- TruncatedNormal :使张量符合截断正态分布的初始化器。
- VarianceScaling :可以根据权重的形状改变其规模的初始化器。
- Orthogonal :可以生成随机正交矩阵的初始化器。
- Identity :可以生成单位矩阵的初始化器。
- lecun_uniform :LeCun 均匀分布初始化器。
- glorot_normal :Glorot 正态分布初始化器,也称为 Xavier 正态分布初始化器。
- glorot_uniform :Glorot 均匀初始化器,也叫 Xavier 均匀初始化器。
- he_normal : He 正态分布初始化器。
- lecun_normal :LeCun 正态分布初始化器。
- he_uniform :He 均匀方差调节初始化器。
更多信息请参阅文档。
出于兴趣,Keras 开发人员为不同类型的神经网络层选择的默认初始值设定如下:
- Dense(例如 MLP): glorot_uniform
- LSTM : glorot_uniform
- CNN : glorot_uniform
您可以在本文中了解更多关于“glorot_uniform”的信息,它也被称为“ Xavier normal ”,是以本方法的开发人员 Xavier Glorot 的名字来命名的:
- 理解深度前馈神经网络训练的难度,2010。
没有单一的最佳方法来初始化神经网络的权重。
现代初始化策略是简单且是启发式的。设计更好的初始化策略是一项艰巨的任务,因为我们还没能清楚理解神经网络优化。 [...]我们对初始点如何影响神经网络的预测能力的理解还特别粗略,几乎还不能为如何选择初始点提供任何指导。
- 第 301 页,深度学习,2016 年。
因此,初始器也是一个超参数。您可以在特定预测性建模问题上探索、测试和试验这个超参数。
您有没有最喜欢的权重初始化方法? 请在下面的评论中告诉我。
进一步阅读
如果您希望深入了解此话题,本节将提供更多相关资源。
书籍
- 深度学习,2016 年。
文章
- 维基百科上的非确定性算法
- 维基百科上的随机算法
- 维基百科上的随机优化
- 维基百科上的随机梯度下降
- 维基百科上的适应度景观
- 神经网络常见问题
- Keras 权重初始化
- 了解深度前馈神经网络训练的难度,2010。
讨论
摘要
在这篇文章中,您学习了为什么必须随机初始化神经网络的权重。
具体来说,您学到了:
- 为什么具有挑战性的问题需要非确定性和随机算法。
- 在随机优化算法的初始化和搜索过程中使用随机性。
- 随机梯度下降是随机优化算法,需要随机初始化网络权重。
您还有任何问题吗? 请在下面的评论中提问,我会尽力回答。