Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to train custom data? #2

Closed
FrankFang0813 opened this issue Dec 27, 2021 · 5 comments
Closed

How to train custom data? #2

FrankFang0813 opened this issue Dec 27, 2021 · 5 comments

Comments

@FrankFang0813
Copy link

Hi! @WalBouss
I use 'swin_small_patch4_window7_224.pth' pretrained model to train my data.
It can run ,but I got acc = 0 and loss = 0, like this picture.

Selection_004

I want to ask how to train custom data.
where I should modify?

thank you!

@WalBouss
Copy link
Owner

Hi,

To train on a custom dataset, first, you must organize and register your dataset by following MMsegmentation guidelines. But since the guidelines are not that clear, here are quick steps to follow:

  1. arrange your custom dataset in the following manner
│   ├── my_dataset
│   │   ├── img_dir
│   │   │   ├── train
│   │   │   │   ├── xxx{img_suffix}
│   │   │   │   ├── yyy{img_suffix}
│   │   │   │   ├── zzz{img_suffix}
│   │   │   ├── val
│   │   ├── ann_dir
│   │   │   ├── train
│   │   │   │   ├── xxx{seg_map_suffix}
│   │   │   │   ├── yyy{seg_map_suffix}
│   │   │   │   ├── zzz{seg_map_suffix}
│   │   │   ├── val
  1. Create a file under mmseg/datasets/my_dataset.py, and specify the classes and the palette used for the annotations (get inspiration from other datasets already implemented).
from .builder import DATASETS
from .custom import CustomDataset

@DATASETS.register_module()
class MyDataset(CustomDataset):
   """My Custom dataset """
   CLASSES = (
       'class0', 'class1', 'class2')

   PALETTE = [[0, 192, 64], [0, 192, 64], [0, 64, 96]] # these are just random numbers between 0 and 255

   def __init__(self, **kwargs):
       super(MyDataset, self).__init__(
           img_suffix='.jpg', seg_map_suffix='_labelTrainIds.png', **kwargs)
  1. Register your dataset in mmseg/dataset/init.py
  2. Create a config for your dataset in senformer_config/base/datasets ( I would advise you to copy and adapt the config file of ade20k).
  3. Create a config file for your model that inherits from senformer_config/base/datasets/my_dataset.py. It should look to something like this:
_base_ = [
    '../../_base_/models/senformer_swin.py', '../../_base_/datasets/my_dataset.py', # <--- change name here
    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'
]
model = dict(
    pretrained='pretrain/swin_tiny_patch4_window7_224.pth',
    backbone=dict(
        embed_dims=96,
        depths=[2, 2, 6, 2],
        num_heads=[3, 6, 12, 24],
        window_size=7,
        use_abs_pos_embed=False,
        drop_path_rate=0.3,
        patch_norm=True),
    neck=dict(
        type='FPNT',
        in_channels=[96, 192, 384, 768],
        out_channels=512,
        num_outs=4,
        depth_swin=1,
        num_heads=8),
    decode_head=dict(
        type='SenFormer',
        num_heads=8,
        branch_depth=6,
        in_channels=[512, 512, 512, 512],
        in_index=[0, 1, 2, 3],
        feature_strides=[4, 8, 16, 32],
        channels=128,  # not used
        dropout_ratio=0.1,
        num_classes=150, # <--- change number of classes
        align_corners=False),
    auxiliary_head=dict(in_channels=384, num_classes=150)) # <--- change number of classes

# AdamW optimizer, no weight decay for position embedding & layer norm in backbone
optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,
                 paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),
                                                 'relative_position_bias_table': dict(decay_mult=0.),
                                                 'norm': dict(decay_mult=0.),
                                                 'queries': dict(decay_mult=0.),
                                                 }))
optimizer_config = dict(_delete_=True, grad_clip=dict(max_norm=0.1, norm_type=2))

lr_config = dict(_delete_=True, policy='poly',
                 warmup='linear',
                 warmup_iters=1500,
                 warmup_ratio=1e-6,
                 power=1.0, min_lr=0.0, by_epoch=False)

# By default, models are trained on 8 GPUs with 2 images per GPU or 4 GPUs with 4 images per GPU
data=dict(samples_per_gpu=4)

Also, if your dataset does not contain many images, I recommend you start from a pretrained model (not just a pretrained backbone). You can download SwinTiny-SenFormer pretrained on ADE20K here. And note that the default learning rate and training schedule is for a batch size of 16 so you may have to adapt them if you change the batch size.

Hope that helps.

@FrankFang0813
Copy link
Author

FrankFang0813 commented Dec 28, 2021

@WalBouss Thank you!
But I got a issue when I change num_classes of decode_head.
I use pretrained model,because I don't have many pictures.

_base_ = [
    '../../_base_/models/senformer_swin.py', '../../_base_/datasets/mydataset.py',
    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'
]

model = dict(
    pretrained='pretrain/swin_tiny_patch4_window7_224.pth',
    backbone=dict(
        embed_dims=96,
        depths=[2, 2, 6, 2],
        num_heads=[3, 6, 12, 24],
        window_size=7,
        use_abs_pos_embed=False,
        drop_path_rate=0.3,
        patch_norm=True),
    neck=dict(
        type='FPNT',
        in_channels=[96, 192, 384, 768],
        out_channels=512,
        num_outs=4,
        depth_swin=1,
        num_heads=8),
    decode_head=dict(
        type='SenFormer',
        num_heads=8,
        branch_depth=6,
        in_channels=[512, 512, 512, 512],
        in_index=[0, 1, 2, 3],
        feature_strides=[4, 8, 16, 32],
        channels=128,  # not used
        dropout_ratio=0.1,
        num_classes=1, # I change here
        align_corners=False),
    auxiliary_head=dict(in_channels=384, num_classes=1)) # I change here

# AdamW optimizer, no weight decay for position embedding & layer norm in backbone
optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,
                 paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),
                                                 'relative_position_bias_table': dict(decay_mult=0.),
                                                 'norm': dict(decay_mult=0.),
                                                 'queries': dict(decay_mult=0.),
                                                 }))
optimizer_config = dict(_delete_=True, grad_clip=dict(max_norm=0.1, norm_type=2))

lr_config = dict(_delete_=True, policy='poly',
                 warmup='linear',
                 warmup_iters=1500,
                 warmup_ratio=1e-6,
                 power=1.0, min_lr=0.0, by_epoch=False)

# By default, models are trained on 8 GPUs with 2 images per GPU or 4 GPUs with 4 images per GPU
data=dict(samples_per_gpu=1)

Selection_005

Selection_006

Is this env problem? my torch == 1.10.1 and cuda == 10.2
I train ade20k datasets is no problem,but I change num_classes of decode_head got the issue.

@WalBouss
Copy link
Owner

Hi Frank,

I suspect that your dataset is not well registered, could you please share the files related to your own dataset implementation, namely mmseg/datasets/mydataset.py and senformer_config/base/datasets/mydataset.py.

Furthermore, you should have at least 2 classes (background + class_1).

@FrankFang0813
Copy link
Author

FrankFang0813 commented Jan 3, 2022

Hi! ! @WalBouss
Thank you! I already trained my custom data!
#2 (comment)
This issue is my classes just have background and class1,but my class1 in picture is [128,128,128] > 2, so I can't train before.then I use opencv fillpoly with color [1,1,1],it can train!

@WalBouss
Copy link
Owner

WalBouss commented Jan 4, 2022

Glad it helped you!
I am closing this issue; don't hesitate to reopen it if you need.

@WalBouss WalBouss closed this as completed Jan 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants