diff --git a/PyTorch/contrib/cv/video/BasicVSR/.keep b/PyTorch/contrib/cv/video/BasicVSR/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/PyTorch/contrib/cv/video/BasicVSR/LICENSE b/PyTorch/contrib/cv/video/BasicVSR/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..8719b270aa584fcece70565c44bf94d147e87721 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/LICENSE @@ -0,0 +1,236 @@ +'''# -*- coding: utf-8 -*- +# BSD 3-Clause License +# +# Copyright (c) 2017 +# All rights reserved. +# Copyright 2022 Huawei Technologies Co., Ltd +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ========================================================================== +''' +Copyright (c) MMEditing Authors. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 MMEditing Authors. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/PyTorch/contrib/cv/video/BasicVSR/README.md b/PyTorch/contrib/cv/video/BasicVSR/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8a6a069e3835f76af329adc9db61262f63ad1c21 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/README.md @@ -0,0 +1,174 @@ +# BasicVSR for PyTorch + +- [概述](概述.md) +- [准备训练环境](准备训练环境.md) +- [开始训练](开始训练.md) +- [训练结果展示](训练结果展示.md) +- [版本说明](版本说明.md) + + + +# 概述 + +## 简述 + +视频超分辨率(VSR)方法往往比图像方法具有更多的组件,因为它们需要利用额外的时间维度。复杂的设计并不少见。在这项研究中,我们希望解开这些结,并重新考虑VSR的一些最重要的组件,这些组件由四个基本功能指导,即传播,对齐,聚合和上采样。通过重用一些以最少的重新设计添加的现有组件,我们展示了一个简洁的管道 BasicVSR,与许多最先进的算法相比,它在速度和恢复质量方面实现了有吸引力的改进。我们进行系统分析,以解释如何获得这种收益并讨论陷阱。我们通过提出信息重填机制和耦合传播方案来促进信息聚合,进一步展示了 BasicVSR 的可扩展性。BasicVSR及其扩展IconVSR可以作为未来VSR方法的强大基准。 +- 适配昇腾 AI 处理器的实现: + + ``` + url=https://gitee.com/ascend/ModelZoo-PyTorch.git + code_path=PyTorch/contrib/cv/detection + ``` + +- 通过Git获取代码方法如下: + + ``` + # BasicVSR所属包为MMEditing包,该包目前以与MMGeneration包和并成为MMagic包。 + # 本项目使用代码为MMEditing-1.0.0rc6代码 + # 本项目依赖包mmcv-2.0.0rc4和MMengine0.6.0 + # 代码相关链接如下,可点击DownloadZIP进行下载,也可Git获取代码 + https://github.com/open-mmlab/mmagic/tree/v1.0.0rc6 #MMEditing + https://github.com/open-mmlab/mmcv/tree/v2.0.0rc4 #MMcv + ``` + +# 准备训练环境 + +## 准备环境 + +- 环境准备指导。 + + 请参考《[Pytorch框架训练环境准备](https://www.hiascend.com/document/detail/zh/ModelZoo/pytorchframework/ptes)》。 + + 安装依赖版本如下: + + **表 1** 版本支持表 + + | name| 依赖环境 | + |----------------------------------| ----------------------------------| + | PyTorch 1.8 | torchvision==0.6.0;pillow==8.4.0 | + | mmedit 1.0.0rc6 | mmcv==2.0.0rc4;mmengine==0.6.0 | + +- 安装依赖。 + + 在模型源码包根目录下执行命令,安装模型对应版本需要的依赖 + ``` + # 首先安装MMCV + # 解压压缩包 + unzip mmcv-2.x.zip + cd mmcv-2.x/ + # 安装到库中 + python3.7 setup.py install + + # 安装MMEditing + # 解压压缩包 + unzip mmediting-1.x.zip + cd mmediting-1.x/ + # 安装到库中 + python3.7 setup.py install + + # 安装MMengine + pip3.7 install mmengine==0.6.0 + + ``` + + +## 准备数据集 + +1. 获取数据集。 + ``` + # 下载REDS数据集 + https://seungjunnah.github.io/Datasets/reds.html + # 下载train_sharp val_sharp train_sharp_bicubic val_sharp_bicubic四个数据集 + https://drive.google.com/open?id=1YLksKtMhd2mWyVSkvhDaDLWSc1qYNCz- # train_sharp.zip + https://drive.google.com/open?id=1MGeObVQ1-Z29f-myDP7-8c3u0_xECKXq # val_sharp.zip + https://drive.google.com/open?id=1a4PrjqT-hShvY9IyJm3sPF0ZaXyrCozR # train_sharp_bicubic.zip + https://drive.google.com/open?id=1sChhtzN9Css10gX7Xsmc2JaC-2Pzco6a # val_sharp_bicubic.zip + + # 创建文件夹REDS,将四个压缩文件放入REDS文件夹即可 + ``` +2. 数据预处理。 + 需要使用MMEditing提供的方案预处理数据集。 + ``` + # 找到处理文件preprocess_reds_dataset.py,进入文件所在路径 + cd mmediting-1.x/tools/dataset_converters/reds/ + + # 执行文件,处理数据集 + python3.7 preprocess_reds_dataset.py --root-path={REDS文件夹所属绝对路径或相对路径}/REDS + + # 得到输出如下(简化版) + Unzip data/REDS\train_sharp.zip to data/REDS\train_sharp + Unzip data/REDS\train_sharp_bicubic.zip to data/REDS\train_sharp_bicubic + Unzip data/REDS\val_sharp_bicubic.zip to data/REDS\val_sharp_bicubic + Unzip data/REDS\val_sharp.zip to data/REDS\val_sharp + Move data/REDS\val_sharp to data/REDS\train_sharp... + Remove data/REDS\val_sharp + Move data/REDS\val_sharp_bicubic\X4 to data/REDS\train_sharp_bicubic\X4... + Remove data/REDS\val_sharp_bicubic + Generate annotation files meta_info_REDS_GT.txt... + + # 自动完成解压整理即生成标注文件 + ``` + +3. 配置文件处理。 + ``` + # 进入路径configs/basicvsr + cd mmediting-1.x/configs/basicvsr/ + # 编辑文件 basicvsr_2xb4_reds4.py + # 将 data_root 编辑为本设备所属路径,以本文设备为例 + data_root = '/home/test_user07/REDS' + ``` + +# 开始训练 + +## 训练模型 + +1. 进入解压后的源码包tools目录。 + + ``` + cd mmediting-1.x/tools/ + ``` + +2. 运行训练脚本。 + + 启动训练。 + + ``` + python3.7 train.py ../configs/basicvsr/basicvsr_2xb4_reds4.py --amp + ``` + + 训练完成后,会在tools目录下保存模型权重文件,并输出模型训练精度和性能信息。 + +# 训练结果展示 + +训练300,000个epoch结果如下: + +**表 2** 训练结果展示表 + +| Method | PSNR | SSIM | +|--------|---------|-------:| +| NPU | 30.8626 | 0.8811 | +| 竞品V | 31.2826 | 0.8892 | + + +# 版本说明 + +## 变更 + +2023.6.20:首次发布 + +## 已知问题 + +**_当前发行版本中存在的问题描述。_** + +无 + + + + + + + + + + + diff --git a/PyTorch/contrib/cv/video/BasicVSR/configs/_base_/datasets/basicvsr_test_config.py b/PyTorch/contrib/cv/video/BasicVSR/configs/_base_/datasets/basicvsr_test_config.py new file mode 100644 index 0000000000000000000000000000000000000000..14804c01eb488f45b5bad583d585e746dd9673a8 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/configs/_base_/datasets/basicvsr_test_config.py @@ -0,0 +1,182 @@ +# configs for REDS4 +reds_data_root = 'data/REDS' + +reds_pipeline = [ + dict(type='GenerateSegmentIndices', interval_list=[1]), + dict(type='LoadImageFromFile', key='img', channel_order='rgb'), + dict(type='LoadImageFromFile', key='gt', channel_order='rgb'), + dict(type='PackEditInputs') +] + +reds_dataloader = dict( + num_workers=1, + batch_size=1, + persistent_workers=False, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type='BasicFramesDataset', + metainfo=dict(dataset_type='reds_reds4', task_name='vsr'), + data_root=reds_data_root, + data_prefix=dict(img='train_sharp_bicubic/X4', gt='train_sharp'), + ann_file='meta_info_reds4_val.txt', + depth=1, + num_input_frames=100, + fixed_seq_len=100, + pipeline=reds_pipeline)) + +reds_evaluator = [ + dict(type='PSNR', prefix='REDS4-BIx4-RGB'), + dict(type='SSIM', prefix='REDS4-BIx4-RGB') +] + +# configs for vimeo90k-bd and vimeo90k-bi +vimeo_90k_data_root = 'data/vimeo90k' +vimeo_90k_file_list = [ + 'im1.png', 'im2.png', 'im3.png', 'im4.png', 'im5.png', 'im6.png', 'im7.png' +] + +vimeo_90k_pipeline = [ + dict(type='LoadImageFromFile', key='img', channel_order='rgb'), + dict(type='LoadImageFromFile', key='gt', channel_order='rgb'), + dict(type='MirrorSequence', keys=['img']), + dict(type='PackEditInputs') +] + +vimeo_90k_bd_dataloader = dict( + num_workers=1, + batch_size=1, + persistent_workers=False, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type='BasicFramesDataset', + metainfo=dict(dataset_type='vimeo90k_seq', task_name='vsr'), + data_root=vimeo_90k_data_root, + data_prefix=dict(img='BDx4', gt='GT'), + ann_file='meta_info_Vimeo90K_test_GT.txt', + depth=2, + num_input_frames=7, + fixed_seq_len=7, + load_frames_list=dict(img=vimeo_90k_file_list, gt=['im4.png']), + pipeline=vimeo_90k_pipeline)) + +vimeo_90k_bi_dataloader = dict( + num_workers=1, + batch_size=1, + persistent_workers=False, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type='BasicFramesDataset', + metainfo=dict(dataset_type='vimeo90k_seq', task_name='vsr'), + data_root=vimeo_90k_data_root, + data_prefix=dict(img='BIx4', gt='GT'), + ann_file='meta_info_Vimeo90K_test_GT.txt', + depth=2, + num_input_frames=7, + fixed_seq_len=7, + load_frames_list=dict(img=vimeo_90k_file_list, gt=['im4.png']), + pipeline=vimeo_90k_pipeline)) + +vimeo_90k_bd_evaluator = [ + dict(type='PSNR', convert_to='Y', prefix='Vimeo-90K-T-BDx4-Y'), + dict(type='SSIM', convert_to='Y', prefix='Vimeo-90K-T-BDx4-Y'), +] + +vimeo_90k_bi_evaluator = [ + dict(type='PSNR', convert_to='Y', prefix='Vimeo-90K-T-BIx4-Y'), + dict(type='SSIM', convert_to='Y', prefix='Vimeo-90K-T-BIx4-Y'), +] + +# config for UDM10 (BDx4) +udm10_data_root = 'data/UDM10' + +udm10_pipeline = [ + dict( + type='GenerateSegmentIndices', + interval_list=[1], + filename_tmpl='{:04d}.png'), + dict(type='LoadImageFromFile', key='img', channel_order='rgb'), + dict(type='LoadImageFromFile', key='gt', channel_order='rgb'), + dict(type='PackEditInputs') +] + +udm10_dataloader = dict( + num_workers=1, + batch_size=1, + persistent_workers=False, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type='BasicFramesDataset', + metainfo=dict(dataset_type='udm10', task_name='vsr'), + data_root=udm10_data_root, + data_prefix=dict(img='BDx4', gt='GT'), + pipeline=udm10_pipeline)) + +udm10_evaluator = [ + dict(type='PSNR', convert_to='Y', prefix='UDM10-BDx4-Y'), + dict(type='SSIM', convert_to='Y', prefix='UDM10-BDx4-Y') +] + +# config for vid4 +vid4_data_root = 'data/Vid4' + +vid4_pipeline = [ + dict(type='GenerateSegmentIndices', interval_list=[1]), + dict(type='LoadImageFromFile', key='img', channel_order='rgb'), + dict(type='LoadImageFromFile', key='gt', channel_order='rgb'), + dict(type='PackEditInputs') +] +vid4_bd_dataloader = dict( + num_workers=1, + batch_size=1, + persistent_workers=False, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type='BasicFramesDataset', + metainfo=dict(dataset_type='vid4', task_name='vsr'), + data_root=vid4_data_root, + data_prefix=dict(img='BDx4', gt='GT'), + ann_file='meta_info_Vid4_GT.txt', + depth=1, + pipeline=vid4_pipeline)) + +vid4_bi_dataloader = dict( + num_workers=1, + batch_size=1, + persistent_workers=False, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type='BasicFramesDataset', + metainfo=dict(dataset_type='vid4', task_name='vsr'), + data_root=vid4_data_root, + data_prefix=dict(img='BIx4', gt='GT'), + ann_file='meta_info_Vid4_GT.txt', + depth=1, + pipeline=vid4_pipeline)) + +vid4_bd_evaluator = [ + dict(type='PSNR', convert_to='Y', prefix='VID4-BDx4-Y'), + dict(type='SSIM', convert_to='Y', prefix='VID4-BDx4-Y'), +] +vid4_bi_evaluator = [ + dict(type='PSNR', convert_to='Y', prefix='VID4-BIx4-Y'), + dict(type='SSIM', convert_to='Y', prefix='VID4-BIx4-Y'), +] + +# config for test +test_cfg = dict(type='EditTestLoop') +test_dataloader = [ + reds_dataloader, + vimeo_90k_bd_dataloader, + vimeo_90k_bi_dataloader, + udm10_dataloader, + vid4_bd_dataloader, + vid4_bi_dataloader, +] +test_evaluator = [ + reds_evaluator, + vimeo_90k_bd_evaluator, + vimeo_90k_bi_evaluator, + udm10_evaluator, + vid4_bd_evaluator, + vid4_bi_evaluator, +] diff --git a/PyTorch/contrib/cv/video/BasicVSR/configs/_base_/default_runtime.py b/PyTorch/contrib/cv/video/BasicVSR/configs/_base_/default_runtime.py new file mode 100644 index 0000000000000000000000000000000000000000..195e1e6d2ee94f01a8ea72cf78b9f9300445c372 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/configs/_base_/default_runtime.py @@ -0,0 +1,39 @@ +default_scope = 'mmedit' +save_dir = './work_dirs' + +default_hooks = dict( + timer=dict(type='EditIterTimerHook'), + logger=dict(type='LoggerHook', interval=100), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict( + type='CheckpointHook', + interval=5000, + out_dir=save_dir, + by_epoch=False, + max_keep_ckpts=10, + save_best='PSNR', + rule='greater', + ), + sampler_seed=dict(type='DistSamplerSeedHook'), +) + +env_cfg = dict( + cudnn_benchmark=False, + mp_cfg=dict(mp_start_method='fork', opencv_num_threads=4), + dist_cfg=dict(backend='nccl'), +) + +log_level = 'INFO' +log_processor = dict(type='EditLogProcessor', window_size=100, by_epoch=False) + +load_from = None +resume = False + +vis_backends = [dict(type='LocalVisBackend')] +visualizer = dict( + type='ConcatImageVisualizer', + vis_backends=vis_backends, + fn_key='gt_path', + img_keys=['gt_img', 'input', 'pred_img'], + bgr2rgb=True) +custom_hooks = [dict(type='BasicVisualizationHook', interval=1)] diff --git a/PyTorch/contrib/cv/video/BasicVSR/configs/basicvsr/basicvsr_2xb4_reds4.py b/PyTorch/contrib/cv/video/BasicVSR/configs/basicvsr/basicvsr_2xb4_reds4.py new file mode 100644 index 0000000000000000000000000000000000000000..53e37f3ec28a63a22b8437995f9f72c01779f7e1 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/configs/basicvsr/basicvsr_2xb4_reds4.py @@ -0,0 +1,119 @@ +_base_ = [ + '../_base_/default_runtime.py', + '../_base_/datasets/basicvsr_test_config.py' +] + +experiment_name = 'basicvsr_2xb4_reds4' +work_dir = f'./work_dirs/{experiment_name}' +save_dir = './work_dirs' + +scale = 4 + +# model settings +model = dict( + type='BasicVSR', + generator=dict( + type='BasicVSRNet', + mid_channels=64, + num_blocks=30, + spynet_pretrained='https://download.openmmlab.com/mmediting/restorers/' + 'basicvsr/spynet_20210409-c6c1bd09.pth'), + pixel_loss=dict(type='CharbonnierLoss', loss_weight=1.0, reduction='mean'), + train_cfg=dict(fix_iter=5000), + data_preprocessor=dict( + type='EditDataPreprocessor', + mean=[0., 0., 0.], + std=[255., 255., 255.], + )) + +train_pipeline = [ + dict(type='GenerateSegmentIndices', interval_list=[1]), + dict(type='LoadImageFromFile', key='img', channel_order='rgb'), + dict(type='LoadImageFromFile', key='gt', channel_order='rgb'), + dict(type='SetValues', dictionary=dict(scale=scale)), + dict(type='PairedRandomCrop', gt_patch_size=256), + dict( + type='Flip', + keys=['img', 'gt'], + flip_ratio=0.5, + direction='horizontal'), + dict( + type='Flip', keys=['img', 'gt'], flip_ratio=0.5, direction='vertical'), + dict(type='RandomTransposeHW', keys=['img', 'gt'], transpose_ratio=0.5), + dict(type='PackEditInputs') +] + +val_pipeline = [ + dict(type='GenerateSegmentIndices', interval_list=[1]), + dict(type='LoadImageFromFile', key='img', channel_order='rgb'), + dict(type='LoadImageFromFile', key='gt', channel_order='rgb'), + dict(type='PackEditInputs') +] + +demo_pipeline = [ + dict(type='GenerateSegmentIndices', interval_list=[1]), + dict(type='LoadImageFromFile', key='img', channel_order='rgb'), + dict(type='PackEditInputs') +] + +data_root = 'data/REDS' + +train_dataloader = dict( + num_workers=6, + batch_size=4, + persistent_workers=False, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type='BasicFramesDataset', + metainfo=dict(dataset_type='reds_reds4', task_name='vsr'), + data_root=data_root, + data_prefix=dict(img='train_sharp_bicubic/X4', gt='train_sharp'), + ann_file='meta_info_reds4_train.txt', + depth=1, + num_input_frames=15, + pipeline=train_pipeline)) + +val_dataloader = dict( + num_workers=1, + batch_size=1, + persistent_workers=False, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type='BasicFramesDataset', + metainfo=dict(dataset_type='reds_reds4', task_name='vsr'), + data_root=data_root, + data_prefix=dict(img='train_sharp_bicubic/X4', gt='train_sharp'), + ann_file='meta_info_reds4_val.txt', + depth=1, + num_input_frames=100, + fixed_seq_len=100, + pipeline=val_pipeline)) + +val_evaluator = dict( + type='EditEvaluator', metrics=[ + dict(type='PSNR'), + dict(type='SSIM'), + ]) + +train_cfg = dict( + type='IterBasedTrainLoop', max_iters=300_000, val_interval=5000) +val_cfg = dict(type='EditValLoop') + +# optimizer +optim_wrapper = dict( + constructor='DefaultOptimWrapperConstructor', + type='OptimWrapper', + optimizer=dict(type='Adam', lr=2e-4, betas=(0.9, 0.99)), + paramwise_cfg=dict(custom_keys={'spynet': dict(lr_mult=0.125)})) + +default_hooks = dict(checkpoint=dict(out_dir=save_dir)) + +# learning policy +param_scheduler = dict( + type='CosineRestartLR', + by_epoch=False, + periods=[300000], + restart_weights=[1], + eta_min=1e-7) + +find_unused_parameters = True diff --git a/PyTorch/contrib/cv/video/BasicVSR/requirements.txt b/PyTorch/contrib/cv/video/BasicVSR/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..bc18a5033c334a259d3db88ea02beb3d0854dead --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/requirements.txt @@ -0,0 +1,3 @@ +-r requirements/runtime.txt +-r requirements/tests.txt +-r requirements/optional.txt diff --git a/PyTorch/contrib/cv/video/BasicVSR/requirements/docs.txt b/PyTorch/contrib/cv/video/BasicVSR/requirements/docs.txt new file mode 100644 index 0000000000000000000000000000000000000000..486729d482c17d47f8fcca6829c9a8cce20c7cf2 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/requirements/docs.txt @@ -0,0 +1,10 @@ +docutils==0.16.0 +modelindex +myst_parser +-e git+https://github.com/open-mmlab/pytorch_sphinx_theme.git#egg=pytorch_sphinx_theme +sphinx==4.5.0 +sphinx-autoapi +sphinx-copybutton +sphinx-notfound-page +sphinx-tabs +sphinx_markdown_tables diff --git a/PyTorch/contrib/cv/video/BasicVSR/requirements/mminstall.txt b/PyTorch/contrib/cv/video/BasicVSR/requirements/mminstall.txt new file mode 100644 index 0000000000000000000000000000000000000000..992f383c8b5c324eab07a9f0f93d36db3515c7bc --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/requirements/mminstall.txt @@ -0,0 +1,2 @@ +mmcv>=2.0.0rc1 +mmengine>=0.4.0 diff --git a/PyTorch/contrib/cv/video/BasicVSR/requirements/optional.txt b/PyTorch/contrib/cv/video/BasicVSR/requirements/optional.txt new file mode 100644 index 0000000000000000000000000000000000000000..3f110c9191dc6ac222c438b19be11441097efbd2 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/requirements/optional.txt @@ -0,0 +1,6 @@ +-e git+https://github.com/openai/CLIP.git@d50d76daa670286dd6cacf3bcd80b5e4823fc8e1#egg=clip +imageio-ffmpeg==0.4.4 +mmdet >= 3.0.0rc2 +open_clip_torch +PyQt5 +transformers diff --git a/PyTorch/contrib/cv/video/BasicVSR/requirements/readthedocs.txt b/PyTorch/contrib/cv/video/BasicVSR/requirements/readthedocs.txt new file mode 100644 index 0000000000000000000000000000000000000000..17e5a5c8ea84e90c3db585473d57df63373ce4d5 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/requirements/readthedocs.txt @@ -0,0 +1,14 @@ +lmdb +lpips +mmcv>=2.0.0rc1 +mmdet >= 3.0.0rc2 +mmengine +prettytable +Pygments +regex +scikit-image +tabulate +titlecase +torch +torchvision +tqdm diff --git a/PyTorch/contrib/cv/video/BasicVSR/requirements/runtime.txt b/PyTorch/contrib/cv/video/BasicVSR/requirements/runtime.txt new file mode 100644 index 0000000000000000000000000000000000000000..d98b318732c7af51ce6788916cfe2819126fcc83 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/requirements/runtime.txt @@ -0,0 +1,19 @@ +av +av==8.0.3; python_version < '3.7' +einops +face-alignment +facexlib +lmdb +lpips +mmcv>=2.0.0rc1 +mmengine +numpy +opencv-python!=4.5.5.62,!=4.5.5.64 +# MMCV depends opencv-python instead of headless, thus we install opencv-python +# Due to a bug from upstream, we skip this two version +# https://github.com/opencv/opencv-python/issues/602 +# https://github.com/opencv/opencv/issues/21366 +# It seems to be fixed in https://github.com/opencv/opencv/pull/21382 +Pillow +resize_right +tensorboard diff --git a/PyTorch/contrib/cv/video/BasicVSR/requirements/tests.txt b/PyTorch/contrib/cv/video/BasicVSR/requirements/tests.txt new file mode 100644 index 0000000000000000000000000000000000000000..d20b4c3785fea9306c793e5f4d3be74cbec7c01b --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/requirements/tests.txt @@ -0,0 +1,14 @@ +-e git+https://github.com/openai/CLIP.git@d50d76daa670286dd6cacf3bcd80b5e4823fc8e1#egg=clip +# codecov +# flake8 +# isort==5.10.1 +# onnxruntime +# pytest +# pytest-runner +# yapf +coverage < 7.0.0 +imageio-ffmpeg==0.4.4 +interrogate +mmdet >= 3.0.0rc2 +pytest +transformers diff --git a/PyTorch/contrib/cv/video/BasicVSR/tools/train.py b/PyTorch/contrib/cv/video/BasicVSR/tools/train.py new file mode 100644 index 0000000000000000000000000000000000000000..37d6214ea424ce37fe3f3b9d9a8e317e44b64a10 --- /dev/null +++ b/PyTorch/contrib/cv/video/BasicVSR/tools/train.py @@ -0,0 +1,111 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import argparse +import logging +import os +import os.path as osp + +from mmengine.config import Config, DictAction +from mmengine.runner import Runner + +from mmedit.utils import print_colored_log + + +def parse_args(): + parser = argparse.ArgumentParser(description='Train a model') + parser.add_argument('config', help='train config file path') + parser.add_argument('--work-dir', help='the dir to save logs and models') + parser.add_argument( + '--resume', action='store_true', help='Whether to resume checkpoint.') + parser.add_argument( + '--amp', + action='store_true', + default=False, + help='enable automatic-mixed-precision training') + parser.add_argument( + '--auto-scale-lr', + action='store_true', + help='enable automatically scaling LR.') + parser.add_argument( + '--cfg-options', + nargs='+', + action=DictAction, + help='override some settings in the used config, the key-value pair ' + 'in xxx=yyy format will be merged into config file. If the value to ' + 'be overwritten is a list, it should be like key="[a,b]" or key=a,b ' + 'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" ' + 'Note that the quotation marks are necessary and that no white space ' + 'is allowed.') + parser.add_argument( + '--launcher', + choices=['none', 'pytorch', 'slurm', 'mpi'], + default='none', + help='job launcher') + parser.add_argument('--local_rank', type=int, default=0) + args = parser.parse_args() + if 'LOCAL_RANK' not in os.environ: + os.environ['LOCAL_RANK'] = str(args.local_rank) + + return args + + +def main(): + args = parse_args() + + # load config + cfg = Config.fromfile(args.config) + cfg.launcher = args.launcher + if args.cfg_options is not None: + cfg.merge_from_dict(args.cfg_options) + + # work_dir is determined in this priority: CLI > segment in file > filename + if args.work_dir: # none or empty str + # update configs according to CLI args if args.work_dir is not None + cfg.work_dir = args.work_dir + elif cfg.get('work_dir', None) is None: + # use config filename as default work_dir if cfg.work_dir is None + cfg.work_dir = osp.join('./work_dirs', + osp.splitext(osp.basename(args.config))[0]) + + # enable automatic-mixed-precision training + if args.amp is True: + if ('constructor' not in cfg.optim_wrapper) or \ + cfg.optim_wrapper['constructor'] == 'DefaultOptimWrapperConstructor': # noqa + optim_wrapper = cfg.optim_wrapper.type + if optim_wrapper == 'AmpOptimWrapper': + print_colored_log( + 'AMP training is already enabled in your config.', + logger='current', + level=logging.WARNING) + else: + assert optim_wrapper == 'OptimWrapper', ( + '`--amp` is only supported when the optimizer wrapper ' + f'`type is OptimWrapper` but got {optim_wrapper}.') + cfg.optim_wrapper.type = 'AmpOptimWrapper' + cfg.optim_wrapper.loss_scale = 'dynamic' + else: + for key, val in cfg.optim_wrapper.items(): + if isinstance(val, dict) and 'type' in val: + assert val.type == 'OptimWrapper', ( + '`--amp` is only supported when the optimizer wrapper ' + f'`type is OptimWrapper` but got {val.type}.') + cfg.optim_wrapper[key].type = 'AmpOptimWrapper' + cfg.optim_wrapper[key].loss_scale = 'dynamic' + + if args.resume: + cfg.resume = True + + # build the runner from config + runner = Runner.from_cfg(cfg) + + print_colored_log(f'Working directory: {cfg.work_dir}') + print_colored_log(f'Log directiry: {runner._log_dir}') + + # start training + runner.train() + + print_colored_log(f'Log saved under {runner._log_dir}') + print_colored_log(f'Checkpoint saved under {cfg.work_dir}') + + +if __name__ == '__main__': + main()