forked from tkianai/ImageClassification.detectron2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
1,599 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<!-- | ||
* @Copyright (c) tkianai All Rights Reserved. | ||
* @Author : tkianai | ||
* @Github : https://github.com/tkianai | ||
* @Date : 2020-04-26 13:58:01 | ||
* @FilePath : /ImageCls.detectron2/README.md | ||
* @Description : | ||
--> | ||
|
||
|
||
# ImageClassification.detectron2 | ||
|
||
Image classification based on detectron2. | ||
|
||
This provides a convenient way to initialize backbone in detectron2. | ||
|
||
|
||
## Usage | ||
|
||
- Trained with detectron2 builtin trainer | ||
|
||
1. Use default data flow in detectron2, you only need rename `forward_d2` to `forward`, while renaming `forward` to `forward_imgnet` in `imgcls/modeling/meta_arch/clsnet.py` | ||
|
||
2. Create your own model config | ||
|
||
3. Run: `python train_net_builtin.py --num-gpus <gpu number> --config-file configs/<your config file>`. For example: `sh scripts/train_net_builtin.sh` | ||
|
||
|
||
- Trained with pytorch formal imagenet trainer | ||
|
||
1. Read carefully with some arguments in `train_net.py` | ||
2. Run: `sh /scripts/train_net.sh` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
MODEL: | ||
META_ARCHITECTURE: "ClsNet" | ||
BACKBONE: | ||
NAME: "build_mnetv1_backbone" | ||
FREEZE_AT: 0 | ||
MNET: | ||
OUT_FEATURES: ['linear'] | ||
WIDTH_MULT: 0.25 | ||
CLSNET: | ||
ENABLE: True | ||
NUM_CLASSES: 1000 | ||
INPUT_SIZE: 224 | ||
|
||
DATASETS: | ||
TRAIN: ("imagenet_train", ) | ||
TEST: ("imagenet_val", ) | ||
DATALOADER: | ||
ASPECT_RATIO_GROUPING: False | ||
NUM_WORKERS: 4 | ||
SOLVER: | ||
IMS_PER_BATCH: 512 | ||
BASE_LR: 0.1 | ||
STEPS: (150000, 180000) | ||
MAX_ITER: 200000 | ||
INPUT: | ||
CROP: | ||
ENABLED: True | ||
VERSION: 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 14:00:17 | ||
@FilePath : /ImageCls.detectron2/imgcls/__init__.py | ||
@Description : | ||
''' | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 14:18:06 | ||
@FilePath : /ImageCls.detectron2/imgcls/config/__init__.py | ||
@Description : | ||
''' | ||
|
||
from detectron2.config import CfgNode | ||
|
||
|
||
__all__ = ['get_cfg'] | ||
|
||
|
||
def get_cfg() -> CfgNode: | ||
"""Get a copy of the default config | ||
Returns: | ||
CfgNode -- a detectron2 CfgNode instance | ||
""" | ||
|
||
from .defaults import _C | ||
return _C.clone() | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 14:26:03 | ||
@FilePath : /ImageCls.detectron2/imgcls/config/defaults.py | ||
@Description : | ||
''' | ||
|
||
|
||
from detectron2.config.defaults import _C | ||
from detectron2.config import CfgNode as CN | ||
|
||
|
||
# ---------------------------------------------------------------------------- # | ||
# MobileNets | ||
# ---------------------------------------------------------------------------- # | ||
_C.MODEL.MNET = CN() | ||
|
||
# Output features | ||
_C.MODEL.MNET.OUT_FEATURES = ['linear'] | ||
# Width mult | ||
_C.MODEL.MNET.WIDTH_MULT = 1.0 | ||
|
||
|
||
# ---------------------------------------------------------------------------- # | ||
# ClsNets | ||
# ---------------------------------------------------------------------------- # | ||
_C.MODEL.CLSNET = CN() | ||
_C.MODEL.CLSNET.ENABLE = False | ||
# classes number | ||
_C.MODEL.CLSNET.NUM_CLASSES = 1000 | ||
# In features | ||
_C.MODEL.CLSNET.IN_FEATURES = ['linear'] | ||
# Input Size | ||
_C.MODEL.CLSNET.INPUT_SIZE = 224 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 16:40:05 | ||
@FilePath : /ImageCls.detectron2/imgcls/data/__init__.py | ||
@Description : | ||
''' | ||
|
||
|
||
from .imagenet import register_imagenet_instances | ||
from .dataset_mapper import DatasetMapper |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 17:01:36 | ||
@FilePath : /ImageCls.detectron2/imgcls/data/classification_utils.py | ||
@Description : | ||
''' | ||
|
||
|
||
import detectron2.data.transforms as T | ||
import logging | ||
|
||
|
||
def build_transform_gen(cfg, is_train): | ||
""" | ||
Create a list of :class:`TransformGen` from config. | ||
Now it includes resizing and flipping. | ||
Returns: | ||
list[TransformGen] | ||
""" | ||
input_size = cfg.MODEL.CLSNET.INPUT_SIZE | ||
|
||
logger = logging.getLogger("detectron2.data.classification_utils") | ||
tfm_gens = [] | ||
tfm_gens.append(T.Resize((input_size, input_size))) | ||
if is_train: | ||
tfm_gens.append(T.RandomContrast(0.5, 1.5)) | ||
tfm_gens.append(T.RandomBrightness(0.5, 1.5)) | ||
tfm_gens.append(T.RandomSaturation(0.5, 1.5)) | ||
tfm_gens.append(T.RandomFlip()) | ||
logger.info( | ||
"TransformGens used in training[Updated]: " + str(tfm_gens)) | ||
return tfm_gens |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 17:01:20 | ||
@FilePath : /ImageCls.detectron2/imgcls/data/dataset_mapper.py | ||
@Description : | ||
''' | ||
|
||
from . import classification_utils as c_utils | ||
|
||
|
||
from detectron2.data.dataset_mapper import DatasetMapper as _DatasetMapper | ||
|
||
|
||
|
||
class DatasetMapper(_DatasetMapper): | ||
|
||
def __init__(self, cfg, is_train=True): | ||
super().__init__(cfg, is_train) | ||
|
||
self.tfm_gens = c_utils.build_transform_gen(cfg, is_train) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 17:02:07 | ||
@FilePath : /ImageCls.detectron2/imgcls/data/imagenet.py | ||
@Description : | ||
''' | ||
|
||
|
||
import os | ||
import os.path as osp | ||
import json | ||
from detectron2.data import DatasetCatalog, MetadataCatalog | ||
|
||
|
||
def register_imagenet_instances(name, metadata, json_file): | ||
|
||
assert isinstance(name, str), name | ||
assert isinstance(json_file, (str, os.PathLike)), json_file | ||
|
||
# 1. register a function which returns dicts | ||
DatasetCatalog.register(name, lambda: json.load(open(json_file))) | ||
|
||
# 2. Optionally, add metadata about this dataset, | ||
# since they might be useful in evaluation, visualization or logging | ||
MetadataCatalog.get(name).set( | ||
json_file=json_file, evaluator_type="imagenet", **metadata | ||
) | ||
|
||
|
||
# Update info | ||
_root = os.getenv("DETECTRON2_DATASETS", "datasets") | ||
imagenet_train_annotation_file = osp.join(_root, "ImageNet2012/imagenet_detectron2_train.json") | ||
imagenet_val_annotation_file = osp.join(_root, "ImageNet2012/imagenet_detectron2_val.json") | ||
|
||
# Register into DatasetCatalog | ||
register_imagenet_instances("imagenet_train", {}, imagenet_train_annotation_file) | ||
register_imagenet_instances("imagenet_val", {}, imagenet_val_annotation_file) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 19:41:56 | ||
@FilePath : /ImageCls.detectron2/imgcls/evaluation/__init__.py | ||
@Description : | ||
''' | ||
|
||
|
||
from .imagenet_evaluation import ImageNetEvaluator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 19:42:05 | ||
@FilePath : /ImageCls.detectron2/imgcls/evaluation/imagenet_evaluation.py | ||
@Description : | ||
''' | ||
|
||
|
||
import itertools | ||
import json | ||
import logging | ||
from collections import OrderedDict | ||
import torch | ||
from fvcore.common.file_io import PathManager | ||
|
||
import detectron2.utils.comm as comm | ||
from detectron2.data import MetadataCatalog | ||
from detectron2.evaluation.evaluator import DatasetEvaluator | ||
|
||
|
||
class ImageNetEvaluator(DatasetEvaluator): | ||
|
||
def __init__(self, dataset_name, cfg, distributed, output_dir=None): | ||
self._distributed = distributed | ||
self._output_dir = output_dir | ||
|
||
self._cpu_device = torch.device("cpu") | ||
self._logger = logging.getLogger("detectron2.evaluation.imagenet_evaluation") | ||
|
||
self._metadata = MetadataCatalog.get(dataset_name) | ||
|
||
json_file = PathManager.get_local_path(self._metadata.json_file) | ||
self._gt = json.load(open(json_file)) | ||
|
||
def reset(self): | ||
self._predictions = [] | ||
|
||
def process(self, inputs, outputs): | ||
for input, output in zip(inputs, outputs): | ||
prediction = {"image_id": input["image_id"]} | ||
prediction["gt"] = input["label"] | ||
prediction["pred"] = output["pred_classes"].to(self._cpu_device) | ||
self._predictions.append(prediction) | ||
|
||
|
||
def evaluate(self): | ||
if self._distributed: | ||
comm.synchronize() | ||
predictions = comm.gather(self._predictions, dst=0) | ||
predictions = list(itertools.chain(*predictions)) | ||
|
||
if not comm.is_main_process(): | ||
return {} | ||
else: | ||
predictions = self._predictions | ||
|
||
if len(predictions) == 0: | ||
self._logger.warning( | ||
"[ImageNetEvaluator] Did not receive valid predictions.") | ||
return {} | ||
|
||
topk = len(self._predictions[0]['pred']) | ||
target = [] | ||
pred = [] | ||
for p in self._predictions: | ||
target.append(p['gt']) | ||
pred.append(p['pred']) | ||
pred = torch.stack(pred, dim=0) | ||
target = torch.as_tensor(target, dtype=pred.dtype) | ||
num_samples = target.size(0) | ||
|
||
pred = pred.t() | ||
correct = pred.eq(target.view(1, -1).expand_as(pred)) | ||
|
||
topk_acc = [] | ||
for k in range(1, topk + 1): | ||
correct_k = correct[:k].view(-1).float().sum(0, keepdim=True) | ||
topk_acc.append(correct_k.mul_(100.0 / num_samples)) | ||
result = OrderedDict( | ||
accuracy={"top{}".format(i + 1): acc.item() for i, acc in enumerate(topk_acc)}, | ||
) | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 14:11:12 | ||
@FilePath : /ImageCls.detectron2/imgcls/modeling/__init__.py | ||
@Description : | ||
''' | ||
|
||
|
||
from .backbone import * | ||
from .meta_arch import * | ||
|
||
|
||
__all__ = [k for k in globals().keys() if not k.startswith("_")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
''' | ||
@Copyright (c) tkianai All Rights Reserved. | ||
@Author : tkianai | ||
@Github : https://github.com/tkianai | ||
@Date : 2020-04-26 14:11:49 | ||
@FilePath : /ImageCls.detectron2/imgcls/modeling/backbone/__init__.py | ||
@Description : | ||
''' | ||
|
||
|
||
from .mobilenet import * | ||
|
||
|
||
__all__ = [k for k in globals().keys() if not k.startswith("_")] |
Oops, something went wrong.