概括
在这篇文章中,您发现了一种可靠的方法来评估您的深度学习模型在未见数据上的性能的重要性。
您发现了三种可以使用 Keras 库在 Python 中评估深度学习模型性能的方法:
- 使用自动验证数据集。
- 使用手动验证数据集。
- 使用手动 k 折交叉验证。
Keras 是一个易于使用且功能强大的 Python 库,用于深度学习。
在设计和配置深度学习模型时,需要做出很多决定。这些决定中的大多数必须通过反复试验并根据实际数据进行评估来凭经验解决。
因此,拥有一种可靠的方法来评估您的神经网络和深度学习模型的性能至关重要。
在这篇文章中,您将发现一些可用于使用 Keras 评估模型性能的方法。
凭经验评估网络配置
在设计和配置深度学习模型时,您必须做出无数决定。
其中许多决策可以通过复制其他人的网络结构并使用启发式方法来解决。最终,最好的技术是实际设计小型实验并使用真实数据凭经验评估选项。
这包括高级决策,例如网络中层的数量、大小和类型。它还包括较低级别的决策,例如损失函数的选择、激活函数、优化过程和时期数。
深度学习通常用于具有非常大数据集的问题。那是数万或数十万个实例。
因此,您需要有一个强大的测试工具,允许您估计给定配置在看不见的数据上的性能,并可靠地将性能与其他配置进行比较。
数据拆分
大量的数据和模型的复杂性需要非常长的训练时间。
因此,通常将数据简单地分离为训练和测试数据集或训练和验证数据集。
Keras 提供了两种方便的方式来评估你的深度学习算法:
- 使用自动验证数据集。
- 使用手动验证数据集。
使用自动验证数据集
Keras 可以将您的一部分训练数据分离到一个验证数据集中,并在每个 epoch 评估您的模型在该验证数据集上的性能。
您可以通过将fit () 函数上的validation_split参数设置为训练数据集大小的百分比来做到这一点。
例如,对于保留用于验证的 20% 或 33% 的训练数据,一个合理的值可能是 0.2 或 0.33。
下面的示例演示了在小型二进制分类问题上使用自动验证数据集。这篇文章中的所有示例都使用了Pima Indians onset of diabetes 数据集。您可以从 UCI 机器学习存储库下载它,并将数据文件保存在您当前的工作目录中,文件?名为 pima-indians-diabetes.csv?(更新:从此处下载)。
# MLP with automatic validation set
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
import numpy
# 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, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, validation_split=0.33, epochs=150, batch_size=10)
注意:您的结果可能会因为算法或评估程序的随机性或数值精度的差异而有所不同。考虑运行该示例几次并比较平均结果。
运行该示例,您可以看到每个 epoch 的详细输出显示了训练数据集和验证数据集的损失和准确性。
...
Epoch 145/150
514/514 [==============================] - 0s - loss: 0.5252 - acc: 0.7335 - val_loss: 0.5489 - val_acc: 0.7244
Epoch 146/150
514/514 [==============================] - 0s - loss: 0.5198 - acc: 0.7296 - val_loss: 0.5918 - val_acc: 0.7244
Epoch 147/150
514/514 [==============================] - 0s - loss: 0.5175 - acc: 0.7335 - val_loss: 0.5365 - val_acc: 0.7441
Epoch 148/150
514/514 [==============================] - 0s - loss: 0.5219 - acc: 0.7354 - val_loss: 0.5414 - val_acc: 0.7520
Epoch 149/150
514/514 [==============================] - 0s - loss: 0.5089 - acc: 0.7432 - val_loss: 0.5417 - val_acc: 0.7520
Epoch 150/150
514/514 [==============================] - 0s - loss: 0.5148 - acc: 0.7490 - val_loss: 0.5549 - val_acc: 0.7520
使用手动验证数据集
Keras 还允许您手动指定要在训练期间用于验证的数据集。
在此示例中,我们使用Python?scikit-learn机器学习库中方便的train_test_split?() 函数将我们的数据分离为训练和测试数据集。我们使用 67% 的数据进行训练,其余 33% 的数据用于验证。
验证数据集可以通过参数指定给fit() ?Keras 中的validation_data 函数。它采用输入和输出数据集的元组。
# MLP with manual validation set
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.model_selection import train_test_split
import numpy
# 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]
# split into 67% for train and 33% for test
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=seed)
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test,y_test), epochs=150, batch_size=10)
注意:您的结果可能会因算法或评估程序的随机性或数值精度的差异而有所不同。考虑运行该示例几次并比较平均结果。
像以前一样,运行该示例提供了详细的训练输出,其中包括模型在每个 epoch 的训练和验证数据集上的损失和准确性。
...
Epoch 145/150
514/514 [==============================] - 0s - loss: 0.4847 - acc: 0.7704 - val_loss: 0.5668 - val_acc: 0.7323
Epoch 146/150
514/514 [==============================] - 0s - loss: 0.4853 - acc: 0.7549 - val_loss: 0.5768 - val_acc: 0.7087
Epoch 147/150
514/514 [==============================] - 0s - loss: 0.4864 - acc: 0.7743 - val_loss: 0.5604 - val_acc: 0.7244
Epoch 148/150
514/514 [==============================] - 0s - loss: 0.4831 - acc: 0.7665 - val_loss: 0.5589 - val_acc: 0.7126
Epoch 149/150
514/514 [==============================] - 0s - loss: 0.4961 - acc: 0.7782 - val_loss: 0.5663 - val_acc: 0.7126
Epoch 150/150
514/514 [==============================] - 0s - loss: 0.4967 - acc: 0.7588 - val_loss: 0.5810 - val_acc: 0.6929
手动 k 折交叉验证
机器学习模型评估的黄金标准是k 折交叉验证。
它提供了对模型在未见数据上的性能的稳健估计。它通过将训练数据集分成 k 个子集并轮流在所有子集上训练模型来实现这一点,除了一个被保留的子集,并在保留的验证数据集上评估模型性能。重复该过程,直到所有子集都有机会成为保留的验证集。然后在创建的所有模型中对性能度量进行平均。
重要的是要了解交叉验证意味着估计模型设计(例如,3 层与 4 层神经网络)而不是特定的拟合模型。我们不想使用特定的数据集来拟合模型并比较结果。因为这可能是由于该特定数据集更适合一个模型设计。相反,我们希望使用多个数据集进行拟合,从而得到相同设计的多个拟合模型,并采用平均性能度量进行比较。
由于计算成本更高,交叉验证通常不用于评估深度学习模型。例如,k 折交叉验证通常与 5 或 10 折一起使用。因此,必须构建和评估 5 或 10 个模型,大大增加了模型的评估时间。
然而,当问题足够小或者你有足够的计算资源时,k-fold 交叉验证可以让你对模型性能的估计偏差更小。
在下面的示例中,我们使用scikit-learn Python 机器学习库中方便的StratifiedKFold类将训练数据集拆分为 10 个折叠。折叠是分层的,这意味着算法试图平衡每个折叠中每个类的实例数量。
该示例使用 10 个数据拆分创建和评估 10 个模型并收集所有分数。verbose=0 通过传递给模型上的fit() andevaluate() ?函数来关闭每个 epoch 的详细输出。
为每个模型打印并存储性能。然后在运行结束时打印模型性能的平均值和标准偏差,以提供对模型精度的稳健估计。
# MLP for Pima Indians Dataset with 10-fold cross validation
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.model_selection import StratifiedKFold
import numpy as np
# fix random seed for reproducibility
seed = 7
np.random.seed(seed)
# load pima indians dataset
dataset = np.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# define 10-fold cross validation test harness
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
cvscores = []
for train, test in kfold.split(X, Y):
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X[train], Y[train], epochs=150, batch_size=10, verbose=0)
# evaluate the model
scores = model.evaluate(X[test], Y[test], verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
cvscores.append(scores[1] * 100)
print("%.2f%% (+/- %.2f%%)" % (np.mean(cvscores), np.std(cvscores)))
注意:您的结果可能会因算法或评估程序的随机性或数值精度的差异而有所不同。考虑运行该示例几次并比较平均结果。
运行该示例将花费不到一分钟的时间,并将产生以下输出:
acc: 77.92%
acc: 68.83%
acc: 72.73%
acc: 64.94%
acc: 77.92%
acc: 35.06%
acc: 74.03%
acc: 68.83%
acc: 34.21%
acc: 72.37%
64.68% (+/- 15.50%)
看技术干货,关注我们的账号,点击主页查看其他技术干货 。
|