突然想到 PyTorch 如何在資料是 one hot 格式下做到 label smoothing loss?

label smoothing 主要是用來嘗試解決 "過擬合" 的問題

然後發現 chat gpt 給出的答案真的可行

這邊做個紀錄

 

 

假設你有一個大小為 (batch_size, num_classes) 的 one-hot 格式的標簽張量。標簽平滑的目標是將一個類別的概率降低,同時增加其他類別的概率。

以下是一個簡單的示例代碼,演示了如何在 PyTorch 中實現標簽平滑:

 

import torch
import torch.nn as nn

class LabelSmoothingLoss(nn.Module):
    def __init__(self, smoothing=0.0):
        super(LabelSmoothingLoss, self).__init__()
        self.smoothing = smoothing

    def forward(self, output, target):
        logprobs = torch.nn.functional.log_softmax(output, dim=-1)
        num_classes = output.size(-1)

        # 將 one-hot 格式的標簽轉換為概率分布
        target_probs = (1.0 - self.smoothing) * target + self.smoothing / num_classes

        # 計算交叉熵損失
        loss = -torch.sum(logprobs * target_probs, dim=-1).mean()
        return loss

# 使用示例
# 假設我們有一個大小為 (batch_size, num_classes) 的輸出張量和對應的 one-hot 格式標簽張量
batch_size = 32
num_classes = 10

# 生成示例的輸出張量和 one-hot 格式的標簽張量
output = torch.randn(batch_size, num_classes)
target = torch.zeros(batch_size, num_classes)
target[:, 0] = 1  # 假設第一個類別是正確的類別

# 創建標簽平滑損失函數
criterion = LabelSmoothingLoss(smoothing=0.1)

# 計算損失
loss = criterion(output, target)
print("Loss:", loss.item())

 

 

在這個示例中,我們首先定義了一個名為 LabelSmoothingLoss 的自定義損失函數,它將輸出張量和 one-hot 格式的標簽張量作為輸入。在損失的計算過程中,我們將 one-hot 格式的標簽轉換為概率分布,並使用交叉熵損失來計算損失值。

請注意,標簽平滑的程度由參數 smoothing 控制,這個參數決定了從正確類別中減去的概率量。通常,smoothing 的值應該在 0 和 1 之間。

 

感謝 chat gpt 大神

發現 keras 這邊就比較方便了

https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalCrossentropy

 

tf.keras.losses.CategoricalCrossentropy(
    from_logits=False,
    label_smoothing=0.0,
    axis=-1,
    reduction=losses_utils.ReductionV2.AUTO,
    name='categorical_crossentropy'
)

 

直接! 就在loss裡就有這功能了