Machine Learning Mastery Keras 深度学习教程(八)
Python 中的 Keras 深度学习库的回归教程
原文:
machinelearningmastery.com/regression-tutorial-keras-deep-learning-library-python/
Keras 是一个深度学习库,包含高效的数字库 Theano 和 TensorFlow。
在这篇文章中,您将了解如何使用 Keras 开发和评估神经网络模型以获得回归问题。
完成本分步教程后,您将了解:
- 如何加载 CSV 数据集并使其可供 Keras 使用。
- 如何使用 Keras 创建一个回归问题的神经网络模型。
- 如何使用 scras-learn 与 Keras 一起使用交叉验证来评估模型。
- 如何进行数据准备以提高 Keras 模型的技能。
- 如何使用 Keras 调整模型的网络拓扑。
让我们开始吧。
- 2017 年 3 月更新:更新了 Keras 2.0.2,TensorFlow 1.0.1 和 Theano 0.9.0 的示例。
- 更新 Mar / 2018 :添加了备用链接以下载数据集,因为原始图像已被删除。
- Update Apr / 2018 :将 nb_epoch 参数更改为 epochs。
使用 Python 中的 Keras 深度学习库的回归教程 Salim Fadhley 的照片,保留一些权利。
1.问题描述
我们将在本教程中看到的问题是波士顿房价数据集。
您可以下载此数据集并将其保存到当前工作中,直接使用文件名housing.csv(更新:从此处下载数据)。
该数据集描述了波士顿郊区房屋的 13 个数字属性,并涉及以数千美元模拟这些郊区房屋的价格。因此,这是回归预测性建模问题。输入属性包括犯罪率,非经营业务占地比例,化学品浓度等。
这是机器学习中经过深入研究的问题。使用起来很方便,因为所有输入和输出属性都是数字的,并且有 506 个实例可供使用。
使用均方误差(MSE)评估的模型的合理表现约为 20 平方千美元(如果取平方根则为 4,500 美元)。这是一个很好的目标,旨在与我们的神经网络模型。
2.开发基线神经网络模型
在本节中,我们将为回归问题创建基线神经网络模型。
让我们从包含本教程所需的所有函数和对象开始。
import numpy
import pandas
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
我们现在可以从本地目录中的文件加载数据集。
事实上,数据集在 UCI 机器学习库中不是 CSV 格式,而是用空格分隔属性。我们可以使用 pandas 库轻松加载它。然后我们可以分割输入(X)和输出(Y)属性,以便使用 Keras 和 scikit-learn 更容易建模。
# load dataset
dataframe = pandas.read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values
# split into input (X) and output (Y) variables
X = dataset[:,0:13]
Y = dataset[:,13]
我们可以使用 Keras 库提供的方便的包装器对象创建 Keras 模型并使用 scikit-learn 来评估它们。这是可取的,因为 scikit-learn 在评估模型方面表现优异,并且允许我们使用强大的数据准备和模型评估方案,只需很少的代码。
Keras 包装器需要一个函数作为参数。我们必须定义的这个函数负责创建要评估的神经网络模型。
下面我们定义用于创建要评估的基线模型的函数。它是一个简单的模型,它有一个完全连接的隐藏层,与输入属性具有相同数量的神经元(13)。网络使用良好的实践,例如隐藏层的整流器激活功能。没有激活函数用于输出层,因为它是回归问题,我们有兴趣直接预测数值而不进行变换。
使用有效的 ADAM 优化算法并且优化均方误差损失函数。这将与我们用于评估模型表现的指标相同。这是一个理想的指标,因为通过取平方根给出了一个误差值,我们可以在问题的背景下直接理解(数千美元)。
# define base model
def baseline_model():
# create model
model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam')
return model
用于 scikit-learn 作为回归估计器的 Keras 包装器对象称为 KerasRegressor。我们创建一个实例并将其传递给函数的名称以创建神经网络模型以及一些参数以便稍后传递给模型的 fit()函数,例如时期数和批量大小。这两个都设置为合理的默认值。
我们还使用常量随机种子初始化随机数生成器,我们将为本教程中评估的每个模型重复该过程。这是为了确保我们一致地比较模型。
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# evaluate model with standardized dataset
estimator = KerasRegressor(build_fn=baseline_model, epochs=100, batch_size=5, verbose=0)
最后一步是评估此基线模型。我们将使用 10 倍交叉验证来评估模型。
kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(estimator, X, Y, cv=kfold)
print("Results: %.2f (%.2f) MSE" % (results.mean(), results.std()))
运行此代码可以估算出模型在看不见的数据问题上的表现。结果报告了均方误差,包括交叉验证评估的所有 10 倍的平均值和标准偏差(平均方差)。
Baseline: 31.64 (26.82) MSE
3.建模标准化数据集
波士顿房价数据集的一个重要问题是输入属性的尺度各不相同,因为它们测量的数量不同。
在使用神经网络模型对数据进行建模之前准备数据几乎总是好的做法。
继续上述基线模型,我们可以使用输入数据集的标准化版本重新评估相同的模型。
我们可以使用 scikit-learn 的 Pipeline 框架在模型评估过程中,在交叉验证的每个折叠内执行标准化。这确保了每个测试集交叉验证折叠中没有数据泄漏到训练数据中。
下面的代码创建了一个 scikit-learn Pipeline,它首先标准化数据集,然后创建和评估基线神经网络模型。
# evaluate model with standardized dataset
numpy.random.seed(seed)
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=baseline_model, epochs=50, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Standardized: %.2f (%.2f) MSE" % (results.mean(), results.std()))
运行该示例可提供比基线模型更高的表现,而无需标准化数据,从而丢弃错误。
Standardized: 29.54 (27.87) MSE
此部分的进一步扩展将类似地对输出变量应用重新缩放,例如将其归一化到 0-1 的范围,并在输出层上使用 Sigmoid 或类似的激活函数,以将输出预测缩小到相同的范围。
4.调整神经网络拓扑
有许多问题可以针对神经网络模型进行优化。
也许最大的杠杆点是网络本身的结构,包括层数和每层神经元的数量。
在本节中,我们将评估另外两种网络拓扑,以进一步提高模型的表现。我们将研究更深入和更广泛的网络拓扑。
4.1。评估更深入的网络拓扑
提高神经网络表现的一种方法是添加更多层。这可能允许模型提取并重新组合数据中嵌入的高阶特征。
在本节中,我们将评估向模型添加一个隐藏层的效果。这就像定义一个新函数一样简单,这个函数将创建这个更深层次的模型,从上面的基线模型中复制出来。然后我们可以在第一个隐藏层之后插入一个新行。在这种情况下,神经元的数量约为一半。
# define the model
def larger_model():
# create model
model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(6, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam')
return model
我们的网络拓扑现在看起来像:
13 inputs -> [13 -> 6] -> 1 output
我们可以采用与上述相同的方式评估此网络拓扑,同时还使用上面显示的数据集的标准化来提高表现。
numpy.random.seed(seed)
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=larger_model, epochs=50, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Larger: %.2f (%.2f) MSE" % (results.mean(), results.std()))
运行此模型确实表明表现从 28 降至 24,000 平方美元进一步改善。
Larger: 22.83 (25.33) MSE
4.2。评估更广泛的网络拓扑
增加模型的表示能力的另一种方法是创建更广泛的网络。
在本节中,我们将评估保持浅层网络架构的效果,并使一个隐藏层中的神经元数量几乎翻倍。
同样,我们需要做的就是定义一个创建神经网络模型的新函数。在这里,与 13 到 20 的基线模型相比,我们增加了隐藏层中神经元的数量。
# define wider model
def wider_model():
# create model
model = Sequential()
model.add(Dense(20, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam')
return model
我们的网络拓扑现在看起来像:
13 inputs -> [20] -> 1 output
我们可以使用与上面相同的方案评估更广泛的网络拓扑:
numpy.random.seed(seed)
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=wider_model, epochs=100, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Wider: %.2f (%.2f) MSE" % (results.mean(), results.std()))
建立模型的确看到误差进一步下降到大约 2.1 万平方美元。对于这个问题,这不是一个糟糕的结果。
Wider: 21.64 (23.75) MSE
很难想象更广泛的网络在这个问题上会胜过更深层次的网络。结果证明了在开发神经网络模型时经验测试的重要性。
摘要
在这篇文章中,您发现了用于建模回归问题的 Keras 深度学习库。
通过本教程,您学习了如何开发和评估神经网络模型,包括:
- 如何加载数据和开发基线模型。
- 如何使用标准化等数据准备技术提升表现。
- 如何针对问题设计和评估具有不同变化拓扑的网络。
您对 Keras 深度学习库或这篇文章有任何疑问吗?在评论中提出您的问题,我会尽力回答。
如何使用 Keras 获得可重现的结果
原文:
machinelearningmastery.com/reproducible-results-neural-networks-keras/
神经网络算法是随机的。
这意味着它们利用随机性,例如初始化为随机权重,反过来,在相同数据上训练的相同网络可以产生不同的结果。
这可能会让初学者感到困惑,因为算法似乎不稳定,实际上它们是设计的。随机初始化允许网络学习正在学习的函数的良好近似。
然而,有时候每次在相同的数据上训练相同的网络时,您需要完全相同的结果。比如教程,或者可能是操作上的。
在本教程中,您将了解如何为随机数生成器设定种子,以便每次都可以从同一网络中获取相同数据的相同结果。
让我们开始吧。
如何从 Keras 的神经网络获得可重现的结果 照片由 Samuel John ,保留一些权利。
教程概述
本教程分为 6 个部分。他们是:
- 为什么每次都会得到不同的结果?
- 证明不同的结果
- 解决方案
- 种子随机数与 Theano 后端
- 种子随机数与 TensorFlow 后端
- 如果我仍然得到不同的结果怎么办?
环境
本教程假定您已安装 Python SciPy 环境。您可以在此示例中使用 Python 2 或 3。
本教程假设您使用 TensorFlow(v1.1.0 +)或 Theano(v0.9 +)后端安装了 Keras(v2.0.3 +)。
本教程还假设您安装了 scikit-learn,Pandas,NumPy 和 Matplotlib。
如果您在设置 Python 环境时需要帮助,请参阅以下帖子:
为什么每次都会得到不同的结果?
这是我从初学者到神经网络和深度学习领域的常见问题。
这种误解也可能以下列问题的形式出现:
- _ 如何获得稳定的结果?_
- _ 如何获得可重复的结果?_
- _ 我应该使用什么种子?_
神经网络通过设计使用随机性,以确保它们有效地学习与问题近似的函数。使用随机性是因为这类机器学习算法比没有它更好。
神经网络中最常用的随机形式是网络权重的随机初始化。虽然随机性可用于其他领域,但这里只是一个简短的列表:
- 初始化中的随机性,例如权重。
- 正则化中的随机性,例如 dropout。
- 层中的随机性,例如单词嵌入。
- 优化中的随机性,例如随机优化。
这些随机性来源等等意味着当您在完全相同的数据上运行完全相同的神经网络算法时,您可以保证得到不同的结果。
有关随机算法背后原因的更多信息,请参阅帖子:
证明不同的结果
我们可以用一个小例子来证明神经网络的随机性。
在本节中,我们将开发一个多层感知机模型,以学习从 0.0 到 0.9 增加 0.1 的短序列。给定 0.0,模型必须预测 0.1;给定 0.1,模型必须输出 0.2;等等。
下面列出了准备数据的代码。
# create sequence
length = 10
sequence = [i/float(length) for i in range(length)]
# create X/y pairs
df = DataFrame(sequence)
df = concat([df.shift(1), df], axis=1)
df.dropna(inplace=True)
# convert to MLPfriendly format
values = df.values
X, y = values[:,0], values[:,1]
我们将使用一个输入的网络,隐藏层中的 10 个神经元和 1 个输出。网络将使用均方误差丢失函数,并将使用有效的 ADAM 算法进行训练。
网络需要大约 1000 个时代来有效地解决这个问题,但我们只会训练它 100 个时代。这是为了确保我们得到一个在做出预测时出错的模型。
在训练网络之后,我们将对数据集做出预测并打印均方误差。
网络代码如下所示。
# design network
model = Sequential()
model.add(Dense(10, input_dim=1))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
# fit network
model.fit(X, y, epochs=100, batch_size=len(X), verbose=0)
# forecast
yhat = model.predict(X, verbose=0)
print(mean_squared_error(y, yhat[:,0]))
在该示例中,我们将创建网络 10 次并打印 10 个不同的网络分数。
完整的代码清单如下。
from pandas import DataFrame
from pandas import concat
from keras.models import Sequential
from keras.layers import Dense
from sklearn.metrics import mean_squared_error
# fit MLP to dataset and print error
def fit_model(X, y):
# design network
model = Sequential()
model.add(Dense(10, input_dim=1))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
# fit network
model.fit(X, y, epochs=100, batch_size=len(X), verbose=0)
# forecast
yhat = model.predict(X, verbose=0)
print(mean_squared_error(y, yhat[:,0]))
# create sequence
length = 10
sequence = [i/float(length) for i in range(length)]
# create X/y pairs
df = DataFrame(sequence)
df = concat([df.shift(1), df], axis=1)
df.dropna(inplace=True)
# convert to MLP friendly format
values = df.values
X, y = values[:,0], values[:,1]
# repeat experiment
repeats = 10
for _ in range(repeats):
fit_model(X, y)
运行该示例将在每行中打印不同的精度。
您的具体结果会有所不同。下面提供了一个示例输出。
0.0282584265697
0.0457025913022
0.145698137198
0.0873461454407
0.0309397604521
0.046649185173
0.0958450337178
0.0130660263779
0.00625176026631
0.00296055161492
解决方案
这是两个主要的解决方案。
解决方案#1:重复您的实验
解决此问题的传统和实用方法是多次运行您的网络(30+)并使用统计量来总结模型的表现,并将您的模型与其他模型进行比较。
我强烈推荐这种方法,但由于某些型号的训练时间很长,因此并不总是可行。
有关此方法的更多信息,请参阅:
解决方案#2:为随机数生成器播种
或者,另一种解决方案是使用固定种子作为随机数发生器。
使用伪随机数生成器生成随机数。随机数生成器是一种数学函数,它将生成一个长序列的数字,这些数字足够随机用于通用目的,例如机器学习算法。
随机数生成器需要种子来启动进程,并且通常在大多数实现中使用当前时间(以毫秒为单位)作为默认值。这是为了确保每次运行代码时都会生成不同的随机数序列,默认情况下。
也可以使用特定数字(例如“1”)指定此种子,以确保每次运行代码时都生成相同的随机数序列。
只要每次运行代码时,特定的种子值都无关紧要。
设置随机数生成器的具体方法因后端而异,我们将在 Theano 和 TensorFlow 中查看如何执行此操作。
种子随机数与 Theano 后端
通常,Keras 从 NumPy 随机数生成器获得随机源。
在大多数情况下,Theano 后端也是如此。
我们可以通过从随机模块调用 seed()函数来播种 NumPy 随机数生成器,如下所示:
from numpy.random import seed
seed(1)
导入和调用种子函数最好在代码文件的顶部完成。
这是最佳实践,因为即使在直接使用它们之前,当各种 Keras 或 Theano(或其他)库作为初始化的一部分导入时,可能会使用某些随机性。
我们可以将两行添加到上面示例的顶部并运行两次。
每次运行代码时都应该看到相同的均方误差值列表(可能由于不同机器上的精度而有一些微小的变化),如下所示:
0.169326527063
2.75750621228e-05
0.0183287291562
1.93553737255e-07
0.0549871087449
0.0906326807824
0.00337575114075
0.00414857518259
8.14587362008e-08
0.0522927019639
您的结果应与我的匹配(忽略精确度的微小差异)。
种子随机数与 TensorFlow 后端
Keras 确实从 NumPy 随机数生成器获得随机源,因此无论您使用的是 Theano 还是 TensorFlow 后端,都必须播种。
必须通过在任何其他导入或其他代码之前调用文件顶部的 seed()函数来播种。
from numpy.random import seed
seed(1)
此外,TensorFlow 还有自己的随机数生成器,必须通过在 NumPy 随机数生成器之后立即调用 set_random_seed()函数来播种,如下所示:
from tensorflow import set_random_seed
set_random_seed(2)
为了清楚起见,代码文件的顶部必须在任何其他文件之前有以下 4 行;
from numpy.random import seed
seed(1)
from tensorflow import set_random_seed
set_random_seed(2)
您可以为两种或不同的种子使用相同的种子。我不认为随机性来源进入不同的过程会产生很大的不同。
将这 4 行添加到上面的示例将允许代码在每次运行时生成相同的结果。您应该看到与下面列出的相同的均方误差值(由于不同机器上的精度,可能会有一些微小的变化):
0.224045112999
0.00154879478823
0.00387589994044
0.0292376881968
0.00945528404353
0.013305765525
0.0206255228201
0.0359538356108
0.00441943512128
0.298706569397
您的结果应与我的匹配(忽略精确度的微小差异)。
如果我仍然得到不同的结果怎么办?
要重新迭代,最有效的报告结果和比较模型的方法是多次重复实验(30+)并使用汇总统计。
如果无法做到这一点,您可以通过为代码使用的随机数生成器播种获得 100%可重复的结果。上述解决方案应涵盖大多数情况,但不是全部。
如果您遵循上述说明并仍然在相同数据上获得相同算法的不同结果,该怎么办?
您可能还有其他未考虑的随机性来源。
来自第三方库的随机性
也许你的代码使用了一个额外的库,它使用了一个也必须种子的不同随机数生成器。
尝试将代码切换回所需的最低要求(例如,一个数据样本,一个训练时期等)并仔细阅读 API 文档,以便缩小引入随机性的其他第三方库。
使用 GPU 的随机性
以上所有示例均假设代码在 CPU 上运行。
当使用 GPU 训练模型时,后端可能被配置为使用复杂的 GPU 库栈,其中一些可能会引入他们自己或可能无法解释的随机源。
例如,有一些证据表明,如果您在栈中使用 Nvidia cuDNN ,则可能会引入其他随机源并阻止您的结果的完全重现性。
来自复杂模型的随机性
由于您的模型的复杂性和训练的平行性,您可能会得到不可重复的结果。
这很可能是由后端库产生的效率引起的,也许是因为无法跨核心使用随机数序列。
我自己没有看到这个,但看到一些 GitHub 问题和 StackOverflow 问题的迹象。
您可以尝试降低模型的复杂性,看看这是否会影响结果的可重复性,只是为了缩小原因。
我建议您阅读后端如何使用随机性,看看是否有任何选项可供您使用。
在 Theano,请参阅:
在 TensorFlow 中,请参阅:
此外,请考虑搜索具有相同问题的其他人以获得进一步的洞察力。一些很棒的搜索地点包括:
- GrasHub 上的 Keras 问题
- The On 对 Github 的问题
- GitHub 上的 TensorFlow 问题
- StackOverflow 通用编程 Q& A
- CrossValidated 机器学习 Q& A
摘要
在本教程中,您了解了如何在 Keras 中获得可重现的神经网络模型结果。
具体来说,你学到了:
- 神经网络在设计上是随机的,并且可以固定随机源以使结果可重复。
- 您可以在 NumPy 和 TensorFlow 中播种随机数生成器,这将使大多数 Keras 代码 100%可重现。
- 在某些情况下,存在其他随机源,并且您有关于如何寻找它们的想法,也许也可以修复它们。
本教程有帮助吗? 在评论中分享您的经验。
您是否仍然可以通过 Keras 获得无法重现的结果? 分享您的经验;也许这里的其他人可以帮忙。
如何在 Linux 服务器上运行深度学习实验
原文:
machinelearningmastery.com/run-deep-learning-experiments-linux-server/
编写代码后,必须在具有大量 RAM,CPU 和 GPU 资源的大型计算机上运行深度学习实验,通常是云中的 Linux 服务器。
最近,我被问到这个问题:
“你如何进行深度学习实验?”
这是一个我喜欢回答的好问题。
在这篇文章中,您将发现我用于在 Linux 上运行深度学习实验的方法,命令和脚本。
阅读这篇文章后,你会知道:
- 如何设计建模实验以将模型保存到文件。
- 如何运行单个 Python 实验脚本。
- 如何从 shell 脚本顺序运行多个 Python 实验。
让我们开始吧。
如何在 Linux 服务器上运行深度学习实验 Patrik Nygren 的照片,保留一些权利。
1. Linux 服务器
我在工作站上编写了所有建模代码,并在远程 Linux 服务器上运行所有代码。
目前,我的偏好是在 EC2 上使用亚马逊深度学习 AMI 。有关为自己的实验设置此服务器的帮助,请参阅帖子:
2.建模代码
我编写代码,以便每个 python 文件有一个实验。
大多数情况下,我正在处理大型数据,如图像字幕,文本摘要和机器翻译。
每个实验都适合模型,并将整个模型或权重保存到 HDF5 文件,以便以后重复使用。
有关将模型保存到文件的更多信息,请参阅以下帖子:
我尝试准备一套实验(通常是 10 个或更多)以便在一个批次中运行。我还尝试将数据准备步骤分离为首先运行的脚本,并创建可随时加载和使用的训练数据集的 pickle 版本。
3.运行实验
每个实验可能会在训练期间输出一些诊断信息,因此,每个脚本的输出都会重定向到特定于实验的日志文件。如果事情失败,我也会重定向标准错误。
在运行时,Python 解释器可能不会经常刷新输出,尤其是在系统负载不足的情况下。我们可以使用 Python 解释器上的 -u 标志强制将输出刷新到日志中。
运行单个脚本(myscript.py)如下所示:
python -u myscript.py >myscript.py.log 2>&1
我可以创建一个“_ 模型”_ 和一个“_ 结果”_ 目录,并更新要保存到这些目录的模型文件和日志文件,以保持代码目录清晰。
4.运行批量实验
每个 Python 脚本都按顺序运行。
创建一个 shell 脚本,按顺序列出多个实验。例如:
#!/bin/sh
# run experiments
python -u myscript1.py >myscript1.py.log 2>&1
python -u myscript2.py >myscript2.py.log 2>&1
python -u myscript3.py >myscript3.py.log 2>&1
python -u myscript4.py >myscript4.py.log 2>&1
python -u myscript5.py >myscript5.py.log 2>&1
该文件将保存为“ run.sh”,与代码文件放在同一目录中并在服务器上运行。
例如,如果所有代码和 run.sh 脚本都位于“ ec2-user ”主目录的“experiments”目录中,则脚本将按如下方式运行:
nohup /home/ec2-user/experiments/run.sh > /home/ec2-user/experiments/run.sh.log </dev/null 2>&1 &
该脚本作为后台进程运行,无法轻易中断。我还捕获了这个脚本的结果,以防万一。
您可以在本文中了解有关在 Linux 上运行脚本的更多信息:
就是这样。
进一步阅读
如果您希望深入了解,本节将提供有关该主题的更多资源。
- 源代码深度学习 AMI(CUDA 8,亚马逊 Linux)
- 保存并加载您的 Keras 深度学习模型
- 如何在 Keras 检查深度学习模型
- 10 个亚马逊网络服务深度学习命令行方案
- 如何使用亚马逊网络服务上的 Keras 开发和评估大型深度学习模型
摘要
在这篇文章中,您发现了我用于在 Linux 上运行深度学习实验的方法,命令和脚本。
具体来说,你学到了:
- 如何设计建模实验以将模型保存到文件。
- 如何运行单个 Python 实验脚本。
- 如何从 shell 脚本顺序运行多个 Python 实验。
你有任何问题吗? 在下面的评论中提出您的问题,我会尽力回答。
保存并加载您的 Keras 深度学习模型
原文:
machinelearningmastery.com/save-load-keras-deep-learning-models/
Keras 是一个简单而强大的 Python 库,用于深度学习。
鉴于深度学习模型可能需要数小时,数天甚至数周才能进行训练,因此了解如何从磁盘保存和加载它们非常重要。
在这篇文章中,您将了解如何将 Keras 模型保存到文件中并再次加载它们以做出预测。
让我们开始吧。
- 2017 年 3 月更新:添加了先安装 h5py 的说明。在每个示例中的最终打印语句中添加了缺少括号。
- 2017 年 3 月更新:更新了 Keras 2.0.2,TensorFlow 1.0.1 和 Theano 0.9.0 的示例。
- 更新 March / 2018 :添加了备用链接以下载数据集,因为原始图像已被删除。
保存并加载您的 Keras 深度学习模型 照片由 art_inthecity 保留,保留一些权利。
教程概述
Keras 将保存模型架构和保存模型权重的问题分开。
模型权重保存为 HDF5 格式。这是一种网格格式,非常适合存储多维数字数组。
可以使用两种不同的格式描述和保存模型结构:JSON 和 YAML。
在这篇文章中,我们将看两个保存模型并将其加载到文件的示例:
- 将模型保存为 JSON。
- 将模型保存到 YAML。
每个示例还将演示如何将模型权重保存并加载到 HDF5 格式的文件中。
这些例子将使用在 Pima Indians 糖尿病二分类数据集开始时训练的相同简单网络。这是一个包含所有数字数据的小型数据集,易于使用。您可以下载此数据集并将其放在您的工作目录中,文件名为“ pima-indians-diabetes.csv ”(更新:从这里下载)。
确认您安装了最新版本的 Keras(截至 2017 年 3 月的 v1.2.2)。
注意:您可能需要先安装h5py:
sudo pip install h5py
将您的神经网络模型保存为 JSON
JSON 是一种用于分层描述数据的简单文件格式。
Keras 提供了使用带有to_json()函数的 JSON 格式描述任何模型的功能。这可以保存到文件中,然后通过model_from_json()函数加载,该函数将根据 JSON 规范创建新模型。
使用save_weights()函数直接从模型保存权重,然后使用对称load_weights()函数加载。
以下示例训练和评估 Pima Indians 数据集上的简单模型。然后将模型转换为 JSON 格式并写入本地目录中的 model.json。网络权重写入本地目录中的model.h5。
从保存的文件加载模型和重量数据,并创建新模型。在加载模型使用之前编译它是很重要的。这样使用该模型进行的预测可以使用 Keras 后端的适当有效计算。
以相同的方式评估模型,打印相同的评估分数。
# MLP for Pima Indians Dataset Serialize to JSON and HDF5
from keras.models import Sequential
from keras.layers import Dense
from keras.models import model_from_json
import numpy
import os
# fix random seed for reproducibility
numpy.random.seed(7)
# load pima indians dataset
dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, kernel_initializer='uniform', activation='relu'))
model.add(Dense(8, kernel_initializer='uniform', activation='relu'))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
# serialize model to JSON
model_json = model.to_json()
with open("model.json", "w") as json_file:
json_file.write(model_json)
# serialize weights to HDF5
model.save_weights("model.h5")
print("Saved model to disk")
# later...
# load json and create model
json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
# load weights into new model
loaded_model.load_weights("model.h5")
print("Loaded model from disk")
# evaluate loaded model on test data
loaded_model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
score = loaded_model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (loaded_model.metrics_names[1], score[1]*100))
运行此示例提供下面的输出。
acc: 78.78%
Saved model to disk
Loaded model from disk
acc: 78.78%
该模型的 JSON 格式如下所示:
{
"keras_version":"2.0.2",
"backend":"theano",
"config":[
{
"config":{
"dtype":"float32",
"bias_regularizer":null,
"activation":"relu",
"bias_constraint":null,
"use_bias":true,
"bias_initializer":{
"config":{
},
"class_name":"Zeros"
},
"kernel_regularizer":null,
"activity_regularizer":null,
"kernel_constraint":null,
"trainable":true,
"name":"dense_1",
"kernel_initializer":{
"config":{
"maxval":0.05,
"minval":-0.05,
"seed":null
},
"class_name":"RandomUniform"
},
"batch_input_shape":[
null,
8
],
"units":12
},
"class_name":"Dense"
},
{
"config":{
"kernel_regularizer":null,
"bias_regularizer":null,
"activation":"relu",
"bias_constraint":null,
"use_bias":true,
"bias_initializer":{
"config":{
},
"class_name":"Zeros"
},
"activity_regularizer":null,
"kernel_constraint":null,
"trainable":true,
"name":"dense_2",
"kernel_initializer":{
"config":{
"maxval":0.05,
"minval":-0.05,
"seed":null
},
"class_name":"RandomUniform"
},
"units":8
},
"class_name":"Dense"
},
{
"config":{
"kernel_regularizer":null,
"bias_regularizer":null,
"activation":"sigmoid",
"bias_constraint":null,
"use_bias":true,
"bias_initializer":{
"config":{
},
"class_name":"Zeros"
},
"activity_regularizer":null,
"kernel_constraint":null,
"trainable":true,
"name":"dense_3",
"kernel_initializer":{
"config":{
"maxval":0.05,
"minval":-0.05,
"seed":null
},
"class_name":"RandomUniform"
},
"units":1
},
"class_name":"Dense"
}
],
"class_name":"Sequential"
}
将您的神经网络模型保存到 YAML
此示例与上述 JSON 示例大致相同,只是 YAML 格式用于模型规范。
使用 YAML 描述模型,保存到文件 model.yaml,然后通过model_from_yaml()函数加载到新模型中。权重的处理方式与上面 HDF5 格式相同,如 model.h5。
# MLP for Pima Indians Dataset serialize to YAML and HDF5
from keras.models import Sequential
from keras.layers import Dense
from keras.models import model_from_yaml
import numpy
import os
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load pima indians dataset
dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, kernel_initializer='uniform', activation='relu'))
model.add(Dense(8, kernel_initializer='uniform', activation='relu'))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
# serialize model to YAML
model_yaml = model.to_yaml()
with open("model.yaml", "w") as yaml_file:
yaml_file.write(model_yaml)
# serialize weights to HDF5
model.save_weights("model.h5")
print("Saved model to disk")
# later...
# load YAML and create model
yaml_file = open('model.yaml', 'r')
loaded_model_yaml = yaml_file.read()
yaml_file.close()
loaded_model = model_from_yaml(loaded_model_yaml)
# load weights into new model
loaded_model.load_weights("model.h5")
print("Loaded model from disk")
# evaluate loaded model on test data
loaded_model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
score = loaded_model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (loaded_model.metrics_names[1], score[1]*100))
运行该示例将显示以下输出:
acc: 78.78%
Saved model to disk
Loaded model from disk
acc: 78.78%
以 YAML 格式描述的模型如下所示:
backend: theano
class_name: Sequential
config:
- class_name: Dense
config:
activation: relu
activity_regularizer: null
batch_input_shape: !!python/tuple [null, 8]
bias_constraint: null
bias_initializer:
class_name: Zeros
config: {}
bias_regularizer: null
dtype: float32
kernel_constraint: null
kernel_initializer:
class_name: RandomUniform
config: {maxval: 0.05, minval: -0.05, seed: null}
kernel_regularizer: null
name: dense_1
trainable: true
units: 12
use_bias: true
- class_name: Dense
config:
activation: relu
activity_regularizer: null
bias_constraint: null
bias_initializer:
class_name: Zeros
config: {}
bias_regularizer: null
kernel_constraint: null
kernel_initializer:
class_name: RandomUniform
config: {maxval: 0.05, minval: -0.05, seed: null}
kernel_regularizer: null
name: dense_2
trainable: true
units: 8
use_bias: true
- class_name: Dense
config:
activation: sigmoid
activity_regularizer: null
bias_constraint: null
bias_initializer:
class_name: Zeros
config: {}
bias_regularizer: null
kernel_constraint: null
kernel_initializer:
class_name: RandomUniform
config: {maxval: 0.05, minval: -0.05, seed: null}
kernel_regularizer: null
name: dense_3
trainable: true
units: 1
use_bias: true
keras_version: 2.0.2
进一步阅读
摘要
在这篇文章中,您了解了如何序列化您的 Keras 深度学习模型。
您学习了如何将训练过的模型保存到文件中,然后加载它们并使用它们做出预测。
您还了解到,使用 HDF5 格式可以轻松存储模型权重,并且网络结构可以以 JSON 或 YAML 格式保存。
您对保存深度学习模型或此帖子有任何疑问吗?在评论中提出您的问题,我会尽力回答。
Python 的 Softmax 激活函数
Softmax 是一个数学函数,它将一个数字向量转换成一个概率向量,其中每个值的概率与向量中每个值的相对比例成正比。
softmax 函数在应用机器学习中最常见的用途是用作神经网络模型中的激活函数。具体而言,网络被配置为输出 N 个值,分类任务中的每个类一个值,并且 softmax 函数被用于归一化输出,将它们从加权和值转换成总和等于 1 的概率。softmax 函数输出中的每个值都被解释为每个类的成员概率。
在本教程中,您将发现神经网络模型中使用的 softmax 激活函数。
完成本教程后,您将知道:
- 线性和 Sigmoid 激活函数不适用于多类分类任务。
- Softmax 可以被认为是 argmax 函数的软化版本,它返回列表中最大值的索引。
- 如何在 Python 中从头实现 softmax 函数,如何将输出转换成类标签。
我们开始吧。
带 Python 的 Softmax 激活函数 图片由伊恩·d·基廷提供,保留部分权利。
教程概述
本教程分为三个部分;它们是:
- 用神经网络预测概率
- 最大值、最大值和最大值
- 软最大激活函数
用神经网络预测概率
神经网络模型可用于对分类预测建模问题进行建模。
分类问题是那些涉及预测给定输入的类标签的问题。建模分类问题的标准方法是使用模型来预测类成员的概率。也就是说,举个例子,它属于每个已知类别标签的概率是多少?
- 对于二元分类问题,使用二项概率分布。这是通过使用在输出层具有单个节点的网络来实现的,该网络预测属于类别 1 的示例的概率。
- 对于多类分类问题,使用多项式概率。这是通过使用一个网络来实现的,该网络在输出层中每个类都有一个节点,并且预测概率的总和等于 1。
神经网络模型需要模型输出层的激活函数来进行预测。
有不同的激活函数可供选择;我们来看几个。
线性激活函数
预测类成员概率的一种方法是使用线性激活。
线性激活函数只是节点的加权输入之和,任何激活函数都需要它作为输入。因此,它通常被称为“无激活函数”,因为不执行额外的转换。
*回想一下概率或可能性是一个介于 0 和 1 之间的数值。
假设没有对输入的加权和执行任何变换,则线性激活函数可以输出任何数值。这使得线性激活函数不适用于预测二项式或多项式情况下的概率。
Sigmoid 激活函数
预测类成员概率的另一种方法是使用 sigmoid 激活函数。
这个函数也被称为逻辑函数。不管输入是什么,函数总是输出一个介于 0 和 1 之间的值。函数的形式是 0 到 1 之间的 S 形,垂直或中间的“ S ”为 0.5。
这允许作为输入加权和给出的非常大的值输出为 1.0,非常小的或负值映射为 0.0。
sigmoid 激活是二元分类问题的理想激活函数,其中输出被解释为二项式概率分布。
sigmoid 激活函数也可以用作多类分类问题的激活函数,其中类是非互斥的。这些通常被称为多标签分类,而不是多类别分类。
sigmoid 激活函数不适用于需要多项式概率分布的互斥类的多类分类问题。
相反,需要一个称为软最大功能的替代激活。
最大值、最大值和最大值
最大函数
最大值或“ max ”数学函数返回数值列表中最大的数值。
我们可以使用 max() Python 函数来实现;例如:
# example of the max of a list of numbers
# define data
data = [1, 3, 2]
# calculate the max of the list
result = max(data)
print(result)
运行该示例将从数字列表中返回最大值“3”。
3
Argmax 函数
argmax 或“ arg max ”数学函数返回列表中包含最大值的索引。
把它想象成 max 的元版本:max 之上的一级间接,指向列表中具有 max 值的位置,而不是值本身。
我们可以使用 argmax() NumPy 函数来实现;例如:
# example of the argmax of a list of numbers
from numpy import argmax
# define data
data = [1, 3, 2]
# calculate the argmax of the list
result = argmax(data)
print(result)
运行该示例将返回列表索引值“1”,该值指向包含列表“3”中最大值的数组索引[1]。
1
软最大函数
softmax,或“T0”soft max,数学函数可以被认为是 argmax 函数的概率或“T2”更软的版本。
之所以使用 softmax 这个术语,是因为这个激活函数代表了赢者通吃激活模型的平滑版本,其中输入最大的单元具有输出+1,而所有其他单元具有输出 0。
—第 238 页,用于模式识别的神经网络,1995。
从概率的角度来看,如果 argmax() 函数在前一节中返回 1,那么对于其他两个数组索引,它将返回 0,对于列表[1,3,2]中最大的值,给索引 1 完全的权重,而不给索引 0 和索引 2 任何权重。
[0, 1, 0]
如果我们不太确定,想用概率来表达 argmax,有可能吗?
这可以通过缩放列表中的值并将其转换为概率来实现,以便返回的列表中的所有值的总和为 1.0。
这可以通过计算列表中每个值的指数并将其除以指数值的总和来实现。
- 概率= exp(值)/列表中的总和 v exp(v)
例如,我们可以将列表[1,3,2]中的第一个值“1”转换为概率,如下所示:
- 概率= exp(1) / (exp(1) + exp(3) + exp(2))
- 概率= exp(1) / (exp(1) + exp(3) + exp(2))
- 概率= 2.718281828459045/30。58865 . 8888888886
- 概率= 0.09003057317038046
我们可以用 Python 为列表[1,3,2]中的每个值演示如下:
# transform values into probabilities
from math import exp
# calculate each probability
p1 = exp(1) / (exp(1) + exp(3) + exp(2))
p2 = exp(3) / (exp(1) + exp(3) + exp(2))
p3 = exp(2) / (exp(1) + exp(3) + exp(2))
# report probabilities
print(p1, p2, p3)
# report sum of probabilities
print(p1 + p2 + p3)
运行该示例将列表中的每个值转换为概率并报告这些值,然后确认所有概率的总和为值 1.0。
我们可以看到,大部分权重被放在指数 1 上(67%),指数 2 上的权重较小(24%),指数 0 上的权重甚至更小(9%)。
0.09003057317038046 0.6652409557748219 0.24472847105479767
1.0
这是 softmax 功能。
我们可以将其实现为一个函数,该函数接受一个数字列表,并返回该列表的软最大值或多项式概率分布。
下面的例子实现了这个函数,并在我们的小数字列表中演示了它。
# example of a function for calculating softmax for a list of numbers
from numpy import exp
# calculate the softmax of a vector
def softmax(vector):
e = exp(vector)
return e / e.sum()
# define data
data = [1, 3, 2]
# convert list of numbers to a list of probabilities
result = softmax(data)
# report the probabilities
print(result)
# report the sum of the probabilities
print(sum(result))
运行该示例会报告大致相同的数字,但精确率略有差异。
[0.09003057 0.66524096 0.24472847]
1.0
最后,我们可以使用内置的 softmax() NumPy 函数来计算一个数组或数字列表的 softmax,如下所示:
# example of calculating the softmax for a list of numbers
from scipy.special import softmax
# define data
data = [1, 3, 2]
# calculate softmax
result = softmax(data)
# report the probabilities
print(result)
# report the sum of the probabilities
print(sum(result))
再次运行该示例,我们得到了非常相似的结果,但精确率差异很小。
[0.09003057 0.66524096 0.24472847]
0.9999999999999997
现在我们已经熟悉了 softmax 函数,让我们看看它是如何在神经网络模型中使用的。
软最大激活函数
softmax 函数用作预测多项式概率分布的神经网络模型的输出层中的激活函数。
也就是说,softmax 被用作多类分类问题的激活函数,其中在两个以上的类标签上需要类成员资格。
任何时候我们希望用 n 个可能值来表示一个离散变量的概率分布,我们都可以使用 softmax 函数。这可以看作是 sigmoid 函数的推广,sigmoid 函数用于表示二元变量的概率分布。
—第 184 页,深度学习,2016。
该函数可以用作神经网络中隐藏层的激活函数,尽管这不太常见。当模型内部需要在瓶颈层或连接层选择或加权多个不同的输入时,可以使用它。
Softmax 单位自然代表一个具有 k 个可能值的离散变量的概率分布,因此它们可以用作一种开关。
—第 196 页,深度学习,2016。
在具有三类分类任务的 Keras 深度学习库中,输出层中 softmax 的使用可能如下所示:
...
model.add(Dense(3, activation='softmax'))
根据定义,softmax 激活将为输出层中的每个节点输出一个值。输出值将表示(或者可以解释为)概率,并且这些值的总和为 1.0。
在对多类分类问题建模时,必须准备好数据。包含类标签的目标变量首先被标签编码,这意味着一个整数被应用于从 0 到 N-1 的每个类标签,其中 N 是类标签的数量。
然后对标签编码(或整数编码)的目标变量进行一次热编码。这是类标签的概率表示,很像 softmax 输出。为每个类标签和位置创建一个带有位置的向量。所有值都标记为 0(不可能),1(确定)用于标记类别标签的位置。
例如,三个类标签将被整数编码为 0、1 和 2。然后编码成矢量,如下所示:
- 类别 0: [1,0,0]
- 类别 1: [0,1,0]
- 类别 2: [0,0,1]
这叫做一热编码。
它表示用于在监督学习下校正模型的每个类的期望多项式概率分布。
softmax 函数将为每个类别标签输出类别成员的概率,并尝试为给定的输入最好地近似预期目标。
例如,如果在一个示例中需要整数编码的类 1,那么目标向量将是:
- [0, 1, 0]
softmax 输出可能如下所示,它将最大的权重放在类 1 上,而将较小的权重放在其他类上。
- [0.09003057 0.66524096 0.24472847]
预期的和预测的多项式概率分布之间的误差通常使用交叉熵来计算,然后使用该误差来更新模型。这被称为交叉熵损失函数。
有关计算概率分布差异的交叉熵的更多信息,请参见教程:
我们可能希望将概率转换回整数编码的类标签。
这可以使用 argmax() 函数来实现,该函数返回具有最大值的列表的索引。假设类标签是从 0 到 N-1 的整数编码,概率的 argmax 将总是整数编码的类标签。
- class integer = arg max([0.09003057 0.66524096 0.24472847])
- 类整数= 1
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
书
- 用于模式识别的神经网络,1995。
- 神经网络:交易的诀窍:交易的诀窍,第二版,2012 年。
- 深度学习,2016 年。
蜜蜂
- num py . argmax API。
- scipy.special.softmax API 。
文章
摘要
在本教程中,您发现了神经网络模型中使用的 softmax 激活函数。
具体来说,您了解到:
- 线性和 Sigmoid 激活函数不适用于多类分类任务。
- Softmax 可以被认为是 argmax 函数的软化版本,它返回列表中最大值的索引。
- 如何在 Python 中从头实现 softmax 函数,如何将输出转换成类标签。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。*
TensorFlow 2 教程:使用tf.keras开始深度学习
最后更新于 2020 年 8 月 27 日
具有深度学习的预测建模是现代开发人员需要了解的技能。
TensorFlow 是由谷歌开发和维护的首要开源深度学习框架。虽然直接使用 TensorFlow 可能具有挑战性,但现代 tf.keras API 将 keras 的简单易用性赋予了 TensorFlow 项目。
使用 tf.keras 允许您设计、拟合、评估和使用深度学习模型,只需几行代码就可以做出预测。它使普通的深度学习任务,如分类和回归预测建模,对于希望完成事情的普通开发人员来说是可访问的。
在本教程中,您将发现一个使用 tf.keras API 在 TensorFlow 中开发深度学习模型的分步指南。
完成本教程后,您将知道:
- Keras 和 tf.keras 的区别以及如何安装和确认 TensorFlow 正在工作。
- tf.keras 模型的 5 步生命周期以及如何使用顺序和功能 API。
- 如何用 tf.keras 开发用于回归、分类和时间序列预测的 MLP、CNN 和 RNN 模型。
- 如何使用 tf.keras API 的高级功能来检查和诊断您的模型。
- 如何通过减少过度训练和加速训练来提高 tf.keras 模型的表现?
这是一个大型教程,非常有趣。你可能想把它做成书签。
例子小而集中;您可以在大约 60 分钟内完成本教程。
用我的新书用 Python 深度学习来启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
- 2020 年 6 月更新:针对 TensorFlow 2.2.0 中的 API 变更进行了更新。
如何用 tf.keras 开发深度学习模型 斯蒂芬·哈兰摄,版权所有。
张量流教程概述
本教程旨在为您的深度学习项目提供 tf.keras 的完整介绍。
重点是将 API 用于常见的深度学习模型开发任务;我们不会深入学习数学和理论。为此,我推荐从这本优秀的书开始。
在 python 中学习深度学习的最好方法是做。一头扎进去。你可以回头再找更多的理论。
我已经将每个代码示例设计成使用最佳实践和独立的,这样您就可以将它直接复制并粘贴到您的项目中,并根据您的特定需求进行调整。这将让你有一个很好的开端来尝试从官方文档中找出应用编程接口。
这是一个大型教程,因此,它分为五个部分;它们是:
- 安装 TensorFlow 和 tf.keras
- 什么是 Keras 和 tf.keras?
- 如何安装张量流
- 如何确认安装了张量流
- 深度学习模型生命周期
- 五步模型生命周期
- 顺序模型应用编程接口(简单)
- 功能模型应用编程接口(高级)
- 如何开发深度学习模型
- 开发多层感知机模型
- 发展卷积神经网络模型
- 开发递归神经网络模型
- 如何使用高级模型功能
- 如何可视化深度学习模型
- 如何绘制模型学习曲线
- 如何保存和加载模型
- 如何获得更好的模型表现
- 如何减少辍学的过度适应
- 如何利用批量标准化加速训练
- 如何适时停止训练,提前停止
你可以用 Python 做深度学习!
按照自己的节奏完成教程。
你不需要什么都懂(至少现在不需要)。您的目标是将教程从头到尾运行一遍并获得结果。你不需要第一遍就明白所有的事情。边走边列出你的问题。大量使用 API 文档来了解您正在使用的所有功能。
你不需要 Prophet 道数学。数学是描述算法如何工作的简洁方式,特别是来自线性代数、概率和统计的工具。这些不是你可以用来学习算法如何工作的唯一工具。您还可以使用代码并探索具有不同输入和输出的算法行为。知道数学不会告诉你选择什么算法或者如何最好地配置它。你只能通过仔细的受控实验来发现这一点。
你不需要知道算法是如何工作的。了解这些限制以及如何配置深度学习算法非常重要。但是关于算法的学习可以在以后进行。你需要长时间慢慢积累这些算法知识。今天,从适应平台开始。
不需要做 Python 程序员。如果你不熟悉 Python 语言,它的语法会很直观。就像其他语言一样,关注函数调用(例如 function())和赋值(例如 a =“b”)。这会让你大受鼓舞。你是一名开发人员,所以你知道如何快速掌握一门语言的基础知识。开始吧,稍后再深入细节。
不需要成为深度学习专家。你可以在后面学习各种算法的好处和局限性,有很多帖子可以在后面阅读,以复习深度学习项目的步骤以及使用交叉验证评估模型技能的重要性。
1. 安装 TensorFlow 和 tf.keras
在本节中,您将发现 tf.keras 是什么,如何安装它,以及如何确认它安装正确。
1.1 什么是 Keras 和 tf.keras?
Keras 是一个用 Python 编写的开源深度学习库。
该项目于 2015 年由 Francois Chollet 启动。它很快成为开发人员的流行框架,成为最流行的深度学习库之一。
在 2015-2019 年期间,使用像 TensorFlow、antio 和 PyTorch 这样的数学库开发深度学习模型是很麻烦的,需要几十甚至几百行代码才能完成最简单的任务。这些库的重点是研究、灵活性和速度,而不是易用性。
Keras 之所以受欢迎,是因为 API 简洁明了,只需几行代码就可以定义、适应和评估标准的深度学习模型。
Keras 起飞的第二个原因是,它允许您使用一系列流行的深度学习数学库中的任何一个作为后端(例如,用于执行计算),例如 TensorFlow 、antao,以及后来的 CNTK 。这使得这些库的能力可以用一个非常干净和简单的接口来利用(例如,图形处理器)。
2019 年,谷歌发布了他们的 TensorFlow 深度学习库(TensorFlow 2)的新版本,该版本直接集成了 Keras API,并将该界面推广为平台上深度学习开发的默认或标准界面。
这种集成通常被称为 tf.keras 接口或 API(“TF”是“ TensorFlow ”的缩写)。这是为了将其与所谓的独立 Keras 开源项目区分开来。
- 独立 Keras 。支持 TensorFlow、Antano 和 CNTK 后端的独立开源项目。
- tf.keras 。Keras API 集成到 TensorFlow 2 中。
Keras 中的 Keras API 实现被称为“ tf.keras ”,因为这是引用 API 时使用的 Python 习惯用法。首先导入 TensorFlow 模块,命名为“TF”;然后,通过调用 tf.keras 访问 Keras API 元素;例如:
# example of tf.keras python idiom
import tensorflow as tf
# use keras API
model = tf.keras.Sequential()
...
我自己一般不用这个成语;我认为它读起来不干净。
鉴于 TensorFlow 是 Keras 开源项目事实上的标准后端,这种集成意味着现在可以使用一个库,而不是两个独立的库。此外,独立的 Keras 项目现在建议所有未来的 Keras 开发都使用 tf.keras API。
此时,我们建议在 TensorFlow 后端使用多后端 Keras 的 Keras 用户切换到 TensorFlow 2.0 中的 tf.keras。tf.keras 得到了更好的维护,并与 TensorFlow 特性(热切执行、分发支持等)有了更好的集成。
——科拉斯项目主页,2019 年 12 月访问。
1.2 如何安装张量流
在安装 TensorFlow 之前,请确保您安装了 Python,例如 Python 3.6 或更高版本。
如果没有安装 Python,可以使用 Anaconda 安装。本教程将向您展示如何:
- 如何用 Anaconda 设置机器学习的 Python 环境
安装 TensorFlow 开源深度学习库的方法有很多。
在您的工作站上安装 TensorFlow 最常见,也可能是最简单的方法是使用 pip 。
例如,在命令行上,您可以键入:
sudo pip install tensorflow
如果您更喜欢使用特定于您的平台或软件包管理器的安装方法,您可以在此查看完整的安装说明列表:
现在没有必要设置 GPU。
本教程中的所有示例在现代中央处理器上都可以正常工作。如果您想为您的图形处理器配置张量流,您可以在完成本教程后进行配置。不要分心!
1.3 如何确认安装了张量流
一旦安装了 TensorFlow,请务必确认库安装成功,并且您可以开始使用它。
不要跳过这一步。
如果未正确安装 TensorFlow 或在此步骤中出现错误,您将无法在以后运行这些示例。
创建一个名为 versions.py 的新文件,并将以下代码复制粘贴到文件中。
# check version
import tensorflow
print(tensorflow.__version__)
保存文件,然后打开你的命令行,将目录改为你保存文件的地方。
然后键入:
python versions.py
然后,您应该会看到如下输出:
2.2.0
这确认了 TensorFlow 安装正确,并且我们都使用相同的版本。
你拿到了什么版本? 在下面的评论中发布你的输出。
这也向您展示了如何从命令行运行 Python 脚本。我建议以这种方式从命令行运行所有代码,不要从笔记本或 IDE 运行。
如果您收到警告消息
有时当您使用 tf.keras API 时,您可能会看到打印的警告。
这可能包括您的硬件支持您的 TensorFlow 安装未配置为使用的功能的消息。
我的工作站上的一些示例包括:
Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
XLA service 0x7fde3f2e6180 executing computations on platform Host. Devices:
StreamExecutor device (0): Host, Default Version
他们不是你的错。你没做错什么。
这些是信息消息,它们不会阻止代码的执行。您现在可以放心地忽略这种类型的消息。
这是 TensorFlow 团队有意做出的设计决定,旨在展示这些警告信息。这个决定的一个缺点是,它让初学者感到困惑,并且训练开发人员忽略所有消息,包括那些可能影响执行的消息。
现在您已经知道了 tf.keras 是什么,如何安装 TensorFlow,以及如何确认您的开发环境正在工作,让我们看看 TensorFlow 中深度学习模型的生命周期。
2.深度学习模型生命周期
在本节中,您将发现深度学习模型的生命周期,以及两个可用于定义模型的 tf.keras APIs。
2.1 五步模型生命周期
模型有一个生命周期,这个非常简单的知识为建模数据集和理解 tf.keras API 提供了基础。
生命周期中的五个步骤如下:
- 定义模型。
- 编译模型。
- 符合模型。
- 评估模型。
- 做预测。
让我们依次仔细看看每一步。
定义模型
定义模型要求您首先选择所需的模型类型,然后选择体系结构或网络拓扑。
从应用编程接口的角度来看,这包括定义模型的层,用许多节点和激活函数配置每一层,并将这些层连接在一起形成一个内聚的模型。
模型既可以用顺序应用编程接口定义,也可以用功能应用编程接口定义,我们将在下一节讨论这一点。
...
# define the model
model = ...
编译模型
编译模型要求您首先选择要优化的损失函数,例如均方误差或交叉熵。
它还要求您选择一个算法来执行优化过程,通常是随机梯度下降,或现代变化,如亚当。它可能还要求您在模型训练过程中选择任何要跟踪的表现指标。
从应用编程接口的角度来看,这包括调用一个函数来编译具有所选配置的模型,这将为有效使用您定义的模型准备适当的数据结构。
可以将优化器指定为已知优化器类的字符串,例如用于随机梯度下降的“ sgd ”,或者您可以配置优化器类的实例并使用它。
有关支持的优化程序列表,请参见:
...
# compile the model
opt = SGD(learning_rate=0.01, momentum=0.9)
model.compile(optimizer=opt, loss='binary_crossentropy')
三种最常见的损失函数是:
- 二元 _ 交叉熵'为二元分类。
- 稀疏 _ 分类 _ 交叉熵,用于多类分类。
- 回归的均方误差。
...
# compile the model
model.compile(optimizer='sgd', loss='mse')
有关支持的损失函数列表,请参见:
度量被定义为已知度量函数的字符串列表或用于评估预测的函数列表。
有关支持的指标列表,请参见:
...
# compile the model
model.compile(optimizer='sgd', loss='binary_crossentropy', metrics=['accuracy'])
适合模型
拟合模型要求您首先选择训练配置,例如时期的数量(通过训练数据集的循环)和批次大小(一个时期中用于估计模型误差的样本数量)。
训练应用选择的优化算法来最小化选择的损失函数,并使用误差反向传播算法来更新模型。
拟合模型是整个过程的缓慢部分,可能需要几秒到几小时到几天的时间,具体取决于模型的复杂性、您使用的硬件以及训练数据集的大小。
从应用编程接口的角度来看,这包括调用一个函数来执行训练过程。在培训过程结束之前,该功能将一直阻止(不返回)。
...
# fit the model
model.fit(X, y, epochs=100, batch_size=32)
有关如何选择批处理大小的帮助,请参见本教程:
在拟合模型时,进度条将总结每个时期的状态和整个训练过程。通过将“ verbose ”参数设置为 2,可以将其简化为每个时期模型表现的简单报告。通过将“详细”设置为 0,可以在训练期间关闭所有输出。
...
# fit the model
model.fit(X, y, epochs=100, batch_size=32, verbose=0)
评估模型
评估模型需要首先选择用于评估模型的保持数据集。这应该是在训练过程中不使用的数据,以便我们在对新数据进行预测时可以获得模型表现的无偏估计。
模型评估的速度与您想要用于评估的数据量成正比,尽管由于模型没有改变,它比训练快得多。
从应用编程接口的角度来看,这包括用保持数据集调用一个函数,并获得一个损失,也许还有其他可以报告的指标。
...
# evaluate the model
loss = model.evaluate(X, y, verbose=0)
做个预测
做预测是生命周期的最后一步。这就是为什么我们首先想要这个模型。
它要求您拥有需要预测的新数据,例如,您没有目标值的地方。
从应用编程接口的角度来看,您只需调用一个函数来预测类标签、概率或数值:无论您设计模型来预测什么。
您可能希望保存模型,然后加载它来进行预测。在开始使用模型之前,您也可以选择在所有可用数据上拟合模型。
现在我们已经熟悉了模型生命周期,让我们来看看使用 tf.keras API 构建模型的两种主要方式:顺序和功能。
...
# make a prediction
yhat = model.predict(X)
2.2 顺序模型应用编程接口(简单)
顺序模型 API 是最简单的,也是我推荐的 API,特别是入门的时候。
之所以称之为“T0”序列,是因为它涉及到定义一个序列类,并从输入到输出以线性方式一个接一个地给模型添加图层。
下面的示例定义了一个顺序 MLP 模型,该模型接受八个输入,有一个包含 10 个节点的隐藏层,然后有一个包含一个节点的输出层来预测数值。
# example of a model defined with the sequential api
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# define the model
model = Sequential()
model.add(Dense(10, input_shape=(8,)))
model.add(Dense(1))
请注意,网络的可见层由第一个隐藏层上的“ input_shape ”参数定义。这意味着在上面的例子中,模型期望一个样本的输入是八个数字的向量。
顺序应用编程接口很容易使用,因为您一直在调用 model.add() ,直到添加完所有图层。
例如,这里是一个有五个隐藏层的深 MLP。
# example of a model defined with the sequential api
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# define the model
model = Sequential()
model.add(Dense(100, input_shape=(8,)))
model.add(Dense(80))
model.add(Dense(30))
model.add(Dense(10))
model.add(Dense(5))
model.add(Dense(1))
2.3 功能模型应用编程接口(高级)
功能 API 更复杂,但也更灵活。
它包括显式地将一个层的输出连接到另一个层的输入。指定了每个连接。
首先,必须通过输入类定义输入图层,并指定输入样本的形状。定义模型时,我们必须保留对输入层的引用。
...
# define the layers
x_in = Input(shape=(8,))
接下来,完全连接的层可以通过调用该层并传递输入层来连接到输入。这将返回对这个新层中输出连接的引用。
...
x = Dense(10)(x_in)
然后,我们可以用同样的方式将它连接到输出层。
...
x_out = Dense(1)(x)
一旦连接,我们定义一个模型对象,并指定输入和输出层。下面列出了完整的示例。
# example of a model defined with the functional api
from tensorflow.keras import Model
from tensorflow.keras import Input
from tensorflow.keras.layers import Dense
# define the layers
x_in = Input(shape=(8,))
x = Dense(10)(x_in)
x_out = Dense(1)(x)
# define the model
model = Model(inputs=x_in, outputs=x_out)
因此,它允许更复杂的模型设计,例如可能具有多个输入路径(独立向量)的模型和具有多个输出路径(例如,一个单词和一个数字)的模型。
当你习惯了函数式应用编程接口,它会给你带来很多乐趣。
有关函数式应用编程接口的更多信息,请参见:
现在我们已经熟悉了模型生命周期和两个可以用来定义模型的 API,让我们来看看开发一些标准模型。
3.如何开发深度学习模型
在本节中,您将发现如何使用标准的深度学习模型进行开发、评估和预测,包括多层感知机(MLP)、卷积神经网络和递归神经网络。
3.1 开发多层感知机模型
多层感知机模型,简称 MLP,是一个标准的全连接神经网络模型。
它由节点层组成,其中每个节点连接到上一层的所有输出,每个节点的输出连接到下一层节点的所有输入。
MLP 由一个或多个密集层创建。这种模型适用于表格数据,即每个变量有一列,每个变量有一行的表格或电子表格中的数据。有三个预测建模问题,你可能想探索与 MLP;它们是二元分类、多类分类和回归。
让我们在真实数据集上为每一种情况拟合一个模型。
注意,本节中的模型是有效的,但没有优化。看看能不能提高他们的成绩。在下面的评论中发表你的发现。
二元分类的 MLP
我们将使用电离层二进制(两级)分类数据集来演示二进制分类的 MLP。
这个数据集包括预测一个结构是否在大气中,给定雷达回波。
数据集将使用熊猫自动下载,不过你可以在这里了解更多。
我们将使用标签编码器将字符串标签编码为整数值 0 和 1。该模型将适用于 67%的数据,剩余的 33%将用于评估,使用 train_test_split() 功能进行分割。
用“ he_normal 权重初始化来激活“ relu 是一个很好的做法。这种组合对于克服训练深度神经网络模型时梯度消失的问题大有帮助。有关 ReLU 的更多信息,请参见教程:
该模型预测 1 类概率,并使用 sigmoid 激活函数。模型使用随机梯度下降的 adam 版本进行优化,并寻求最小化交叉熵损失。
下面列出了完整的示例。
# mlp for binary classification
from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# load the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/ionosphere.csv'
df = read_csv(path, header=None)
# split into input and output columns
X, y = df.values[:, :-1], df.values[:, -1]
# ensure all data are floating point values
X = X.astype('float32')
# encode strings to integer
y = LabelEncoder().fit_transform(y)
# split into train and test datasets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
# determine the number of input features
n_features = X_train.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(8, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# fit the model
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=0)
# evaluate the model
loss, acc = model.evaluate(X_test, y_test, verbose=0)
print('Test Accuracy: %.3f' % acc)
# make a prediction
row = [1,0,0.99539,-0.05889,0.85243,0.02306,0.83398,-0.37708,1,0.03760,0.85243,-0.17755,0.59755,-0.44945,0.60536,-0.38223,0.84356,-0.38542,0.58212,-0.32192,0.56971,-0.29674,0.36946,-0.47357,0.56811,-0.51171,0.41078,-0.46168,0.21266,-0.34090,0.42267,-0.54487,0.18641,-0.45300]
yhat = model.predict([row])
print('Predicted: %.3f' % yhat)
运行该示例首先报告数据集的形状,然后拟合模型并在测试数据集上对其进行评估。最后,对单行数据进行预测。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
**你得到了什么结果?**能不能换个型号做得更好? 将你的发现发布到下面的评论中。
在这种情况下,我们可以看到模型达到了大约 94%的分类准确率,然后预测一行数据属于类别 1 的概率为 0.9。
(235, 34) (116, 34) (235,) (116,)
Test Accuracy: 0.940
Predicted: 0.991
MLP 支持多类分类
我们将使用鸢尾花多类分类数据集来演示多类分类的 MLP。
这个问题涉及到预测鸢尾花的种类给定的花的措施。
数据集将使用 Pandas 自动下载,但您可以在这里了解更多信息。
鉴于它是一个多类分类,模型必须在输出层为每个类有一个节点,并使用 softmax 激活函数。损失函数是“稀疏 _ 分类 _ 交叉熵”,它适用于整数编码的类标签(例如,一个类为 0,下一个类为 1,等等)。)
下面列出了在鸢尾花数据集上拟合和评估 MLP 的完整示例。
# mlp for multiclass classification
from numpy import argmax
from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# load the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/iris.csv'
df = read_csv(path, header=None)
# split into input and output columns
X, y = df.values[:, :-1], df.values[:, -1]
# ensure all data are floating point values
X = X.astype('float32')
# encode strings to integer
y = LabelEncoder().fit_transform(y)
# split into train and test datasets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
# determine the number of input features
n_features = X_train.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(8, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(3, activation='softmax'))
# compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
# fit the model
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=0)
# evaluate the model
loss, acc = model.evaluate(X_test, y_test, verbose=0)
print('Test Accuracy: %.3f' % acc)
# make a prediction
row = [5.1,3.5,1.4,0.2]
yhat = model.predict([row])
print('Predicted: %s (class=%d)' % (yhat, argmax(yhat)))
运行该示例首先报告数据集的形状,然后拟合模型并在测试数据集上对其进行评估。最后,对单行数据进行预测。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
**你得到了什么结果?**能不能换个型号做得更好? 将你的发现发布到下面的评论中。
在这种情况下,我们可以看到该模型实现了大约 98%的分类准确率,然后预测了一行数据属于每个类的概率,尽管类 0 的概率最高。
(100, 4) (50, 4) (100,) (50,)
Test Accuracy: 0.980
Predicted: [[0.8680804 0.12356871 0.00835086]] (class=0)
回归的 MLP
我们将使用波士顿住房回归数据集来演示用于回归预测建模的 MLP。
这个问题涉及到根据房子和邻居的属性来预测房子的价值。
数据集将使用 Pandas 自动下载,但您可以在这里了解更多信息。
这是一个涉及预测单个数值的回归问题。因此,输出层只有一个节点,并使用默认或线性激活函数(无激活函数)。拟合模型时,均方误差(mse)损失最小。
回想一下,这是回归,不是分类;因此,我们无法计算分类精确率。有关这方面的更多信息,请参见教程:
下面列出了在波士顿住房数据集上拟合和评估 MLP 的完整示例。
# mlp for regression
from numpy import sqrt
from pandas import read_csv
from sklearn.model_selection import train_test_split
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# load the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv'
df = read_csv(path, header=None)
# split into input and output columns
X, y = df.values[:, :-1], df.values[:, -1]
# split into train and test datasets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
# determine the number of input features
n_features = X_train.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(8, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1))
# compile the model
model.compile(optimizer='adam', loss='mse')
# fit the model
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=0)
# evaluate the model
error = model.evaluate(X_test, y_test, verbose=0)
print('MSE: %.3f, RMSE: %.3f' % (error, sqrt(error)))
# make a prediction
row = [0.00632,18.00,2.310,0,0.5380,6.5750,65.20,4.0900,1,296.0,15.30,396.90,4.98]
yhat = model.predict([row])
print('Predicted: %.3f' % yhat)
运行该示例首先报告数据集的形状,然后拟合模型并在测试数据集上对其进行评估。最后,对单行数据进行预测。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
**你得到了什么结果?**能不能换个型号做得更好? 将你的发现发布到下面的评论中。
在这种情况下,我们可以看到模型实现了大约 60 的最小均方误差,这是大约 7 的 RMSE(单位是千美元)。然后为单个例子预测大约 26 的值。
(339, 13) (167, 13) (339,) (167,)
MSE: 60.751, RMSE: 7.794
Predicted: 26.983
3.2 开发卷积神经网络模型
卷积神经网络,简称 CNNs,是一种为图像输入而设计的网络。
它们由带有提取特征(称为特征图)的卷积层和提取特征到最显著元素的汇集层的模型组成。
中枢神经系统最适合图像分类任务,尽管它们可以用于大量以图像为输入的任务。
一个流行的图像分类任务是 MNIST 手写数字分类。它涉及成千上万的手写数字,这些数字必须被归类为 0 到 9 之间的数字。
tf.keras API 提供了一个方便的函数来直接下载和加载这个数据集。
以下示例加载数据集并绘制前几幅图像。
# example of loading and plotting the mnist dataset
from tensorflow.keras.datasets.mnist import load_data
from matplotlib import pyplot
# load dataset
(trainX, trainy), (testX, testy) = load_data()
# summarize loaded dataset
print('Train: X=%s, y=%s' % (trainX.shape, trainy.shape))
print('Test: X=%s, y=%s' % (testX.shape, testy.shape))
# plot first few images
for i in range(25):
# define subplot
pyplot.subplot(5, 5, i+1)
# plot raw pixel data
pyplot.imshow(trainX[i], cmap=pyplot.get_cmap('gray'))
# show the figure
pyplot.show()
运行该示例会加载 MNIST 数据集,然后汇总默认的训练和测试数据集。
Train: X=(60000, 28, 28), y=(60000,)
Test: X=(10000, 28, 28), y=(10000,)
然后创建一个图,显示训练数据集中手写图像示例的网格。
来自 MNIST 数据集的手写数字图
我们可以训练一个 CNN 模型来对 MNIST 数据集中的图像进行分类。
注意,图像是灰度像素数据的阵列;因此,我们必须在数据中添加通道维度,然后才能将图像用作模型的输入。原因是 CNN 模型期望图像采用通道-最后一种格式,即网络的每个示例都有维度[行、列、通道],其中通道表示图像数据的颜色通道。
训练 CNN 时,将像素值从默认范围 0-255 缩放到 0-1 也是一个好主意。有关缩放像素值的更多信息,请参见教程:
下面列出了在 MNIST 数据集上拟合和评估 CNN 模型的完整示例。
# example of a cnn for image classification
from numpy import asarray
from numpy import unique
from numpy import argmax
from tensorflow.keras.datasets.mnist import load_data
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import MaxPool2D
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dropout
# load dataset
(x_train, y_train), (x_test, y_test) = load_data()
# reshape data to have a single channel
x_train = x_train.reshape((x_train.shape[0], x_train.shape[1], x_train.shape[2], 1))
x_test = x_test.reshape((x_test.shape[0], x_test.shape[1], x_test.shape[2], 1))
# determine the shape of the input images
in_shape = x_train.shape[1:]
# determine the number of classes
n_classes = len(unique(y_train))
print(in_shape, n_classes)
# normalize pixel values
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
# define model
model = Sequential()
model.add(Conv2D(32, (3,3), activation='relu', kernel_initializer='he_uniform', input_shape=in_shape))
model.add(MaxPool2D((2, 2)))
model.add(Flatten())
model.add(Dense(100, activation='relu', kernel_initializer='he_uniform'))
model.add(Dropout(0.5))
model.add(Dense(n_classes, activation='softmax'))
# define loss and optimizer
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
# fit the model
model.fit(x_train, y_train, epochs=10, batch_size=128, verbose=0)
# evaluate the model
loss, acc = model.evaluate(x_test, y_test, verbose=0)
print('Accuracy: %.3f' % acc)
# make a prediction
image = x_train[0]
yhat = model.predict(asarray([image]))
print('Predicted: class=%d' % argmax(yhat))
运行该示例首先报告数据集的形状,然后拟合模型并在测试数据集上对其进行评估。最后,对单个图像进行预测。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
**你得到了什么结果?**能不能换个型号做得更好? 将你的发现发布到下面的评论中。
首先,报告每个图像的形状以及类的数量;我们可以看到,每幅图像都是 28×28 像素,有 10 个类,正如我们所料。
在这种情况下,我们可以看到该模型在测试数据集上实现了大约 98%的分类准确率。然后我们可以看到,模型为训练集中的第一幅图像预测了类别 5。
(28, 28, 1) 10
Accuracy: 0.987
Predicted: class=5
3.3 开发递归神经网络模型
递归神经网络,简称 rnn,被设计用于对数据序列进行操作。
它们已经被证明对于自然语言处理问题非常有效,其中文本序列被提供作为模型的输入。rnn 在时间序列预测和语音识别方面也取得了一定的成功。
最受欢迎的 RNN 类型是长短期记忆网络,简称 LSTM。LSTMs 可用于模型中,以接受输入数据序列并进行预测,例如分配类别标签或预测数值,如序列中的下一个值或多个值。
我们将使用汽车销售数据集来演示用于单变量时间序列预测的 LSTM RNN。
这个问题涉及预测每月汽车销量。
数据集将使用 Pandas 自动下载,但您可以在这里了解更多信息。
我们将把问题框定为利用过去五个月的数据来预测当月的数据。
为了实现这一点,我们将定义一个名为 split_sequence() 的新函数,该函数将将输入序列分割成适合于拟合监督学习模型的数据窗口,如 LSTM。
例如,如果序列是:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
那么用于训练模型的样本将如下所示:
Input Output
1, 2, 3, 4, 5 6
2, 3, 4, 5, 6 7
3, 4, 5, 6, 7 8
...
我们将使用过去 12 个月的数据作为测试数据集。
LSTMs 期望数据集中的每个样本都有两个维度;第一个是时间步长数(在本例中为 5),第二个是每个时间步长的观测值数(在本例中为 1)。
由于是回归型问题,我们将在输出层使用线性激活函数(无激活 函数)并优化均方误差损失函数。我们还将使用平均绝对误差(MAE)度量来评估模型。
下面列出了针对单变量时间序列预测问题拟合和评估 LSTM 的完整示例。
# lstm for time series forecasting
from numpy import sqrt
from numpy import asarray
from pandas import read_csv
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import LSTM
# split a univariate sequence into samples
def split_sequence(sequence, n_steps):
X, y = list(), list()
for i in range(len(sequence)):
# find the end of this pattern
end_ix = i + n_steps
# check if we are beyond the sequence
if end_ix > len(sequence)-1:
break
# gather input and output parts of the pattern
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return asarray(X), asarray(y)
# load the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/monthly-car-sales.csv'
df = read_csv(path, header=0, index_col=0, squeeze=True)
# retrieve the values
values = df.values.astype('float32')
# specify the window size
n_steps = 5
# split into samples
X, y = split_sequence(values, n_steps)
# reshape into [samples, timesteps, features]
X = X.reshape((X.shape[0], X.shape[1], 1))
# split into train/test
n_test = 12
X_train, X_test, y_train, y_test = X[:-n_test], X[-n_test:], y[:-n_test], y[-n_test:]
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
# define model
model = Sequential()
model.add(LSTM(100, activation='relu', kernel_initializer='he_normal', input_shape=(n_steps,1)))
model.add(Dense(50, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(50, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1))
# compile the model
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
# fit the model
model.fit(X_train, y_train, epochs=350, batch_size=32, verbose=2, validation_data=(X_test, y_test))
# evaluate the model
mse, mae = model.evaluate(X_test, y_test, verbose=0)
print('MSE: %.3f, RMSE: %.3f, MAE: %.3f' % (mse, sqrt(mse), mae))
# make a prediction
row = asarray([18024.0, 16722.0, 14385.0, 21342.0, 17180.0]).reshape((1, n_steps, 1))
yhat = model.predict(row)
print('Predicted: %.3f' % (yhat))
运行该示例首先报告数据集的形状,然后拟合模型并在测试数据集上对其进行评估。最后,对一个实例进行了预测。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
**你得到了什么结果?**能不能换个型号做得更好? 将你的发现发布到下面的评论中。
首先,显示训练和测试数据集的形状,确认最后 12 个示例用于模型评估。
在这种情况下,模型的 MAE 约为 2,800,并预测测试集中的下一个值为 13,199,其中期望值为 14,577(非常接近)。
(91, 5, 1) (12, 5, 1) (91,) (12,)
MSE: 12755421.000, RMSE: 3571.473, MAE: 2856.084
Predicted: 13199.325
注:在拟合模型之前,最好先对数据进行缩放,使序列平稳。为了获得更好的表现,我建议将其作为扩展。有关为建模准备时间序列数据的更多信息,请参见教程:
4.如何使用高级模型功能
在本节中,您将了解如何使用一些稍微高级的模型功能,例如查看学习曲线和保存模型以备后用。
4.1 如何可视化深度学习模型
深度学习模型的架构可能很快变得庞大而复杂。
因此,清楚地了解模型中的连接和数据流非常重要。如果您正在使用功能 API 来确保您确实已经按照您想要的方式连接了模型的各个层,这一点尤其重要。
有两种工具可以用来可视化模型:文本描述和绘图。
模型文本描述
通过调用模型上的 summary()函数,可以显示模型的文本描述。
下面的例子定义了一个三层的小模型,然后总结了结构。
# example of summarizing a model
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(8,)))
model.add(Dense(8, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1, activation='sigmoid'))
# summarize the model
model.summary()
运行该示例会打印每个图层的摘要,以及总摘要。
对于检查模型中的输出形状和参数(权重)数量,这是一个非常有价值的诊断。
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 10) 90
_________________________________________________________________
dense_1 (Dense) (None, 8) 88
_________________________________________________________________
dense_2 (Dense) (None, 1) 9
=================================================================
Total params: 187
Trainable params: 187
Non-trainable params: 0
_________________________________________________________________
模型架构图
您可以通过调用 plot_model()函数来创建模型的绘图。
这将创建一个图像文件,其中包含模型中各层的方框图和折线图。
下面的示例创建了一个小型的三层模型,并将模型体系结构的一个图保存到包含输入和输出形状的“model.png”。
# example of plotting a model
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import plot_model
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(8,)))
model.add(Dense(8, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1, activation='sigmoid'))
# summarize the model
plot_model(model, 'model.png', show_shapes=True)
运行该示例会创建一个模型图,其中显示了每个图层的方框以及连接图层的箭头,显示了通过网络的数据流。
神经网络体系结构图
4.2 如何绘制模型学习曲线
学习曲线是神经网络模型表现随时间变化的曲线,例如在每个训练时期结束时计算的曲线。
学习曲线图提供了对模型学习动态的洞察,例如模型是否学习良好,是否对训练数据集拟合不足,或者是否对训练数据集过度拟合。
对于学习曲线以及如何使用它们来诊断模型的学习动态的温和介绍,请参见教程:
您可以轻松地为深度学习模型创建学习曲线。
首先,您必须更新对 fit 函数的调用,以包含对验证数据集的引用。这是训练集中不用于拟合模型的一部分,而是用于在训练期间评估模型的表现。
您可以手动拆分数据并指定 validation_data 参数,也可以使用 validation_split 参数并指定训练数据集的百分比拆分,让 API 为您执行拆分。后者目前比较简单。
拟合函数将返回一个历史对象,该对象包含在每个训练时期结束时记录的表现指标的轨迹。这包括所选的损失函数和每个已配置的度量,例如准确性,并且每个损失和度量都是为训练和验证数据集计算的。
学习曲线是训练数据集和验证数据集的损失图。我们可以使用 Matplotlib 库从历史对象创建该图。
下面的例子适合一个合成二进制分类问题的小神经网络。30%的验证分割用于在训练期间评估模型,然后使用线图绘制训练和验证数据集上的交叉熵损失。
# example of plotting learning curves
from sklearn.datasets import make_classification
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import SGD
from matplotlib import pyplot
# create the dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(1, activation='sigmoid'))
# compile the model
sgd = SGD(learning_rate=0.001, momentum=0.8)
model.compile(optimizer=sgd, loss='binary_crossentropy')
# fit the model
history = model.fit(X, y, epochs=100, batch_size=32, verbose=0, validation_split=0.3)
# plot learning curves
pyplot.title('Learning Curves')
pyplot.xlabel('Epoch')
pyplot.ylabel('Cross Entropy')
pyplot.plot(history.history['loss'], label='train')
pyplot.plot(history.history['val_loss'], label='val')
pyplot.legend()
pyplot.show()
运行该示例适合数据集上的模型。运行结束时,返回历史对象,并将其用作创建线图的基础。
训练数据集的交叉熵损失通过“损失键访问,验证数据集的损失通过历史对象的历史属性上的“ val_loss 键访问。
深度学习模型的交叉熵损失学习曲线
4.3 如何保存和加载模型
训练和评估模型很棒,但是我们可能希望以后使用模型,而不是每次都重新训练它。
这可以通过将模型保存到文件中,然后加载它并使用它进行预测来实现。
这可以使用模型上的 save() 功能保存模型来实现。以后可以使用 load_model()功能进行加载。
模型以 H5 格式保存,这是一种高效的阵列存储格式。因此,您必须确保工作站上安装了 h5py 库。这可以使用 pip 实现;例如:
pip install h5py
下面的例子适合一个合成二进制分类问题的简单模型,然后保存模型文件。
# example of saving a fit model
from sklearn.datasets import make_classification
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import SGD
# create the dataset
X, y = make_classification(n_samples=1000, n_features=4, n_classes=2, random_state=1)
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(1, activation='sigmoid'))
# compile the model
sgd = SGD(learning_rate=0.001, momentum=0.8)
model.compile(optimizer=sgd, loss='binary_crossentropy')
# fit the model
model.fit(X, y, epochs=100, batch_size=32, verbose=0, validation_split=0.3)
# save model to file
model.save('model.h5')
运行该示例符合模型,并将其保存到名为“ model.h5 的文件中。
然后,我们可以加载模型并使用它进行预测,或者继续训练它,或者用它做我们想做的任何事情。
下面的示例加载模型并使用它进行预测。
# example of loading a saved model
from sklearn.datasets import make_classification
from tensorflow.keras.models import load_model
# create the dataset
X, y = make_classification(n_samples=1000, n_features=4, n_classes=2, random_state=1)
# load the model from file
model = load_model('model.h5')
# make a prediction
row = [1.91518414, 1.14995454, -1.52847073, 0.79430654]
yhat = model.predict([row])
print('Predicted: %.3f' % yhat[0])
运行该示例从文件加载图像,然后使用它对新的数据行进行预测并打印结果。
Predicted: 0.831
5.如何获得更好的模型表现
在本节中,您将发现一些可以用来提高深度学习模型表现的技术。
提高深度学习绩效的一大部分涉及到通过减慢学习过程或在正确的时间停止学习过程来避免过度适应。
5.1 如何减少辍学的过度适应
Dropout 是一种聪明的正则化方法,它减少了训练数据集的过拟合,使模型更加健壮。
这是在训练期间实现的,其中一些层输出被随机忽略或“掉出”这样做的效果是使该层看起来像——并被当作——一个具有不同节点数和与前一层连接的层。
退出会使训练过程变得嘈杂,迫使层内的节点在概率上承担或多或少的输入责任。
有关辍学工作原理的更多信息,请参见本教程:
您可以将脱离作为新图层添加到模型中,该图层位于您希望输入连接脱离的图层之前。
这包括添加一个名为 Dropout() 的层,该层接受一个参数,该参数指定前一层的每个输出下降的概率。例如,0.4 表示每次更新模型时,40%的输入将被丢弃。
您可以在 MLP、美国有线电视新闻网和 RNN 模型中添加 dropout 图层,不过也有专门的 Dropout 版本供美国有线电视新闻网和 RNN 模型使用,您可能还想探索一下。
下面的例子适合一个合成二进制分类问题的小型神经网络模型。
在第一隐藏层和输出层之间插入 50%脱落的脱落层。
# example of using dropout
from sklearn.datasets import make_classification
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Dropout
from matplotlib import pyplot
# create the dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy')
# fit the model
model.fit(X, y, epochs=100, batch_size=32, verbose=0)
5.2 如何通过批量标准化加速培训
对一个层的输入的规模和分布可以极大地影响该层可以被训练的容易程度或速度。
这就是为什么在用神经网络模型建模之前缩放输入数据是一个好主意。
批处理标准化是一种训练深度神经网络的技术,它为每个小批处理标准化了一个层的输入。这具有稳定学习过程和显著减少训练深层网络所需的训练时期数量的效果。
有关批处理规范化如何工作的更多信息,请参见本教程:
您可以在网络中使用批处理规范化,方法是在希望具有标准化输入的层之前添加批处理规范化层。您可以对 MLP、美国有线电视新闻网和 RNN 模型使用批处理规范化。
这可以通过直接添加 BatchNormalization 层来实现。
下面的例子为二进制分类预测问题定义了一个小的 MLP 网络,在第一个隐藏层和输出层之间有一个批处理规范化层。
# example of using batch normalization
from sklearn.datasets import make_classification
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import BatchNormalization
from matplotlib import pyplot
# create the dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(BatchNormalization())
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy')
# fit the model
model.fit(X, y, epochs=100, batch_size=32, verbose=0)
此外,tf.keras 还有一系列您可能喜欢探索的其他规范化层;参见:
5.3 如何适时停止训练,提前停止
神经网络很难训练。
训练太少,模型不足;训练过多,模型过度训练数据集。这两种情况都导致了一个不如预期有效的模型。
解决这个问题的一个方法是使用提前停止。这包括监控训练数据集和验证数据集(不用于拟合模型的训练集子集)的损失。一旦验证集的丢失开始显示出过度拟合的迹象,就可以停止训练过程。
有关提前停止的更多信息,请参见教程:
通过首先确保您有一个验证数据集,提前停止可以用于您的模型。您可以通过 fit() 函数的 validation_data 参数手动定义验证数据集,也可以使用 validation_split 并指定要保留以进行验证的训练数据集的数量。
然后,您可以定义一个早期预测,并指示它监控哪个表现度量,例如验证数据集中的损失的“ val_loss ”,以及采取措施之前观察到的过度拟合的时期数,例如 5。
这种配置的早期提示回调可以通过获取回调列表的“回调参数提供给 fit() 函数。
这使您可以将纪元的数量设置为一个很大的数字,并确信一旦模型开始过度拟合,训练就会结束。您可能还想创建一个学习曲线,以发现更多关于跑步学习动态以及何时停止训练的见解。
下面的例子演示了一个关于合成二进制分类问题的小型神经网络,一旦模型开始过拟合(大约 50 个时期后),它就使用提前停止来停止训练。
# example of using early stopping
from sklearn.datasets import make_classification
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.callbacks import EarlyStopping
# create the dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy')
# configure early stopping
es = EarlyStopping(monitor='val_loss', patience=5)
# fit the model
history = model.fit(X, y, epochs=200, batch_size=32, verbose=0, validation_split=0.3, callbacks=[es])
tf.keras API 提供了许多您可能想探索的回调;您可以在这里了解更多信息:
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
教程
- 如何控制批量训练神经网络的稳定性
- 整流线性单元的温和介绍
- 机器学习中分类和回归的区别
- 如何手动缩放图像像素数据进行深度学习
- 4 时间序列预测的常用机器学习数据转换
- 如何利用学习曲线诊断机器学习模型表现
- 轻度介绍用于调节深层神经网络的缺失
- 深度神经网络批量归一化简介
- 提前停车避免过度训练神经网络的温和介绍
书
- 深度学习,2016 年。
指导
蜜蜂
摘要
在本教程中,您发现了一个使用 tf.keras API 在 TensorFlow 中开发深度学习模型的分步指南。
具体来说,您了解到:
- Keras 和 tf.keras 的区别以及如何安装和确认 TensorFlow 正在工作。
- tf.keras 模型的 5 步生命周期以及如何使用顺序和功能 API。
- 如何用 tf.keras 开发用于回归、分类和时间序列预测的 MLP、CNN 和 RNN 模型。
- 如何使用 tf.keras API 的高级功能来检查和诊断您的模型。
- 如何通过减少过度训练和加速训练来提高 tf.keras 模型的表现?
你有什么问题吗? 在下面的评论中提问,我会尽力回答。