鱼C论坛

 找回密码
 立即注册
查看: 421|回复: 1

简单神经网络使用k折交叉验证报错

[复制链接]
发表于 2024-10-22 20:22:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
训练模型代码
  1. #使用dnn模型
  2. import torch
  3. import torch.nn as nn
  4. from torch.utils import data
  5. from torch.utils.data import Dataset,DataLoader
  6. from torch import optim

  7. #定义神经网络模型
  8. dropout1, dropout2 = 0.3, 0.6
  9. class SimpleNN(nn.Module):
  10.     def __init__(self):
  11.         super(SimpleNN, self).__init__()  # 继承需要用 SimpleNN
  12.         self.dense = nn.Sequential(
  13.             nn.Flatten(),
  14.             nn.Linear(12, 128),
  15.             nn.ReLU(),  
  16.             nn.Dropout(dropout1),
  17.             nn.Linear(128, 256),
  18.             nn.ReLU(),  
  19.             nn.Dropout(dropout2),
  20.             nn.Linear(256, 1),
  21.         )
  22.       
  23.     def forward(self, X):
  24.         x = self.dense(X)
  25.         output = torch.sigmoid(x)
  26.         return output

  27.    
  28. #初始化模型和优化器
  29. nn_model = SimpleNN()
  30. loss = nn.BCELoss() #定义损失函数
  31. optimizer = optim.Adam(nn_model.parameters(),lr=0.0001) #定义优化器

  32. #初始化列表
  33. acc_list = []
  34. loss_list = []

  35. #k折交叉验证选取训练集与验证集
  36. def get_k_fold_data(k, i, X, y):
  37.     assert k > 1
  38.     fold_size = len(X) // k
  39.     X_train, y_train = None, None
  40.     for j in range(k):
  41.         start = j * fold_size
  42.         end = (j + 1) * fold_size
  43.         if j == i:
  44.             X_valid, y_valid = X.iloc[start:end], y.iloc[start:end]
  45.         elif X_train is None:
  46.             X_train, y_train = X.iloc[:start], y.iloc[start:end]
  47.         else:
  48.             X_train = pd.concat([X_train, X.iloc[start:end]], ignore_index=True)
  49.             y_train = pd.concat([y_train, y.iloc[start:end]], ignore_index=True)
  50.     return X_train, y_train, X_valid, y_valid


  51. # 开始训练
  52. k = 5
  53. batch_size = 99
  54. num_epochs = 1000


  55. for i in range(k):
  56.     X_train, y_train, X_valid, y_valid = get_k_fold_data(k, i, X, y)
  57.     print(f'FOLD {i}')
  58.     print('--------------------------------')
  59.    
  60.     #将DataFrame数据转换为NumPy数组,然后再转换为PyTorch张量
  61.     X_train = torch.tensor(X_train.astype(np.float32).values, dtype=torch.float32)
  62.     y_train = torch.tensor(y_train.astype(np.float32).values, dtype=torch.float32)
  63.     X_valid = torch.tensor(X_valid.astype(np.float32).values, dtype=torch.float32)
  64.     y_valid = torch.tensor(y_valid.astype(np.float32).values, dtype=torch.float32)
  65.    
  66.     #创建数据集
  67.     train_dataset = data.TensorDataset(X_train, y_train)
  68.     valid_dataset = data.TensorDataset(X_valid, y_valid)

  69.     # 获取一个数据迭代器
  70.     train_iter = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True,num_workers=2)#shuffle=True相当于sampler=RandomSampler(dataset)
  71.     valid_iter = DataLoader(dataset=valid_dataset,batch_size=batch_size,shuffle=True,num_workers=2)
  72.    
  73.     #开始迭代
  74.     for epoch in range(num_epochs):
  75.         train_loss = 0
  76.         num_right = 0
  77.         for tensor_x, tensor_y in train_iter:#训练集执行梯度更新
  78.             tensor_x = tensor_x.float()
  79.             tensor_y = tensor_y.float().reshape(-1, 1)
  80.             optimizer.zero_grad() #梯度清零
  81.             pre_train = nn_model(tensor_x)
  82.             train_l = loss(pre_train, tensor_y) #损失应避免与全局变量loss重名
  83.             train_l.backward()#前向传播
  84.             optimizer.step()#梯度下降

  85.             train_loss += train_l.item() * len(tensor_x)
  86.             result = [1 if out >= 0.5 else 0 for out in pre_train]
  87.             num_right += np.sum(np.array(result) == tensor_y.numpy().reshape(-1))

  88.             train_loss = train_loss / len(train_iter.dataset)
  89.             train_accuracy = num_right / len(train_iter.dataset)

  90.         if epoch % 200 == 0:
  91.             print('Loss: {} Accuracy: {} Epoch:{}'.format(train_loss, train_accuracy, epoch))
  92.         
  93.         with torch.no_grad():
  94.             valid_loss = 0
  95.             num_right = 0
  96.             for tensor_x, tensor_y in valid_iter:
  97.                 tensor_x = tensor_x.float()
  98.                 tensor_y = tensor_y.float().reshape(-1, 1)
  99.                 pre_valid = nn_model(tensor_x)
  100.                 valid_l = loss(pre_valid, tensor_y)
  101.                 valid_loss += valid_l.item() * len(tensor_x)
  102.                 result = [1 if out >= 0.5 else 0 for out in pre_valid]
  103.                 num_right += np.sum(np.array(result) == tensor_y.numpy().reshape(-1))
  104.             
  105.             valid_loss = valid_loss / len(valid_iter.dataset)
  106.             valid_accuracy = num_right / len(valid_iter.dataset)
  107.         
  108.             if epoch % 200 == 0:
  109.                 print('Valid Loss: {} Accuracy: {} Epoch:{}'.format(valid_loss, valid_accuracy, epoch))
  110.         
  111.     #将每次迭代的结果写入列表
  112.     loss_list.append(valid_loss)
  113.     acc_list.append(valid_accuracy)
  114.         
  115. print('Training Ended')
  116. print('Average Loss: {} Average Accuracy: {}'.format(np.mean(loss_list), np.mean(acc_list)))
复制代码


报错代码
  1. ---------------------------------------------------------------------------
  2. AssertionError                            Traceback (most recent call last)
  3. Cell In[28], line 75
  4.      72 y_valid = torch.tensor(y_valid.astype(np.float32).values, dtype=torch.float32)
  5.      74 #创建数据集
  6. ---> 75 train_dataset = data.TensorDataset(X_train, y_train)
  7.      76 valid_dataset = data.TensorDataset(X_valid, y_valid)
  8.      78 # 获取一个数据迭代器

  9. File /opt/conda/lib/python3.10/site-packages/torch/utils/data/dataset.py:204, in TensorDataset.__init__(self, *tensors)
  10.     203 def __init__(self, *tensors: Tensor) -> None:
  11. --> 204     assert all(tensors[0].size(0) == tensor.size(0) for tensor in tensors), "Size mismatch between tensors"
  12.     205     self.tensors = tensors

  13. AssertionError: Size mismatch between tensors
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-10-22 20:22:54 | 显示全部楼层
这个错误的原因是`X_train`和`y_train`的大小不匹配。要解决这个问题,可以检查`get_k_fold_data`函数中的索引和拼接部分,确保每个折的训练和验证集的大小正确。以下是一些您可以检查和修正的点:

1. **数据分割**:
  
  1. if j == i:
  2.        X_valid, y_valid = X.iloc[start:end], y.iloc[start:end]
  3.    else:
  4.        X_train = pd.concat([X_train, X.iloc[start:end]], ignore_index=True) if X_train is not None else X.iloc[start:end]
  5.        y_train = pd.concat([y_train, y.iloc[start:end]], ignore_index=True) if y_train is not None else y.iloc[start:end]
复制代码


2. **数据类型**:
   确保`X`和`y`是Pandas DataFrame和Series对象,因此可以使用`.iloc`进行正确的索引。

3. **确保交叉验证正确**:
   验证确保每次k-fold划分后的`X_train`和`y_train`长度一致。

4. **调试信息**:
   可以在每次生成`TensorDataset`之前打印`X_train.shape`和`y_train.shape`,检查它们是否一致。

通过这些检查和修正,应该能够解决您的问题。如果仍有错误,请根据具体信息分析`X`和`y`的内容和形状。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-19 16:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表