• Tutorials >
  • Semi-Supervised Learning using USB built upon PyTorch
Shortcuts

基于PyTorch的USB半监督学习

创建于:2023年12月07日 | 最后更新:2024年03月07日 | 最后验证:未验证

作者: Hao Chen

统一半监督学习基准(USB)是一个基于PyTorch构建的半监督学习(SSL)框架。基于PyTorch提供的数据集和模块,USB成为一个灵活、模块化且易于使用的半监督学习框架。它支持多种半监督学习算法,包括FixMatchFreeMatchDeFixMatchSoftMatch等。它还支持多种不平衡半监督学习算法。USB包含了计算机视觉、自然语言处理和语音处理等不同数据集的基准测试结果。

本教程将引导您了解使用USB照明包的基础知识。 让我们从在CIFAR-10上使用预训练的视觉变换器(ViT)训练FreeMatch/SoftMatch模型开始吧! 我们将展示如何轻松更改半监督算法并在不平衡数据集上进行训练。

USB framework illustration

半监督学习中的FreeMatchSoftMatch介绍

这里我们简要介绍FreeMatchSoftMatch。 首先,我们介绍一个著名的半监督学习基线方法,称为FixMatchFixMatch是一个非常简单的半监督学习框架,它利用强增强技术为未标记数据生成伪标签。 它采用置信度阈值策略,通过固定的阈值设置过滤掉低置信度的伪标签。 FreeMatchSoftMatch是两种改进FixMatch的算法。 FreeMatch提出了自适应阈值策略,以取代FixMatch中的固定阈值策略。自适应阈值根据模型在每个类别上的学习状态逐步增加阈值。 SoftMatch吸收了置信度阈值的思想作为一种加权机制。它提出了一种高斯加权机制,以克服伪标签中的数量-质量权衡。在本教程中,我们将使用USB来训练FreeMatchSoftMatch

使用USB在CIFAR-10上训练FreeMatch/SoftMatch,仅使用40个标签

USB易于使用和扩展,对小团队来说价格合理,并且全面适用于开发和评估SSL算法。 USB提供了基于一致性正则化的14种SSL算法的实现,以及来自CV、NLP和音频领域的15个评估任务。 它具有模块化设计,允许用户通过添加新算法和任务轻松扩展包。 它还支持Python API,以便更容易地适应新数据上的不同SSL算法。

现在,让我们使用USB在CIFAR-10上训练FreeMatchSoftMatch。 首先,我们需要安装USB包semilearn并从USB导入必要的API函数。 如果你在Google Colab中运行此代码,请通过运行以下命令安装semilearn!pip install semilearn

以下是我们将从semilearn中使用的函数列表:

  • get_dataset 用于加载数据集,这里我们使用 CIFAR-10

  • get_data_loader 用于创建训练(有标签和无标签)和测试数据

加载器,未标记的训练加载器将提供未标记数据的强增强和弱增强 - get_net_builder 用于创建模型,这里我们使用预训练的ViT - get_algorithm 用于创建半监督学习算法, 这里我们使用 FreeMatchSoftMatch - get_config: 用于获取算法的默认配置 - Trainer: 一个用于在数据集上训练和评估算法的Trainer类

请注意,使用semilearn包进行训练需要支持CUDA的后端。 有关在Google Colab中启用CUDA的说明,请参见Enabling CUDA in Google Colab

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个标签进行500次迭代训练后,我们获得了一个分类器,该分类器在验证集上的准确率约为87%。

trainer.evaluate(eval_loader)

使用USB在不平衡的CIFAR-10上训练SoftMatch,并应用特定的不平衡算法

现在假设我们有一个不平衡的CIFAR-10标记集和未标记集,并且我们想在其上训练一个SoftMatch模型。我们通过将lb_imb_ratioulb_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)

我们现在可以开始在CIFAR-10上使用40个标签训练算法了。 我们训练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 秒)

Gallery generated by Sphinx-Gallery