はじめに
Deep learningの学習の際には、過学習のみならずOver-confidence(自信過剰)が問題になることがあります。過学習を抑えるため、Weight decay、Early stopping、DropoutなどのRegularization手法が用いられます。Over-confidenceを抑えるためには、Platt’s scalingやIsotonic regressionが用いられます。
Label smoothing(ラベルスムージング)とは
今回紹介するLabel smoothing(ラベルスムージング)は、この過学習とOver-confidenceの2つの問題を一挙に対処することのできる手法です。
通常分類問題の正解ラベルとして1が、不正解ラベルとして0が設定されますが、Label smoothingを用いる場合、正解ラベルを1 – εに、不正解ラベルをεとして設定します。εは小さな値に設定します。
例えばεを0.1にすると、正解ラベルは0.9、不正解ラベルは0.1になります。これにより0または1を予測させるよりも、モデルは控えめな予測をするようになり、自信過剰が防げるというわけです。Label smoothingありの損失関数を式で表してみると以下のようになります。
ce (i)は正解例のcross-entropy loss、ce (j)は不正解例のcross-entropy loss、Nは分類クラスの数です。
PyTorchでの実装
PyTorchでの実装は下記のようにシンプルです。
まず必要なHelper関数を定義しておきます。
def linear_combination(x, y, epsilon): return (1 - epsilon) * x + epsilon * y def reduce_loss(loss, reduction='mean'): return loss.mean() if reduction == 'mean' else loss.sum() if reduction == 'sum' else loss
さらに必要なものをimportしておきます。
import torch.nn.functional as F
import torch.nn as nn
Label smoothingありの損失関数は、PyTorchのnn.Moduleを基に、以下のように作ることができます。εを0.1に設定しましたが、これは自由に変更することができます。
class LabelSmoothingCrossEntropy(nn.Module): def __init__(self, epsilon=0.1, reduction='mean'): super().__init__() self.epsilon = epsilon self.reduction = reduction def forward(self, preds, target): n = preds.size()[-1] log_preds = F.log_softmax(preds, dim=-1) loss = reduce_loss(-log_preds.sum(dim=-1), self.reduction) nll = F.nll_loss(log_preds, target, reduction=self.reduction) return linear_combination(nll, loss/n, self.epsilon)
これを使用するには、PyTorchでモデルを書くときに、この作成した損失関数をcriterionに指定してあげます。
criterion = LabelSmoothingCrossEntropy()
するとLabel smoothingありの損失関数を用いて、学習が進んでいきます。
まとめ
今回はLabel smoothingについて簡単に解説し、実装をしてみましたがいかがでしたでしょうか。もし少しでもお役に立てば嬉しいです。
コメント