PyTorch: объект «CrossEntropyLoss» не имеет атрибута «item»

#python #python-3.x #neural-network #pytorch #conv-neural-network

#питон #python-3.x #нейронная сеть #пыторч #conv-нейронная сеть

Вопрос:

В настоящее время развертывается модель CNN.

 model = CNN(height=96, width=96, channels=3)
 

и хочет наблюдать за его перекрестной потерей энтропии.

 criterion = nn.CrossEntropyLoss()
 

Класс Trainer задается следующим образом,

 class Trainer:
def __init__(
    self,
    model: nn.Module,
    train_loader: DataLoader,
    val_loader: DataLoader,
    criterion: nn.Module,
    optimizer: Optimizer,
    summary_writer: SummaryWriter,
    device: torch.device,
):
    self.model = model.to(device)
    self.device = device
    self.train_loader = train_loader
    self.val_loader = val_loader
    self.criterion = criterion
    self.optimizer = optimizer
    self.summary_writer = summary_writer
    self.step = 0

def train(
        self,
        epochs: int,
        val_frequency: int,
        print_frequency: int = 20,
        log_frequency: int = 5,
        start_epoch: int = 0
):
    self.model.train()
    for epoch in range(start_epoch, epochs):
        self.model.train()
        data_load_start_time = time.time()
        for batch, labels in self.train_loader:
            batch = batch.to(self.device)
            labels = labels.to(self.device)
            data_load_end_time = time.time()
            loss=self.criterion
            logits=self.model.forward(batch)

            with torch.no_grad():
                preds = logits
                accuracy = compute_accuracy(labels, preds)

            data_load_time = data_load_end_time - data_load_start_time
            step_time = time.time() - data_load_end_time
            if ((self.step   1) % log_frequency) == 0:
                self.log_metrics(epoch, accuracy, loss, data_load_time, step_time)
            if ((self.step   1) % print_frequency) == 0:
                self.print_metrics(epoch, accuracy, loss, data_load_time, step_time)

            self.step  = 1
            data_load_start_time = time.time()

        self.summary_writer.add_scalar("epoch", epoch, self.step)
        if ((epoch   1) % val_frequency) == 0:
            self.validate()
            self.model.train()
 

Функция для регистрации потерь,

     def log_metrics(self, epoch, accuracy, loss, data_load_time, step_time):
    self.summary_writer.add_scalar("epoch", epoch, self.step)
    self.summary_writer.add_scalars(
            "accuracy",
            {"train": accuracy},
            self.step
    )
    self.summary_writer.add_scalars(
            "loss",
            {"train": float(loss.item())},
            self.step
    )
    self.summary_writer.add_scalar(
            "time/data", data_load_time, self.step
    )
    self.summary_writer.add_scalar(
            "time/data", step_time, self.step
    )
 

Я получаю ошибку атрибута «объект «CrossEntropyLoss» не имеет атрибута «item»«. Я попытался удалить несколько способов, таких как удаление «item ()» из разных частей кода и пробовал различные типы функций потери, такие как MSELoss и т. Д.
Любое решение или направление будут высоко оценены. Спасибо.

Редактировать-1:

Вот трассировка ошибки

 Traceback (most recent call last):


 File "/Users/xyz/main.py", line 316, in <module>
main(parser.parse_args())
 File "/Users/xyz/main.py", line 128, in main
    log_frequency=args.log_frequency,
  File "/Users/xyz/main.py", line 198, in train
    self.log_metrics(epoch, accuracy, loss, data_load_time, step_time)
  File "/Users/xyz/main.py", line 232, in log_metrics
    {"train": float(loss.item)},
  File "/Users/xyz/main.py", line 585, in __getattr__
    type(self).__name__, name))
AttributeError: 'CrossEntropyLoss' object has no attribute 'item'
 

Комментарии:

1. Ваш код даже не вычисляется loss , поэтому неясно, что здесь происходит. Вам нужно будет предоставить полный воспроизводимый пример. Кроме того, вы должны предоставить полную обратную трассировку ошибок.

2. не могли бы вы сказать мне, что вы подразумеваете под «воспроизводимым примером»? Спасибо за указание.

Ответ №1:

Похоже loss , что в вызове self.log_metrics(epoch, accuracy, loss, data_load_time, step_time) является сам критерий (объект CrossEntropyLoss), а не результат его вызова.

Ваш цикл обучения должен вызывать критерий для вычисления потерь, я не вижу его в предоставленном вами коде.

Комментарии:

1. Я пропустил это при копировании кода в stack. спасибо, что дали мне знать.

2. критерий потери = self.находится в функции train. но ошибка все равно осталась

3. Должно быть что-то вроде loss = self.criterion(labels_predicted, labels_expected) . Как я уже сказал, loss должно быть результатом вызова функции критерия, а не самой функции.