跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 卖家故事 > 【人工智能概论】 K折交叉验证

【人工智能概论】 K折交叉验证

时间:2024-04-10 12:55:29 来源:网络cs 作者:利杜鹃 栏目:卖家故事 阅读:

标签: 交叉  验证  概论 
阅读本书更多章节>>>>

【人工智能概论】 K折交叉验证

文章目录

【人工智能概论】 K折交叉验证一. 简单验证及其缺点1.1 简单验证简介1.2 简单验证的缺点 二. K折交叉验证2.1 K折交叉验证的思路2.2 小细节2.3 K折交叉验证的缺点2.4 K折交叉验证的代码


一. 简单验证及其缺点

1.1 简单验证简介

简单验证: 将原始数据集随机划分成训练集和验证集两部分,例,将数据按照7:3的比例分成两部分,70%的样本用于训练模型;30%的样本用于模型验证,如下图。

1.2 简单验证的缺点

数据都只被用了一次;验证集上计算出来的评估指标与原始分组有很大关系;对于时序序列,要保存时序信息,往往不能打乱数据的顺序对数据进行随机截取,这就带来了问题,比如总用春、夏、秋的数据做训练,用冬的数据做测试,这显然是有问题的,是不能容忍的。

二. K折交叉验证

为了解决简单交叉验证的不足,引出K折交叉验证,其既可以解决数据集的数据量不够大的问题,也可以解决参数调优的问题。。

2.1 K折交叉验证的思路

首先,将全部样本划分成k个大小相等的样本子集;依次遍历这k个子集,每次把当前子集作为验证集,其余所有样本作为训练集,进行模型的训练和评估;最后把k次评估指标的平均值作为最终的评估指标。在实际实验中,k通常取10,如下图。

在这里插入图片描述

2.2 小细节

K折交叉验证中有这样一个细节,下一折的训练不是在上一折的基础上进行的,即每训练新的一折都要重新初始化模型参数。K折交叉验证只能做验证使用,因此不能根据它的结果做为模型参数的保存判断依据,但可以基于它做超参组合的确定与模型结构的调整,然后再重新初始化模型,进行训练得到较好的模型参数。对于有时序信息的数据,要看看不同折之间性能表现会不会有明显差距。

2.3 K折交叉验证的缺点

因为K折交叉验证执行一次训练的总轮数是每一折的训练轮数(epochs)与总折数(K)的乘积,因此训练的成本会翻倍。

2.4 K折交叉验证的代码

import torchimport randomfrom torch.utils.data import DataLoader, TensorDatasetfrom Model.ReconsModel.Recoder import ReconsModel, Loss_functionfrom Model.ModelConfig import ModelConfig# 返回第 i+1 折(i取 0 ~ k-1)的训练集(train)与验证集(valid)def get_Kfold_data(k, i, x):  # k是折数,取第i+1折,x是特征数据    fold_size = x.size(0) // k  # 计算每一折中的数据数量    val_start = i * fold_size  # 第 i+1折 数据的测试集初始数据编号    if i != k - 1:  # 不是最后一折的话,数据的分配策略        val_end = (i + 1) * fold_size  # 验证集的结束        valid_data = x[val_start: val_end]        train_data = torch.cat((x[0: val_start], x[val_end:]), dim=0)    else:  # 如果是最后一折,数据的分配策略,主要涉及到不能K整除时,多出的数据如何处理        valid_data = x[val_start:]  # 实际上,多出来的样本,都放在最后一折里了        train_data = x[0: val_start]    return train_data, valid_data# k折交叉验证,某一折的训练def train(model, train_data, valid_data, batch_size, lr,epochs):    # 数据准备    train_loader = DataLoader(TensorDataset(train_data), batch_size, shuffle=True)    valid_loader = DataLoader(TensorDataset(valid_data), batch_size, shuffle=True)    # 损失函数,优化函数的准备    criterion = Loss_function()    optimizer = torch.optim.Adam(params=model.parameters(), lr=lr)    # 记录每一个epoch的平均损失    train_loss = []    valid_loss = []    for epoch in range(epochs):        tra_loss = 0        val_loss = 0        for i , data in enumerate(train_loader):            # 假设数据的处理 此时的data是list类型的数据,转化成Tensor,并且把多出来的第0维去掉            data = torch.stack(data)            data = data.squeeze(0)            optimizer.zero_grad()  # 梯度清零            recon, mu, log_std = model(data, if_train=True)  # if_train不能少            # 计算损失            loss = criterion.loss_function(recon, data, mu, log_std)            # 反向传播            loss.backward()            optimizer.step()            tra_loss = tra_loss + loss.item()        tra_loss = tra_loss / len(train_data)        train_loss.append(tra_loss)        # 计算测试集损失        with torch.no_grad():            for i, data in enumerate(valid_loader):                # 假设数据的处理 此时的data是list类型的数据,转化成Tensor,并且把多出来的第0维去掉                data = torch.stack(data)                data = data.squeeze(0)                optimizer.zero_grad()                recon, mu, log_std = model(data, if_train=False)                test_loss = criterion.loss_function(recon, data, mu, log_std).item()                val_loss = val_loss + test_loss            val_loss = val_loss / len(valid_data)            valid_loss.append(val_loss)        print('第 %d 轮, 训练的平均误差为%.3f, 测试的平均误差为%.3f 。'%(epoch+1, tra_loss, val_loss))    return train_loss, valid_loss# k折交叉验证def k_test(config, datas): # k是总折数,    valid_loss_sum = 0    for i in range(config.k):        model = ReconsModel(config) # 细节,每一折,并不是在上一折训练好的模型基础上继续训练,而是重新训练        print('-'*25,'第',i+1,'折','-'*25)        train_data , valid_data = get_Kfold_data(config.k, i, datas) # 获取某一折的训练数据、测试数据        train_loss, valid_loss = train(model, train_data, valid_data, config.batch_size, config.lr, config.epochs)        # 求某一折的平均损失        train_loss_ave = sum(train_loss)/len(train_loss)        valid_loss_ave = sum(valid_loss)/len(valid_loss)        print('-*-*-*- 第 %d 折, 平均训练损失%.3f,平均检验损失%.3f -*-*-*-'%(i+1, train_loss_ave,valid_loss_ave))        valid_loss_sum = valid_loss_sum + valid_loss_ave    valid_loss_k_ave = valid_loss_sum / config.k  # 基于K折交叉验证的验证损失    print('*' * 60, )    print('基于K折交叉验证的验证损失为%.4f'%valid_loss_k_ave)if __name__ == "__main__":    # 创建数据集,或者说数据集只要是这样的形式即可    X = torch.rand(5000, 16, 38)  # 5000条数据,,每条有16个时间步,每步38个特征,时序数据    # 随机打乱    index = [i for i in range(len(X))]    random.shuffle(index)    X = X[index]  # 要是有标签的话,index要对得上    config = ModelConfig()    config.load('./Model/config.json')    k_test(config, X)
阅读本书更多章节>>>>

本文链接:https://www.kjpai.cn/gushi/2024-04-10/156501.html,文章来源:网络cs,作者:利杜鹃,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇:图片引入---img标签

下一篇:返回列表

文章评论