Label Smoothing(ラベルスムージング)をPyTorchで実装する

未分類

はじめに

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ありの損失関数を式で表してみると以下のようになります。 

Image for post

 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について簡単に解説し、実装をしてみましたがいかがでしたでしょうか。もし少しでもお役に立てば嬉しいです。

コメント

タイトルとURLをコピーしました