Commit 1401de15 authored by dongchy920's avatar dongchy920
Browse files

stylegan2_mmcv

parents
Pipeline #1274 canceled with stages
# define GAN model
model = dict(
type='BasiccGAN',
generator=dict(type='SNGANGenerator', output_scale=128, base_channels=64),
discriminator=dict(
type='ProjDiscriminator', input_scale=128, base_channels=64),
gan_loss=dict(type='GANLoss', gan_type='hinge'))
train_cfg = dict(disc_steps=2)
test_cfg = None
# define optimizer
optimizer = dict(
generator=dict(type='Adam', lr=0.0002, betas=(0.5, 0.999)),
discriminator=dict(type='Adam', lr=0.0002, betas=(0.5, 0.999)))
# define GAN model
model = dict(
type='BasiccGAN',
generator=dict(type='SNGANGenerator', output_scale=32, base_channels=256),
discriminator=dict(
type='ProjDiscriminator', input_scale=32, base_channels=128),
gan_loss=dict(type='GANLoss', gan_type='hinge'))
train_cfg = dict(disc_steps=5)
test_cfg = None
# define optimizer
optimizer = dict(
generator=dict(type='Adam', lr=0.0002, betas=(0.5, 0.999)),
discriminator=dict(type='Adam', lr=0.0002, betas=(0.5, 0.999)))
# define GAN model
d_reg_interval = 16
g_reg_interval = 4
g_reg_ratio = g_reg_interval / (g_reg_interval + 1)
d_reg_ratio = d_reg_interval / (d_reg_interval + 1)
model = dict(
type='StaticUnconditionalGAN',
generator=dict(
type='StyleGANv2Generator',
out_size=None, # Need to be set.
style_channels=512,
),
discriminator=dict(
type='StyleGAN2Discriminator',
in_size=None, # Need to be set.
),
gan_loss=dict(type='GANLoss', gan_type='wgan-logistic-ns'),
disc_auxiliary_loss=dict(
type='R1GradientPenalty',
loss_weight=10. / 2. * d_reg_interval,
interval=d_reg_interval,
norm_mode='HWC',
data_info=dict(real_data='real_imgs', discriminator='disc')),
gen_auxiliary_loss=dict(
type='GeneratorPathRegularizer',
loss_weight=2. * g_reg_interval,
pl_batch_shrink=2,
interval=g_reg_interval,
data_info=dict(generator='gen', num_batches='batch_size')))
train_cfg = dict(use_ema=True)
test_cfg = None
# define optimizer
optimizer = dict(
generator=dict(
type='Adam', lr=0.002 * g_reg_ratio, betas=(0, 0.99**g_reg_ratio)),
discriminator=dict(
type='Adam', lr=0.002 * d_reg_ratio, betas=(0, 0.99**d_reg_ratio)))
# define GAN model
d_reg_interval = 16
g_reg_interval = 4
g_reg_ratio = g_reg_interval / (g_reg_interval + 1)
d_reg_ratio = d_reg_interval / (d_reg_interval + 1)
model = dict(
type='StaticUnconditionalGAN',
generator=dict(
type='StyleGANv3Generator',
noise_size=512,
style_channels=512,
out_size=None, # Need to be set.
img_channels=3,
),
discriminator=dict(
type='StyleGAN2Discriminator',
in_size=None, # Need to be set.
),
gan_loss=dict(type='GANLoss', gan_type='wgan-logistic-ns'),
disc_auxiliary_loss=dict(
type='R1GradientPenalty',
loss_weight=10. / 2. * d_reg_interval,
interval=d_reg_interval,
norm_mode='HWC',
data_info=dict(real_data='real_imgs', discriminator='disc')),
gen_auxiliary_loss=dict(
type='GeneratorPathRegularizer',
loss_weight=2. * g_reg_interval,
pl_batch_shrink=2,
interval=g_reg_interval,
data_info=dict(generator='gen', num_batches='batch_size')))
train_cfg = dict(use_ema=True)
test_cfg = None
# define optimizer
optimizer = dict(
generator=dict(
type='Adam', lr=0.0025 * g_reg_ratio, betas=(0, 0.99**g_reg_ratio)),
discriminator=dict(
type='Adam', lr=0.002 * d_reg_ratio, betas=(0, 0.99**d_reg_ratio)))
model = dict(
type='StyleGANV1',
generator=dict(
type='StyleGANv1Generator', out_size=None, style_channels=512),
discriminator=dict(type='StyleGAN1Discriminator', in_size=None),
gan_loss=dict(type='GANLoss', gan_type='wgan-logistic-ns'),
disc_auxiliary_loss=[
dict(
type='R1GradientPenalty',
loss_weight=10,
norm_mode='HWC',
data_info=dict(
discriminator='disc_partial', real_data='real_imgs'))
])
train_cfg = dict(
use_ema=True,
transition_kimgs=600,
optimizer_cfg=dict(
generator=dict(type='Adam', lr=0.001, betas=(0.0, 0.99)),
discriminator=dict(type='Adam', lr=0.001, betas=(0.0, 0.99))),
g_lr_base=0.001,
d_lr_base=0.001,
g_lr_schedule=dict({
'128': 0.0015,
'256': 0.002,
'512': 0.003,
'1024': 0.003
}),
d_lr_schedule=dict({
'128': 0.0015,
'256': 0.002,
'512': 0.003,
'1024': 0.003
}))
test_cfg = None
optimizer = None
model = dict(
type='StaticUnconditionalGAN',
generator=dict(type='WGANGPGenerator', noise_size=128, out_scale=128),
discriminator=dict(
type='WGANGPDiscriminator',
in_channel=3,
in_scale=128,
conv_module_cfg=dict(
conv_cfg=None,
kernel_size=3,
stride=1,
padding=1,
bias=True,
act_cfg=dict(type='LeakyReLU', negative_slope=0.2),
norm_cfg=dict(type='GN'),
order=('conv', 'norm', 'act'))),
gan_loss=dict(type='GANLoss', gan_type='wgan'),
disc_auxiliary_loss=[
dict(
type='GradientPenaltyLoss',
loss_weight=10,
norm_mode='HWC',
data_info=dict(
discriminator='disc',
real_data='real_imgs',
fake_data='fake_imgs'))
])
train_cfg = dict(disc_steps=5)
test_cfg = None
optimizer = dict(
generator=dict(type='Adam', lr=0.0001, betas=(0.5, 0.9)),
discriminator=dict(type='Adam', lr=0.0001, betas=(0.5, 0.9)))
# ADA
> [Training Generative Adversarial Networks with Limited Data](https://arxiv.org/pdf/2006.06676.pdf)
<!-- [ALGORITHM] -->
## Abstract
Training generative adversarial networks (GAN) using too little data typically leads to discriminator overfitting, causing training to diverge. We propose an adaptive discriminator augmentation mechanism that significantly stabilizes training in limited data regimes. The approach does not require changes to loss functions or network architectures, and is applicable both when training from scratch and when fine-tuning an existing GAN on another dataset. We demonstrate, on several datasets, that good results are now possible using only a few thousand training images, often matching StyleGAN2 results with an order of magnitude fewer images. We expect this to open up new application domains for GANs. We also find that the widely used CIFAR-10 is, in fact, a limited data benchmark, and improve the record FID from 5.59 to 2.42.
<!-- [IMAGE] -->
<div align=center>
<img src="https://user-images.githubusercontent.com/22982797/165902671-ee835ca5-3957-451e-8e7d-e3741d90e0b1.png"/>
</div>
## Results and Models
<div align="center">
<b> Results (compressed) from StyleGAN3-ada trained by MMGeneration</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/165905181-66d6b4e7-6d40-48db-8281-50ebd2705f64.png" width="800"/>
</div>
| Model | Dataset | Iter | FID50k | Config | Log | Download |
| :-------------: | :---------------: | :----: | :----: | :--------------------------------------------------: | :-----------------------------------------------: | :-----------------------------------------------------: |
| stylegan3-t-ada | metface 1024x1024 | 130000 | 15.09 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/styleganv3/stylegan3_t_ada_fp16_gamma6.6_metfaces_1024_b4x8.py) | [log](https://download.openmmlab.com/mmgen/stylegan3/stylegan3_t_ada_fp16_gamma6.6_metfaces_1024_b4x8_20220328_142211.log.json) | [model](https://download.openmmlab.com/mmgen/stylegan3/stylegan3_t_ada_fp16_gamma6.6_metfaces_1024_b4x8_best_fid_iter_130000_20220401_115101-f2ef498e.pth) |
## Usage
Currently we only implement ada for StyleGANv2/v3. To use this training trick. You should use `ADAStyleGAN2Discriminator` as your discriminator.
An example:
```python
model = dict(
xxx,
discriminator=dict(
type='ADAStyleGAN2Discriminator',
in_size=1024,
data_aug=dict(type='ADAAug', aug_pipeline=aug_kwargs, ada_kimg=100)),
xxx
)
```
Here, you can adjust `ada_kimg` to change the magnitude of augmentation(The smaller the value, the greater the magnitude).
`aug_kwargs` is usually set as follows:
```python
aug_kwargs = {
'xflip': 1,
'rotate90': 1,
'xint': 1,
'scale': 1,
'rotate': 1,
'aniso': 1,
'xfrac': 1,
'brightness': 1,
'contrast': 1,
'lumaflip': 1,
'hue': 1,
'saturation': 1
}
```
Here, the number is Probability multiplier for each operation. For details, you can refer to [augment](https://github.com/open-mmlab/mmgeneration/tree/master/mmgen/models/architectures/stylegan/ada/augment.py).
## Citation
```latex
@inproceedings{Karras2020ada,
title = {Training Generative Adversarial Networks with Limited Data},
author = {Tero Karras and Miika Aittala and Janne Hellsten and Samuli Laine and Jaakko Lehtinen and Timo Aila},
booktitle = {Proc. NeurIPS},
year = {2020}
}
```
Collections:
- Metadata:
Architecture:
- ADA
Name: ADA
Paper:
- https://arxiv.org/pdf/2006.06676.pdf
README: configs/ada/README.md
Models:
- Config: https://github.com/open-mmlab/mmgeneration/tree/master/configs/styleganv3/stylegan3_t_ada_fp16_gamma6.6_metfaces_1024_b4x8.py
In Collection: ADA
Metadata:
Training Data: Others
Name: stylegan3_t_ada_fp16_gamma6.6_metfaces_1024_b4x8
Results:
- Dataset: Others
Metrics:
FID50k: 15.09
Iter: 130000.0
Log: '[log]'
Task: Tricks for GANs
Weights: https://download.openmmlab.com/mmgen/stylegan3/stylegan3_t_ada_fp16_gamma6.6_metfaces_1024_b4x8_best_fid_iter_130000_20220401_115101-f2ef498e.pth
_base_ = [
'../_base_/models/stylegan/stylegan3_base.py',
'../_base_/datasets/ffhq_flip.py', '../_base_/default_runtime.py'
]
synthesis_cfg = {
'type': 'SynthesisNetwork',
'channel_base': 65536,
'channel_max': 1024,
'magnitude_ema_beta': 0.999,
'conv_kernel': 1,
'use_radial_filters': True
}
r1_gamma = 3.3 # set by user
d_reg_interval = 16
load_from = 'https://download.openmmlab.com/mmgen/stylegan3/stylegan3_r_ffhq_1024_b4x8_cvt_official_rgb_20220329_234933-ac0500a1.pth' # noqa
# ada settings
aug_kwargs = {
'xflip': 1,
'rotate90': 1,
'xint': 1,
'scale': 1,
'rotate': 1,
'aniso': 1,
'xfrac': 1,
'brightness': 1,
'contrast': 1,
'lumaflip': 1,
'hue': 1,
'saturation': 1
}
model = dict(
type='StaticUnconditionalGAN',
generator=dict(
out_size=1024,
img_channels=3,
rgb2bgr=True,
synthesis_cfg=synthesis_cfg),
discriminator=dict(
type='ADAStyleGAN2Discriminator',
in_size=1024,
input_bgr2rgb=True,
data_aug=dict(type='ADAAug', aug_pipeline=aug_kwargs, ada_kimg=100)),
gan_loss=dict(type='GANLoss', gan_type='wgan-logistic-ns'),
disc_auxiliary_loss=dict(loss_weight=r1_gamma / 2.0 * d_reg_interval))
imgs_root = 'data/metfaces/images/'
data = dict(
samples_per_gpu=4,
train=dict(dataset=dict(imgs_root=imgs_root)),
val=dict(imgs_root=imgs_root))
ema_half_life = 10. # G_smoothing_kimg
ema_kimg = 10
ema_nimg = ema_kimg * 1000
ema_beta = 0.5**(32 / max(ema_nimg, 1e-8))
custom_hooks = [
dict(
type='VisualizeUnconditionalSamples',
output_dir='training_samples',
interval=5000),
dict(
type='ExponentialMovingAverageHook',
module_keys=('generator_ema', ),
interp_mode='lerp',
interp_cfg=dict(momentum=ema_beta),
interval=1,
start_iter=0,
priority='VERY_HIGH')
]
inception_pkl = 'work_dirs/inception_pkl/metface_1024x1024_noflip.pkl'
metrics = dict(
fid50k=dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
inception_args=dict(type='StyleGAN'),
bgr2rgb=True))
evaluation = dict(
type='GenerativeEvalHook',
interval=dict(milestones=[100000], interval=[10000, 5000]),
metrics=dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
inception_args=dict(type='StyleGAN'),
bgr2rgb=True),
sample_kwargs=dict(sample_model='ema'))
lr_config = None
total_iters = 160000
_base_ = [
'../_base_/models/stylegan/stylegan3_base.py',
'../_base_/datasets/ffhq_flip.py', '../_base_/default_runtime.py'
]
synthesis_cfg = {
'type': 'SynthesisNetwork',
'channel_base': 32768,
'channel_max': 512,
'magnitude_ema_beta': 0.999
}
r1_gamma = 6.6 # set by user
d_reg_interval = 16
load_from = 'https://download.openmmlab.com/mmgen/stylegan3/stylegan3_t_ffhq_1024_b4x8_cvt_official_rgb_20220329_235113-db6c6580.pth' # noqa
# ada settings
aug_kwargs = {
'xflip': 1,
'rotate90': 1,
'xint': 1,
'scale': 1,
'rotate': 1,
'aniso': 1,
'xfrac': 1,
'brightness': 1,
'contrast': 1,
'lumaflip': 1,
'hue': 1,
'saturation': 1
}
model = dict(
type='StaticUnconditionalGAN',
generator=dict(
out_size=1024,
img_channels=3,
rgb2bgr=True,
synthesis_cfg=synthesis_cfg),
discriminator=dict(
type='ADAStyleGAN2Discriminator',
in_size=1024,
input_bgr2rgb=True,
data_aug=dict(type='ADAAug', aug_pipeline=aug_kwargs, ada_kimg=100)),
gan_loss=dict(type='GANLoss', gan_type='wgan-logistic-ns'),
disc_auxiliary_loss=dict(loss_weight=r1_gamma / 2.0 * d_reg_interval))
imgs_root = 'data/metfaces/images/'
data = dict(
samples_per_gpu=4,
train=dict(dataset=dict(imgs_root=imgs_root)),
val=dict(imgs_root=imgs_root))
ema_half_life = 10. # G_smoothing_kimg
ema_kimg = 10
ema_nimg = ema_kimg * 1000
ema_beta = 0.5**(32 / max(ema_nimg, 1e-8))
custom_hooks = [
dict(
type='VisualizeUnconditionalSamples',
output_dir='training_samples',
interval=5000),
dict(
type='ExponentialMovingAverageHook',
module_keys=('generator_ema', ),
interp_mode='lerp',
interp_cfg=dict(momentum=ema_beta),
interval=1,
start_iter=0,
priority='VERY_HIGH')
]
inception_pkl = 'work_dirs/inception_pkl/metface_1024x1024_noflip.pkl'
metrics = dict(
fid50k=dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
inception_args=dict(type='StyleGAN'),
bgr2rgb=True))
evaluation = dict(
type='GenerativeEvalHook',
interval=dict(milestones=[80000], interval=[10000, 5000]),
metrics=dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
inception_args=dict(type='StyleGAN'),
bgr2rgb=True),
sample_kwargs=dict(sample_model='ema'))
lr_config = None
total_iters = 160000
# BigGAN
> [Large Scale GAN Training for High Fidelity Natural Image Synthesis](https://openreview.net/forum?id=B1xsqj09Fm)
<!-- [ALGORITHM] -->
## Abstract
<!-- [ABSTRACT] -->
Despite recent progress in generative image modeling, successfully generating high-resolution, diverse samples from complex datasets such as ImageNet remains an elusive goal. To this end, we train Generative Adversarial Networks at the largest scale yet attempted, and study the instabilities specific to such scale. We find that applying orthogonal regularization to the generator renders it amenable to a simple "truncation trick," allowing fine control over the trade-off between sample fidelity and variety by reducing the variance of the Generator's input. Our modifications lead to models which set the new state of the art in class-conditional image synthesis. When trained on ImageNet at 128x128 resolution, our models (BigGANs) achieve an Inception Score (IS) of 166.5 and Frechet Inception Distance (FID) of 7.4, improving over the previous best IS of 52.52 and FID of 18.6.
<!-- [IMAGE] -->
<div align=center>
<img src="https://user-images.githubusercontent.com/28132635/143154280-4cb22e16-92c8-4b34-9e2c-6357ed0bdac8.png"/>
</div>
## Introduction
The `BigGAN/BigGAN-Deep` is a conditional generation model that can generate both high-resolution and high-quality images by scaling up the batch size and the number of model parameters.
We have finished training `BigGAN` in `Cifar10` (32x32) and are aligning training performance in `ImageNet1k` (128x128). Some sampled results are shown below for your reference.
<div align="center">
<b> Results from our BigGAN trained in CIFAR10</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/126476913-3ce8e2c8-f189-4caa-90ed-b44e279cb669.png" width="800"/>
</div>
<div align="center">
<b> Results from our BigGAN trained in ImageNet</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/127615534-6278ce1b-5cff-4189-83c6-9ecc8de08dfc.png" width="800"/>
</div>
Evaluation of our trained BigGAN.
| Models | Dataset | FID (Iter) | IS (Iter) | Config | Download |
| :------------------------------------------------: | :--------: | :---------------: | :-----------------: | :-------------------------------------------------: | :---------------------------------------------------: |
| BigGAN 32x32 | CIFAR10 | 9.78(390000) | 8.70(390000) | [config](https://github.com/open-mmlab/mmgeneration/blob/master/configs/biggan/biggan_cifar10_32x32_b25x2_500k.py) | [model](https://download.openmmlab.com/mmgen/biggan/biggan_cifar10_32x32_b25x2_500k_20210728_110906-08b61a44.pth)\|[log](https://download.openmmlab.com/mmgen/biggan/biggan_cifar10_32_b25x2_500k_20210706_171051.log.json) |
| BigGAN 128x128 Best FID | ImageNet1k | **8.69**(1232000) | 101.15(1232000) | [config](https://github.com/open-mmlab/mmgeneration/blob/master/configs/biggan/biggan_ajbrock-sn_imagenet1k_128x128_b32x8_1500k.py) | [model](https://download.openmmlab.com/mmgen/biggan/biggan_imagenet1k_128x128_b32x8_best_fid_iter_1232000_20211111_122548-5315b13d.pth)\|[log](https://download.openmmlab.com/mmgen/biggan/biggan_imagenet1k_128x128_b32x8_1500k_20211111_122548-5315b13d.log.json) |
| BigGAN 128x128 Best IS | ImageNet1k | 13.51(1328000) | **129.07**(1328000) | [config](https://github.com/open-mmlab/mmgeneration/blob/master/configs/biggan/biggan_ajbrock-sn_imagenet1k_128x128_b32x8_1500k.py) | [model](https://download.openmmlab.com/mmgen/biggan/biggan_imagenet1k_128x128_b32x8_best_is_iter_1328000_20211111_122911-28c688bc.pth)\|[log](https://download.openmmlab.com/mmgen/biggan/biggan_imagenet1k_128x128_b32x8_1500k_20211111_122548-5315b13d.log.json) |
| Note: `BigGAN-Deep` trained on `ImageNet1k` will come later. | | | | | |
## Converted weights
Since we haven't finished training our models, we provide you with several pre-trained weights which have been evaluated. Here, we refer to [BigGAN-PyTorch](https://github.com/ajbrock/BigGAN-PyTorch) and [pytorch-pretrained-BigGAN](https://github.com/huggingface/pytorch-pretrained-BigGAN).
Evaluation results and download links are provided below.
| Models | Dataset | FID | IS | Config | Download | Original Download link |
| :-----------------: | :--------: | :-----: | :-----: | :--------------------------------------------: | :----------------------------------------------: | :-------------------------------------------------------------: |
| BigGAN 128x128 | ImageNet1k | 10.1414 | 96.728 | [config](https://github.com/open-mmlab/mmgeneration/blob/master/configs/_base_/models/biggan/biggan_128x128_cvt_BigGAN-PyTorch_rgb.py) | [model](https://download.openmmlab.com/mmgen/biggan/biggan_imagenet1k_128x128_cvt_BigGAN-PyTorch_rgb_20210730_125223-3e353fef.pth) | [link](https://drive.google.com/open?id=1nAle7FCVFZdix2--ks0r5JBkFnKw8ctW) |
| BigGAN-Deep 128x128 | ImageNet1k | 5.9471 | 107.161 | [config](https://github.com/open-mmlab/mmgeneration/blob/master/configs/_base_/models/biggan/biggan-deep_128x128_cvt_hugging-face_rgb.py) | [model](https://download.openmmlab.com/mmgen/biggan/biggan-deep_imagenet1k_128x128_cvt_hugging-face_rgb_20210728_111659-099e96f9.pth) | [link](https://s3.amazonaws.com/models.huggingface.co/biggan/biggan-deep-128-pytorch_model.bin) |
| BigGAN-Deep 256x256 | ImageNet1k | 11.3151 | 135.107 | [config](https://github.com/open-mmlab/mmgeneration/blob/master/configs/_base_/models/biggan/biggan-deep_256x256_cvt_hugging-face_rgb.py) | [model](https://download.openmmlab.com/mmgen/biggan/biggan-deep_imagenet1k_256x256_cvt_hugging-face_rgb_20210728_111735-28651569.pth) | [link](https://s3.amazonaws.com/models.huggingface.co/biggan/biggan-deep-256-pytorch_model.bin) |
| BigGAN-Deep 512x512 | ImageNet1k | 16.8728 | 124.368 | [config](https://github.com/open-mmlab/mmgeneration/blob/master/configs/_base_/models/biggan/biggan-deep_512x512_cvt_hugging-face_rgb.py) | [model](https://download.openmmlab.com/mmgen/biggan/biggan-deep_imagenet1k_512x512_cvt_hugging-face_rgb_20210728_112346-a42585f2.pth) | [link](https://s3.amazonaws.com/models.huggingface.co/biggan/biggan-deep-512-pytorch_model.bin) |
Sampling results are shown below.
<div align="center">
<b> Results from our BigGAN-Deep with Pre-trained weights in ImageNet 128x128 with truncation factor 0.4</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/126481730-8da7180b-7b1b-42f0-9bec-78d879b6265b.png" width="800"/>
</div>
<div align="center">
<b> Results from our BigGAN-Deep with Pre-trained weights in ImageNet 256x256 with truncation factor 0.4</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/126486040-64effa29-959e-4e43-bcae-15925a2e0599.png" width="800"/>
</div>
<div align="center">
<b> Results from our BigGAN-Deep with Pre-trained weights in ImageNet 512x512 truncation factor 0.4</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/126487428-50101454-59cb-469d-a1f1-36ffb6291582.png" width="800"/>
</div>
Sampling with truncation trick above can be performed by command below.
```bash
python demo/conditional_demo.py CONFIG_PATH CKPT_PATH --sample-cfg truncation=0.4 # set truncation value as you want
```
For converted weights, we provide model configs under `configs/_base_/models` listed as follows:
```bash
# biggan_128x128_cvt_BigGAN-PyTorch_rgb.py
# biggan-deep_128x128_cvt_hugging-face_rgb.py
# biggan-deep_256x256_cvt_hugging-face_rgb.py
# biggan-deep_512x512_cvt_hugging-face_rgb.py
```
## Interpolation
To perform image Interpolation on BigGAN(or other conditional models), run
```bash
python apps/conditional_interpolate.py CONFIG_PATH CKPT_PATH --samples-path SAMPLES_PATH
```
<div align="center">
<b> Image interpolating Results of our BigGAN-Deep</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/126580403-2baa987b-ff55-4fb5-a53a-b08e8a6a72a2.png" width="800"/>
</div>
To perform image Interpolation on BigGAN with fixed noise, run
```bash
python apps/conditional_interpolate.py CONFIG_PATH CKPT_PATH --samples-path SAMPLES_PATH --fix-z
```
<div align="center">
<b> Image interpolating Results of our BigGAN-Deep with fixed noise</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/128123804-6df1dfca-1057-4b96-8428-787a86f81ef1.png" width="800"/>
</div>
To perform image Interpolation on BigGAN with fixed label, run
```bash
python apps/conditional_interpolate.py CONFIG_PATH CKPT_PATH --samples-path SAMPLES_PATH --fix-y
```
<div align="center">
<b> Image interpolating Results of our BigGAN-Deep with fixed label</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/128124596-421396f1-3f23-4098-b629-b00d29d710a9.png" width="800"/>
</div>
## Citation
```latex
@inproceedings{
brock2018large,
title={Large Scale {GAN} Training for High Fidelity Natural Image Synthesis},
author={Andrew Brock and Jeff Donahue and Karen Simonyan},
booktitle={International Conference on Learning Representations},
year={2019},
url={https://openreview.net/forum?id=B1xsqj09Fm},
}
```
model = dict(
type='BasiccGAN',
generator=dict(
type='BigGANDeepGenerator',
output_scale=128,
noise_size=128,
num_classes=1000,
base_channels=128,
shared_dim=128,
with_shared_embedding=True,
sn_eps=1e-6,
sn_style='torch',
init_type='ortho',
act_cfg=dict(type='ReLU', inplace=True),
concat_noise=True,
auto_sync_bn=False,
rgb2bgr=True),
discriminator=dict(
type='BigGANDeepDiscriminator',
input_scale=128,
num_classes=1000,
base_channels=128,
sn_eps=1e-6,
sn_style='torch',
init_type='ortho',
act_cfg=dict(type='ReLU', inplace=True),
with_spectral_norm=True),
gan_loss=dict(type='GANLoss', gan_type='hinge'))
train_cfg = dict(
disc_steps=8, gen_steps=1, batch_accumulation_steps=8, use_ema=True)
test_cfg = None
optimizer = dict(
generator=dict(type='Adam', lr=0.0001, betas=(0.0, 0.999), eps=1e-6),
discriminator=dict(type='Adam', lr=0.0004, betas=(0.0, 0.999), eps=1e-6))
model = dict(
type='BasiccGAN',
generator=dict(
type='BigGANDeepGenerator',
output_scale=256,
noise_size=128,
num_classes=1000,
base_channels=128,
shared_dim=128,
with_shared_embedding=True,
sn_eps=1e-6,
sn_style='torch',
init_type='ortho',
act_cfg=dict(type='ReLU', inplace=True),
concat_noise=True,
auto_sync_bn=False,
rgb2bgr=True),
discriminator=dict(
type='BigGANDeepDiscriminator',
input_scale=256,
num_classes=1000,
base_channels=128,
sn_eps=1e-6,
sn_style='torch',
init_type='ortho',
act_cfg=dict(type='ReLU', inplace=True),
with_spectral_norm=True),
gan_loss=dict(type='GANLoss', gan_type='hinge'))
train_cfg = dict(
disc_steps=8, gen_steps=1, batch_accumulation_steps=8, use_ema=True)
test_cfg = None
optimizer = dict(
generator=dict(type='Adam', lr=0.0001, betas=(0.0, 0.999), eps=1e-6),
discriminator=dict(type='Adam', lr=0.0004, betas=(0.0, 0.999), eps=1e-6))
model = dict(
type='BasiccGAN',
generator=dict(
type='BigGANDeepGenerator',
output_scale=512,
noise_size=128,
num_classes=1000,
base_channels=128,
shared_dim=128,
with_shared_embedding=True,
sn_eps=1e-6,
sn_style='torch',
init_type='ortho',
act_cfg=dict(type='ReLU', inplace=True),
concat_noise=True,
auto_sync_bn=False,
rgb2bgr=True),
discriminator=dict(
type='BigGANDeepDiscriminator',
input_scale=512,
num_classes=1000,
base_channels=128,
sn_eps=1e-6,
sn_style='torch',
init_type='ortho',
act_cfg=dict(type='ReLU', inplace=True),
with_spectral_norm=True),
gan_loss=dict(type='GANLoss', gan_type='hinge'))
train_cfg = dict(
disc_steps=8, gen_steps=1, batch_accumulation_steps=8, use_ema=True)
test_cfg = None
optimizer = dict(
generator=dict(type='Adam', lr=0.0001, betas=(0.0, 0.999), eps=1e-6),
discriminator=dict(type='Adam', lr=0.0004, betas=(0.0, 0.999), eps=1e-6))
model = dict(
type='BasiccGAN',
generator=dict(
type='BigGANGenerator',
output_scale=128,
noise_size=120,
num_classes=1000,
base_channels=96,
shared_dim=128,
with_shared_embedding=True,
sn_eps=1e-6,
init_type='ortho',
act_cfg=dict(type='ReLU', inplace=True),
split_noise=True,
auto_sync_bn=False,
rgb2bgr=True),
discriminator=dict(
type='BigGANDiscriminator',
input_scale=128,
num_classes=1000,
base_channels=96,
sn_eps=1e-6,
init_type='ortho',
act_cfg=dict(type='ReLU', inplace=True),
with_spectral_norm=True),
gan_loss=dict(type='GANLoss', gan_type='hinge'))
train_cfg = dict(
disc_steps=8, gen_steps=1, batch_accumulation_steps=8, use_ema=True)
test_cfg = None
optimizer = dict(
generator=dict(type='Adam', lr=0.0001, betas=(0.0, 0.999), eps=1e-6),
discriminator=dict(type='Adam', lr=0.0004, betas=(0.0, 0.999), eps=1e-6))
_base_ = [
'../_base_/models/biggan/biggan_128x128.py',
'../_base_/datasets/imagenet_noaug_128.py', '../_base_/default_runtime.py'
]
# define dataset
# you must set `samples_per_gpu`
data = dict(samples_per_gpu=32, workers_per_gpu=8)
# adjust running config
lr_config = None
checkpoint_config = dict(interval=5000, by_epoch=False, max_keep_ckpts=10)
custom_hooks = [
dict(
type='VisualizeUnconditionalSamples',
output_dir='training_samples',
interval=10000),
dict(
type='ExponentialMovingAverageHook',
module_keys=('generator_ema', ),
interval=8,
start_iter=160000,
interp_cfg=dict(momentum=0.9999, momentum_nontrainable=0.9999),
priority='VERY_HIGH')
]
# Traning sets' datasize 1,281,167
total_iters = 1500000
# use ddp wrapper for faster training
use_ddp_wrapper = True
find_unused_parameters = False
runner = dict(
type='DynamicIterBasedRunner',
is_dynamic_ddp=False, # Note that this flag should be False.
pass_training_status=True)
# Note set your inception_pkl's path
inception_pkl = 'work_dirs/inception_pkl/imagenet.pkl'
evaluation = dict(
type='GenerativeEvalHook',
interval=10000,
metrics=[
dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
bgr2rgb=True),
dict(type='IS', num_images=50000)
],
sample_kwargs=dict(sample_model='ema'),
best_metric=['fid', 'is'])
metrics = dict(
fid50k=dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
bgr2rgb=True,
inception_args=dict(type='StyleGAN')),
is50k=dict(type='IS', num_images=50000))
_base_ = [
'../_base_/models/biggan/biggan_32x32.py',
'../_base_/datasets/cifar10_noaug.py', '../_base_/default_runtime.py'
]
# define dataset
# you must set `samples_per_gpu`
data = dict(samples_per_gpu=25, workers_per_gpu=8)
# adjust running config
lr_config = None
checkpoint_config = dict(interval=5000, by_epoch=False, max_keep_ckpts=20)
custom_hooks = [
dict(
type='VisualizeUnconditionalSamples',
output_dir='training_samples',
interval=5000),
dict(
type='ExponentialMovingAverageHook',
module_keys=('generator_ema', ),
interval=4,
start_iter=4000,
interp_cfg=dict(momentum=0.9999),
priority='VERY_HIGH')
]
total_iters = 500000
# use ddp wrapper for faster training
use_ddp_wrapper = True
find_unused_parameters = False
runner = dict(
type='DynamicIterBasedRunner',
is_dynamic_ddp=False, # Note that this flag should be False.
pass_training_status=True)
# Note set your inception_pkl's path
inception_pkl = None
evaluation = dict(
type='GenerativeEvalHook',
interval=10000,
metrics=[
dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
bgr2rgb=True),
dict(type='IS', num_images=50000)
],
sample_kwargs=dict(sample_model='ema'),
best_metric=['fid', 'is'])
metrics = dict(
fid50k=dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
bgr2rgb=True),
is50k=dict(type='IS', num_images=50000))
_base_ = [
'../_base_/models/biggan/biggan_128x128.py',
'../_base_/datasets/imagenet_noaug_128.py', '../_base_/default_runtime.py'
]
# define dataset
# you must set `samples_per_gpu`
data = dict(samples_per_gpu=32, workers_per_gpu=8)
model = dict(
generator=dict(sn_style='torch'), discriminator=dict(sn_style='torch'))
# adjust running config
lr_config = None
checkpoint_config = dict(interval=5000, by_epoch=False, max_keep_ckpts=10)
custom_hooks = [
dict(
type='VisualizeUnconditionalSamples',
output_dir='training_samples',
interval=10000),
dict(
type='ExponentialMovingAverageHook',
module_keys=('generator_ema', ),
interval=8,
start_iter=160000,
interp_cfg=dict(momentum=0.9999, momentum_nontrainable=0.9999),
priority='VERY_HIGH')
]
# Traning sets' datasize 1,281,167
total_iters = 1500000
# use ddp wrapper for faster training
use_ddp_wrapper = True
find_unused_parameters = False
runner = dict(
type='DynamicIterBasedRunner',
is_dynamic_ddp=False, # Note that this flag should be False.
pass_training_status=True)
# Note set your inception_pkl's path
inception_pkl = 'work_dirs/inception_pkl/imagenet.pkl'
evaluation = dict(
type='GenerativeEvalHook',
interval=10000,
metrics=[
dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
bgr2rgb=True),
dict(type='IS', num_images=50000)
],
sample_kwargs=dict(sample_model='ema'),
best_metric=['fid', 'is'])
metrics = dict(
fid50k=dict(
type='FID',
num_images=50000,
inception_pkl=inception_pkl,
bgr2rgb=True,
inception_args=dict(type='StyleGAN')),
is50k=dict(type='IS', num_images=50000))
Collections:
- Metadata:
Architecture:
- BigGAN
Name: BigGAN
Paper:
- https://openreview.net/forum?id=B1xsqj09Fm
README: configs/biggan/README.md
Models:
- Config: https://github.com/open-mmlab/mmgeneration/blob/master/configs/biggan/biggan_cifar10_32x32_b25x2_500k.py
In Collection: BigGAN
Metadata:
Training Data: CIFAR
Name: biggan_cifar10_32x32_b25x2_500k
Results:
- Dataset: CIFAR
Metrics:
FID: 9.78
IS: 8.7
Task: Conditional GANs
Weights: https://download.openmmlab.com/mmgen/biggan/biggan_cifar10_32x32_b25x2_500k_20210728_110906-08b61a44.pth
- Config: https://github.com/open-mmlab/mmgeneration/blob/master/configs/biggan/biggan_ajbrock-sn_imagenet1k_128x128_b32x8_1500k.py
In Collection: BigGAN
Metadata:
Training Data: IMAGENET
Name: biggan_ajbrock-sn_imagenet1k_128x128_b32x8_1500k
Results:
- Dataset: IMAGENET
Metrics:
FID: 8.69
IS: 101.15
Task: Conditional GANs
Weights: https://download.openmmlab.com/mmgen/biggan/biggan_imagenet1k_128x128_b32x8_best_fid_iter_1232000_20211111_122548-5315b13d.pth
- Config: https://github.com/open-mmlab/mmgeneration/blob/master/configs/biggan/biggan_ajbrock-sn_imagenet1k_128x128_b32x8_1500k.py
In Collection: BigGAN
Metadata:
Training Data: IMAGENET
Name: biggan_ajbrock-sn_imagenet1k_128x128_b32x8_1500k
Results:
- Dataset: IMAGENET
Metrics:
FID: 13.51
IS: 129.07
Task: Conditional GANs
Weights: https://download.openmmlab.com/mmgen/biggan/biggan_imagenet1k_128x128_b32x8_best_is_iter_1328000_20211111_122911-28c688bc.pth
- Config: https://github.com/open-mmlab/mmgeneration/blob/master/configs/_base_/models/biggan/biggan_128x128_cvt_BigGAN-PyTorch_rgb.py
In Collection: BigGAN
Metadata:
Training Data: Others
Name: biggan_128x128_cvt_BigGAN-PyTorch_rgb
Results:
- Dataset: Others
Metrics:
FID: 10.1414
IS: 96.728
Task: Conditional GANs
Weights: https://download.openmmlab.com/mmgen/biggan/biggan_imagenet1k_128x128_cvt_BigGAN-PyTorch_rgb_20210730_125223-3e353fef.pth
- Config: https://github.com/open-mmlab/mmgeneration/blob/master/configs/_base_/models/biggan/biggan-deep_128x128_cvt_hugging-face_rgb.py
In Collection: BigGAN
Metadata:
Training Data: Others
Name: biggan-deep_128x128_cvt_hugging-face_rgb
Results:
- Dataset: Others
Metrics:
FID: 5.9471
IS: 107.161
Task: Conditional GANs
Weights: https://download.openmmlab.com/mmgen/biggan/biggan-deep_imagenet1k_128x128_cvt_hugging-face_rgb_20210728_111659-099e96f9.pth
- Config: https://github.com/open-mmlab/mmgeneration/blob/master/configs/_base_/models/biggan/biggan-deep_256x256_cvt_hugging-face_rgb.py
In Collection: BigGAN
Metadata:
Training Data: Others
Name: biggan-deep_256x256_cvt_hugging-face_rgb
Results:
- Dataset: Others
Metrics:
FID: 11.3151
IS: 135.107
Task: Conditional GANs
Weights: https://download.openmmlab.com/mmgen/biggan/biggan-deep_imagenet1k_256x256_cvt_hugging-face_rgb_20210728_111735-28651569.pth
- Config: https://github.com/open-mmlab/mmgeneration/blob/master/configs/_base_/models/biggan/biggan-deep_512x512_cvt_hugging-face_rgb.py
In Collection: BigGAN
Metadata:
Training Data: Others
Name: biggan-deep_512x512_cvt_hugging-face_rgb
Results:
- Dataset: Others
Metrics:
FID: 16.8728
IS: 124.368
Task: Conditional GANs
Weights: https://download.openmmlab.com/mmgen/biggan/biggan-deep_imagenet1k_512x512_cvt_hugging-face_rgb_20210728_112346-a42585f2.pth
# CycleGAN: Unpaired Image-to-Image Translation Using Cycle-Consistent Adversarial Networks
> [CycleGAN: Unpaired Image-to-Image Translation Using Cycle-Consistent Adversarial Networks](https://openaccess.thecvf.com/content_iccv_2017/html/Zhu_Unpaired_Image-To-Image_Translation_ICCV_2017_paper.html)
<!-- [ALGORITHM] -->
## Abstract
<!-- [ABSTRACT] -->
Image-to-image translation is a class of vision and graphics problems where the goal is to learn the mapping between an input image and an output image using a training set of aligned image pairs. However, for many tasks, paired training data will not be available. We present an approach for learning to translate an image from a source domain X to a target domain Y in the absence of paired examples. Our goal is to learn a mapping G: X \\rightarrow Y such that the distribution of images from G(X) is indistinguishable from the distribution Y using an adversarial loss. Because this mapping is highly under-constrained, we couple it with an inverse mapping F: Y \\rightarrow X and introduce a cycle consistency loss to push F(G(X)) \\approx X (and vice versa). Qualitative results are presented on several tasks where paired training data does not exist, including collection style transfer, object transfiguration, season transfer, photo enhancement, etc. Quantitative comparisons against several prior methods demonstrate the superiority of our approach.
<!-- [IMAGE] -->
<div align=center>
<img src="https://user-images.githubusercontent.com/28132635/143049598-23c24d98-7a64-4ab3-a9ba-351db6a0a53d.JPG" />
</div>
## Results and Models
<div align="center">
<b> Results from CycleGAN trained by MMGeneration</b>
<br/>
<img src="https://user-images.githubusercontent.com/22982797/114303527-108ed200-9b01-11eb-978c-274392e4d8e0.PNG" width="800"/>
</div>
We use `FID` and `IS` metrics to evaluate the generation performance of CycleGAN.<sup>1</sup>
| Models | Dataset | FID | IS | Config | Download |
| :----: | :---------------: | :------: | :---: | :-------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------: |
| Ours | facades | 124.8033 | 1.792 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_resnet_in_facades_b1x1_80k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_resnet_in_1x1_80k_facades_20210902_165905-5e2c0876.pth) \| [log](https://download.openmmlab.com/mmgen/cyclegan/cyclegan_lsgan_resnet_in_1x1_80k_facades_20210317_160938.log.json) <sup>2</sup> |
| Ours | facades-id0 | 125.1694 | 1.905 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_id0_resnet_in_facades_b1x1_80k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_id0_resnet_in_1x1_80k_facades_convert-bgr_20210902_164411-d8e72b45.pth) |
| Ours | summer2winter | 83.7177 | 2.771 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_resnet_in_summer2winter_b1x1_250k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_resnet_in_1x1_246200_summer2winter_convert-bgr_20210902_165932-fcf08dc1.pth) |
| Ours | summer2winter-id0 | 83.1418 | 2.720 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_id0_resnet_in_summer2winter_b1x1_250k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_id0_resnet_in_1x1_246200_summer2winter_convert-bgr_20210902_165640-8b825581.pth) |
| Ours | winter2summer | 72.8025 | 3.129 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_resnet_in_summer2winter_b1x1_250k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_resnet_in_1x1_246200_summer2winter_convert-bgr_20210902_165932-fcf08dc1.pth) |
| Ours | winter2summer-id0 | 73.5001 | 3.107 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_id0_resnet_in_summer2winter_b1x1_250k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_id0_resnet_in_1x1_246200_summer2winter_convert-bgr_20210902_165640-8b825581.pth) |
| Ours | horse2zebra | 64.5225 | 1.418 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_resnet_in_horse2zebra_b1x1_270k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_resnet_in_1x1_266800_horse2zebra_convert-bgr_20210902_170004-a32c733a.pth) |
| Ours | horse2zebra-id0 | 74.7770 | 1.542 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_id0_resnet_in_horse2zebra_b1x1_270k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_id0_resnet_in_1x1_266800_horse2zebra_convert-bgr_20210902_165724-77c9c806.pth) |
| Ours | zebra2horse | 141.1517 | 3.154 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_resnet_in_horse2zebra_b1x1_270k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_resnet_in_1x1_266800_horse2zebra_convert-bgr_20210902_170004-a32c733a.pth) |
| Ours | zebra2horse-id0 | 134.3728 | 3.091 | [config](https://github.com/open-mmlab/mmgeneration/tree/master/configs/cyclegan/cyclegan_lsgan_id0_resnet_in_horse2zebra_b1x1_270k.py) | [model](https://download.openmmlab.com/mmgen/cyclegan/refactor/cyclegan_lsgan_id0_resnet_in_1x1_266800_horse2zebra_convert-bgr_20210902_165724-77c9c806.pth) |
`FID` comparison with official:
| Dataset | facades | facades-id0 | summer2winter | summer2winter-id0 | winter2summer | winter2summer-id0 | horse2zebra | horse2zebra-id0 | zebra2horse | zebra2horse-id0 | average |
| :------: | :---------: | :---------: | :-----------: | :---------------: | :-----------: | :---------------: | :---------: | :-------------: | :---------: | :-------------: | :--------: |
| official | **123.626** | **119.726** | **77.342** | **76.773** | **72.631** | 74.239 | **62.111** | 77.202 | **138.646** | **137.050** | **95.935** |
| ours | 124.8033 | 125.1694 | 83.7177 | 83.1418 | 72.8025 | **73.5001** | 64.5225 | **74.7770** | 141.1571 | **134.3728** | 97.79 |
`IS` comparison with evaluation:
| Dataset | facades | facades-id0 | summer2winter | summer2winter-id0 | winter2summer | winter2summer-id0 | horse2zebra | horse2zebra-id0 | zebra2horse | zebra2horse-id0 | average |
| :------: | :-------: | :---------: | :-----------: | :---------------: | :-----------: | :---------------: | :---------: | :-------------: | :---------: | :-------------: | :-------: |
| official | 1.638 | 1.697 | 2.762 | **2.750** | **3.293** | **3.110** | 1.375 | **1.584** | **3.186** | 3.047 | 2.444 |
| ours | **1.792** | **1.905** | **2.771** | 2.720 | 3.129 | 3.107 | **1.418** | 1.542 | 3.154 | **3.091** | **2.462** |
Note:
1. With a larger identity loss, the image-to-image translation becomes more conservative, which makes less changes. The original authors did not say what is the best weight for identity loss. Thus, in addition to the default setting, we also set the weight of identity loss to 0 (denoting `id0`) to make a more comprehensive comparison.
2. This is the training log before refactoring. Updated logs will be released soon.
## Citation
```latex
@inproceedings{zhu2017unpaired,
title={Unpaired image-to-image translation using cycle-consistent adversarial networks},
author={Zhu, Jun-Yan and Park, Taesung and Isola, Phillip and Efros, Alexei A},
booktitle={Proceedings of the IEEE international conference on computer vision},
pages={2223--2232},
year={2017},
url={https://openaccess.thecvf.com/content_iccv_2017/html/Zhu_Unpaired_Image-To-Image_Translation_ICCV_2017_paper.html},
}
```
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment