DRW的公式推导及代码解析

流程

分阶段指定β值

python 复制代码
    # 根据当前epoch计算使用的beta值
    idx = epoch // 160  # 每160轮epoch切换一次加权系数
    betas = [0, 0.9999]  # 两个beta值
    beta = betas[idx]  # 根据idx选择beta值

计算有效样本的权重

对权重进行归一化

(每类权重值 / 权重总和)* 样本数量

python 复制代码
    # 将权重进行归一化
    per_cls_weights = per_cls_weights / np.sum(per_cls_weights) * len(cls_num_list)
    print(f"Class weights after normalization: {per_cls_weights}")

代码

python 复制代码
import numpy as np
import torch

def calculate_per_cls_weights(cls_num_list, epoch, device):
    # 训练采样器设为空
    train_sampler = None
    print(f"Train sampler: {train_sampler}")
    
    # 根据当前epoch计算使用的beta值
    idx = epoch // 160  # 每160轮epoch切换一次加权系数
    print(f"Epoch: {epoch}, Beta index (idx): {idx}")
    
    betas = [0, 0.9999]  # 两个beta值
    beta = betas[idx]  # 根据idx选择beta值
    print(f"Selected beta value: {beta}")
    
    # 计算每个类别的有效样本数 effective_num
    effective_num = 1.0 - np.power(beta, cls_num_list)
    print(f"Effective number (for each class): {effective_num}")
    
    # 计算每个类别的权重 per_cls_weights
    per_cls_weights = (1.0 - beta) / effective_num
    print(f"Class weights before normalization: {per_cls_weights}")
    
    # 将权重进行归一化
    per_cls_weights = per_cls_weights / np.sum(per_cls_weights) * len(cls_num_list)
    print(f"Class weights after normalization: {per_cls_weights}")
    
    # 将权重转为张量并移动到指定设备上
    per_cls_weights = torch.FloatTensor(per_cls_weights).to(device)
    print(f"Final weights as a tensor on device ({device}): {per_cls_weights}")
    
    return per_cls_weights

# 示例
cls_num_list = [100, 50, 10, 5]  # 假设数据集中有4个类别,样本数分别为100、50、10、5
epoch = 200  # 当前训练轮次
device = 'cuda' if torch.cuda.is_available() else 'cpu'  # 选择设备

# 计算类别权重
per_cls_weights = calculate_per_cls_weights(cls_num_list, epoch, device)
print("Per class weights:", per_cls_weights)

解析

前面部分所有类别权重相等。

在你的 Acne04 数据集上,BKD 在第 77 个 epoch 时测试集准确率达到最大值,并且此时并没有使用有效样本的计算,而是直接按照类平衡去计算就取得了最大的效果。出现这种现象的原因可能包括以下几点:

  1. 类平衡策略的优势:BKD 的类平衡蒸馏策略通过对尾部类别施加更高的权重来使得模型在尾部类别上获得更好的表现。即使没有用到有效样本的计算,类平衡蒸馏本身已经纠正了模型对频繁类别的偏向,从而大幅提升了尾部类别的表现。这种简单的类平衡策略可能已经足够有效,以至于能够在较早的 epoch 中达到最佳的分类效果。

  2. 数据集规模和分布的影响:Acne04 数据集的规模较小,类别不平衡的情况可能并没有特别严重,因此即使没有采用更复杂的有效样本计算,类平衡蒸馏就能够取得显著的性能提升。对于这种中等规模或类别分布不那么极端的数据集,较为简单的类平衡方法往往足够有效。

  3. 训练的早期收敛:在第 77 个 epoch 时,模型可能已经充分学习到了数据中的特征,尤其是在使用 BKD 的情况下,模型不仅能够学到头部类别的泛化特征,还能够有效提升尾部类别的表现。这表明 BKD 提供的类平衡机制已经足以解决该数据集上的类不平衡问题,而不需要依赖更复杂的有效样本策略。

  4. 蒸馏温度和超参数的影响:BKD 蒸馏过程中使用的温度参数 TTT 可能在此时已经使得教师模型的软标签足够平滑,进一步帮助学生模型更好地学习尾部类别的特征,而无需通过有效样本策略来调整每类的权重分布。

因此,在 Acne04 数据集上,BKD 的类平衡机制已经足够有效,使得模型在第 77 个 epoch 时就达到了测试集准确率的最大值,即使没有使用更加复杂的有效样本策略​(Balanced Knowledge Dist...)

程度没有那么严重的不平衡数据集,是不是就用类平衡策略就可以了,比其他的平衡策略更好使一点?

是的,对于不平衡程度没有那么严重的数据集,使用类平衡策略(如 BKD 中的类平衡蒸馏)通常已经足够有效,且可能比其他复杂的平衡策略表现得更好。原因如下:

  1. 简单有效:类平衡策略通过调整不同类别的权重,让模型在学习时关注那些少数类。这种方法的简单性意味着它能够快速适应不太严重的类不平衡数据集,而不需要像更复杂的重采样或有效样本计算那样复杂的机制。

  2. 避免过度调整:在不太严重的不平衡数据集中,过度使用复杂的平衡策略(如重采样或有效样本计算)可能会导致对尾部类别的过度关注,反而损害头部类别的表现。类平衡策略通过温和的权重调整,更好地维持了头部和尾部类别之间的平衡,不会过度影响整体模型的泛化能力。

  3. 计算效率:类平衡策略相对简单,计算开销较低,不需要频繁调整采样或计算每个类别的有效样本数,因此训练过程更加高效。对于不太严重的类不平衡问题,这种高效的解决方案通常已经足够有效。

  4. 蒸馏的优势:BKD 的类平衡蒸馏策略在学习时不仅关注少数类,还能通过蒸馏从教师模型中学习整体数据的分布。因此,它能够在提升尾部类别性能的同时保持对头部类别的良好表现,这对于不太严重的不平衡问题尤为重要。

因此,对于不平衡程度较低的数据集,类平衡策略通常能提供足够的性能提升,同时避免了更复杂策略可能带来的负面影响,如过度拟合少数类或损害模型的整体性能​(Balanced Knowledge Dist...)。

相关推荐
湘美书院--湘美谈教育4 小时前
湘美谈教育AI系列经验集锦:赋能整理聊斋志异大寓言
大数据·人工智能·深度学习·神经网络·机器学习
大模型最新论文速读6 小时前
小红书提出 RedKnot:分头处理 kv 缓存,延时降低 60%效果还提升
论文阅读·人工智能·深度学习·机器学习·缓存·自然语言处理
星浩AI7 小时前
(七)GPT2中文生成模型定制化微调训练[附源码]
pytorch·深度学习·llm
卡梅德生物科技小能手7 小时前
卡梅德生物科普MCAM(黑色素瘤细胞黏附分子)
人工智能·经验分享·深度学习
月疯7 小时前
torch:expand和repeate的区别
开发语言·python·深度学习
xianghongtao01168 小时前
把 Prompt 当成“可训练参数“:SkillOpt 如何用深度学习的纪律去优化 Agent 技能
人工智能·深度学习·性能优化·prompt
装不满的克莱因瓶9 小时前
PyTorch 与它的自动微分工具:Autograd
人工智能·pytorch·python·深度学习·神经网络·机器学习·ai
EQUINOX19 小时前
【ch03】Coding-attention-mechanisms
人工智能·深度学习·机器学习
老饼讲解-BP神经网络9 小时前
具体说说-RBF神经网络-newrbe函数和newrb函数的区别
人工智能·深度学习·神经网络
机器学习之心10 小时前
198种组合算法+优化CNN-LSTM+SHAP分析+新数据预测+多输出!深度学习可解释分析,强烈安利,粉丝必备
深度学习·算法·cnn-lstm·shap分析·198种组合算法