網站首頁 編程語言 正文
K折交叉交叉驗證的過程如下
以200條數據,十折交叉驗證為例子,十折也就是將數據分成10組,進行10組訓練,每組用于測試的數據為:數據總條數/組數,即每組20條用于valid,180條用于train,每次valid的都是不同的。
(1)將200條數據,分成按照 數據總條數/組數(折數),進行切分。然后取出第i份作為第i次的valid,剩下的作為train
(2)將每組中的train數據利用DataLoader和Dataset,進行封裝。
(3)將train數據用于訓練,epoch可以自己定義,然后利用valid做驗證。得到一次的train_loss和?valid_loss。
(4)重復(2)(3)步驟,得到最終的 averge_train_loss和averge_valid_loss
上述過程如下圖所示:
上述的代碼如下:
import torch
import torch.nn as nn
from torch.utils.data import DataLoader,Dataset
import torch.nn.functional as F
from torch.autograd import Variable
#####構造的訓練集####
x = torch.rand(100,28,28)
y = torch.randn(100,28,28)
x = torch.cat((x,y),dim=0)
label =[1] *100 + [0]*100
label = torch.tensor(label,dtype=torch.long)
######網絡結構##########
class Net(nn.Module):
#定義Net
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(28*28, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 2)
def forward(self, x):
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:]
num_features = 1
for s in size:
num_features *= s
return num_features
##########定義dataset##########
class TraindataSet(Dataset):
def __init__(self,train_features,train_labels):
self.x_data = train_features
self.y_data = train_labels
self.len = len(train_labels)
def __getitem__(self,index):
return self.x_data[index],self.y_data[index]
def __len__(self):
return self.len
########k折劃分############
def get_k_fold_data(k, i, X, y): ###此過程主要是步驟(1)
# 返回第i折交叉驗證時所需要的訓練和驗證數據,分開放,X_train為訓練數據,X_valid為驗證數據
assert k > 1
fold_size = X.shape[0] // k # 每份的個數:數據總條數/折數(組數)
X_train, y_train = None, None
for j in range(k):
idx = slice(j * fold_size, (j + 1) * fold_size) #slice(start,end,step)切片函數
##idx 為每組 valid
X_part, y_part = X[idx, :], y[idx]
if j == i: ###第i折作valid
X_valid, y_valid = X_part, y_part
elif X_train is None:
X_train, y_train = X_part, y_part
else:
X_train = torch.cat((X_train, X_part), dim=0) #dim=0增加行數,豎著連接
y_train = torch.cat((y_train, y_part), dim=0)
#print(X_train.size(),X_valid.size())
return X_train, y_train, X_valid,y_valid
def k_fold(k, X_train, y_train, num_epochs=3,learning_rate=0.001, weight_decay=0.1, batch_size=5):
train_loss_sum, valid_loss_sum = 0, 0
train_acc_sum ,valid_acc_sum = 0,0
for i in range(k):
data = get_k_fold_data(k, i, X_train, y_train) # 獲取k折交叉驗證的訓練和驗證數據
net = Net() ### 實例化模型
### 每份數據進行訓練,體現步驟三####
train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,\
weight_decay, batch_size)
print('*'*25,'第',i+1,'折','*'*25)
print('train_loss:%.6f'%train_ls[-1][0],'train_acc:%.4f\n'%valid_ls[-1][1],\
'valid loss:%.6f'%valid_ls[-1][0],'valid_acc:%.4f'%valid_ls[-1][1])
train_loss_sum += train_ls[-1][0]
valid_loss_sum += valid_ls[-1][0]
train_acc_sum += train_ls[-1][1]
valid_acc_sum += valid_ls[-1][1]
print('#'*10,'最終k折交叉驗證結果','#'*10)
####體現步驟四#####
print('train_loss_sum:%.4f'%(train_loss_sum/k),'train_acc_sum:%.4f\n'%(train_acc_sum/k),\
'valid_loss_sum:%.4f'%(valid_loss_sum/k),'valid_acc_sum:%.4f'%(valid_acc_sum/k))
#########訓練函數##########
def train(net, train_features, train_labels, test_features, test_labels, num_epochs, learning_rate,weight_decay, batch_size):
train_ls, test_ls = [], [] ##存儲train_loss,test_loss
dataset = TraindataSet(train_features, train_labels)
train_iter = DataLoader(dataset, batch_size, shuffle=True)
### 將數據封裝成 Dataloder 對應步驟(2)
#這里使用了Adam優化算法
optimizer = torch.optim.Adam(params=net.parameters(), lr= learning_rate, weight_decay=weight_decay)
for epoch in range(num_epochs):
for X, y in train_iter: ###分批訓練
output = net(X)
loss = loss_func(output,y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
### 得到每個epoch的 loss 和 accuracy
train_ls.append(log_rmse(0,net, train_features, train_labels))
if test_labels is not None:
test_ls.append(log_rmse(1,net, test_features, test_labels))
#print(train_ls,test_ls)
return train_ls, test_ls
def log_rmse(flag,net,x,y):
if flag == 1: ### valid 數據集
net.eval()
output = net(x)
result = torch.max(output,1)[1].view(y.size())
corrects = (result.data == y.data).sum().item()
accuracy = corrects*100.0/len(y) #### 5 是 batch_size
loss = loss_func(output,y)
net.train()
return (loss.data.item(),accuracy)
loss_func = nn.CrossEntropyLoss() ###申明loss函
k_fold(10,x,label) ### k=10,十折交叉驗證
上述代碼中,直接按照順序從x中每次截取20條作為valid,也可以先打亂然后在截取,這樣效果應該會更好。
如下所示:
import random
import torch
x = torch.rand(100,28,28)
y = torch.randn(100,28,28)
x = torch.cat((x,y),dim=0)
label =[1] *100 + [0]*100
label = torch.tensor(label,dtype=torch.long)
index = [i for i in range(len(x))]
random.shuffle(index)
x = x[index]
label = label[index]
交叉驗證區分k折代碼分析
from sklearn.model_selection import GroupKFold
x = np.array([1,2,3,4,5,6,7,8,9,10])
y = np.array([1,2,3,4,5,6,7,8,9,10])
z = np.array(['hello1','hello2','hello3','hello4','hello5','hello6','hello7','hello8','hello9','hello10'])
gkf = GroupKFold(n_splits = 5)
for i,(train_idx,valid_idx) in enumerate(list(gkf.split(x,y,z))):
#groups:object,Always ignored,exists for compatibility.
print('train_idx = ')
print(train_idx)
print('valid_idx = ')
print(valid_idx)
可以看出來首先train_idx以及valid_idx的相應值都是從中亂序提取的,其次每個相應值只提取一次,不會重復提取。
注意交叉驗證的流程:這里首先放一個對應的交叉驗證的圖片:
注意這里的訓練方式是每個初始化的模型分別訓練n折的數值,然后算出對應的權重內容
也就是說這里每一次計算對應的權重內容(1~n)的時候,需要將模型的權重初始化,然后再進行訓練,訓練最終結束之后,模型的權重為訓練完成之后的平均值,多模類似于模型融合
總結
原文鏈接:https://blog.csdn.net/foneone/article/details/104445320
相關推薦
- 2023-04-21 C語言哈希表概念超詳細講解_C 語言
- 2023-06-03 C++一個函數如何調用其他.cpp文件中的函數_C 語言
- 2023-04-01 pytorch和numpy默認浮點類型位數詳解_python
- 2022-09-16 C語言庫函數getchar()新見解_C 語言
- 2023-01-11 Rust結構體的定義與實例化詳細講解_Rust語言
- 2023-02-04 python協程之yield和yield?from實例詳解_python
- 2022-04-06 一篇文章帶你了解C/C++的回調函數_C 語言
- 2022-10-26 jQuery?表單事件與遍歷詳情_jquery
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支