备注
点击此处下载完整示例代码
基于 PyTorch 的使用 USB 的半监督学习 ¶
创建时间:2025 年 4 月 1 日 | 最后更新时间:2025 年 4 月 1 日 | 最后验证:未验证
作者:陈浩
统一半监督学习基准(USB)是一个基于 PyTorch 构建的半监督学习(SSL)框架。基于 PyTorch 提供的数据集和模块,USB 成为一个灵活、模块化且易于使用的半监督学习框架。它支持多种半监督学习算法,包括 FixMatch
, FreeMatch
, DeFixMatch
, SoftMatch
,等等。它还支持多种不平衡半监督学习算法。USB 包含了计算机视觉、自然语言处理和语音处理不同数据集的基准结果。
本教程将向您介绍如何使用 USB 照明包的基础知识。让我们从在 CIFAR-10 上使用预训练的视觉 Transformer(ViT)训练一个 FreeMatch
/ SoftMatch
模型开始!我们将展示如何轻松更改半监督算法并在不平衡数据集上训练。

半监督学习中的 FreeMatch
和 SoftMatch
简介
我们在这里简要介绍 FreeMatch
和 SoftMatch
。首先,我们介绍一个名为 FixMatch
的半监督学习著名基线。 FixMatch
是一个用于半监督学习的非常简单的框架,其中它利用强大的增强来为未标记数据生成伪标签。它采用置信度阈值策略,通过固定的阈值来过滤掉低置信度的伪标签。 FreeMatch
和 SoftMatch
是两种改进 FixMatch
的算法。 FreeMatch
提出了一种自适应阈值策略来替代 FixMatch
中的固定阈值策略。自适应阈值根据模型在每个类上的学习状态逐步增加阈值。 SoftMatch
吸收了置信度阈值作为加权机制的想法。它提出了一种高斯加权机制来克服伪标签中的数量-质量权衡。在本教程中,我们将使用 USB 来训练 FreeMatch
和 SoftMatch
。
使用 USB 在 CIFAR-10 上仅用 40 个标签训练 FreeMatch
/ SoftMatch
USB 易于使用和扩展,对小型团队来说价格合理,在开发和评估 SSL 算法方面功能全面。USB 提供了基于一致性正则化的 14 种 SSL 算法的实现,以及来自计算机视觉、自然语言处理和音频领域的 15 个评估任务。它具有模块化设计,允许用户通过添加新的算法和任务轻松扩展软件包。它还支持 Python API,以便更容易地适应新数据上的不同 SSL 算法。
现在,让我们使用 USB 在 CIFAR-10 上训练 FreeMatch
和 SoftMatch
。首先,我们需要安装 USB 软件包 semilearn
,并从 USB 导入必要的 API 函数。如果您在 Google Colab 上运行此代码,请通过运行 !pip install semilearn
来安装 semilearn
。
下面是我们将从 semilearn
中使用的函数列表:
get_dataset
用于加载数据集,这里我们使用 CIFAR-10创建训练(标记和未标记)和测试数据
加载器,训练未标记加载器将提供未标记数据的强和弱增强 - 创建模型,这里我们使用预训练的 ViT - 创建半监督学习算法,这里我们使用 FreeMatch
和 SoftMatch
- 获取算法的默认配置 - 为训练和评估算法在数据集上使用的 Trainer 类
注意,使用 semilearn
包进行训练需要 CUDA 启用的后端。有关在 Google Colab 中启用 CUDA 的说明,请参阅启用 Google Colab 中的 CUDA。
import semilearn
from semilearn import get_dataset, get_data_loader, get_net_builder, get_algorithm, get_config, Trainer
导入必要的函数后,我们首先设置算法的超参数。
config = {
'algorithm': 'freematch',
'net': 'vit_tiny_patch2_32',
'use_pretrain': True,
'pretrain_path': 'https://github.com/microsoft/Semi-supervised-learning/releases/download/v.0.0.0/vit_tiny_patch2_32_mlp_im_1k_32.pth',
# optimization configs
'epoch': 1,
'num_train_iter': 500,
'num_eval_iter': 500,
'num_log_iter': 50,
'optim': 'AdamW',
'lr': 5e-4,
'layer_decay': 0.5,
'batch_size': 16,
'eval_batch_size': 16,
# dataset configs
'dataset': 'cifar10',
'num_labels': 40,
'num_classes': 10,
'img_size': 32,
'crop_ratio': 0.875,
'data_dir': './data',
'ulb_samples_per_class': None,
# algorithm specific configs
'hard_label': True,
'T': 0.5,
'ema_p': 0.999,
'ent_loss_ratio': 0.001,
'uratio': 2,
'ulb_loss_ratio': 1.0,
# device configs
'gpu': 0,
'world_size': 1,
'distributed': False,
"num_workers": 4,
}
config = get_config(config)
然后,我们加载数据集并创建用于训练和测试的数据加载器。并指定要使用的模型和算法。
dataset_dict = get_dataset(config, config.algorithm, config.dataset, config.num_labels, config.num_classes, data_dir=config.data_dir, include_lb_to_ulb=config.include_lb_to_ulb)
train_lb_loader = get_data_loader(config, dataset_dict['train_lb'], config.batch_size)
train_ulb_loader = get_data_loader(config, dataset_dict['train_ulb'], int(config.batch_size * config.uratio))
eval_loader = get_data_loader(config, dataset_dict['eval'], config.eval_batch_size)
algorithm = get_algorithm(config, get_net_builder(config.net, from_name=False), tb_log=None, logger=None)
现在,我们可以开始使用 CIFAR-10 的 40 个标签训练算法了。我们训练 500 次迭代,每 500 次迭代评估一次。
trainer = Trainer(config, algorithm)
trainer.fit(train_lb_loader, train_ulb_loader, eval_loader)
最后,让我们在验证集上评估训练好的模型。在 CIFAR-10 的 40 个标签上使用 FreeMatch
训练 500 次迭代后,我们在验证集上获得了一个大约 87%准确率的分类器。
trainer.evaluate(eval_loader)
使用 USB 在不平衡的 CIFAR-10 上使用特定的不平衡算法训练 SoftMatch
。
现在假设我们有一个不平衡的 CIFAR-10 标签集和不平衡的无标签集,并且我们想在它上面训练一个 SoftMatch
模型。我们通过将 lb_imb_ratio
和 ulb_imb_ratio
设置为 10 来创建一个不平衡的 CIFAR-10 标签集和不平衡的无标签集。同时,我们将 algorithm
替换为 softmatch
,并将 imbalanced
设置为 True
。
config = {
'algorithm': 'softmatch',
'net': 'vit_tiny_patch2_32',
'use_pretrain': True,
'pretrain_path': 'https://github.com/microsoft/Semi-supervised-learning/releases/download/v.0.0.0/vit_tiny_patch2_32_mlp_im_1k_32.pth',
# optimization configs
'epoch': 1,
'num_train_iter': 500,
'num_eval_iter': 500,
'num_log_iter': 50,
'optim': 'AdamW',
'lr': 5e-4,
'layer_decay': 0.5,
'batch_size': 16,
'eval_batch_size': 16,
# dataset configs
'dataset': 'cifar10',
'num_labels': 1500,
'num_classes': 10,
'img_size': 32,
'crop_ratio': 0.875,
'data_dir': './data',
'ulb_samples_per_class': None,
'lb_imb_ratio': 10,
'ulb_imb_ratio': 10,
'ulb_num_labels': 3000,
# algorithm specific configs
'hard_label': True,
'T': 0.5,
'ema_p': 0.999,
'ent_loss_ratio': 0.001,
'uratio': 2,
'ulb_loss_ratio': 1.0,
# device configs
'gpu': 0,
'world_size': 1,
'distributed': False,
"num_workers": 4,
}
config = get_config(config)
然后,我们重新加载数据集,并为训练和测试创建数据加载器。并指定要使用的模型和算法。
dataset_dict = get_dataset(config, config.algorithm, config.dataset, config.num_labels, config.num_classes, data_dir=config.data_dir, include_lb_to_ulb=config.include_lb_to_ulb)
train_lb_loader = get_data_loader(config, dataset_dict['train_lb'], config.batch_size)
train_ulb_loader = get_data_loader(config, dataset_dict['train_ulb'], int(config.batch_size * config.uratio))
eval_loader = get_data_loader(config, dataset_dict['eval'], config.eval_batch_size)
algorithm = get_algorithm(config, get_net_builder(config.net, from_name=False), tb_log=None, logger=None)
现在,我们可以开始使用 40 个标签在 CIFAR-10 上训练算法了。我们训练 500 次迭代,并在每 500 次迭代后进行评估。
trainer = Trainer(config, algorithm)
trainer.fit(train_lb_loader, train_ulb_loader, eval_loader)
最后,让我们在验证集上评估训练好的模型。
trainer.evaluate(eval_loader)
参考文献:- [1] USB: https://github.com/microsoft/Semi-supervised-learning - [2] Kihyuk Sohn 等人. FixMatch:利用一致性和置信度简化半监督学习 - [3] Yidong Wang 等人. FreeMatch:半监督学习中的自适应阈值 - [4] Hao Chen 等人. SoftMatch:解决半监督学习中的数量-质量权衡问题
脚本总运行时间:(0 分钟 0.000 秒)