ในกรณีที่จำนวนข้อมูลตัวอย่าง ในแต่ละ Class แตกต่างกันมาก เรียกว่า Class Imbalance แทนที่เราจะใช้ Cross Entropy Loss ตามปกติที่เรามักจะใช้ในงาน Classification เราจะใช้ Cross Entropy Loss เวอร์ชันพิเศษ เรียกว่า Weighted Cross Entropy Loss เข้ามาช่วย
Weighted Cross Entropy Loss คืออะไร
\( \text{WCE}\left(p, \hat{p}\right) = -\left(\beta p \log\left(\hat{p}\right) + (1-p) \log\left(1 – \hat{p}\right)\right) \)ในกรณีที่ Class Imbalance มาก ๆ เช่น 80/20 ถ้าโมเดล ทายมั่ว ๆ ว่าเป็น 0 ทุกครั้ง ก็จะได้ Accuracy ถึง 80% ซึ่งทำให้การเทรนโมเดลให้ได้ประสิทธิภาพที่ดี เป็นไปได้ยาก
PyTorch
torch.nn.CrossEntropyLoss(weight: Optional[torch.Tensor] = None, size_average=None, ignore_index: int = -100, reduce=None, reduction: str = 'mean')
# Create Loss Function with 'weight'.
weights = torch.tensor([[0.2] + [0.8]]).cuda()
loss_func = CrossEntropyLoss(weight=weights)
TensorFlow
tf.keras.losses.CategoricalCrossentropy(
from_logits=False, label_smoothing=0, reduction=losses_utils.ReductionV2.AUTO,
name='categorical_crossentropy'
)
# Calling with 'sample_weight'.
cce(y_true, y_pred, sample_weight=tf.constant([0.2, 0.8])).numpy()
สังเกตว่า ในคลาส Cross Entropy Loss ของทั้ง PyTorch และ TensorFlow มี parameter ชื่อ weight และ sample_weight ให้เราสามารถกำหนดน้ำหนักความสำคัญของแต่ละคลาสได้ไม่เท่ากัน ตามต้องการ
ตัวอย่างเช่น การกำหนด Weight ของ Class 0 เช่น ให้น้อยลง เทียบกับ คลาส 1 จะทำให้ Loss ของ Class นั้น ๆ มีสัดส่วนน้อยลง ส่งผลให้สัดส่วน Gradient ลดลงมาพอ ๆ กัน ทำให้โมเดลไปสนใจเรียนรู้ เทรนโมเดล ที่ให้ผลลัพธ์กับทุก Class เท่าเทียมกันมากขึ้น ดังตัวอย่างใน ep Pneumonia คืออะไร พัฒนาระบบ AI ช่วยวินิจฉัยโรค Pneumonia จากฟิล์ม X-Ray ที่มีจำนวนตัวอย่าง Pneumonia มากกว่า ตัวอย่าง Normal ถึง 3 เท่าตัว
การคำนวน Weight ที่ทำให้ Class-Balanced
จากการทดลอง เราไม่สามารถกำหนด Weight ตามสัดส่วนของจำนวน Sample ของแต่ละ Class หรือ สัดส่วนยกกำลังสองของจำนวน Sample ของแต่ละ Class ได้โดยตรง เนื่องจากค่า Loss ที่ได้จากแต่ละ Class จะมีน้ำหนักมากเกินไป
สาเหตุคือ เมื่อเราเพิ่มจำนวน Sample ขึ้นเรื่อย ๆ ไม่ว่าจะเป็นจากการ Data Augmentation แต่ประโยชน์ของ Data Point ใหม่ ๆ ไม่ได้เพิ่มขึ้นตามไปด้วย ดังอธิบายไว้ใน Paper Class-Balanced Loss Based on Effective Number of Samples ว่า
Effective number of samples can be imagined as the actual volume that will be covered by n samples where the total volume N is represented by total samples.
จึงต้องมีการคำนวน Effective Number of Samples คำนวน Weight ดังสูตรด้านล่าง
\( (1-\beta^{n})/(1-\beta)\beta \in [0,1)
\)
ตัวอย่าง Python Code ดังนี้
beta = 0.99
no_of_classes = 2
effective_num = 1.0 - np.power(beta, samples_per_cls)
weights = (1.0 - beta) / np.array(effective_num)
weights = weights / np.sum(weights) * no_of_classes
weights = (1.0 - np.power(beta, samples_per_cls))
weights = tensor(weights).cuda()
loss_func = CrossEntropyLossFlat(weight=weights, axis=1)
Credit
- https://pytorch.org/docs/master/generated/torch.nn.CrossEntropyLoss.html
- https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalCrossentropy
- https://arxiv.org/abs/1901.05555