错误:在训练训练 CNN 模型时,维度超出范围(预计在 [-1, 0] 范围内,但得到 1)

乘风 pytorch 192

原文标题error: Dimension out of range (expected to be in range of [-1, 0], but got 1) when training to train a CNN model

我正在尝试遵循使用 resnet18 来训练二进制分类模型的代码片段,因为我应该训练多分类模型,我通过更改损失函数、激活函数对代码进行了一些修改

import torchmetrics

class CheastCancer(pl.LightningModule):

  def __init__(self,init_weights=True):
    super().__init__()

    self.model = torchvision.models.resnet18()
    self.model.conv1 = torch.nn.Conv2d(1, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
    self.model.fc = torch.nn.Linear(in_features=512, out_features=3, bias=True)

    self.optimizer = torch.optim.Adam(self.model.parameters(), lr = 1e-4)
    self.loss_fn = torch.nn.CrossEntropyLoss()

    self.train_acc = torchmetrics.Accuracy()
    self.val_acc = torchmetrics.Accuracy()

  def forward(self, data):
    pred = self.model(data)
    return pred

  def training_step(self, batch, batch_idx):
    img, label = batch
    label = label.float()
    pred = self(img)[:,0]
    loss = self.loss_fn(pred,label)

    self.log("Train Loss", loss)
    self.log("Step Train ACC", self.train_acc(torch.softmax(pred), label.int()))

    return loss
  
  def training_epoch_end(self, outs):
    self.log("Train ACC", self.train_acc.compute())

  def validation_step(self, batch, batch_idx):
    img, label = batch
    label = label.float()
    pred = self(img)[:,0]
    loss = self.loss_fn(pred,label)

    self.log("Train Loss", loss)
    self.log("Step Train ACC", self.val_acc(torch.poisson(pred), label.int()))

    return loss
  
  def training_epoch_end(self, outs):
    self.log("Train ACC", self.val_acc.compute())

  def configure_optimizers(self):
      return [self.optimizer]

但是,我收到以下错误消息:

LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]

  | Name      | Type             | Params
-----------------------------------------------
0 | model     | ResNet           | 11.2 M
1 | loss_fn   | CrossEntropyLoss | 0     
2 | train_acc | Accuracy         | 0     
3 | val_acc   | Accuracy         | 0     
-----------------------------------------------
11.2 M    Trainable params
0         Non-trainable params
11.2 M    Total params
44.687    Total estimated model params size (MB)
Sanity Checking:
0/? [00:00<?, ?it/s]
/usr/local/lib/python3.7/dist-packages/pytorch_lightning/trainer/connectors/data_connector.py:245: PossibleUserWarning: The dataloader, val_dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 8 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.
  category=PossibleUserWarning,
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-132-5af489ac4112> in <module>()
----> 1 trainer.fit(model, train_loader, val_loader)

17 frames
/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction, label_smoothing)
   2844     if size_average is not None or reduce is not None:
   2845         reduction = _Reduction.legacy_get_string(size_average, reduce)
-> 2846     return torch._C._nn.cross_entropy_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index, label_smoothing)
   2847 
   2848 

IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)

从我到目前为止的搜索来看,当标签的维度与预测不同时,通常会出现此错误。但我不确定我该如何解决?有人可以帮忙吗。

原文链接:https://stackoverflow.com//questions/71947002/error-dimension-out-of-range-expected-to-be-in-range-of-1-0-but-got-1-wh

回复

我来回复
  • jhso的头像
    jhso 评论

    如果您查看文档,您会看到输入CrossEntropyLoss的目标是类索引。我猜也许你已经得到了一个热格式,所以你需要做的是:

    y = torch.Tensor([[0,0,1],[0,1,0]])
    y = y.argmax(dim=1)
    

    除此之外,看看你的输出的形状是什么,看看它是否符合你预期的标签形状。

    2年前 0条评论