DASSL est une boîte à outils Pytorch initialement développée pour notre apprentissage d'ensemble adaptatif de domaine (DAEL) pour soutenir la recherche dans l'adaptation et la généralisation du domaine --- car dans DAEL, nous étudions comment unifier ces deux problèmes dans un seul cadre d'apprentissage. Étant donné que l'adaptation du domaine est étroitement liée à l'apprentissage semi-supervisé - les deux étudient comment exploiter les données non marquées --- nous incorporons également des composants qui soutiennent la recherche pour ce dernier.
Pourquoi le nom "Dassl"? DASSL combine les initiales de l'adaptation du domaine (DA) et de l'apprentissage semi-supervisé (SSL), ce qui semble naturel et informatif.
DASSL a une conception modulaire et des interfaces unifiées, permettant un prototypage et une expérimentation rapides de nouvelles méthodes DA / DG / SSL. Avec DASSL, une nouvelle méthode peut être implémentée avec seulement quelques lignes de code. Vous ne croyez pas? Jetez un œil au dossier du moteur, qui contient les implémentations de nombreuses méthodes existantes (alors vous reviendrez et mettrez en vedette ce dépôt). :-)
Fondamentalement, DASSL est parfait pour faire des recherches dans les domaines suivants:
Mais, grâce à la conception soignée, DASSL peut également être utilisé comme base de code pour développer tous les projets d'apprentissage en profondeur, comme celui-ci. :-)
Un inconvénient de DASSL est qu'il ne prend pas (encore? HMM) La formation multi-GPU distribuée (DASSL utilise DataParallel pour envelopper un modèle, qui est moins efficace que DistributedDataParallel ).
Nous ne fournissons pas de documentations détaillées pour DASSL, contrairement à un autre projet. En effet, DASSL est développé à des fins de recherche et en tant que chercheur, nous pensons qu'il est important de pouvoir lire le code source et nous vous encourageons fortement à le faire --- certainement pas parce que nous sommes paresseux. :-)
v0.6.0 : rendre cfg.TRAINER.METHOD_NAME cohérent avec le nom de la classe de méthode.v0.5.0 : modifications importantes apportées à transforms.py . 1) center_crop devient une transformation par défaut dans les tests (appliqué après le redimensionnement du bord plus petit à une certaine taille pour maintenir le rapport d'aspect de l'image). 2) Pour la formation, Resize(cfg.INPUT.SIZE) est désactivé lorsque random_crop ou random_resized_crop est utilisé. Ces modifications ne feront aucune différence dans les transformations de formation utilisées dans les fichiers de configuration existants, ni pour les transformations de test à moins que les images brutes ne soient carrées (la seule différence est que le rapport d'aspect de l'image est maintenant respecté).v0.4.3 : Copiez les attributs dans self.dm (Data Manager) pour SimpleTrainer et rendre self.dm facultatif, ce qui signifie à partir de maintenant, vous pouvez créer des chargeurs de données à partir de n'importe quelle source que vous aimez plutôt que d'être obligé d'utiliser DataManager .v0.4.2 : Une mise à jour importante consiste à définir drop_last=is_train and len(data_source)>=batch_size lors de la construction d'un chargeur de données pour éviter la longueur 0. DASSL a implémenté les méthodes suivantes:
Adaptation de domaine à source unique
Adaptation du domaine multi-source
Généralisation du domaine
Apprentissage semi-supervisé
N'hésitez pas à faire un RP pour ajouter vos méthodes ici pour faciliter la tâche des autres!
DASSL prend en charge les ensembles de données suivants:
Adaptation du domaine
Généralisation du domaine
Apprentissage semi-supervisé
Assurez-vous que Conda est correctement installée.
# Clone this repo
git clone https://github.com/KaiyangZhou/Dassl.pytorch.git
cd Dassl.pytorch/
# Create a conda environment
conda create -y -n dassl python=3.8
# Activate the environment
conda activate dassl
# Install torch (requires version >= 1.8.1) and torchvision
# Please refer to https://pytorch.org/ if you need a different cuda version
conda install pytorch torchvision cudatoolkit=10.2 -c pytorch
# Install dependencies
pip install -r requirements.txt
# Install this library (no need to re-build if the source code is modified)
python setup.py developSuivez les instructions dans DataSets.md pour prétraiter les ensembles de données.
L'interface principale est implémentée dans tools/train.py , qui fait essentiellement
cfg = setup_cfg(args) où args contient l'entrée de ligne de commande (voir tools/train.py pour la liste des arguments d'entrée);trainer avec build_trainer(cfg) qui charge l'ensemble de données et construit un modèle de réseau neuronal profond;trainer.train() pour la formation et l'évaluation du modèle.Ci-dessous, nous fournissons un exemple pour la formation d'une base de référence uniquement sur l'ensemble de données d'adaptation du domaine populaire, Office-31,
CUDA_VISIBLE_DEVICES=0 python tools/train.py
--root $DATA
--trainer SourceOnly
--source-domains amazon
--target-domains webcam
--dataset-config-file configs/datasets/da/office31.yaml
--config-file configs/trainers/da/source_only/office31.yaml
--output-dir output/source_only_office31 $DATA indique l'emplacement où les ensembles de données sont installés. --dataset-config-file charge le paramètre commun pour l'ensemble de données (Office-31 dans ce cas) tel que la taille de l'image et l'architecture du modèle. --config-file charge le paramètre spécifique à l'algorithme tel que les hyper-paramètres et les paramètres d'optimisation.
Pour utiliser plusieurs sources, à savoir la tâche d'adaptation du domaine multi-sources, il suffit d'ajouter plus de sources à --source-domains . Par exemple, pour former une base de référence uniquement sur Minidomainnet, on peut faire
CUDA_VISIBLE_DEVICES=0 python tools/train.py
--root $DATA
--trainer SourceOnly
--source-domains clipart painting real
--target-domains sketch
--dataset-config-file configs/datasets/da/mini_domainnet.yaml
--config-file configs/trainers/da/source_only/mini_domainnet.yaml
--output-dir output/source_only_minidnUne fois la formation terminée, les poids du modèle seront enregistrés sous le répertoire de sortie spécifié, ainsi qu'un fichier journal et un fichier Tensorboard pour la visualisation.
Pour imprimer les résultats enregistrés dans le fichier journal (afin que vous n'ayez pas besoin de passer de manière exhaustive par tous les fichiers journaux et de calculer la moyenne / STD par vous-même), vous pouvez utiliser tools/parse_test_res.py . L'instruction peut être trouvée dans le code.
Pour d'autres formateurs tels que MCD , vous pouvez définir --trainer MCD tout en gardant le fichier de configuration inchangé, c'est-à-dire en utilisant les mêmes paramètres de formation que SourceOnly (dans le cas le plus simple). Pour modifier les hyper-paramètres dans MCD, comme N_STEP_F (nombre d'étapes pour mettre à jour l'extracteur de fonctionnalité), vous pouvez ajouter TRAINER.MCD.N_STEP_F 4 aux arguments d'entrée existants (sinon la valeur par défaut sera utilisée). Alternativement, vous pouvez créer un nouveau fichier de configuration .yaml pour stocker votre paramètre personnalisé. Voir ici pour une liste complète des hyper-paramètres spécifiques à l'algorithme.
Les tests de modèle peuvent être effectués en utilisant --eval-only , qui demande au code d'exécuter trainer.test() . Vous devez également fournir le modèle formé et spécifier quel fichier de modèle (c'est-à-dire enregistré à quelle époque) utilise. Par exemple, pour utiliser model.pth.tar-20 enregistré à output/source_only_office31/model , vous pouvez faire
CUDA_VISIBLE_DEVICES=0 python tools/train.py
--root $DATA
--trainer SourceOnly
--source-domains amazon
--target-domains webcam
--dataset-config-file configs/datasets/da/office31.yaml
--config-file configs/trainers/da/source_only/office31.yaml
--output-dir output/source_only_office31_test
--eval-only
--model-dir output/source_only_office31
--load-epoch 20 Notez que --model-dir prend en entrée le chemin du répertoire qui a été spécifié dans --output-dir au stade de la formation.
Une bonne pratique consiste à passer par dassl/engine/trainer.py pour devenir familier avec les classes de base de base, qui offrent des fonctions génériques et des boucles de formation. Pour écrire une classe de formateur pour l'adaptation du domaine ou l'apprentissage semi-supervisé, la nouvelle classe peut sous-classer TrainerXU . Pour la généralisation du domaine, la nouvelle classe peut sous-classer TrainerX . En particulier, TrainerXU et TrainerX diffèrent principalement dans la question de savoir si l'utilisation d'un chargeur de données pour les données non marquées. Avec les classes de base, un nouveau formateur peut uniquement avoir besoin d'implémenter la méthode forward_backward() , qui effectue un calcul des pertes et une mise à jour du modèle. Voir dassl/enigne/da/source_only.py par exemple.
backbone correspond à un modèle de réseau neuronal convolutionnel qui effectue une extraction de caractéristiques. head (qui est un module en option) est montée sur le haut de backbone pour un traitement ultérieur, qui peut être, par exemple, un MLP. backbone et head sont des blocs de construction de base pour la construction d'un SimpleNet() (voir dassl/engine/trainer.py ) qui sert de modèle principal pour une tâche. network contient des modèles de réseau neuronal personnalisés, tels qu'un générateur d'images.
Pour ajouter un nouveau module, à savoir une colonne vertébrale / tête / réseau, vous devez d'abord enregistrer le module à l'aide du registry correspondant, IE BACKBONE_REGISTRY pour backbone , HEAD_REGISTRY pour head et NETWORK_RESIGTRY pour network . Notez que pour une nouvelle backbone , nous avons besoin que le modèle de sous-classe Backbone tel que défini dans dassl/modeling/backbone/backbone.py et spécifiez l'attribut self._out_features .
Nous fournissons un exemple ci-dessous pour ajouter une nouvelle backbone .
from dassl . modeling import Backbone , BACKBONE_REGISTRY
class MyBackbone ( Backbone ):
def __init__ ( self ):
super (). __init__ ()
# Create layers
self . conv = ...
self . _out_features = 2048
def forward ( self , x ):
# Extract and return features
@ BACKBONE_REGISTRY . register ()
def my_backbone ( ** kwargs ):
return MyBackbone () Ensuite, vous pouvez définir MODEL.BACKBONE.NAME à my_backbone pour utiliser votre propre architecture. Pour plus de détails, veuillez consulter le code source dans dassl/modeling .
Un exemple de structure de code est illustré ci-dessous. Assurez-vous de sous-classer DatasetBase et enregistrez l'ensemble de données avec @DATASET_REGISTRY.register() . Tout ce dont vous avez besoin est de charger train_x , train_u (facultatif), val (facultatif) et test , parmi lesquels train_u et val pourraient être None ou simplement ignorés. Chacune de ces variables contient une liste d'objets Datum . Un objet Datum (implémenté ici) contient des informations pour une seule image, comme impath (String) et label (int).
from dassl . data . datasets import DATASET_REGISTRY , Datum , DatasetBase
@ DATASET_REGISTRY . register ()
class NewDataset ( DatasetBase ):
dataset_dir = ''
def __init__ ( self , cfg ):
train_x = ...
train_u = ... # optional, can be None
val = ... # optional, can be None
test = ...
super (). __init__ ( train_x = train_x , train_u = train_u , val = val , test = test )Nous vous suggérons de jeter un œil au code de jeu de données dans certains projets comme celui-ci, qui est construit au-dessus de DASSL.
Nous aimerions partager ici nos recherches pertinentes pour DASSL.
Si vous trouvez ce code utile à vos recherches, veuillez rendre hommage au document suivant
@article{zhou2022domain,
title={Domain generalization: A survey},
author={Zhou, Kaiyang and Liu, Ziwei and Qiao, Yu and Xiang, Tao and Loy, Chen Change},
journal={IEEE Transactions on Pattern Analysis and Machine Intelligence},
year={2022},
publisher={IEEE}
}
@article{zhou2021domain,
title={Domain adaptive ensemble learning},
author={Zhou, Kaiyang and Yang, Yongxin and Qiao, Yu and Xiang, Tao},
journal={IEEE Transactions on Image Processing},
volume={30},
pages={8008--8018},
year={2021},
publisher={IEEE}
}