From fb36b23678ae9092bec6b6784712df2ff2772b29 Mon Sep 17 00:00:00 2001 From: Xingyu Liao Date: Wed, 31 Mar 2021 17:07:19 +0800 Subject: [PATCH] bugfix for attribute project (#450) Summary: refactor sample weight in attribute recognition; change all options to False in defaults.py and modify yaml files --- configs/Base-bagtricks.yml | 5 ++++ configs/VERIWild/bagtricks_R50-ibn.yml | 2 +- configs/VehicleID/bagtricks_R50-ibn.yml | 3 ++- fastreid/config/defaults.py | 18 ++++++------- projects/FastAttr/configs/Base-attribute.yml | 14 ++++++---- projects/FastAttr/fastattr/attr_baseline.py | 26 +++++++++++-------- projects/FastAttr/fastattr/attr_dataset.py | 5 ++-- projects/FastAttr/fastattr/attr_evaluation.py | 2 +- projects/FastAttr/fastattr/attr_head.py | 14 +++------- projects/FastAttr/fastattr/data_build.py | 13 +++------- projects/FastAttr/train_net.py | 20 ++++++++------ projects/FastClas/configs/base-clas.yaml | 15 ++--------- .../{fastcls => fastclas}/__init__.py | 0 .../FastClas/{fastcls => fastclas}/bee_ant.py | 0 .../FastClas/{fastcls => fastclas}/dataset.py | 0 projects/FastClas/train_net.py | 2 +- .../FastRetri/configs/base-image_retri.yml | 5 ++-- projects/NAIC20/configs/Base-naic.yml | 5 ++++ projects/NAIC20/configs/submit.yml | 3 +++ 19 files changed, 79 insertions(+), 73 deletions(-) rename projects/FastClas/{fastcls => fastclas}/__init__.py (100%) rename projects/FastClas/{fastcls => fastclas}/bee_ant.py (100%) rename projects/FastClas/{fastcls => fastclas}/dataset.py (100%) diff --git a/configs/Base-bagtricks.yml b/configs/Base-bagtricks.yml index 71a7065..acab5f1 100644 --- a/configs/Base-bagtricks.yml +++ b/configs/Base-bagtricks.yml @@ -34,9 +34,14 @@ MODEL: INPUT: SIZE_TRAIN: [ 256, 128 ] SIZE_TEST: [ 256, 128 ] + REA: ENABLED: True PROB: 0.5 + + FLIP: + ENABLED: True + PADDING: ENABLED: True diff --git a/configs/VERIWild/bagtricks_R50-ibn.yml b/configs/VERIWild/bagtricks_R50-ibn.yml index 475b20d..2878727 100644 --- a/configs/VERIWild/bagtricks_R50-ibn.yml +++ b/configs/VERIWild/bagtricks_R50-ibn.yml @@ -9,7 +9,7 @@ MODEL: WITH_IBN: True HEADS: - POOL_LAYER: gempool + POOL_LAYER: GeneralizedMeanPooling LOSSES: TRI: diff --git a/configs/VehicleID/bagtricks_R50-ibn.yml b/configs/VehicleID/bagtricks_R50-ibn.yml index 222ee02..8603573 100644 --- a/configs/VehicleID/bagtricks_R50-ibn.yml +++ b/configs/VehicleID/bagtricks_R50-ibn.yml @@ -8,7 +8,8 @@ MODEL: BACKBONE: WITH_IBN: True HEADS: - POOL_LAYER: gempool + POOL_LAYER: GeneralizedMeanPooling + LOSSES: TRI: HARD_MINING: False diff --git a/fastreid/config/defaults.py b/fastreid/config/defaults.py index a14d131..d5ce1a4 100644 --- a/fastreid/config/defaults.py +++ b/fastreid/config/defaults.py @@ -47,7 +47,7 @@ _C.MODEL.BACKBONE.WITH_SE = False # If use Non-local block in backbone _C.MODEL.BACKBONE.WITH_NL = False # If use ImageNet pretrain model -_C.MODEL.BACKBONE.PRETRAIN = True +_C.MODEL.BACKBONE.PRETRAIN = False # Pretrain model path _C.MODEL.BACKBONE.PRETRAIN_PATH = '' @@ -63,14 +63,14 @@ _C.MODEL.HEADS.NUM_CLASSES = 0 # Embedding dimension in head _C.MODEL.HEADS.EMBEDDING_DIM = 0 # If use BNneck in embedding -_C.MODEL.HEADS.WITH_BNNECK = True +_C.MODEL.HEADS.WITH_BNNECK = False # Triplet feature using feature before(after) bnneck _C.MODEL.HEADS.NECK_FEAT = "before" # options: before, after # Pooling layer type -_C.MODEL.HEADS.POOL_LAYER = "avgpool" +_C.MODEL.HEADS.POOL_LAYER = "GlobalAvgPool" # Classification layer type -_C.MODEL.HEADS.CLS_LAYER = "linear" # "arcSoftmax" or "circleSoftmax" +_C.MODEL.HEADS.CLS_LAYER = "Linear" # ArcSoftmax" or "CircleSoftmax" # Margin and Scale for margin-based classification layer _C.MODEL.HEADS.MARGIN = 0.15 @@ -100,7 +100,7 @@ _C.MODEL.LOSSES.FL.SCALE = 1.0 _C.MODEL.LOSSES.TRI = CN() _C.MODEL.LOSSES.TRI.MARGIN = 0.3 _C.MODEL.LOSSES.TRI.NORM_FEAT = False -_C.MODEL.LOSSES.TRI.HARD_MINING = True +_C.MODEL.LOSSES.TRI.HARD_MINING = False _C.MODEL.LOSSES.TRI.SCALE = 1.0 # Circle Loss options @@ -150,11 +150,11 @@ _C.INPUT.CROP.SCALE = [0.16, 1] _C.INPUT.CROP.RATIO = [3./4., 4./3.] # Random probability for image horizontal flip -_C.INPUT.FLIP = CN({"ENABLED": True}) +_C.INPUT.FLIP = CN({"ENABLED": False}) _C.INPUT.FLIP.PROB = 0.5 # Value of padding size -_C.INPUT.PADDING = CN({"ENABLED": True}) +_C.INPUT.PADDING = CN({"ENABLED": False}) _C.INPUT.PADDING.MODE = 'constant' _C.INPUT.PADDING.SIZE = 10 @@ -201,7 +201,7 @@ _C.DATASETS.COMBINEALL = False # ----------------------------------------------------------------------------- _C.DATALOADER = CN() # Options: TrainingSampler, NaiveIdentitySampler, BalancedIdentitySampler -_C.DATALOADER.SAMPLER_TRAIN = "NaiveIdentitySampler" +_C.DATALOADER.SAMPLER_TRAIN = "TrainingSampler" # Number of instance for each person _C.DATALOADER.NUM_INSTANCE = 4 _C.DATALOADER.NUM_WORKERS = 8 @@ -224,7 +224,7 @@ _C.SOLVER.BIAS_LR_FACTOR = 1. _C.SOLVER.HEADS_LR_FACTOR = 1. _C.SOLVER.MOMENTUM = 0.9 -_C.SOLVER.NESTEROV = True +_C.SOLVER.NESTEROV = False _C.SOLVER.WEIGHT_DECAY = 0.0005 _C.SOLVER.WEIGHT_DECAY_BIAS = 0. diff --git a/projects/FastAttr/configs/Base-attribute.yml b/projects/FastAttr/configs/Base-attribute.yml index f9ee16e..d832ab1 100644 --- a/projects/FastAttr/configs/Base-attribute.yml +++ b/projects/FastAttr/configs/Base-attribute.yml @@ -14,8 +14,8 @@ MODEL: HEADS: NAME: AttrHead WITH_BNNECK: True - POOL_LAYER: fastavgpool - CLS_LAYER: linear + POOL_LAYER: FastGlobalAvgPool + CLS_LAYER: Linear NUM_CLASSES: 26 LOSSES: @@ -28,11 +28,15 @@ MODEL: INPUT: SIZE_TRAIN: [ 256, 192 ] SIZE_TEST: [ 256, 192 ] - REA: - ENABLED: False - DO_PAD: True + + FLIP: + ENABLED: True + + PADDING: + ENABLED: True DATALOADER: + SAMPLER_TRAIN: TrainingSampler NUM_WORKERS: 8 SOLVER: diff --git a/projects/FastAttr/fastattr/attr_baseline.py b/projects/FastAttr/fastattr/attr_baseline.py index ae14356..46657b3 100644 --- a/projects/FastAttr/fastattr/attr_baseline.py +++ b/projects/FastAttr/fastattr/attr_baseline.py @@ -11,13 +11,16 @@ from .bce_loss import cross_entropy_sigmoid_loss @META_ARCH_REGISTRY.register() class AttrBaseline(Baseline): - def __init__(self, cfg, sample_weights): - super(AttrBaseline, self).__init__(cfg) - bce_weight_enabled = cfg.MODEL.LOSSES.BCE.WEIGHT_ENABLED - if bce_weight_enabled: - self.register_buffer("sample_weight", sample_weights) - else: - self.sample_weights = None + + @classmethod + def from_config(cls, cfg): + base_res = Baseline.from_config(cfg) + base_res["loss_kwargs"].update({ + 'bce': { + 'scale': cfg.MODEL.LOSSES.BCE.SCALE + } + }) + return base_res def losses(self, outputs, gt_labels): r""" @@ -25,16 +28,17 @@ class AttrBaseline(Baseline): must be the same as the outputs of the model forwarding. """ # model predictions - cls_outputs = outputs['cls_outputs'] + cls_outputs = outputs["cls_outputs"] loss_dict = {} - loss_names = self._cfg.MODEL.LOSSES.NAME + loss_names = self.loss_kwargs["loss_names"] if "BinaryCrossEntropyLoss" in loss_names: + bce_kwargs = self.loss_kwargs.get('bce') loss_dict["loss_bce"] = cross_entropy_sigmoid_loss( cls_outputs, gt_labels, - self.sample_weight, - ) * self._cfg.MODEL.LOSSES.BCE.SCALE + self.sample_weights, + ) * bce_kwargs.get('scale') return loss_dict diff --git a/projects/FastAttr/fastattr/attr_dataset.py b/projects/FastAttr/fastattr/attr_dataset.py index 0d78a46..2d8d62b 100644 --- a/projects/FastAttr/fastattr/attr_dataset.py +++ b/projects/FastAttr/fastattr/attr_dataset.py @@ -13,10 +13,10 @@ from fastreid.data.data_utils import read_image class AttrDataset(Dataset): """Image Person Attribute Dataset""" - def __init__(self, img_items, attr_dict, transform=None): + def __init__(self, img_items, transform, attr_dict): self.img_items = img_items - self.attr_dict = attr_dict self.transform = transform + self.attr_dict = attr_dict def __len__(self): return len(self.img_items) @@ -24,6 +24,7 @@ class AttrDataset(Dataset): def __getitem__(self, index): img_path, labels = self.img_items[index] img = read_image(img_path) + if self.transform is not None: img = self.transform(img) labels = torch.as_tensor(labels) diff --git a/projects/FastAttr/fastattr/attr_evaluation.py b/projects/FastAttr/fastattr/attr_evaluation.py index eb06dde..1725818 100644 --- a/projects/FastAttr/fastattr/attr_evaluation.py +++ b/projects/FastAttr/fastattr/attr_evaluation.py @@ -12,7 +12,7 @@ import torch from fastreid.evaluation.evaluator import DatasetEvaluator from fastreid.utils import comm -logger = logging.getLogger(__name__) +logger = logging.getLogger("fastreid.attr_evaluation") class AttrEvaluator(DatasetEvaluator): diff --git a/projects/FastAttr/fastattr/attr_head.py b/projects/FastAttr/fastattr/attr_head.py index 4441809..621de8a 100644 --- a/projects/FastAttr/fastattr/attr_head.py +++ b/projects/FastAttr/fastattr/attr_head.py @@ -28,22 +28,16 @@ class AttrHead(EmbeddingHead): """ pool_feat = self.pool_layer(features) neck_feat = self.bottleneck(pool_feat) - neck_feat = neck_feat[..., 0, 0] + neck_feat = neck_feat.view(neck_feat.size(0), -1) - if self.cls_layer.__class__.__name__ == 'Linear': - logits = F.linear(neck_feat, self.weight) - else: - logits = F.linear(F.normalize(neck_feat), F.normalize(self.weight)) + logits = F.linear(neck_feat, self.weight) + logits = self.bnneck(logits) # Evaluation if not self.training: - logits = self.bnneck(logits * self.cls_layer.s) cls_outptus = torch.sigmoid(logits) return cls_outptus - cls_outputs = self.cls_layer(logits, targets) - cls_outputs = self.bnneck(cls_outputs) - return { - 'cls_outputs': cls_outputs, + "cls_outputs": logits, } diff --git a/projects/FastAttr/fastattr/data_build.py b/projects/FastAttr/fastattr/data_build.py index 1b52a44..d1b9959 100644 --- a/projects/FastAttr/fastattr/data_build.py +++ b/projects/FastAttr/fastattr/data_build.py @@ -20,9 +20,6 @@ _root = os.getenv("FASTREID_DATASETS", "datasets") def build_attr_train_loader(cfg): - cfg = cfg.clone() - cfg.defrost() - train_items = list() attr_dict = None for d in cfg.DATASETS.NAMES: @@ -30,13 +27,13 @@ def build_attr_train_loader(cfg): if comm.is_main_process(): dataset.show_train() if attr_dict is not None: - assert attr_dict == dataset.attr_dict, "attr_dict in {} does not match with previous ones".format(d) + assert attr_dict == dataset.attr_dict, f"attr_dict in {d} does not match with previous ones" else: attr_dict = dataset.attr_dict train_items.extend(dataset.train) train_transforms = build_transforms(cfg, is_train=True) - train_set = AttrDataset(train_items, attr_dict, train_transforms) + train_set = AttrDataset(train_items, train_transforms, attr_dict) num_workers = cfg.DATALOADER.NUM_WORKERS mini_batch_size = cfg.SOLVER.IMS_PER_BATCH // comm.get_world_size() @@ -55,16 +52,14 @@ def build_attr_train_loader(cfg): def build_attr_test_loader(cfg, dataset_name): - cfg = cfg.clone() - cfg.defrost() - dataset = DATASET_REGISTRY.get(dataset_name)(root=_root, combineall=cfg.DATASETS.COMBINEALL) + attr_dict = dataset.attr_dict if comm.is_main_process(): dataset.show_test() test_items = dataset.test test_transforms = build_transforms(cfg, is_train=False) - test_set = AttrDataset(test_items, dataset.attr_dict, test_transforms) + test_set = AttrDataset(test_items, test_transforms, attr_dict) mini_batch_size = cfg.TEST.IMS_PER_BATCH // comm.get_world_size() data_sampler = samplers.InferenceSampler(len(test_set)) diff --git a/projects/FastAttr/train_net.py b/projects/FastAttr/train_net.py index 5d16370..7eaa0b7 100644 --- a/projects/FastAttr/train_net.py +++ b/projects/FastAttr/train_net.py @@ -3,14 +3,12 @@ @author: xingyu liao @contact: sherlockliao01@gmail.com """ -import logging import sys sys.path.append('.') from fastreid.config import get_cfg from fastreid.engine import DefaultTrainer -from fastreid.modeling import build_model from fastreid.engine import default_argument_parser, default_setup, launch from fastreid.utils.checkpoint import Checkpointer @@ -18,22 +16,28 @@ from fastattr import * class Trainer(DefaultTrainer): + sample_weights = None - def build_model(self, cfg): + @classmethod + def build_model(cls, cfg): """ Returns: torch.nn.Module: It now calls :func:`fastreid.modeling.build_model`. Overwrite it if you'd like a different model. """ - model = build_model(cfg, sample_weights=self.sample_weights) - logger = logging.getLogger("fastreid.attr_model") - logger.info("Model:\n{}".format(model)) + model = DefaultTrainer.build_model(cfg) + if cfg.MODEL.LOSSES.BCE.WEIGHT_ENABLED and \ + Trainer.sample_weights is not None: + setattr(model, "sample_weights", Trainer.sample_weights.to(model.device)) + else: + setattr(model, "sample_weights", None) return model - def build_train_loader(self, cfg): + @classmethod + def build_train_loader(cls, cfg): data_loader = build_attr_train_loader(cfg) - self.sample_weights = data_loader.dataset.sample_weights + Trainer.sample_weights = data_loader.dataset.sample_weights return data_loader @classmethod diff --git a/projects/FastClas/configs/base-clas.yaml b/projects/FastClas/configs/base-clas.yaml index 9b953ed..031ca4c 100644 --- a/projects/FastClas/configs/base-clas.yaml +++ b/projects/FastClas/configs/base-clas.yaml @@ -26,25 +26,14 @@ MODEL: INPUT: SIZE_TEST: [256, 256] + CROP: ENABLED: True SIZE: [224, 224] + FLIP: ENABLED: True - AUGMIX: - ENABLED: False - AUTOAUG: - ENABLED: False - PADDING: - ENABLED: False - CJ: - ENABLED: False - AFFINE: - ENABLED: False - REA: - ENABLED: False - DATALOADER: SAMPLER_TRAIN: TrainingSampler NUM_WORKERS: 8 diff --git a/projects/FastClas/fastcls/__init__.py b/projects/FastClas/fastclas/__init__.py similarity index 100% rename from projects/FastClas/fastcls/__init__.py rename to projects/FastClas/fastclas/__init__.py diff --git a/projects/FastClas/fastcls/bee_ant.py b/projects/FastClas/fastclas/bee_ant.py similarity index 100% rename from projects/FastClas/fastcls/bee_ant.py rename to projects/FastClas/fastclas/bee_ant.py diff --git a/projects/FastClas/fastcls/dataset.py b/projects/FastClas/fastclas/dataset.py similarity index 100% rename from projects/FastClas/fastcls/dataset.py rename to projects/FastClas/fastclas/dataset.py diff --git a/projects/FastClas/train_net.py b/projects/FastClas/train_net.py index 7ff7ad4..9824c4f 100644 --- a/projects/FastClas/train_net.py +++ b/projects/FastClas/train_net.py @@ -20,7 +20,7 @@ from fastreid.utils.checkpoint import Checkpointer, PathManager from fastreid.utils import comm from fastreid.engine import DefaultTrainer -from fastcls import * +from fastclas import * class Trainer(DefaultTrainer): diff --git a/projects/FastRetri/configs/base-image_retri.yml b/projects/FastRetri/configs/base-image_retri.yml index 85294d3..cdf2bc9 100644 --- a/projects/FastRetri/configs/base-image_retri.yml +++ b/projects/FastRetri/configs/base-image_retri.yml @@ -34,8 +34,8 @@ INPUT: SCALE: [0.16, 1.] RATIO: [0.75, 1.33333] - PADDING: - ENABLED: False + FLIP: + ENABLED: True CJ: ENABLED: False @@ -44,6 +44,7 @@ INPUT: SATURATION: 0.1 HUE: 0.1 + DATALOADER: SAMPLER_TRAIN: TrainingSampler NUM_WORKERS: 8 diff --git a/projects/NAIC20/configs/Base-naic.yml b/projects/NAIC20/configs/Base-naic.yml index a132fb0..2c92dad 100644 --- a/projects/NAIC20/configs/Base-naic.yml +++ b/projects/NAIC20/configs/Base-naic.yml @@ -35,6 +35,11 @@ INPUT: SIZE_TRAIN: [ 256, 128 ] SIZE_TEST: [ 256, 128 ] + FLIP: + ENABLED: True + + PADDING: + ENABLED: True AUGMIX: ENABLED: True diff --git a/projects/NAIC20/configs/submit.yml b/projects/NAIC20/configs/submit.yml index 7b8cb40..6058776 100644 --- a/projects/NAIC20/configs/submit.yml +++ b/projects/NAIC20/configs/submit.yml @@ -19,6 +19,9 @@ TEST: K2: 3 LAMBDA: 0.8 + FLIP: + ENABLED: True + SAVE_DISTMAT: True OUTPUT_DIR: projects/NAIC20/logs/r34_ibn-128x256-submit \ No newline at end of file