假定在某一个项目中,没有现成的数据集划分,你需要手动将该数据集划分为训练、验证和测试集,一般比例取60%:20%:20%。 但是仅仅通过随机选取某一个数据集划分可能是不全面的,因而我们应该使用五折交叉验证,使得每个子集都有可能成为测试集,从而取五折测试集的平均性能作为整体算法的性能,即如下图所示。

深度学习模型的五折交叉验证 五折交叉验证法代码_深度学习

那么如何用代码实现呢?

假定我们有一个图像文件夹img_path,希望通过遍历该图像文件夹来获取五折划分对应的训练-验证-测试子集。

这里我们首先考虑一个简单的非图像数据,我们直接给出相应的代码:

import numpy as np

# 定义数据集,假设有4222个样本
Num=4222
data = np.arange(Num)

# 定义 5 折交叉验证的 k 值
k = 5

# 计算每个折的大小
fold_size = int(len(data) / k)

# 设置随机种子,以确保无论运行多少次,打乱后的结果都会相同
np.random.seed(42)

# 随机打乱数据集
np.random.shuffle(data)

# 划分训练集、测试集和验证集
for i in range(k):
    # 计算当前折的起始位置和结束位置
    start = i * fold_size
    end = (i + 1) * fold_size
    if Num-end < fold_size: # 防止末尾有剩余
        end = Num

    # 将当前折作为测试集,其余折作为训练集
    test_set = data[start:end]

    #邻近测试集的下一个折作为验证集
    val_start = end%Num
    val_end = val_start + fold_size
    if Num-val_end < fold_size:  # 防止末尾有剩余
        val_end = Num

    val_set = data[val_start:val_end]
    test_val_set = np.concatenate([test_set, val_set])

    # 其余为训练集,第一种算法,优选
    train_set = np.array([x for x in data if x not in test_val_set])
    # 计算两个集合的差集,第二种算法
    train_set2 = np.array(list(set(data) - set(test_val_set)))


    # 输出当前折的数据情况
    print(f"Fold {i + 1}:")
    print(f"Train set size: {len(train_set)}")
    print(f"Validation set size: {len(val_set)}")
    print(f"Test set size: {len(test_set)}")
    print("=====================")

在此基础上,我们给出图像数据的代码:

import numpy as np
from os.path import join, splitext, split, isfile
import os, sys, argparse
import time

# 定义数据集,假设有4222个样本
img_path = 'H:/dataset/CVBL/IrisImage-single/'
imgs = [i for i in os.listdir(img_path)]
Num = len(imgs)
data = np.arange(Num)

# 定义 5 折交叉验证的 k 值
k = 5

# 计算每个折的大小
fold_size = int(len(data) / k)

# 设置随机种子,以确保无论运行多少次,打乱后的结果都会相同
np.random.seed(42)
# 随机打乱数据集
np.random.shuffle(data)

# 划分训练集、测试集和验证集
for i in range(k):
    # 计算当前折的起始位置和结束位置
    start = i * fold_size
    end = (i + 1) * fold_size
    if Num-end < fold_size: # 防止末尾有剩余
        end = Num

    # 将当前折作为测试集,其余折作为训练集
    test_set = data[start:end]
    test_img_set = [imgs[index] for index in test_set]

    #邻近测试集的下一个折作为验证集
    val_start = end%Num
    val_end = val_start + fold_size
    if Num-val_end < fold_size:  # 防止末尾有剩余
        val_end = Num

    val_set = data[val_start:val_end]
    val_img_set = [imgs[index] for index in val_set]
    test_val_set = np.concatenate([test_set, val_set])

    # 其余为训练集,第一种算法,优选
    train_set = np.array([x for x in data if x not in test_val_set])
    # 计算两个集合的差集,第二种算法
    train_set2 = np.array(list(set(data) - set(test_val_set)))
    train_img_set = [imgs[index] for index in train_set]

    # 输出当前折的数据情况
    print(f"Fold {i + 1}:")
    print(f"Train set size: {len(train_set)}")
    print(f"Validation set size: {len(val_set)}")
    print(f"Test set size: {len(test_set)}")
    print("=====================")