【问题标题】:K fold cross validation using keras使用 keras 进行 K 折交叉验证
【发布时间】:2017-05-04 00:41:36
【问题描述】:

由于神经网络的巨大运行时间,convn 网络中的 k 折交叉验证似乎没有被认真对待。我有一个小数据集,我有兴趣使用给定的here 示例进行 k 折交叉验证。可能吗?谢谢。

【问题讨论】:

  • 是的,有可能。我认为 Keras 中没有一些开箱即用的 k 折交叉验证。您必须自己将数据集拆分为 k 折并跟踪性能指标。
  • 要添加到@SergiiGryshkevych,您需要修改 keras/engine/training.py 中的 fit() 更重要的是 _fit_loop() 以实现 K 折交叉验证。
  • 看看这篇博文machinelearningmastery.com/…

标签: keras cross-validation


【解决方案1】:

如果您使用带有数据生成器的图像,这里有一种方法可以使用 Keras 和 scikit-learn 进行 10 倍交叉验证。策略是根据每个折叠将文件复制到trainingvalidationtest子文件夹。

import numpy as np
import os
import pandas as pd
import shutil
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# used to copy files according to each fold
def copy_images(df, directory):
    destination_directory = "{path to your data directory}/" + directory
    print("copying {} files to {}...".format(directory, destination_directory))

    # remove all files from previous fold
    if os.path.exists(destination_directory):
        shutil.rmtree(destination_directory)

    # create folder for files from this fold
    if not os.path.exists(destination_directory):
        os.makedirs(destination_directory)

    # create subfolders for each class
    for c in set(list(df['class'])):
        if not os.path.exists(destination_directory + '/' + c):
            os.makedirs(destination_directory + '/' + c)

    # copy files for this fold from a directory holding all the files
    for i, row in df.iterrows():
        try:
            # this is the path to all of your images kept together in a separate folder
            path_from = "{path to all of your images}"
            path_from = path_from + "{}.jpg"
            path_to = "{}/{}".format(destination_directory, row['class'])

            # move from folder keeping all files to training, test, or validation folder (the "directory" argument)
            shutil.copy(path_from.format(row['filename']), path_to)
        except Exception, e:
            print("Error when copying {}: {}".format(row['filename'], str(e)))

# dataframe containing the filenames of the images (e.g., GUID filenames) and the classes
df = pd.read_csv('{path to your data}.csv')
df_y = df['class']
df_x = df
del df_x['class']

skf = StratifiedKFold(n_splits = 10)
total_actual = []
total_predicted = []
total_val_accuracy = []
total_val_loss = []
total_test_accuracy = []

for i, (train_index, test_index) in enumerate(skf.split(df_x, df_y)):
    x_train, x_test = df_x.iloc[train_index], df_x.iloc[test_index]
    y_train, y_test = df_y.iloc[train_index], df_y.iloc[test_index]

    train = pd.concat([x_train, y_train], axis=1)
    test = pd.concat([x_test, y_test], axis = 1)

    # take 20% of the training data from this fold for validation during training
    validation = train.sample(frac = 0.2)

    # make sure validation data does not include training data
    train = train[~train['filename'].isin(list(validation['filename']))]

    # copy the images according to the fold
    copy_images(train, 'training')
    copy_images(validation, 'validation')
    copy_images(test, 'test')

    print('**** Running fold '+ str(i))

    # here you call a function to create and train your model, returning validation accuracy and validation loss
    val_accuracy, val_loss = create_train_model();

    # append validation accuracy and loss for average calculation later on
    total_val_accuracy.append(val_accuracy)
    total_val_loss.append(val_loss)

    # here you will call a predict() method that will predict the images on the "test" subfolder 
    # this function returns the actual classes and the predicted classes in the same order
    actual, predicted = predict()

    # append accuracy from the predictions on the test data
    total_test_accuracy.append(accuracy_score(actual, predicted))

    # append all of the actual and predicted classes for your final evaluation
    total_actual = total_actual + actual
    total_predicted = total_predicted + predicted

    # this is optional, but you can also see the performance on each fold as the process goes on
    print(classification_report(total_actual, total_predicted))
    print(confusion_matrix(total_actual, total_predicted))

print(classification_report(total_actual, total_predicted))
print(confusion_matrix(total_actual, total_predicted))
print("Validation accuracy on each fold:")
print(total_val_accuracy)
print("Mean validation accuracy: {}%".format(np.mean(total_val_accuracy) * 100))

print("Validation loss on each fold:")
print(total_val_loss)
print("Mean validation loss: {}".format(np.mean(total_val_loss)))

print("Test accuracy on each fold:")
print(total_test_accuracy)
print("Mean test accuracy: {}%".format(np.mean(total_test_accuracy) * 100))

在您的 predict() 函数中,如果您使用的是数据生成器,我能找到的在测试时保持预测顺序相同的唯一方法是使用 batch_size1

generator = ImageDataGenerator().flow_from_directory(
        '{path to your data directory}/test',
        target_size = (img_width, img_height),
        batch_size = 1,
        color_mode = 'rgb',
        # categorical for a multiclass problem
        class_mode = 'categorical',
        # this will also ensure the same order
        shuffle = False)

通过这段代码,我能够使用数据生成器进行 10 倍交叉验证(因此我不必将所有文件都保存在内存中)。如果您有数百万张图片,这可能需要大量工作,如果您的测试集很大,batch_size = 1 可能会成为瓶颈,但对于我的项目来说,这很有效。

【讨论】:

    猜你喜欢
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 2016-01-15
    • 2022-06-15
    • 2020-07-08
    • 1970-01-01
    相关资源
    最近更新 更多