鱼C论坛

 找回密码
 立即注册
查看: 785|回复: 14

预测函数报错,长度不对

[复制链接]
发表于 2024-11-7 10:25:43 | 显示全部楼层 |阅读模式

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

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

x
  1. /tmp/ipykernel_30/1399239022.py:2: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at /usr/local/src/pytorch/torch/csrc/utils/tensor_new.cpp:278.)
  2.   predictions = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)
  3. ---------------------------------------------------------------------------
  4. ValueError                                Traceback (most recent call last)
  5. Cell In[50], line 2
  6.       1 pre_valid = inference(model,valid_dataloader)
  7. ----> 2 predictions = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)

  8. ValueError: expected sequence of length 8 at dim 1 (got 7)
复制代码

报错如上,代码如下
  1. pre_valid = inference(model,valid_dataloader)
  2. predictions = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)
  3. result = [1 if x > 0.5 else 0 for x in predictions]
复制代码

是什么原因
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-7 10:31:00 | 显示全部楼层
根据错误信息和代码片段,问题可能出在张量的形状不匹配上。报错信息中提到在`softmax`函数执行时,期望的维度长度是8,而当前实际得到的长度是7。这通常意味着你的`pre_valid`输出的形状和预期的不一致。

可以采取以下步骤来排查和解决这个问题:

1. **检查`pre_valid`的输出形状**:
   你可以在调用`softmax`之前打印出`pre_valid`的形状,看看它实际是什么样的。

  
  1. pre_valid = inference(model, valid_dataloader)
  2.    print(pre_valid.shape)  # 输出形状进行检查
复制代码


2. **确认模型输出设置**:
   检查你的模型最后一层的输出设置,确保它的输出节点数量是期望的8个。如果不是,你可能需要根据任务(如分类的类别数)调整模型的结构。

3. **数据问题**:
   确保在`valid_dataloader`中,每个样本的预处理和数据加载过程没有问题,尤其是输入数据的形状和模型期望的输入形状一致。

4. **查看代码流程**:
   仔细检查整个推理(`inference`)和数据流经模型的过程,确认没有由于其他原因导致输出形状发生变化。

通过这些步骤,你应该能够逐步排查出问题所在,并进行相应的调整来修正错误。如果还有具体的代码需要进一步调试或者解释,欢迎提供更多细节。

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

使用道具 举报

发表于 2024-11-7 10:34:54 | 显示全部楼层
在将列表转换为 torch.tensor 之前,应确保列表中的所有元素都是相同维度的 numpy.ndarray。如果列表中的元素是 torch.Tensor,可以先将它们转换为 numpy.ndarray,然后再转换为 torch.tensor。
如果列表中的元素是 torch.Tensor,可以使用 torch.stack 来堆叠它们,而不是直接使用 torch.tensor。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-11-7 10:51:29 | 显示全部楼层
很cool的阳 发表于 2024-11-7 10:34
在将列表转换为 torch.tensor 之前,应确保列表中的所有元素都是相同维度的 numpy.ndarray。如果列表中的元 ...
  1. valid_eval_loader = DataLoader(valid_dataset,batch_size=8,shuffle=False,pin_memory=True,drop_last=True)
  2. pre_valid = inference(model,valid_eval_loader)
  3. predictions = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)
  4. result = [1 if x > 0.5 else 0 for x in predictions]
复制代码


predictions输出的形状是2列,报错如下
  1. ---------------------------------------------------------------------------
  2. RuntimeError                              Traceback (most recent call last)
  3. Cell In[59], line 4
  4.       2 pre_valid = inference(model,valid_eval_loader)
  5.       3 predictions = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)
  6. ----> 4 result = [1 if x > 0.5 else 0 for x in predictions]

  7. Cell In[59], line 4, in <listcomp>(.0)
  8.       2 pre_valid = inference(model,valid_eval_loader)
  9.       3 predictions = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)
  10. ----> 4 result = [1 if x > 0.5 else 0 for x in predictions]

  11. RuntimeError: Boolean value of Tensor with more than one value is ambiguous
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-7 11:02:14 | 显示全部楼层
Terence888 发表于 2024-11-7 10:51
predictions输出的形状是2列,报错如下

你需要对每个样本的概率值进行迭代,而不是对整个 predictions 张量进行迭代。你可以使用 predictions 张量的 .tolist() 方法将其转换为列表,然后对每个样本进行迭代,最后对每个样本的概率值进行比较。
predictions = torch.nn.functional.softmax(torch.tensor(pre_valid, dtype=torch.float32), dim=-1)
result = [1 if max(prob) > 0.5 else 0 for prob in predictions]
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-11-7 11:15:55 | 显示全部楼层
FishC 发表于 2024-11-7 10:31
根据错误信息和代码片段,问题可能出在张量的形状不匹配上。报错信息中提到在`softmax`函数执行时,期望的 ...
  1. valid_eval_loader = DataLoader(valid_dataset,batch_size=8,shuffle=False,pin_memory=True,drop_last=True)
  2. pre_valid = inference(model,valid_eval_loader)
  3. predictions = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)
  4. result = [1 if x > 0.5 else 0 for x in predictions]
复制代码

predictions的形状如下
  1. torch.Size([228, 8, 2])
复制代码

为什么是这个形状
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-7 11:16:08 | 显示全部楼层
Terence888 发表于 2024-11-07 11:15
valid_eval_loader = DataLoader(valid_dataset,batch ...


在你的代码中,你已经配置了`valid_eval_loader`的数据加载器,其中设置`batch_size`为8。如果每个样本对应一个输出,那么 `pre_valid` 应该是形如 `[batch_size, num_classes]` 的张量,其中 `num_classes` 是你的模型输出的类别数。此外,你提到 `torch.Size()` 时没有给出具体的大小,可能省略了一些内容,具体不详。

下面是一些检查方法,帮你解决输出形状问题:

1. **检查模型输出**:
   在 `inference` 函数内,确保每个 batch 的输出是符合预期的形状。你可以在执行预测时,打印模型输出的 shape:

  
  1. def inference(model, dataloader):
  2.        model.eval()
  3.        outputs = []
  4.        with torch.no_grad():
  5.            for data in dataloader:
  6.                # 假设 data 包含输入和标签
  7.                inputs, _ = data
  8.                output = model(inputs)
  9.                print(output.shape)  # 打印输出形状
  10.                outputs.append(output)
  11.        return torch.cat(outputs, dim=0)  # 根据需要拼接成完整的输出
复制代码


2. **确认类别数**:
   确定 `model` 的最后一层输出的节点数是否等于预期的类别数量(如你在调试输出时提到的 8)。

3. **预处理和数据集配置**:
   检查 `valid_dataset` 的配置,确保其输出是模型可以接受的输入形状和格式。

4. **打印预测结果形状**:
   
   在执行 `softmax` 函数前,打印 `pre_valid` 的形状:

  
  1. print(pre_valid.shape)  # 在进行 softmax 之前查看形状
复制代码


通过这些步骤,你可以更清楚地了解数据流在网络中的传递情况,以及查明为什么输出的形状和预期不符。如果 `torch.Size()` 输出为空,这可能表明输出的张量形状错误或未初始化,需要检查整个数据和模型的流程。

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

使用道具 举报

 楼主| 发表于 2024-11-7 11:27:30 | 显示全部楼层
FishC 发表于 2024-11-7 11:16
在你的代码中,你已经配置了`valid_eval_loader`的数据加载器,其中设置`batch_size`为8。如果每个样本 ...

predicitons的形状是三维张量,第一维数量是228,这表示什么
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-7 11:27:42 | 显示全部楼层
Terence888 发表于 2024-11-07 11:27
predicitons的形状是三维张量,第一维数量是228,这表 ...


在你的描述中,`predictions` 是一个三维张量,第一维的数量是 228。这通常表示在数据加载过程中,数据被分成了 228 个批次(batches)。具体来说:

- **第一维(228)**:通常代表批次的数量(batch size)。在你的数据集中,可能有 228 个批次的数据被处理。
- **第二维和第三维**:这些维度通常与每个样本的特征或模型输出的类别数相关。

如果 `predictions` 是模型的输出,那么:

- **第二维**:可能是每个批次中样本的数量(例如,你的 `batch_size` 设置为 8)。
- **第三维**:可能是模型输出的类别数(例如,分类任务中的类别数量)。

为了更准确地理解这些维度的含义,你可以查看模型的输出层和数据加载器的配置。这样可以帮助你确认每个维度在你的特定任务中代表的意义。

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

使用道具 举报

 楼主| 发表于 2024-11-7 11:53:55 | 显示全部楼层
FishC 发表于 2024-11-7 11:27
在你的描述中,`predictions` 是一个三维张量,第一维的数量是 228。这通常表示在数据加载过程中,数据 ...
  1. valid_eval_loader = DataLoader(valid_dataset,batch_size=8,shuffle=False,pin_memory=True,drop_last=True)
  2. pre_valid = inference(model,valid_eval_loader)
  3. predictions = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)
复制代码

  1. np.argmax(predictions,axis=2)
复制代码


要想得到二分类的结果,如何把经过softmax的概率值转化为0或1
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-7 11:54:04 | 显示全部楼层
Terence888 发表于 2024-11-07 11:53
valid_eval_loader = DataLoader(valid_dataset,batch ...


要将经过 softmax 得到的二分类概率值转化为 0 或 1 类别,可以使用 `argmax` 函数选择概率较大的类别索引。

对于二分类问题,通常 softmax 的输出会是形状为 (batch_size, num_classes) 的二维张量,其中 `num_classes` 应该为 2。你可以通过以下步骤实现:

1. **计算概率**: `softmax` 已经将输出转换为概率,如果输出形状不是 (batch_size, num_classes),那么需要检查模型和数据处理过程。

2. **转换为类别**:
   
  
  1. # 使用 argmax 函数选择概率最大的类别
  2.    predicted_classes = torch.argmax(predictions, dim=1)
复制代码


3. **处理批次**:如果 `predictions` 是三维的,如 (num_batches, batch_size, 2),则需要调整 `axis` 参数以适应你的数据。通常,你会处理单个批次的结果,因此可以对第二个维度进行 `argmax`:

  
  1. # 确定类别索引,假设 predictions 是三维的
  2.    predicted_classes = np.argmax(predictions, axis=2)  # 这里 axis=2 用于选择最后一个维度的最大值索引
复制代码


这样 `predicted_classes` 就会是一个数组,其中每个元素为 0 或 1,分别表示预测为第一个类别或第二个类别。确保输入 `softmax` 函数的张量维度与问题相匹配并考虑适当的维度进行最大概率索引获取。

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

使用道具 举报

 楼主| 发表于 2024-11-7 16:41:58 | 显示全部楼层
FishC 发表于 2024-11-7 11:54
要将经过 softmax 得到的二分类概率值转化为 0 或 1 类别,可以使用 `argmax` 函数选择概率较大的类别 ...

pre的形状是三维的,为什么argmax之后还是二维的
  1. result = np.argmax(pre,axis=2)
  2. result.shape
复制代码
  1. torch.Size([228, 8])
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-11-7 16:44:19 | 显示全部楼层
FishC 发表于 2024-11-7 11:54
要将经过 softmax 得到的二分类概率值转化为 0 或 1 类别,可以使用 `argmax` 函数选择概率较大的类别 ...

  1. valid_eval_loader = DataLoader(valid_dataset,batch_size=8,shuffle=False,pin_memory=True,drop_last=True)
  2. pre_valid = inference(model,valid_eval_loader)
  3. pre = torch.nn.functional.softmax(torch.tensor(pre_valid,dtype=torch.float32), dim=-1)
复制代码
  1. def inference(model,test_dataloader):
  2.     all_preds = []
  3.     model.eval()

  4.     with torch.no_grad():
  5.         for batch in tqdm(test_dataloader):
  6.             input_ids = batch['input_ids'].to(device)
  7.             attention_mask = batch['attention_mask'].to(device)
  8.             
  9.             logits = model(input_ids,attention_mask)
  10.             logits = logits.detach().cpu().numpy()
  11.             all_preds.append(logits)
  12.    
  13.     return all_preds
复制代码

代码哪里有问题?pre输出的形状不是(batch_size, num_classes)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-7 16:45:30 | 显示全部楼层
Terence888 发表于 2024-11-07 16:44
valid_eval_loader = DataLoader(valid_dataset,batch ...


你的代码的问题可能出在 `inference` 函数的实现上或者是数据的组织形式。为了进行二分类,可以按照以下步骤来检查和修正:

1. **检查 `inference` 函数**:
   确保 `inference` 函数返回的结果是每个样本经过模型后获得的**单个预测结果**,而不是包括输入特征的数据等其他信息。

  
  1. def inference(model, dataloader):
  2.        model.eval()  # 切换模型到评估模式
  3.        outputs = []
  4.        with torch.no_grad():  # 评估时不需要计算梯度
  5.            for data in dataloader:
  6.                # 如果 dataloader 返回 features 和 labels, 只用 features
  7.                inputs = data
  8.                output = model(inputs)
  9.                outputs.append(output)
  10.        return torch.cat(outputs, dim=0)
复制代码


2. **检查输出的形状**:
   确保 `model` 的最后一层输出的是一个形状为 `(batch_size, num_classes)` 的张量,其中 num_classes 理想情况下为 2(对二分类问题而言)。

3. **调试步骤**:
   在通过 `softmax` 之前,打印输出的形状以确保它正确。

  
  1. pre_valid = inference(model, valid_eval_loader)
  2.    print(pre_valid.shape)  # 期待 (total_samples, num_classes),例如 (8, 2)
复制代码


4. **使用 `argmax` 进行分类**:
   确保在使用 `argmax` 时,针对的是 softmax 后的输出:

  
  1. predictions = torch.nn.functional.softmax(pre_valid, dim=-1)
  2.    predicted_classes = torch.argmax(predictions, dim=1)
复制代码


通过这一系列步骤确保你的程序输出符合预测的形状,并能够顺利进行后续的分类。确保模型、数据集以及数据加载器的设置都是为了获取正确维度的输出,从而使每一个样本的预测在 `softmax` 后能用于分类。

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

使用道具 举报

发表于 2024-11-7 16:54:16 | 显示全部楼层
Terence888 发表于 2024-11-07 16:41
pre的形状是三维的,为什么argmax之后还是二维的
res ...


在处理三维张量时,对最后一个轴使用 `argmax` 会使结果的维度减少一个。因此,如果你有一个形状为 `(batch_num, batch_size, num_classes)` 的三维张量,并在最后一个轴(即 `axis=2`)上使用 `argmax`,结果会是一个形状为 `(batch_num, batch_size)` 的二维张量。这是因为 `argmax` 返回的是每个批次中哪个类别具有最大概率,这样自然会减少一个维度。

例如:

1. **输入张量**:
   - 假设 `pre` 的形状是 `(228, 8, 2)`,即有 228 个批次,每个批次有 8 个样本,每个样本有两个类别的概率值。

2. **`np.argmax(pre, axis=2)` 的结果**:
   - `argmax` 会在每个样本的类别维度上选出概率最大的类别索引,返回的结果形状为 `(228, 8)`,即每个批次中每个样本的预测类别索引。

如果 `result.shape` 显示 `torch.Size()` 且无具体数值,可能是输出形状未正确打印,或使用的工具对结果形状的理解或显示有误。通常情况下,`result` 应该有具体的数字形式的形状信息,确保以下操作完整:

  1. pre = torch.tensor(pre_valid, dtype=torch.float32)
  2. result = torch.argmax(pre, dim=2)
  3. print(result.shape)  # 打印结果形状
复制代码


或者如果使用 `numpy`:

  1. pre_valid = pre_valid.detach().numpy()  # 如果是张量需转为numpy
  2. result = np.argmax(pre_valid, axis=2)
  3. print(result.shape)  # 打印结果形状
复制代码


确保使用正确的方法查看维度信息,以帮助确认计算是否符合预期。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-18 17:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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