From fd0f5cce9280d351a9cf50ff99ab0fe6f89e35d6 Mon Sep 17 00:00:00 2001 From: Ma Zerun Date: Thu, 14 Oct 2021 15:26:47 +0800 Subject: [PATCH] [Docs] Add model-pages in Model Zoo (#480) * Add model-pages * Add shortname in configs * Use link directly instead of `switch_language.md` * Auto collapse model-zoo pages. * Fix link in RegVGG * Add link replace * fix lint --- configs/lenet/README.md | 1 + configs/mobilenet_v2/README.md | 1 + configs/mobilenet_v3/README.md | 1 + configs/regnet/README.md | 1 + configs/repvgg/README.md | 3 +- configs/resnest/README.md | 1 + configs/resnet/README.md | 1 + configs/resnext/README.md | 1 + configs/seresnet/README.md | 1 + configs/seresnext/README.md | 1 + configs/shufflenet_v1/README.md | 1 + configs/shufflenet_v2/README.md | 1 + configs/swin_transformer/README.md | 1 + configs/vgg/README.md | 1 + configs/vision_transformer/README.md | 1 + docs/_static/js/custom.js | 1 + docs/conf.py | 2 + docs/index.rst | 15 ++---- docs/stat.py | 72 ++++++++++++++++++++++------ docs/switch_language.md | 3 -- docs_zh-CN/index.rst | 15 ++---- docs_zh-CN/stat.py | 70 +++++++++++++++++++++------ docs_zh-CN/switch_language.md | 3 -- 23 files changed, 142 insertions(+), 56 deletions(-) create mode 100644 docs/_static/js/custom.js delete mode 100644 docs/switch_language.md delete mode 100644 docs_zh-CN/switch_language.md diff --git a/configs/lenet/README.md b/configs/lenet/README.md index 3b2d7bea..49647ce4 100644 --- a/configs/lenet/README.md +++ b/configs/lenet/README.md @@ -1,4 +1,5 @@ # Backpropagation Applied to Handwritten Zip Code Recognition + ## Introduction diff --git a/configs/mobilenet_v2/README.md b/configs/mobilenet_v2/README.md index 86cba69d..75008d3c 100644 --- a/configs/mobilenet_v2/README.md +++ b/configs/mobilenet_v2/README.md @@ -1,4 +1,5 @@ # MobileNetV2: Inverted Residuals and Linear Bottlenecks + ## Introduction diff --git a/configs/mobilenet_v3/README.md b/configs/mobilenet_v3/README.md index 47340a18..2bb95508 100644 --- a/configs/mobilenet_v3/README.md +++ b/configs/mobilenet_v3/README.md @@ -1,4 +1,5 @@ # Searching for MobileNetV3 + ## Introduction diff --git a/configs/regnet/README.md b/configs/regnet/README.md index 7aa2cf01..10c42d42 100644 --- a/configs/regnet/README.md +++ b/configs/regnet/README.md @@ -1,4 +1,5 @@ # Designing Network Design Spaces + ## Introduction diff --git a/configs/repvgg/README.md b/configs/repvgg/README.md index 0a3e1930..20e8c35b 100644 --- a/configs/repvgg/README.md +++ b/configs/repvgg/README.md @@ -1,4 +1,5 @@ # Repvgg: Making vgg-style convnets great again + ## Introduction @@ -43,7 +44,7 @@ python ./tools/convert_models/reparameterize_repvgg.py ${CFG_PATH} ${SRC_CKPT_PA `${CFG_PATH}` is the config file, `${SRC_CKPT_PATH}` is the source chenpoint file, `${TARGET_CKPT_PATH}` is the target deploy weight file path. -To use reparameterized repvgg weight, the config file must switch to [the deploy config files](./configs/repvgg/deploy) as below: +To use reparameterized repvgg weight, the config file must switch to [the deploy config files](./deploy) as below: ```bash python ./tools/test.py ${RapVGG_Deploy_CFG} ${CHECK_POINT} diff --git a/configs/resnest/README.md b/configs/resnest/README.md index 9333316d..704d24a7 100644 --- a/configs/resnest/README.md +++ b/configs/resnest/README.md @@ -1,4 +1,5 @@ # ResNeSt: Split-Attention Networks + ## Introduction diff --git a/configs/resnet/README.md b/configs/resnet/README.md index 185fffd3..8e30bcb4 100644 --- a/configs/resnet/README.md +++ b/configs/resnet/README.md @@ -1,4 +1,5 @@ # Deep Residual Learning for Image Recognition + ## Introduction diff --git a/configs/resnext/README.md b/configs/resnext/README.md index 5f80978c..8a4786aa 100644 --- a/configs/resnext/README.md +++ b/configs/resnext/README.md @@ -1,4 +1,5 @@ # Aggregated Residual Transformations for Deep Neural Networks + ## Introduction diff --git a/configs/seresnet/README.md b/configs/seresnet/README.md index 5f9ca35f..1241e3fc 100644 --- a/configs/seresnet/README.md +++ b/configs/seresnet/README.md @@ -1,4 +1,5 @@ # Squeeze-and-Excitation Networks + ## Introduction diff --git a/configs/seresnext/README.md b/configs/seresnext/README.md index 8dc45fc9..393cc518 100644 --- a/configs/seresnext/README.md +++ b/configs/seresnext/README.md @@ -1,4 +1,5 @@ # Squeeze-and-Excitation Networks + ## Introduction diff --git a/configs/shufflenet_v1/README.md b/configs/shufflenet_v1/README.md index a5314184..b1893456 100644 --- a/configs/shufflenet_v1/README.md +++ b/configs/shufflenet_v1/README.md @@ -1,4 +1,5 @@ # ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices + ## Introduction diff --git a/configs/shufflenet_v2/README.md b/configs/shufflenet_v2/README.md index d1645fc7..35024258 100644 --- a/configs/shufflenet_v2/README.md +++ b/configs/shufflenet_v2/README.md @@ -1,4 +1,5 @@ # Shufflenet v2: Practical guidelines for efficient cnn architecture design + ## Introduction diff --git a/configs/swin_transformer/README.md b/configs/swin_transformer/README.md index 1bb590d3..b1fade80 100644 --- a/configs/swin_transformer/README.md +++ b/configs/swin_transformer/README.md @@ -1,4 +1,5 @@ # Swin Transformer: Hierarchical Vision Transformer using Shifted Windows + ## Introduction diff --git a/configs/vgg/README.md b/configs/vgg/README.md index f1f59255..a1aca53d 100644 --- a/configs/vgg/README.md +++ b/configs/vgg/README.md @@ -1,4 +1,5 @@ # Very Deep Convolutional Networks for Large-Scale Image Recognition + ## Introduction diff --git a/configs/vision_transformer/README.md b/configs/vision_transformer/README.md index de818be1..f9a88980 100644 --- a/configs/vision_transformer/README.md +++ b/configs/vision_transformer/README.md @@ -1,4 +1,5 @@ # An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale + ## Introduction diff --git a/docs/_static/js/custom.js b/docs/_static/js/custom.js new file mode 100644 index 00000000..44a4057d --- /dev/null +++ b/docs/_static/js/custom.js @@ -0,0 +1 @@ +var collapsedSections = ['Model zoo']; diff --git a/docs/conf.py b/docs/conf.py index 5c6d7214..28e900cd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -161,6 +161,7 @@ html_theme_options = { # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] html_css_files = ['css/readthedocs.css'] +html_js_files = ['js/custom.js'] master_doc = 'index' @@ -270,4 +271,5 @@ def setup(app): 'enable_eval_rst': True, }, True) app.add_transform(AutoStructify) + app.add_js_file('./_static/js/custom.js') app.connect('builder-inited', builder_inited_handler) diff --git a/docs/index.rst b/docs/index.rst index 59c4900b..db70248e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,14 +13,6 @@ You can switch between Chinese and English documents in the lower-left corner of getting_started.md -.. toctree:: - :maxdepth: 1 - :caption: Model zoo - - modelzoo_statistics.md - model_zoo.md - - .. toctree:: :maxdepth: 1 :caption: Tutorials @@ -31,6 +23,9 @@ You can switch between Chinese and English documents in the lower-left corner of tutorials/new_modules.md +.. include:: _model_zoo.rst + + .. toctree:: :maxdepth: 1 :caption: Useful Tools and Scripts @@ -57,8 +52,8 @@ You can switch between Chinese and English documents in the lower-left corner of .. toctree:: :caption: Language Switch - switch_language.md - + English + 简体中文 Indices and tables diff --git a/docs/stat.py b/docs/stat.py index 1dcd9f58..feee2fe0 100755 --- a/docs/stat.py +++ b/docs/stat.py @@ -1,14 +1,18 @@ #!/usr/bin/env python import functools as func import glob -import os.path as osp +import os import re +from pathlib import Path import numpy as np +MMCLS_ROOT = Path(__file__).absolute().parents[1] url_prefix = 'https://github.com/open-mmlab/mmclassification/blob/master/' -files = sorted(glob.glob('../configs/*/README.md')) +papers_root = Path('papers') +papers_root.mkdir(exist_ok=True) +files = [Path(f) for f in sorted(glob.glob('../configs/*/README.md'))] stats = [] titles = [] @@ -16,35 +20,59 @@ num_ckpts = 0 num_configs = 0 for f in files: - url = osp.dirname(f.replace('../', url_prefix)) - with open(f, 'r') as content_file: content = content_file.read() - title = content.split('\n')[0].replace('# ', '').strip() - + # Extract checkpoints ckpts = set(x.lower().strip() for x in re.findall(r'\[model\]\((https?.*)\)', content)) - if len(ckpts) == 0: continue + num_ckpts += len(ckpts) + # Extract paper title + title = content.split('\n')[0].replace('# ', '').strip() + titles.append(title) + + # Extract paper abbreviation + abbr = [x for x in re.findall(r'', content)] + abbr = abbr[0] if len(abbr) > 0 else title + + # Extract paper type _papertype = [x for x in re.findall(r'\[([A-Z]+)\]', content)] assert len(_papertype) > 0 papertype = _papertype[0] - paper = set([(papertype, title)]) - num_ckpts += len(ckpts) - titles.append(title) + # Write a copy of README + copy = papers_root / (f.parent.name + '.md') + if copy.exists(): + os.remove(copy) + + def replace_link(matchobj): + # Replace relative link to GitHub link. + name = matchobj.group(1) + link = matchobj.group(2) + if not link.startswith('http') and (f.parent / link).exists(): + rel_link = (f.parent / link).absolute().relative_to(MMCLS_ROOT) + link = url_prefix + str(rel_link) + return f'[{name}]({link})' + + content = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', replace_link, content) + + with open(copy, 'w') as copy_file: + copy_file.write(content) statsmsg = f""" -\t* [{papertype}] [{title}]({url}) ({len(ckpts)} ckpts) +\t* [{papertype}] [{title}]({copy}) ({len(ckpts)} ckpts) """ - stats.append((paper, ckpts, statsmsg)) + stats.append( + dict( + paper=paper, ckpts=ckpts, statsmsg=statsmsg, abbr=abbr, copy=copy)) -allpapers = func.reduce(lambda a, b: a.union(b), [p for p, _, _ in stats]) -msglist = '\n'.join(x for _, _, x in stats) +allpapers = func.reduce(lambda a, b: a.union(b), + [stat['paper'] for stat in stats]) +msglist = '\n'.join(stat['statsmsg'] for stat in stats) papertypes, papercounts = np.unique([t for t, _ in allpapers], return_counts=True) @@ -52,7 +80,7 @@ countstr = '\n'.join( [f' - {t}: {c}' for t, c in zip(papertypes, papercounts)]) modelzoo = f""" -# Model Zoo Statistics +# Model Zoo Summary * Number of papers: {len(set(titles))} {countstr} @@ -63,3 +91,17 @@ modelzoo = f""" with open('modelzoo_statistics.md', 'w') as f: f.write(modelzoo) + +toctree = """ +.. toctree:: + :maxdepth: 1 + :caption: Model zoo + :glob: + + modelzoo_statistics.md + model_zoo.md +""" +with open('_model_zoo.rst', 'w') as f: + f.write(toctree) + for stat in stats: + f.write(f' {stat["abbr"]} <{stat["copy"]}>\n') diff --git a/docs/switch_language.md b/docs/switch_language.md deleted file mode 100644 index 15f87184..00000000 --- a/docs/switch_language.md +++ /dev/null @@ -1,3 +0,0 @@ -# English - -# 简体中文 diff --git a/docs_zh-CN/index.rst b/docs_zh-CN/index.rst index 460f2fed..81eebf1b 100644 --- a/docs_zh-CN/index.rst +++ b/docs_zh-CN/index.rst @@ -13,14 +13,6 @@ You can switch between Chinese and English documents in the lower-left corner of getting_started.md -.. toctree:: - :maxdepth: 1 - :caption: 模型库 - - modelzoo_statistics.md - model_zoo.md - - .. toctree:: :maxdepth: 1 :caption: 教程 @@ -31,6 +23,9 @@ You can switch between Chinese and English documents in the lower-left corner of tutorials/new_modules.md +.. include:: _model_zoo.rst + + .. toctree:: :maxdepth: 1 :caption: 实用工具 @@ -57,8 +52,8 @@ You can switch between Chinese and English documents in the lower-left corner of .. toctree:: :caption: 语言切换 - switch_language.md - + English + 简体中文 索引与表格 diff --git a/docs_zh-CN/stat.py b/docs_zh-CN/stat.py index 88f94ee8..8968cbed 100755 --- a/docs_zh-CN/stat.py +++ b/docs_zh-CN/stat.py @@ -1,14 +1,18 @@ #!/usr/bin/env python import functools as func import glob -import os.path as osp +import os import re +from pathlib import Path import numpy as np +MMCLS_ROOT = Path(__file__).absolute().parents[1] url_prefix = 'https://github.com/open-mmlab/mmclassification/blob/master/' -files = sorted(glob.glob('../configs/*/README.md')) +papers_root = Path('papers') +papers_root.mkdir(exist_ok=True) +files = [Path(f) for f in sorted(glob.glob('../configs/*/README.md'))] stats = [] titles = [] @@ -16,35 +20,59 @@ num_ckpts = 0 num_configs = 0 for f in files: - url = osp.dirname(f.replace('../', url_prefix)) - with open(f, 'r') as content_file: content = content_file.read() - title = content.split('\n')[0].replace('# ', '').strip() - + # Extract checkpoints ckpts = set(x.lower().strip() for x in re.findall(r'\[model\]\((https?.*)\)', content)) - if len(ckpts) == 0: continue + num_ckpts += len(ckpts) + # Extract paper title + title = content.split('\n')[0].replace('# ', '').strip() + titles.append(title) + + # Extract paper abbreviation + abbr = [x for x in re.findall(r'', content)] + abbr = abbr[0] if len(abbr) > 0 else title + + # Extract paper type _papertype = [x for x in re.findall(r'\[([A-Z]+)\]', content)] assert len(_papertype) > 0 papertype = _papertype[0] - paper = set([(papertype, title)]) - num_ckpts += len(ckpts) - titles.append(title) + # Write a copy of README + copy = papers_root / (f.parent.name + '.md') + if copy.exists(): + os.remove(copy) + + def replace_link(matchobj): + # Replace relative link to GitHub link. + name = matchobj.group(1) + link = matchobj.group(2) + if not link.startswith('http') and (f.parent / link).exists(): + rel_link = (f.parent / link).absolute().relative_to(MMCLS_ROOT) + link = url_prefix + str(rel_link) + return f'[{name}]({link})' + + content = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', replace_link, content) + + with open(copy, 'w') as copy_file: + copy_file.write(content) statsmsg = f""" -\t* [{papertype}] [{title}]({url}) ({len(ckpts)} ckpts) +\t* [{papertype}] [{title}]({copy}) ({len(ckpts)} ckpts) """ - stats.append((paper, ckpts, statsmsg)) + stats.append( + dict( + paper=paper, ckpts=ckpts, statsmsg=statsmsg, abbr=abbr, copy=copy)) -allpapers = func.reduce(lambda a, b: a.union(b), [p for p, _, _ in stats]) -msglist = '\n'.join(x for _, _, x in stats) +allpapers = func.reduce(lambda a, b: a.union(b), + [stat['paper'] for stat in stats]) +msglist = '\n'.join(stat['statsmsg'] for stat in stats) papertypes, papercounts = np.unique([t for t, _ in allpapers], return_counts=True) @@ -63,3 +91,17 @@ modelzoo = f""" with open('modelzoo_statistics.md', 'w') as f: f.write(modelzoo) + +toctree = """ +.. toctree:: + :maxdepth: 1 + :caption: 模型库 + :glob: + + modelzoo_statistics.md + model_zoo.md +""" +with open('_model_zoo.rst', 'w') as f: + f.write(toctree) + for stat in stats: + f.write(f' {stat["abbr"]} <{stat["copy"]}>\n') diff --git a/docs_zh-CN/switch_language.md b/docs_zh-CN/switch_language.md deleted file mode 100644 index 15f87184..00000000 --- a/docs_zh-CN/switch_language.md +++ /dev/null @@ -1,3 +0,0 @@ -# English - -# 简体中文