Terence888 发表于 2024-10-24 23:38:23

损失上百万如何解决


#使用dnn模型(k折交叉验证)
import torch
import torch.nn as nn
from torch.utils import data
from torch.utils.data import Dataset,DataLoader
from torch import optim

#定义神经网络模型
dropout1, dropout2 = 0.3, 0.6
class SimpleNN(nn.Module):
    def __init__(self):
      super(SimpleNN, self).__init__()# 继承需要用 SimpleNN
      self.dense = nn.Sequential(
            nn.Flatten(),
            nn.Linear(154, 256),
            nn.ReLU(),
            nn.Dropout(dropout1),
            nn.Linear(256, 128),
            nn.ReLU(),
            nn.Dropout(dropout2),
            nn.Linear(128, 1),
      )
      
    def forward(self, X):
      output = self.dense(X)
      return output
   
#初始化模型和优化器
dnn_model = SimpleNN()
loss = nn.MSELoss() #定义损失函数
optimizer = optim.Adam(dnn_model.parameters(),lr=0.0001,weight_decay=0) #定义优化器


#k折交叉验证选取训练集与验证集
def get_k_fold_data(k, i, X, y):
    assert k > 1
    fold_size = len(X) // k
    X_train, y_train = None, None
    for j in range(k):
      start = j * fold_size
      end = (j + 1) * fold_size
      if j == i:
            X_valid, y_valid = X.iloc, y.iloc
      elif X_train is None:
            X_train, y_train = X.iloc, y.iloc
      else:
            X_train = pd.concat(], ignore_index=True)
            y_train = pd.concat(], ignore_index=True)
    return X_train, y_train, X_valid, y_valid


# 开始训练
k = 5
batch_size = 64
num_epochs = 100
#weight_decay = 0

#初始化损失
train_l_sum, valid_l_sum = 0, 0

#初始化列表
train_ls, valid_ls = [], []

for i in range(k):
    X_train, y_train, X_valid, y_valid = get_k_fold_data(k, i, X, y)
    print(f'FOLD {i}')
    print('--------------------------------')
   

    #将DataFrame数据转换为NumPy数组,然后再转换为PyTorch张量
    X_train = torch.tensor(X_train.astype(np.float32).values, dtype=torch.float32)
    y_train = torch.tensor(y_train.astype(np.float32).values, dtype=torch.float32)
    X_valid = torch.tensor(X_valid.astype(np.float32).values, dtype=torch.float32)
    y_valid = torch.tensor(y_valid.astype(np.float32).values, dtype=torch.float32)
   
    #创建数据集
    train_dataset = data.TensorDataset(X_train, y_train)
    valid_dataset = data.TensorDataset(X_valid, y_valid)

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

            train_loss += train_l.item() * len(tensor_x) #批量规模损失累加
            
      train_loss /= len(tensor_x) #每次迭代平均损失
      
      if epoch % 20 == 0:
            print('Loss: {}Epoch:{}'.format(train_loss, epoch))
      
      with torch.no_grad():
            valid_loss = 0
            
            for tensor_x, tensor_y in valid_iter:
                tensor_x = tensor_x.float()
                tensor_y = tensor_y.float().reshape(-1, 1)
                pre_valid = dnn_model(tensor_x)
                valid_l = loss(pre_valid, tensor_y)
                valid_loss += valid_l.item() * len(tensor_x)
                  
            valid_loss /= len(tensor_x)
                  
            if epoch % 20 == 0:
                print('Valid Loss: {}Epoch:{}'.format(valid_loss, epoch))
      
    #将每折的损失添加到列表中
    train_ls.append(train_loss)
    valid_ls.append(valid_loss)

      
print('Training Ended')
print('Train Average Loss: {} Valid Average Loss: {}'.format(np.mean(train_l),np.mean(valid_l)))

结果FOLD 0
--------------------------------
Loss: 3789863458133.3335Epoch:0
Valid Loss: 320499525807.54285Epoch:0
Loss: 530483369472.0Epoch:200
Valid Loss: 33814231434.971428Epoch:200
Loss: 378945008640.0Epoch:400
Valid Loss: 30172513587.2Epoch:400
Loss: 341601432192.0Epoch:600
Valid Loss: 22432290753.82857Epoch:600

FishC 发表于 2024-10-24 23:38:29

训练损失和验证损失非常高,考虑几个可能的解决方案:

1. **数据标准化**:确保输入数据经过标准化处理。这可以通过减去均值并除以标准差实现。

2. **学习率调整**:当前学习率可能过高(或过低),尝试不同的学习率,比如使用学习率调度器逐步调整学习率。

3. **模型复杂度**:模型可能过于简单或复杂。可以试着增加或减少网络层数和神经元数量。

4. **正则化**:试着引入正则化(例如 L2 正则化)来减少过拟合。

5. **Batch Normalization**:在模型层之间加入批量归一化层,有助于稳定训练过程。

6. **数据质量和数量**:检查是否有异常数据或缺失值,确保数据集足够大并具有代表性。

7. **过拟合与欠拟合**:从训练与验证损失的差异和下降趋势判断模型是否过拟合或欠拟合。

按照这些方法逐步调试,观察每次修改对损失的影响,逐步改善模型性能。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-25 19:19:08

FishC 发表于 2024-10-24 23:38
训练损失和验证损失非常高,考虑几个可能的解决方案:

1. **数据标准化**:确保输入数据经过标准化处理 ...

上述代码写的有错吗

FishC 发表于 2024-10-25 19:19:23

Terence888 发表于 2024-10-25 19:19
上述代码写的有错吗

上面的代码有一些问题需要修正:

1. **`pd.concat`中的`X.iloc`和`y.iloc`**:
   - 在`get_k_fold_data`函数中,`X.iloc`和`y.iloc`需要指定行范围,比如`X.iloc`。

2. **`torch.tensor`应该用`X_train.values`**:
   - `torch.tensor`在转换DataFrame时应使用`X_train.values`而不是`X_train.astype(np.float32).values`。

3. **`train_ls, valid_ls`初始化**:
   - 应该初始化为空列表:`train_ls, valid_ls = [], []`。

4. **`len(tensor_x)`修正为`len(train_dataset)`或`len(valid_dataset)`**:
   - 计算损失平均值应使用完整数据集长度。

5. **损失命名**:
   - `train_l_sum`和`valid_l_sum`是多余的变量,如果不用可以删除。

6. **最后打印损失**:
   - 修正为:`np.mean(train_ls)`和`np.mean(valid_ls)`。

以下是修正后的代码示例:

import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
from torch import optim
import numpy as np
import pandas as pd

# 定义神经网络模型
dropout1, dropout2 = 0.3, 0.6

class SimpleNN(nn.Module):
    def __init__(self):
      super(SimpleNN, self).__init__()
      self.dense = nn.Sequential(
            nn.Flatten(),
            nn.Linear(154, 256),
            nn.ReLU(),
            nn.Dropout(dropout1),
            nn.Linear(256, 128),
            nn.ReLU(),
            nn.Dropout(dropout2),
            nn.Linear(128, 1),
      )

    def forward(self, X):
      return self.dense(X)

# 初始化模型和优化器
dnn_model = SimpleNN()
loss = nn.MSELoss()
optimizer = optim.Adam(dnn_model.parameters(), lr=0.0001, weight_decay=0)

# k折交叉验证
def get_k_fold_data(k, i, X, y):
    assert k > 1
    fold_size = len(X) // k
    X_train, y_train = None, None
    for j in range(k):
      start = j * fold_size
      end = (j + 1) * fold_size
      if j == i:
            X_valid, y_valid = X.iloc, y.iloc
      elif X_train is None:
            X_train, y_train = X.iloc, y.iloc
      else:
            X_train = pd.concat(], ignore_index=True)
            y_train = pd.concat(], ignore_index=True)
    return X_train, y_train, X_valid, y_valid

# 开始训练
k = 5
batch_size = 64
num_epochs = 100

train_ls, valid_ls = [], []

for i in range(k):
    X_train, y_train, X_valid, y_valid = get_k_fold_data(k, i, X, y)
    print(f'FOLD {i}')
    print('--------------------------------')

    X_train = torch.tensor(X_train.values, dtype=torch.float32)
    y_train = torch.tensor(y_train.values, dtype=torch.float32)
    X_valid = torch.tensor(X_valid.values, dtype=torch.float32)
    y_valid = torch.tensor(y_valid.values, dtype=torch.float32)

    train_dataset = TensorDataset(X_train, y_train)
    valid_dataset = TensorDataset(X_valid, y_valid)

    train_iter = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
    valid_iter = DataLoader(dataset=valid_dataset, batch_size=batch_size, shuffle=True)

    for epoch in range(num_epochs):
      train_loss = 0
      for tensor_x, tensor_y in train_iter:
            tensor_x = tensor_x.float()
            tensor_y = tensor_y.float().reshape(-1, 1)
            optimizer.zero_grad()
            pre_train = dnn_model(tensor_x)
            train_l = loss(pre_train, tensor_y)
            train_l.backward()
            optimizer.step()

            train_loss += train_l.item() * len(tensor_x)

      train_loss /= len(train_dataset)

      if epoch % 20 == 0:
            print(f'Loss: {train_loss}Epoch:{epoch}')

      with torch.no_grad():
            valid_loss = 0
            for tensor_x, tensor_y in valid_iter:
                tensor_x = tensor_x.float()
                tensor_y = tensor_y.float().reshape(-1, 1)
                pre_valid = dnn_model(tensor_x)
                valid_l = loss(pre_valid, tensor_y)
                valid_loss += valid_l.item() * len(tensor_x)

            valid_loss /= len(valid_dataset)

            if epoch % 20 == 0:
                print(f'Valid Loss: {valid_loss}Epoch:{epoch}')

    train_ls.append(train_loss)
    valid_ls.append(valid_loss)

print('Training Ended')
print('Train Average Loss: {} Valid Average Loss: {}'.format(np.mean(train_ls), np.mean(valid_ls)))

如果问题仍持续,检查数据的质量和适用性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-25 19:40:42

FishC 发表于 2024-10-25 19:19
上面的代码有一些问题需要修正:

1. **`pd.concat`中的`X.iloc`和`y.iloc`**:


FOLD 0
--------------------------------
Loss: 97.42294922967751Epoch:0
Valid Loss: 6.524005912031446Epoch:0
Loss: 16.883943930268288Epoch:20
Valid Loss: 1.2612734511494637Epoch:20
Loss: 12.02363520860672Epoch:40
Valid Loss: 1.4185494550636837Epoch:40
Loss: 10.411116076012453Epoch:60
Valid Loss: 1.0686074222837176Epoch:60
Loss: 10.3524863148729Epoch:80
Valid Loss: 1.3295930474996567Epoch:80
FOLD 1
--------------------------------
Loss: 9.407793649161855Epoch:0
Valid Loss: 0.7865632244518825Epoch:0
Loss: 7.4260556523998575Epoch:20
Valid Loss: 0.8285839977008956Epoch:20
Loss: 7.77119686237226Epoch:40
Valid Loss: 0.8801546487425055Epoch:40
Loss: 7.2721458574136095Epoch:60
Valid Loss: 0.8985730343631335Epoch:60
Loss: 7.1905520757039385Epoch:80
Valid Loss: 0.8706890802298274Epoch:80
FOLD 2
--------------------------------
Loss: 7.54795270661513Epoch:0
Valid Loss: 0.6300470565046583Epoch:0
Loss: 6.906829031805198Epoch:20
Valid Loss: 1.0208279056208474Epoch:20
Loss: 7.556330171103279Epoch:40
Valid Loss: 0.7214151620864868Epoch:40
Loss: 5.766326169172923Epoch:60
Valid Loss: 0.9135981251086508Epoch:60
Loss: 5.499882264683644Epoch:80
Valid Loss: 0.5656084013836724Epoch:80
FOLD 3
--------------------------------
Loss: 5.7565529346466064Epoch:0
Valid Loss: 0.41647012499826297Epoch:0
Loss: 5.3368079115947085Epoch:20
Valid Loss: 0.5377804839185306Epoch:20
Loss: 5.869775238136451Epoch:40
Valid Loss: 0.6251639655658177Epoch:40
Loss: 5.750744904081027Epoch:60
Valid Loss: 0.38832607098988126Epoch:60
Loss: 6.132762424647808Epoch:80
Valid Loss: 0.5039193288023983Epoch:80
FOLD 4
--------------------------------
Loss: 4.891226700196664Epoch:0
Valid Loss: 0.44391103706189566Epoch:0
Loss: 4.8997232268253965Epoch:20
Valid Loss: 0.4042023944003241Epoch:20
Loss: 4.657132951542735Epoch:40
Valid Loss: 0.521915601832526Epoch:40
Loss: 5.400473614611353Epoch:60
Valid Loss: 0.5404082979474749Epoch:60

验证集损失低于训练集是什么原因

FishC 发表于 2024-10-25 19:40:51

Terence888 发表于 2024-10-25 19:40
FOLD 0
--------------------------------
Loss: 97 ...

验证集损失低于训练集的情况可以通过以下方面进行分析:

1. **数据不均衡**:
   - 验证集可能比训练集更简单,或训练集包含更多的噪声。

2. **正则化**:
   - 正则化可能在训练集上发挥过度作用,限制了模型的学习能力。

3. **小样本问题**:
   - 数据量较小时,不同数据集之间的损失差异可能较大。

4. **过拟合初期**:
   - 在训练初期,模型可能暂时在验证集上表现好,但随着训练深入,可能会反弹。

5. **数据分割**:
   - 检查数据分割的方法,确保训练集和验证集的分配方式和数据分布一致。

可以采取以下措施进行进一步验证和调整:

- 增加训练数据。
- 重新检查数据集的分配,确保其合理性。
- 尝试不同的模型架构和超参数设置。
- 使用交叉验证来更全面地评估模型性能。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-25 20:50:06

FishC 发表于 2024-10-25 19:40
验证集损失低于训练集的情况可以通过以下方面进行分析:

1. **数据不均衡**:


full_dataset.fillna(0)
full_dataset.select_dtypes().mean()

---------------------------------------------------------------------------
ValueError                              Traceback (most recent call last)
/tmp/ipykernel_30/2491567194.py in ?()
      1 full_dataset.fillna(0)
----> 2 full_dataset.select_dtypes().mean()

/opt/conda/lib/python3.10/site-packages/pandas/core/frame.py in ?(self, include, exclude)
   5038
   5039         selection = (frozenset(include), frozenset(exclude))
   5040
   5041         if not any(selection):
-> 5042             raise ValueError("at least one of include or exclude must be nonempty")
   5043
   5044         # convert the myriad valid dtypes object to a single representation
   5045         def check_int_infer_dtype(dtypes):

ValueError: at least one of include or exclude must be nonempty
要求数值型特征的平均值,并对其进行从大到小排序

FishC 发表于 2024-10-25 20:50:17

Terence888 发表于 2024-10-25 20:50
full_dataset.fillna(0)
full_dataset.select_dtypes ...

要对数据集中所有数值型特征的平均值进行计算,并按照从大到小的顺序进行排序,可以按照以下步骤进行操作:

1. 使用 `fillna(0)` 对数据集中所有缺失值填充为 0。
2. 使用 `select_dtypes(include=['number'])` 选择出所有数值型列。
3. 使用 `mean()` 计算每个数值型列的平均值。
4. 使用 `sort_values(ascending=False)` 对这些平均值从大到小排序。

以下是完整的代码示例:

import pandas as pd

# 假设 full_dataset 是你的 DataFrame
# 使用 fillna(0) 方法填充缺失值
full_dataset = full_dataset.fillna(0)

# 选择所有数值型列,并计算它们的平均值,然后进行排序
numeric_means = full_dataset.select_dtypes(include=['number']).mean().sort_values(ascending=False)

print(numeric_means)

这个代码示例会首先填充数据集中的所有缺失值,然后选择所有数值型列,并计算这些列的平均值,最后将这些平均值按照从大到小的顺序进行排序并输出。

如果你的数据集不包含任何数值型列,这个操作仍将产生错误。再次确保你的数据集中确实包含数值型列,并正确地使用上述步骤。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-25 22:32:16

FishC 发表于 2024-10-25 19:40
验证集损失低于训练集的情况可以通过以下方面进行分析:

1. **数据不均衡**:



#使用dnn模型(k折交叉验证)
import torch
import torch.nn as nn
from torch.utils import data
from torch.utils.data import Dataset,DataLoader
from torch import optim

#定义神经网络模型
dropout1, dropout2 = 0.2, 0.2
class SimpleNN(nn.Module):
    def __init__(self):
      super(SimpleNN, self).__init__()# 继承需要用 SimpleNN
      self.dense = nn.Sequential(
            nn.Flatten(),
            nn.Linear(154, 256),
            nn.ReLU(),
            nn.Dropout(dropout1),
            nn.Linear(256, 128),
            nn.ReLU(),
            nn.Dropout(dropout2),
            nn.Linear(128, 1),
      )
      
    def forward(self, X):
      output = self.dense(X)
      return output
   
#初始化模型和优化器
dnn_model = SimpleNN()
loss = nn.MSELoss() #定义损失函数
optimizer = optim.Adam(dnn_model.parameters(),lr=0.0001,weight_decay=0) #定义优化器


#k折交叉验证选取训练集与验证集
def get_k_fold_data(k, i, X, y):
    assert k > 1
    fold_size = len(X) // k
    X_train, y_train = None, None
    for j in range(k):
      start = j * fold_size
      end = (j + 1) * fold_size
      if j == i:
            X_valid, y_valid = X.iloc, y.iloc
      elif X_train is None:
            X_train, y_train = X.iloc, y.iloc
      else:
            X_train = pd.concat(], ignore_index=True)
            y_train = pd.concat(], ignore_index=True)
    return X_train, y_train, X_valid, y_valid


# 开始训练
k = 5
batch_size = 64
num_epochs = 100
#weight_decay = 0

#初始化损失
train_l_sum, valid_l_sum = 0, 0

#初始化列表
train_ls, valid_ls = [], []

for i in range(k):
    X_train, y_train, X_valid, y_valid = get_k_fold_data(k, i, X, y)
    print(f'FOLD {i}')
    print('--------------------------------')
   

    #将DataFrame数据转换为NumPy数组,然后再转换为PyTorch张量
    X_train = torch.tensor(X_train.astype(np.float32).values, dtype=torch.float32)
    y_train = torch.tensor(y_train.astype(np.float32).values, dtype=torch.float32)
    X_valid = torch.tensor(X_valid.astype(np.float32).values, dtype=torch.float32)
    y_valid = torch.tensor(y_valid.astype(np.float32).values, dtype=torch.float32)
   
    #创建数据集
    train_dataset = data.TensorDataset(X_train, y_train)
    valid_dataset = data.TensorDataset(X_valid, y_valid)

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

            train_loss += train_l.item() * len(tensor_x) #批量规模损失累加
            
      train_loss /= len(tensor_x) #每次迭代平均损失
      
      if epoch % 20 == 0:
            print('Loss: {}Epoch:{}'.format(train_loss, epoch))
      
      with torch.no_grad():
            valid_loss = 0
            
            for tensor_x, tensor_y in valid_iter:
                tensor_x = tensor_x.float()
                tensor_y = tensor_y.float().reshape(-1, 1)
                pre_valid = dnn_model(tensor_x)
                valid_l = loss(pre_valid, tensor_y)
                valid_loss += valid_l.item() * len(tensor_x)
                  
            valid_loss /= len(tensor_x)
                  
            if epoch % 20 == 0:
                print('Valid Loss: {}Epoch:{}'.format(valid_loss, epoch))
      
    #将每折的损失添加到列表中
    train_ls.append(train_loss)
    valid_ls.append(valid_loss)

      
print('Training Ended')
print('Train Average Loss: {} Valid Average Loss: {}'.format(np.mean(train_ls),np.mean(valid_ls)))

上述模型如何减小正则化

FishC 发表于 2024-10-25 22:45:22

Terence888 发表于 2024-10-25 22:32
#使用dnn模型(k折交叉验证)
import torch
import ...

在您的代码中,可以通过以下方式调整正则化来减少其影响:

1. **权重衰减(weight decay)**:
   - 在优化器中 `weight_decay` 参数设置为小于当前的值,例如 `weight_decay=0.0001`。如果设置为 0,则完全没有正则化。

2. **Dropout**:
   - 减小 Dropout 率,可以减小正则化。例如,设置 `dropout1, dropout2` 为 0.1。

以下是修改的代码示例:

# 初始化模型和优化器
dropout1, dropout2 = 0.1, 0.1# 更新 Dropout 率
dnn_model = SimpleNN()
optimizer = optim.Adam(dnn_model.parameters(), lr=0.0001, weight_decay=0.0001)# 调整 weight_decay

通过这些调整,您可以减小模型的正则化效果,从而可能改善训练集的表现。但同时要小心不要过拟合,必要时可以通过交叉验证进行评估。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-25 23:26:09

FishC 发表于 2024-10-25 22:45
在您的代码中,可以通过以下方式调整正则化来减少其影响:

1. **权重衰减(weight decay)**:



#tensor_test_x = torch.FloatTensor(X_test)

with torch.no_grad():
    test_output = dnn_model(X_test)
    submission = pd.DataFrame({'PassengerId': X_test['PassengerId'], 'SalePrice': test_output})
    submission.to_csv('submission.csv', index=False)

提交答案时碰到以下问题---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_30/3230020909.py in ?()
      1 #tensor_test_x = torch.FloatTensor(X_test)
      2
      3 with torch.no_grad():
----> 4   test_output = dnn_model(X_test)
      5   submission = pd.DataFrame({'PassengerId': X_test['PassengerId'], 'SalePrice': test_output})
      6   submission.to_csv('submission.csv', index=False)

/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py in ?(self, *args, **kwargs)
   1549   def _wrapped_call_impl(self, *args, **kwargs):
   1550         if self._compiled_call_impl is not None:
   1551             return self._compiled_call_impl(*args, **kwargs)# type: ignore
   1552         else:
-> 1553             return self._call_impl(*args, **kwargs)

/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py in ?(self, *args, **kwargs)
   1558         # this function, and just call forward.
   1559         if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
   1560               or _global_backward_pre_hooks or _global_backward_hooks
   1561               or _global_forward_hooks or _global_forward_pre_hooks):
-> 1562             return forward_call(*args, **kwargs)
   1563
   1564         try:
   1565             result = None

/tmp/ipykernel_30/2794702383.py in ?(self, X)
   24   def forward(self, X):
---> 25         output = self.dense(X)
   26         return output

/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py in ?(self, *args, **kwargs)
   1549   def _wrapped_call_impl(self, *args, **kwargs):
   1550         if self._compiled_call_impl is not None:
   1551             return self._compiled_call_impl(*args, **kwargs)# type: ignore
   1552         else:
-> 1553             return self._call_impl(*args, **kwargs)

/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py in ?(self, *args, **kwargs)
   1558         # this function, and just call forward.
   1559         if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
   1560               or _global_backward_pre_hooks or _global_backward_hooks
   1561               or _global_forward_hooks or _global_forward_pre_hooks):
-> 1562             return forward_call(*args, **kwargs)
   1563
   1564         try:
   1565             result = None

/opt/conda/lib/python3.10/site-packages/torch/nn/modules/container.py in ?(self, input)
    217   def forward(self, input):
    218         for module in self:
--> 219             input = module(input)
    220         return input

/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py in ?(self, *args, **kwargs)
   1549   def _wrapped_call_impl(self, *args, **kwargs):
   1550         if self._compiled_call_impl is not None:
   1551             return self._compiled_call_impl(*args, **kwargs)# type: ignore
   1552         else:
-> 1553             return self._call_impl(*args, **kwargs)

/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py in ?(self, *args, **kwargs)
   1558         # this function, and just call forward.
   1559         if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
   1560               or _global_backward_pre_hooks or _global_backward_hooks
   1561               or _global_forward_hooks or _global_forward_pre_hooks):
-> 1562             return forward_call(*args, **kwargs)
   1563
   1564         try:
   1565             result = None

/opt/conda/lib/python3.10/site-packages/torch/nn/modules/flatten.py in ?(self, input)
   49   def forward(self, input: Tensor) -> Tensor:
---> 50         return input.flatten(self.start_dim, self.end_dim)

/opt/conda/lib/python3.10/site-packages/pandas/core/generic.py in ?(self, name)
   6295             and name not in self._accessors
   6296             and self._info_axis._can_hold_identifiers_and_holds_name(name)
   6297         ):
   6298             return self
-> 6299         return object.__getattribute__(self, name)

AttributeError: 'DataFrame' object has no attribute 'flatten'

FishC 发表于 2024-10-25 23:31:24

Terence888 发表于 2024-10-25 23:26
#tensor_test_x = torch.FloatTensor(X_test)

with ...

错误的原因是您尝试将一个 pandas DataFrame 对象传递给模型。但是模型期望输入的是 PyTorch 张量。您需要先将 DataFrame 转换为张量。

这里是修正后的代码示例:

import torch
import pandas as pd

# 假设 X_test 是 pandas DataFrame
X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)

with torch.no_grad():
    test_output = dnn_model(X_test_tensor)
    # 将张量转换为 numpy 数组
    test_output_numpy = test_output.numpy().flatten()
    submission = pd.DataFrame({'PassengerId': X_test.index, 'SalePrice': test_output_numpy})
    submission.to_csv('submission.csv', index=False)

注意事项:
- 确保 `X_test` 转换为 PyTorch 张量前已去除可能的缺失值。
- 使用 `flatten()` 来将输出张量转换为一维,以符合输出格式要求。
- 使用 `X_test.index` 来填充 `PassengerId`,假设其代表唯一标识符。根据需要进行调整。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-26 12:11:11

FishC 发表于 2024-10-25 23:31
错误的原因是您尝试将一个 pandas DataFrame 对象传递给模型。但是模型期望输入的是 PyTorch 张量。您 ...

#模型期望输入的是PyTorch 张量,先将 DataFrame 转换为张量
X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)


with torch.no_grad():
    test_output = dnn_model(X_test_tensor)
    test_output_numpy = test_output.numpy().flatten() # 将张量转换为 numpy 数组
    submission = pd.DataFrame({'Id': X_test['Id'], 'SalePrice': test_output})
    submission.to_csv('submission.csv', index=False)
代码报错
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In, line 2
      1 #模型期望输入的是PyTorch 张量,先将 DataFrame 转换为张量
----> 2 X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)
      5 with torch.no_grad():
      6   test_output = dnn_model(X_test_tensor)

TypeError: can't convert np.ndarray of type numpy.object_. The only supported types are: float64, float32, float16, complex64, complex128, int64, int32, int16, int8, uint64, uint32, uint16, uint8, and bool.

FishC 发表于 2024-10-26 12:11:23

Terence888 发表于 2024-10-26 12:11
#模型期望输入的是PyTorch 张量,先将 DataFrame 转换 ...

此错误通常是因为 `X_test` 数据框中包含了一些非数值型数据,例如字符串或对象。为了避免此问题,可以先检查并确保 `X_test` 中所有列都为数值型。

以下是具体的解决方法:

1. **检查并转换非数值型数据**:确保所有数据列都为数值型。
2. **填写缺失值**:处理数据中的缺失值。

可以使用以下代码来进行预处理:

import pandas as pd
import torch

# 确保所有列都是数值型数据
X_test = X_test.apply(pd.to_numeric, errors='coerce').fillna(0)

# 转换为 PyTorch 张量
X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)

with torch.no_grad():
    test_output = dnn_model(X_test_tensor)
    test_output_numpy = test_output.numpy().flatten() # 将张量转换为 numpy 数组
   
    # 假设 X_test 有一个索引可以作为 'Id'
    submission = pd.DataFrame({'Id': X_test.index, 'SalePrice': test_output_numpy})
    submission.to_csv('submission.csv', index=False)

print("Submission file created successfully.")

注意事项:
- `apply(pd.to_numeric, errors='coerce').fillna(0)` 将所有非数值型数据转换为 NaN 并用 0 填充。
- `X_test.index` 用在 `submission` 中作为 'Id',假定这是合理的唯一标识符。如果 `X_test` 中确实需要特定的列作为 'Id',应根据实际需要进行调整。

希望这些修改能解决您的问题!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-26 12:41:24

FishC 发表于 2024-10-26 12:11
此错误通常是因为 `X_test` 数据框中包含了一些非数值型数据,例如字符串或对象。为了避免此问题,可以 ...

如何观察array数组X_test是否有非数值型数据

FishC 发表于 2024-10-26 12:42:36

Terence888 发表于 2024-10-26 12:41
如何观察array数组X_test是否有非数值型数据

要检查 `X_test` 数组中是否有非数值型数据,可以使用以下方法:

1. **检查数据类型**:
   - 用 `dtypes` 查看每列的数据类型,确保是数值型。

print(X_test.dtypes)

2. **查找非数值型数据**:
   - 使用 `select_dtypes` 选择非数值型数据。

non_numeric_columns = X_test.select_dtypes(exclude=).columns
print("Non-numeric columns:", non_numeric_columns)

3. **查看示例值**:
   - 使用 `head()` 查看每列的前几个值,确认是否有异常。

print(X_test.head())

如果列出了非数值型列,您可以考虑使用以下方法将其转换为数值:

- **使用编码**:将分类数据转换为数值,例如用 `pd.get_dummies()`。
- **转化类型**:使用 `astype` 转换列的数据类型。

确认所有列为数值型后,再进行后续的张量转换操作。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-26 15:44:32

FishC 发表于 2024-10-26 12:42
要检查 `X_test` 数组中是否有非数值型数据,可以使用以下方法:

1. **检查数据类型**:


bool类型被识别为object类型怎么办

FishC 发表于 2024-10-26 15:44:39

Terence888 发表于 2024-10-26 15:44
bool类型被识别为object类型怎么办

如果布尔类型的列被识别为 `object` 类型,可以通过以下步骤将其转换为数值类型:

1. **使用 `astype` 转换为布尔型**:
   - 先将 `object` 类型转换为布尔类型。

X_test['your_column_name'] = X_test['your_column_name'].astype(bool)

2. **将布尔型转换为数值型**:
   - 将布尔型(`True`/`False`)转换为数值型(`1`/`0`)。

X_test['your_column_name'] = X_test['your_column_name'].astype(int)

3. **批量处理所有布尔类型的列**:
   - 找到所有 `object` 列并尝试转换。

for col in X_test.columns:
    if X_test.dtype == 'object':
      X_test = X_test.astype(bool).astype(int)

通过这些步骤,所有布尔值列将被转换为数值型,确保后续的处理不会遇到数据类型问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

Terence888 发表于 2024-10-26 16:02:35

FishC 发表于 2024-10-26 15:44
如果布尔类型的列被识别为 `object` 类型,可以通过以下步骤将其转换为数值类型:

1. **使用 `astyp ...

#模型期望输入的是PyTorch 张量,先将 DataFrame 转换为张量
X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)

with torch.no_grad():
    test_output = dnn_model(X_test_tensor)
    test_output_numpy = test_output.numpy().flatten() # 将张量转换为 numpy 数组
    submission = pd.DataFrame({'Id': X_test['Id'], 'SalePrice': test_output})
    #submission.to_csv('submission.csv', index=False)

报错---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In, line 2
      1 #模型期望输入的是PyTorch 张量,先将 DataFrame 转换为张量
----> 2 X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)
      4 with torch.no_grad():
      5   test_output = dnn_model(X_test_tensor)

TypeError: can't convert np.ndarray of type numpy.object_. The only supported types are: float64, float32, float16, complex64, complex128, int64, int32, int16, int8, uint64, uint32, uint16, uint8, and bool.

FishC 发表于 2024-10-26 16:02:48

Terence888 发表于 2024-10-26 16:02
#模型期望输入的是PyTorch 张量,先将 DataFrame 转换 ...

出现这个错误的原因是数据框 `X_test` 仍然包含一些无法转换为数值型的数据。我们需要对 `X_test` 做进一步检查和转换。以下是具体步骤:

1. 检查 `X_test` 中的非数值型数据。
2. 将所有列转换为数值型,如果有需要,根据数据情况处理布尔型等列。

可以使用以下代码来确保 `X_test` 中的所有列都是数值型数据:

import pandas as pd
import numpy as np
import torch

# 假设 X_test 是你的 DataFrame

# 1. 检查所有列的数据类型
print(X_test.dtypes)

# 2. 将所有object类型尝试转换为数值型,如果无法转换则用0替换
X_test = X_test.apply(pd.to_numeric, errors='coerce').fillna(0)

# 3. 再次检查数据类型,确保所有列都是数值型
print(X_test.dtypes)

# 4. 转换为 PyTorch 张量
X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)

# 5. 进行预测
with torch.no_grad():
    test_output = dnn_model(X_test_tensor)
    test_output_numpy = test_output.numpy().flatten()# 将张量转换为 numpy 数组
   
    # 假设 X_test 有一个 Id 列用于唯一标识,如果没有需要自行定义
    submission = pd.DataFrame({'Id': X_test.index, 'SalePrice': test_output_numpy})
    submission.to_csv('submission.csv', index=False)

print("Submission file created successfully.")

注意事项:

1. **处理缺失值**:使用 `fillna(0)` 将缺失值替换为 0。
2. **`Id` 列**:确保 `Id` 列存在并且能用于唯一标识每一行;如果没有,可以使用 `X_test.index` 作为标识符。

以上代码段将确保 `X_test` 中的所有列都是数值型数据,并能够正确转换为 PyTorch 张量进行预测。这样就不会再出现类型错误。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1] 2
查看完整版本: 损失上百万如何解决