転移学習を使用して、StanfordCarsデータセットのResNet-18分類モデルを構築しています。 ラベル平滑化 を実装して、自信過剰な予測にペナルティを課し、一般化を改善したいと思います。
TensorFlowには、 CrossEntropyLoss に単純なキーワード引数があります。プラグアンドプレイできるPyTorch用の同様の関数を作成した人はいますか?
私が知っているものはありません。
PyTorch実装の2つの例を次に示します。
LabelSmoothingLoss
module 機械翻訳用のOpenNMTフレームワーク
attention-is-all-you-need-pytorch
、Googleの再実装 紙が必要なのは注意だけです
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
別のオプション: