评估深度学习模型的性能
在设计和配置深度学习模型时做出的许多决策都是通过试验凭经验求解,然后用真实数据评估模型。
由于上述原因,您必须有一种强大的方法来评估您在Keras中的模型性能。在本节中,您将学习:
- 使用自动验证数据集评估Keras中的模型。
- 使用手动验证数据集评估Keras中的模型。
- 使用k -fold交叉验证评估Keras中的模型。
在神经网络的设计过程中,您必须做出多个决策,其中许多决策可以使用已知的体系结构或使用启发式方法来解决。最后的最佳技术是设计小型实验并使用真实数据进行评估。这还包括低级决策,例如:损失函数,优化和epochs数。深度学习通常涉及大型数据集,因此您需要一种方法来帮助您比较不同配置之间的性能。
数据分离
大量数据和模型的复杂性需要非常长的训练时间。因此,通常将数据分开:
- 训练和测试数据
- 验证数据。
Keras提供了两种评估深度学习算法的方法:
- 使用一组自动验证数据。
- 使用手动验证数据集。
自动验证
Keras可以将您的训练数据分为两部分,即训练和验证数据集。在fit()函数中使用validation_split参数,使用合理的百分比。对于将保留用于验证的20%或33%的训练数据,建议值可以是0.2或0.33。以下示例演示了在Pima Indian数据集中使用自动配置。
# MLP with manual validation set
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import train_test_split
import numpy as np
# fix random seed for reproducibility
seed = 7
np.random.seed(seed)
# load pima indians dataset
FILENAME = '../data/pima-indians-diabetes.csv'
dataset = np.loadtxt(FILENAME, delimiter=',')
# split into input (X) and output (Y) variables
features = dataset[:, 0:8]
labels = dataset[:, 8]
# split into 67% for train and 33% for test
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(features, labels, validation_split=0.33, epochs=150, batch_size=10)
model.summary()
手动验证
Keras允许您手动定义要用于训练的数据集,以及用于验证的数据集。在这个例子中,我们将使用Python scikit-learn函数train_test_split(),它允许我们在训练和验证中分离我们的数据。我们将使用67%进行训练,其余33%进行验证。可以通过验证数据参数将验证数据集指定给Keras中的fit()函数。需要输入和输出数据集的元组。
# MLP with manual validation set
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import train_test_split
import numpy as np
# fix random seed for reproducibility
seed = 7
np.random.seed(seed)
# load pima indians dataset
FILENAME = '../data/pima-indians-diabetes.csv'
dataset = np.loadtxt(FILENAME, delimiter=',')
# split into input (X) and output (Y) variables
features = dataset[:, 0:8]
labels = dataset[:, 8]
# split into 67% for train and 33% for test
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=seed) # 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_train, y_train, validation_data=(X_test, y_test), epochs=150, batch_size=10)
model.summary()
使用k-fold交叉验证
评估机器学习模型的标准是k-fold交叉验证。该方法提供了对模型性能的稳健估计以进行预测。它通过将训练数据集划分为k个子集并在除了维护的子集之外的所有子集中交替训练模型并且在保留的验证数据集中评估模型的性能来实现这一点。重复该过程,直到所有子集都有机会成为扩展验证集。然后,在所有创建的模型中对性能度量进行平均。
由于较高的计算开销,交叉验证通常不用于评估深度学习模型。例如,k次的交叉验证通常使用5或10 folds 。因此,必须构建和评估5或10个模型,这极大地增加了模型的评估时间。但是,当问题足够小或者您有足够的计算资源时,k-fold交叉验证可以让您对模型的性能进行较少的偏差估计。
在下面的例子中,我们使用了有用的StratifiedKFold的scikit学习将训练数据组划分为10倍。折叠是分层的,这意味着算法试图平衡每个折叠中每个类的实例数。该示例使用数据的10个分区创建和评估10个模型,并收集所有分数。
通过将verbose = 0传递给模型中的函数fit()和evaluate()来停用每个循环的输出。为每个型号打印并存储性能。在运行结束时打印模型性能的平均值和标准偏差,以给出模型精度的稳健估计。
# MLP for Pima Indians Dataset with 10-fold cross validation
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import StratifiedKFold
import numpy
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load pima indians dataset
FILENAME = '../data/pima-indians-diabetes.csv'
dataset = numpy.loadtxt(FILENAME, 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, 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[train], Y[train], nb_epoch=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%%)" % (numpy.mean(cvscores), numpy.std(cvscores)))
请注意,必须在每个周期中重新创建模型,然后训练和评估数据