web-dev-qa-db-ja.com

PyTorchでのラベルスムージング

転移学習を使用して、StanfordCarsデータセットのResNet-18分類モデルを構築しています。 ラベル平滑化 を実装して、自信過剰な予測にペナルティを課し、一般化を改善したいと思います。

TensorFlowには、 CrossEntropyLoss に単純なキーワード引数があります。プラグアンドプレイできるPyTorch用の同様の関数を作成した人はいますか?

2
Jared Nielsen

私が知っているものはありません。

PyTorch実装の2つの例を次に示します。

4
Jindřich

PyTorchの他の損失クラスのように_Lossから派生し、reductionなどの基本的なパラメーターを尊重するオプションを探していました。残念ながら、私は簡単な代替品を見つけることができないので、自分で書くことになりました。ただし、これはまだ完全にはテストしていません。

import torch
from torch.nn.modules.loss import _WeightedLoss
import torch.nn.functional as F

class SmoothCrossEntropyLoss(_WeightedLoss):
    def __init__(self, weight=None, reduction='mean', smoothing=0.0):
        super().__init__(weight=weight, reduction=reduction)
        self.smoothing = smoothing
        self.weight = weight
        self.reduction = reduction

    @staticmethod
    def _smooth_one_hot(targets:torch.Tensor, n_classes:int, smoothing=0.0):
        assert 0 <= smoothing < 1
        with torch.no_grad():
            targets = torch.empty(size=(targets.size(0), n_classes),
                    device=targets.device) \
                .fill_(smoothing /(n_classes-1)) \
                .scatter_(1, targets.data.unsqueeze(1), 1.-smoothing)
        return targets

    def forward(self, inputs, targets):
        targets = SmoothCrossEntropyLoss._smooth_one_hot(targets, inputs.size(-1),
            self.smoothing)
        lsm = F.log_softmax(inputs, -1)

        if self.weight is not None:
            lsm = lsm * self.weight.unsqueeze(0)

        loss = -(targets * lsm).sum(-1)

        if  self.reduction == 'sum':
            loss = loss.sum()
        Elif  self.reduction == 'mean':
            loss = loss.mean()

        return loss

別のオプション:

0
Shital Shah