鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: Terence888

好心人帮忙看一下简单神经网络dnn模型的代码有什么问题

[复制链接]
 楼主| 发表于 2024-10-22 22:21:03 | 显示全部楼层
FishC 发表于 2024-10-22 01:22
从提供的错误信息和代码来看,主要问题出现在自定义数据集 `SimpleDataset` 的 `__getitem__` 方法中。 ...
  1. #dnn模型(train_test_split)
  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. simple_dnn_model = SimpleNN()
  30. loss = nn.BCELoss() #定义损失函数
  31. optimizer = optim.Adam(nn_model.parameters(),lr=0.0001) #定义优化器

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



  35. # 开始训练
  36. batch_size = 99
  37. num_epochs = 1000

  38.    
  39. #创建数据集
  40. train_dataset = data.TensorDataset(X_train, y_train)
  41. valid_dataset = data.TensorDataset(X_valid, y_valid)

  42. # 获取一个数据迭代器
  43. train_iter = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True,num_workers=2)#shuffle=True相当于sampler=RandomSampler(dataset)
  44. valid_iter = DataLoader(dataset=valid_dataset,batch_size=batch_size,shuffle=True,num_workers=2)

  45. #开始迭代
  46. for epoch in range(num_epochs):
  47.     train_loss = 0
  48.     num_right = 0
  49.     for tensor_x, tensor_y in train_iter:#训练集执行梯度更新
  50.         tensor_x = tensor_x.float()
  51.         tensor_y = tensor_y.float().reshape(-1, 1)
  52.         optimizer.zero_grad() #梯度清零
  53.         pre_train = simple_dnn_model(tensor_x)
  54.         train_l = loss(pre_train, tensor_y) #损失应避免与全局变量loss重名
  55.         train_l.backward()#前向传播
  56.         optimizer.step()#梯度下降

  57.         train_loss += train_l.item() * len(tensor_x)#批量损失
  58.         result = [1 if out >= 0.5 else 0 for out in pre_train]
  59.         num_right += np.sum(np.array(result) == tensor_y.numpy().reshape(-1))

  60.         train_loss = train_loss / len(train_iter.dataset)
  61.         train_accuracy = num_right / len(train_iter.dataset)

  62.     if epoch % 200 == 0:
  63.         print('Loss: {} Accuracy: {} Epoch:{}'.format(train_loss, train_accuracy, epoch))

  64.     with torch.no_grad():
  65.         valid_loss = 0
  66.         num_right = 0
  67.         for tensor_x, tensor_y in valid_iter:
  68.             tensor_x = tensor_x.float()
  69.             tensor_y = tensor_y.float().reshape(-1, 1)
  70.             pre_valid = simple_dnn_model(tensor_x)
  71.             valid_l = loss(pre_valid, tensor_y)
  72.             valid_loss += valid_l.item() * len(tensor_x)
  73.             result = [1 if out >= 0.5 else 0 for out in pre_valid]
  74.             num_right += np.sum(np.array(result) == tensor_y.numpy().reshape(-1))

  75.         valid_loss = valid_loss / len(valid_iter.dataset)
  76.         valid_accuracy = num_right / len(valid_iter.dataset)

  77.         if epoch % 200 == 0:
  78.             print('Valid Loss: {} Accuracy: {} Epoch:{}'.format(valid_loss, valid_accuracy, epoch))

  79. #将每次迭代的结果写入列表
  80. loss_list.append(valid_loss)
  81. acc_list.append(valid_accuracy)

  82. print('Training Ended')
  83. print('Average Loss: {} Average Accuracy: {}'.format(np.mean(loss_list), np.mean(acc_list)))
复制代码


数据的特征和标签类型是tensor,转换为numpy后形状分别是
  1. X_train.values.shape,y_train.values.shape,X_valid.values.shape,y_valid.values.shape
复制代码

((569, 12), (569,), (143, 12), (143,))

训练模型代码报错如下
  1. ---------------------------------------------------------------------------
  2. TypeError                                 Traceback (most recent call last)
  3. Cell In[63], line 47
  4.      43 num_epochs = 1000
  5.      46 #创建数据集
  6. ---> 47 train_dataset = data.TensorDataset(X_train, y_train)
  7.      48 valid_dataset = data.TensorDataset(X_valid, y_valid)
  8.      50 # 获取一个数据迭代器

  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. File /opt/conda/lib/python3.10/site-packages/torch/utils/data/dataset.py:204, in <genexpr>(.0)
  14.     203 def __init__(self, *tensors: Tensor) -> None:
  15. --> 204     assert all(tensors[0].size(0) == tensor.size(0) for tensor in tensors), "Size mismatch between tensors"
  16.     205     self.tensors = tensors

  17. TypeError: 'int' object is not callable
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-10-22 22:24:36 | 显示全部楼层
Terence888 发表于 2024-10-22 22:21
#dnn模型(train_test_split)
import torch
import  ...


您遇到的错误是因为 `data.TensorDataset` 的参数需要是 PyTorch 张量类型。在构造 `TensorDataset` 时,请确保 `X_train` 和 `y_train` 是 PyTorch 张量,而不是 NumPy 数组或其他类型。以下是解决方案:

1. **确保数据是 PyTorch 张量**:

  
  1. X_train = torch.tensor(X_train.values, dtype=torch.float32)
  2.    y_train = torch.tensor(y_train.values, dtype=torch.float32)
  3.    X_valid = torch.tensor(X_valid.values, dtype=torch.float32)
  4.    y_valid = torch.tensor(y_valid.values, dtype=torch.float32)
复制代码


2. **创建数据集**:
   
  
  1. train_dataset = data.TensorDataset(X_train, y_train)
  2.    valid_dataset = data.TensorDataset(X_valid, y_valid)
复制代码


3. **检查一致性**:
   确保 `X_train` 和 `y_train` 的第一个维度大小相同,即样本数量保持一致。

请按照这些步骤确保数据类型和维度一致性。

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

使用道具 举报

 楼主| 发表于 2024-10-22 22:40:18 | 显示全部楼层
FishC 发表于 2024-10-22 22:24
您遇到的错误是因为 `data.TensorDataset` 的参数需要是 PyTorch 张量类型。在构造 `TensorDataset` 时 ...
  1. #dnn模型(train_test_split)
  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. simple_dnn_model = SimpleNN()
  30. loss = nn.BCELoss() #定义损失函数
  31. optimizer = optim.Adam(nn_model.parameters(),lr=0.0001) #定义优化器

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

  35. #将DataFrame数据转换为NumPy数组,然后再转换为PyTorch张量
  36. X_train = torch.tensor(X_train.astype(np.float32).values, dtype=torch.float32)
  37. y_train = torch.tensor(y_train.astype(np.float32).values, dtype=torch.float32)
  38. X_valid = torch.tensor(X_valid.astype(np.float32).values, dtype=torch.float32)
  39. y_valid = torch.tensor(y_valid.astype(np.float32).values, dtype=torch.float32)

  40.    
  41. #创建数据集
  42. train_dataset = data.TensorDataset(X_train, y_train)
  43. valid_dataset = data.TensorDataset(X_valid, y_valid)

  44. # 获取一个数据迭代器
  45. train_iter = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True,num_workers=2)#shuffle=True相当于sampler=RandomSampler(dataset)
  46. valid_iter = DataLoader(dataset=valid_dataset,batch_size=batch_size,shuffle=True,num_workers=2)

  47. # 开始训练
  48. batch_size = 99
  49. num_epochs = 1000
  50. #开始迭代
  51. for epoch in range(num_epochs):
  52.     train_loss = 0
  53.     num_right = 0
  54.     for tensor_x, tensor_y in train_iter:#训练集执行梯度更新
  55.         tensor_x = tensor_x.float()
  56.         tensor_y = tensor_y.float().reshape(-1, 1)
  57.         optimizer.zero_grad() #梯度清零
  58.         pre_train = simple_dnn_model(tensor_x)
  59.         train_l = loss(pre_train, tensor_y) #损失应避免与全局变量loss重名
  60.         train_l.backward()#前向传播
  61.         optimizer.step()#梯度下降

  62.         train_loss += train_l.item() * len(tensor_x)#批量损失
  63.         result = [1 if out >= 0.5 else 0 for out in pre_train]
  64.         num_right += np.sum(np.array(result) == tensor_y.numpy().reshape(-1))

  65.         train_loss = train_loss / len(train_iter.dataset)
  66.         train_accuracy = num_right / len(train_iter.dataset)

  67.     if epoch % 200 == 0:
  68.         print('Loss: {} Accuracy: {} Epoch:{}'.format(train_loss, train_accuracy, epoch))

  69.     with torch.no_grad():
  70.         valid_loss = 0
  71.         num_right = 0
  72.         for tensor_x, tensor_y in valid_iter:
  73.             tensor_x = tensor_x.float()
  74.             tensor_y = tensor_y.float().reshape(-1, 1)
  75.             pre_valid = simple_dnn_model(tensor_x)
  76.             valid_l = loss(pre_valid, tensor_y)
  77.             valid_loss += valid_l.item() * len(tensor_x)
  78.             result = [1 if out >= 0.5 else 0 for out in pre_valid]
  79.             num_right += np.sum(np.array(result) == tensor_y.numpy().reshape(-1))

  80.         valid_loss = valid_loss / len(valid_iter.dataset)
  81.         valid_accuracy = num_right / len(valid_iter.dataset)

  82.         if epoch % 200 == 0:
  83.             print('Valid Loss: {} Accuracy: {} Epoch:{}'.format(valid_loss, valid_accuracy, epoch))

  84. #将每次迭代的结果写入列表
  85. loss_list.append(valid_loss)
  86. acc_list.append(valid_accuracy)

  87. print('Training Ended')
  88. print('Average Loss: {} Average Accuracy: {}'.format(np.mean(loss_list), np.mean(acc_list)))
复制代码


上述代码存在什么问题导致预测准确率过低
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-10-22 22:40:32 | 显示全部楼层
Terence888 发表于 2024-10-22 22:40
#dnn模型(train_test_split)
import torch
import  ...


在该代码中,有一些地方可能会影响模型的性能和准确性。以下是检查和改进的建议:

1. **初始化列表**:
   - 确保 `acc_list` 和 `loss_list` 被正确初始化,例如使用空列表 `acc_list = []` 和 `loss_list = []`。

2. **未定义变量**:
   - `nn_model` 应替换为 `simple_dnn_model`。

3. **结果计算**:
   - 需要实现对 `result` 的计算。可以将预测值转化为二进制类别,例如:`result = (pre_train > 0.5).float()`。

4. **数据标准化**:
   - 确保输入数据经过标准化或归一化,以便网络更好地学习。

5. **学习率调整**:
   - 调整 `optimizer` 的学习率(`lr=0.0001`),可能较低或较高的学习率都会影响网络的收敛。

6. **批量大小和迭代次数**:
   - 尝试不同的 `batch_size` 和 `num_epochs` 以找到最佳组合。

7. **网络架构和过拟合**:
   - 使用较小的网络或正则化技术,减少过拟合。

如果尝试这些改进后,仍发现准确度低,可以尝试进一步探索数据集特性或网络结构。

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

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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