diff --git a/configs/restorers/liif/README.md b/configs/restorers/liif/README.md new file mode 100644 index 0000000000..1a66533cc9 --- /dev/null +++ b/configs/restorers/liif/README.md @@ -0,0 +1,38 @@ +# Learning Continuous Image Representation with Local Implicit Image Function (LIIF) + +## Introduction + +[ALGORITHM] + +```bibtex +@article{chen2020learning, + title={Learning Continuous Image Representation with Local Implicit Image Function}, + author={Chen, Yinbo and Liu, Sifei and Wang, Xiaolong}, + journal={arXiv preprint arXiv:2012.09161}, + year={2020} +} +``` + +## Results and Models + +Evaluated on RGB channels, `scale` pixels in each border are cropped before evaluation. + +The metrics are `PSNR / SSIM`. + +Data is normalized according to [EDSR](/configs/restorers/edsr). + +△ refers to ditto. + +|method|scale|Set5| Set14 | DIV2K | Download | +| :--------------: | :--------------: | :--------------: | :--------------: | :--------------: | :--------------: | +|[liif_edsr_norm_x2-4_c64b16_g1_1000k_div2k](configs/restorers/liif/liif_edsr_norm_x2-4_c64b16_g1_1000k_div2k.py)| x2 | 35.7148 / 0.9367 | 31.5936 / 0.8889 | 34.5896 / 0.9352 | [model](https://download.openmmlab.com/mmediting/restorers/liif/liif_edsr_norm_c64b16_g1_1000k_div2k_20210319-329ce255.pth) \| [log](https://download.openmmlab.com/mmediting/restorers/liif/liif_edsr_norm_c64b16_g1_1000k_div2k_20210319-329ce255.log.json) | +|△| x3 | 32.3596 / 0.8914 | 28.4475 / 0.8040 | 30.9154 / 0.8720 | △ | +|△| x4 | 30.2583 / 0.8513 | 26.7867 / 0.7377 | 29.0048 / 0.8183 | △ | +|[liif_edsr_norm_c64b16_g1_1000k_div2k](/configs/restorers/liif/liif_edsr_norm_c64b16_g1_1000k_div2k.py)| x2 | 35.7120 / 0.9365 | 31.6106 / 0.8891 | 34.6401 / 0.9353 | △ | +|△| x3 | 32.3655 / 0.8913 | 28.4605 / 0.8039 | 30.9597 / 0.8711 | △ | +|△| x4 | 30.2668 / 0.8511 | 26.8093 / 0.7377 | 29.0059 / 0.8183 | △ | +|△| x6 | 27.0907 / 0.7775 | 24.7129 / 0.6438 | 26.7694 / 0.7422 | △ | +|△| x12 | 22.9046 / 0.6255 | 21.5378 / 0.5088 | 23.7269 / 0.6373 | △ | +|△| x18 | 20.8445 / 0.5390 | 20.0215 / 0.4521 | 22.1920 / 0.5947 | △ | +|△| x24 | 19.7305 / 0.5033 | 19.0703 / 0.4218 | 21.2025 / 0.5714 | △ | +|△| x30 | 18.6646 / 0.4818 | 18.0210 / 0.3905 | 20.5022 / 0.5568 | △ | diff --git a/configs/restorers/liif/liif_edsr_norm_c64b16_g1_1000k_div2k.py b/configs/restorers/liif/liif_edsr_norm_c64b16_g1_1000k_div2k.py new file mode 100644 index 0000000000..fb764711b6 --- /dev/null +++ b/configs/restorers/liif/liif_edsr_norm_c64b16_g1_1000k_div2k.py @@ -0,0 +1,131 @@ +exp_name = 'liif_edsr_norm_c64b16_g1_1000k_div2k' +scale_min, scale_max = 1, 4 + +# model settings +model = dict( + type='LIIF', + generator=dict( + type='EDSR', + in_channels=3, + out_channels=3, + mid_channels=64, + num_blocks=16), + imnet=dict( + type='MLPRefiner', + in_dim=64, + out_dim=3, + hidden_list=[256, 256, 256, 256]), + local_ensemble=True, + feat_unfold=True, + cell_decode=True, + rgb_mean=(0.4488, 0.4371, 0.4040), + rgb_std=(1., 1., 1.), + eval_bsize=30000, + pixel_loss=dict(type='L1Loss', loss_weight=1.0, reduction='mean')) +# model training and testing settings +train_cfg = None +test_cfg = dict(metrics=['PSNR', 'SSIM'], crop_border=scale_max) + +# dataset settings +scale_min, scale_max = 1, 4 +# dataset settings +train_dataset_type = 'SRFolderGTDataset' +val_dataset_type = 'SRFolderGTDataset' +test_dataset_type = 'SRFolderGTDataset' +train_pipeline = [ + dict( + type='LoadImageFromFile', + io_backend='disk', + key='gt', + flag='color', + channel_order='rgb'), + dict( + type='RandomDownSampling', + scale_min=scale_min, + scale_max=scale_max, + inp_size=48), + dict(type='RescaleToZeroOne', keys=['lq', 'gt']), + dict( + type='Flip', keys=['lq', 'gt'], flip_ratio=0.5, + direction='horizontal'), + dict(type='Flip', keys=['lq', 'gt'], flip_ratio=0.5, direction='vertical'), + dict(type='RandomTransposeHW', keys=['lq', 'gt'], transpose_ratio=0.5), + dict(type='ImageToTensor', keys=['lq', 'gt']), + dict(type='GenerateCoordinateAndCell', sample_q=2304), + dict( + type='Collect', + keys=['lq', 'gt', 'coord', 'cell'], + meta_keys=['gt_path']) +] +valid_pipeline = [ + dict( + type='LoadImageFromFile', + io_backend='disk', + key='gt', + flag='color', + channel_order='rgb'), + dict(type='RandomDownSampling', scale_min=scale_max, scale_max=scale_max), + dict(type='RescaleToZeroOne', keys=['lq', 'gt']), + dict(type='ImageToTensor', keys=['lq', 'gt']), + dict(type='GenerateCoordinateAndCell'), + dict( + type='Collect', + keys=['lq', 'gt', 'coord', 'cell'], + meta_keys=['gt_path']) +] + +data = dict( + workers_per_gpu=8, + train_dataloader=dict(samples_per_gpu=16, drop_last=True), + val_dataloader=dict(samples_per_gpu=1), + test_dataloader=dict(samples_per_gpu=1), + train=dict( + type='RepeatDataset', + times=20, + dataset=dict( + type=train_dataset_type, + gt_folder='data/DIV2K/DIV2K_train_HR', + pipeline=train_pipeline, + scale=scale_max)), + val=dict( + type=val_dataset_type, + gt_folder='data/val_set5/Set5', + pipeline=valid_pipeline, + scale=scale_max), + test=dict( + type=test_dataset_type, + gt_folder='data/val_set5/Set5', + pipeline=valid_pipeline, + scale=scale_max, + filename_tmpl='{}')) + +# optimizer +optimizers = dict(type='Adam', lr=1.e-4) + +# learning policy +iter_per_epoch = 1000 +total_iters = 1000 * iter_per_epoch +lr_config = dict( + policy='Step', + by_epoch=False, + step=[200000, 400000, 600000, 800000], + gamma=0.5) + +checkpoint_config = dict( + interval=iter_per_epoch, save_optimizer=True, by_epoch=False) +evaluation = dict(interval=iter_per_epoch, save_image=True, gpu_collect=True) +log_config = dict( + interval=100, + hooks=[ + dict(type='TextLoggerHook', by_epoch=False), + dict(type='TensorboardLoggerHook') + ]) +visual_config = None + +# runtime settings +dist_params = dict(backend='nccl') +log_level = 'INFO' +work_dir = f'./work_dirs/{exp_name}' +load_from = None +resume_from = None +workflow = [('train', 1)] diff --git a/configs/restorers/liif/liif_edsr_norm_x2-4_c64b16_g1_1000k_div2k.py b/configs/restorers/liif/liif_edsr_norm_x2-4_c64b16_g1_1000k_div2k.py new file mode 100644 index 0000000000..f10294b044 --- /dev/null +++ b/configs/restorers/liif/liif_edsr_norm_x2-4_c64b16_g1_1000k_div2k.py @@ -0,0 +1,153 @@ +exp_name = 'liif_edsr_norm_x2-4_c64b16_g1_1000k_div2k' +scale_min, scale_max = 1, 4 + +# model settings +model = dict( + type='LIIF', + generator=dict( + type='EDSR', + in_channels=3, + out_channels=3, + mid_channels=64, + num_blocks=16), + imnet=dict( + type='MLPRefiner', + in_dim=64, + out_dim=3, + hidden_list=[256, 256, 256, 256]), + local_ensemble=True, + feat_unfold=True, + cell_decode=True, + rgb_mean=(0.4488, 0.4371, 0.4040), + rgb_std=(1., 1., 1.), + eval_bsize=30000, + pixel_loss=dict(type='L1Loss', loss_weight=1.0, reduction='mean')) +# model training and testing settings +train_cfg = None +test_cfg = dict(metrics=['PSNR', 'SSIM'], crop_border=scale_max) + +# dataset settings +scale_min, scale_max = 1, 4 +# dataset settings +train_dataset_type = 'SRFolderGTDataset' +val_dataset_type = 'SRFolderGTDataset' +test_dataset_type = 'SRFolderDataset' +train_pipeline = [ + dict( + type='LoadImageFromFile', + io_backend='disk', + key='gt', + flag='color', + channel_order='rgb'), + dict( + type='RandomDownSampling', + scale_min=scale_min, + scale_max=scale_max, + inp_size=48), + dict(type='RescaleToZeroOne', keys=['lq', 'gt']), + dict( + type='Flip', keys=['lq', 'gt'], flip_ratio=0.5, + direction='horizontal'), + dict(type='Flip', keys=['lq', 'gt'], flip_ratio=0.5, direction='vertical'), + dict(type='RandomTransposeHW', keys=['lq', 'gt'], transpose_ratio=0.5), + dict(type='ImageToTensor', keys=['lq', 'gt']), + dict(type='GenerateCoordinateAndCell', sample_q=2304), + dict( + type='Collect', + keys=['lq', 'gt', 'coord', 'cell'], + meta_keys=['gt_path']) +] +valid_pipeline = [ + dict( + type='LoadImageFromFile', + io_backend='disk', + key='gt', + flag='color', + channel_order='rgb'), + dict(type='RandomDownSampling', scale_min=scale_max, scale_max=scale_max), + dict(type='RescaleToZeroOne', keys=['lq', 'gt']), + dict(type='ImageToTensor', keys=['lq', 'gt']), + dict(type='GenerateCoordinateAndCell'), + dict( + type='Collect', + keys=['lq', 'gt', 'coord', 'cell'], + meta_keys=['gt_path']) +] +test_pipeline = [ + dict( + type='LoadImageFromFile', + io_backend='disk', + key='gt', + flag='color', + channel_order='rgb'), + dict( + type='LoadImageFromFile', + io_backend='disk', + key='lq', + flag='color', + channel_order='rgb'), + dict(type='RescaleToZeroOne', keys=['lq', 'gt']), + dict(type='ImageToTensor', keys=['lq', 'gt']), + dict(type='GenerateCoordinateAndCell', scale=scale_max), + dict( + type='Collect', + keys=['lq', 'gt', 'coord', 'cell'], + meta_keys=['gt_path']) +] + +data = dict( + workers_per_gpu=8, + train_dataloader=dict(samples_per_gpu=16, drop_last=True), + val_dataloader=dict(samples_per_gpu=1), + test_dataloader=dict(samples_per_gpu=1), + train=dict( + type='RepeatDataset', + times=20, + dataset=dict( + type=train_dataset_type, + gt_folder='data/DIV2K/DIV2K_train_HR', + pipeline=train_pipeline, + scale=scale_max)), + val=dict( + type=val_dataset_type, + gt_folder='data/val_set5/Set5', + pipeline=valid_pipeline, + scale=scale_max), + test=dict( + type=test_dataset_type, + lq_folder='data/val_set5/Set5_bicLRx{:d}'.format(scale_max), + gt_folder='data/val_set5/Set5', + pipeline=test_pipeline, + scale=scale_max, + filename_tmpl='{}')) + +# optimizer +optimizers = dict(type='Adam', lr=1.e-4) + +# learning policy +iter_per_epoch = 1000 +total_iters = 1000 * iter_per_epoch +lr_config = dict( + policy='Step', + by_epoch=False, + step=[200000, 400000, 600000, 800000], + gamma=0.5) + +checkpoint_config = dict( + interval=iter_per_epoch, save_optimizer=True, by_epoch=False) +evaluation = dict(interval=iter_per_epoch, save_image=True, gpu_collect=True) +log_config = dict( + interval=100, + hooks=[ + dict(type='TextLoggerHook', by_epoch=False), + dict(type='TensorboardLoggerHook') + ]) +visual_config = None + +# runtime settings +dist_params = dict(backend='nccl') +log_level = 'INFO' +work_dir = f'./work_dirs/{exp_name}' +load_from = None +resume_from = None +workflow = [('train', 1)]