如何拆分训练和测试数据 - 在Tensorflow上使用Keras

25

我目前正在使用神经网络训练我的数据,并使用fit函数。

history=model.fit(X, encoded_Y, batch_size=50, nb_epoch=500, validation_split = 0.2, verbose=1)

现在我已经将validation_split设为20%。我理解的是我的训练数据将占80%,测试数据将占20%。我不清楚后台是如何处理这些数据的。是像取前80%的样本用于训练,下面20%用于测试,还是随机从中间选择?如果我想提供单独的训练和测试数据,我该怎么用fit()实现?

此外,我的第二个问题是如何检查数据是否很好地适合于模型?我可以从结果中看出,训练准确率约为90%,而验证准确率约为55%。这是过拟合还是欠拟合的情况?

我的最后一个问题是evaluate返回什么?文档说它返回损失,但我在每个epoch(作为fit()中history的返回)中已经得到了损失和准确率。evaluate返回的准确率和分数是什么意思?如果evaluate返回的准确率为90%,那么我是否可以说我的数据很好地适合,而不考虑每个epoch的各自准确度和损失率?

以下是我的代码:

import numpy
import pandas
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from keras.utils import np_utils
from sklearn.model_selection import KFold
from sklearn.metrics import confusion_matrix
import itertools

seed = 7
numpy.random.seed(seed)

dataframe = pandas.read_csv("INPUTFILE.csv", skiprows=range(0, 0))

dataset = dataframe.values
X = dataset[:,0:50].astype(float) # number of cols-1
Y = dataset[:,50]

encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)

encoded_Y = np_utils.to_categorical(encoded_Y)
print("encoded_Y=", encoded_Y) 
# baseline model
def create_baseline():
    # create model
    model = Sequential()
    model.add(Dense(5, input_dim=5, kernel_initializer='normal', activation='relu'))
    model.add(Dense(5, kernel_initializer='normal', activation='relu'))
    #model.add(Dense(2, kernel_initializer='normal', activation='sigmoid'))

    model.add(Dense(2, kernel_initializer='normal', activation='softmax'))

    # Compile model
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])  # for binayr classification
        #model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])  # for multi class
    return model


model=create_baseline();
history=model.fit(X, encoded_Y, batch_size=50, nb_epoch=500, validation_split = 0.2, verbose=1)

print(history.history.keys())
# list all data in history
print(history.history.keys())
# summarize history for accuracy
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# summarize history for loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()


pre_cls=model.predict_classes(X)    
cm1 = confusion_matrix(encoder.transform(Y),pre_cls)
print('Confusion Matrix : \n')
print(cm1)


score, acc = model.evaluate(X,encoded_Y)
print('Test score:', score)
print('Test accuracy:', acc)

“evaluate” 用于在新数据上评估拟合模型(不用于训练),因此在这里使用它并没有太多意义。 - desertnaut
1个回答

59
  1. Keras文档中说:“在洗牌之前,验证数据从提供的x和y数据中选择最后一批样本。” 这意味着洗牌发生在分割之后,也有一个名为“shuffle”的布尔参数,默认设置为true,因此,如果您不希望数据被洗牌,只需将其设置为false。

  2. 在训练数据上获得良好结果,然后在评估数据上获得差或不太好的结果通常意味着您的模型出现了过拟合。过拟合是指您的模型仅能在非常具体的情况下学习,并且无法在新数据上取得良好的结果。

  3. 评估是在“从未见过”的新数据上测试您的模型的过程,通常您将数据划分为训练和测试两组,但有时您可能还想创建第三组数据,因为如果您仅仅为了在测试数据上获得更好的结果而调整您的模型,这在某种程度上就像作弊,因为您在某种程度上告诉您的模型您要用于评估的数据长什么样子,这可能会导致过拟合。

另外,如果您想在没有使用Keras的情况下拆分数据,我建议您使用sklearn的train_test_split()函数。这个函数易于使用,看起来像这样:链接

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)

感谢您的详细回复。我能否使用evaluate函数生成混淆矩阵?如果我想要使用来自另一个文件的测试数据而不是使用相同的数据集进行训练和测试,我该如何操作? - eshaa
只是澄清另一个混淆点。这是否意味着如果我使用评估,那么它将仅返回最终准确性,我能查看每个样本的准确性吗? - eshaa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接