katidoki1123
@katidoki1123

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

CrossEntropyLoss()をBCEloss()に変更するとエラーが出る。

解決したいこと

pytorchを使用して、画像の2値分類に取り組んでいます。
最近、2値分類の損失計算にはCrossEntropyLoss()ではなく、BCEloss()を使用したほうが良いことを知りました。しかし、CrossEntropyLoss()をBCEloss()に変更すると以下のようなエラーが発生します。

発生している問題・エラー

# 損失関数定義
#criterion = nn.CrossEntropyLoss()
criterion = torch.nn.BCELoss()

#以下、エラー
Target size (torch.Size([10])) must be the same as input size (torch.Size([10, 2]))

inputサイズとtargetサイズは同じにするというエラーなのですが、どこを変更すればよいかわかりません。
以下のコードで損失計算は定義しております。

損失関数値計算

# 損失関数値計算用
def eval_loss(loader, device, net, criterion):
  
    # DataLoaderから最初の1セットを取得する
    for images, labels in loader:
        break

    # デバイスの割り当て
    inputs = images.to(device)
    labels = labels.to(device)

    # 予測値の計算
    outputs = net(inputs)

    #  損失値の計算
    loss = criterion(outputs, labels)

    return loss

損失計算ソースコード

# 学習用関数
def fit(net, optimizer, criterion, num_epochs, train_loader, test_loader, device, history):

    base_epochs = len(history)
  
    for epoch in range(base_epochs, num_epochs+base_epochs):
        train_loss = 0
        train_acc = 0
        val_loss = 0
        val_acc = 0

        #訓練フェーズ
        net.train()
        count = 0

        for inputs, labels in tqdm(train_loader):
            count += len(labels)
            inputs = inputs.to(device)
            labels = labels.to(device)

            # 勾配の初期化
            optimizer.zero_grad()

            # 予測計算
            outputs = net(inputs)

            # 損失計算
            loss = criterion(outputs, labels)
            train_loss += loss.item()

            # 勾配計算
            loss.backward()

            # パラメータ修正
            optimizer.step()

            # 予測値算出
            predicted = torch.max(outputs, 1)[1]


            # 正解件数算出
            train_acc += (predicted == labels).sum().item()

            # 損失と精度の計算
            avg_train_loss = train_loss / count
            avg_train_acc = train_acc / count

        #予測フェーズ
        net.eval()
        count = 0

        for inputs, labels in test_loader:
            count += len(labels)

            inputs = inputs.to(device)
            labels = labels.to(device)

            # 予測計算
            outputs = net(inputs)

            # 損失計算
            loss = criterion(outputs, label)
            val_loss += loss.item()

            #予測値算出
            predicted = torch.max(outputs, 1)[1]

            #正解件数算出
            val_acc += (predicted == labels).sum().item()

            # 損失と精度の計算
            avg_val_loss = val_loss / count
            avg_val_acc = val_acc / count

        print (f'Epoch [{(epoch+1)}/{num_epochs+base_epochs}], loss: {avg_train_loss:.3f} acc: {avg_train_acc:.3f} val_loss: {avg_val_loss:.3f}, val_acc: {avg_val_acc:.3f}')
        item = np.array([epoch+1, avg_train_loss, avg_train_acc, avg_val_loss, avg_val_acc])
        history = np.vstack((history, item))
   

    return history

勉強している書籍

「最短コースでわかる PyTorch &深層学習プログラミング」という書籍で勉強しています。

0

1Answer

こんにちは、私は日本語が読めず、翻訳ソフトでやりとりしているため、質問が多くなってしまい申し訳ありませんが、お答えしようと思います。 エラーとして報告された情報を分析したところ、batch_sizeを10に設定した画像2の分類問題を扱っていると思われます。 10枚の画像の入力がネットワークを通過する際に、各画像が各カテゴリーに属する確率が導かれるので、出力サイズは [10, 2] となりますが、画像のラベルデータは予測結果とは異なり、単にこの画像がどの画像に属しているのかを示しています 例えば、ある画像は最初のカテゴリーに属するので、そのラベルは[1, 0]であるべきですが、予測は[0.8, 0.2]になります。

0Like

Your answer might help someone💌