[
  {
    "path": ".gitignore",
    "content": "**/.ipynb_checkpoints/*\r\n**/.vscode/*\r\n**/__pycache__/*\r\n**/srun_outputs/*\r\n**/checkpoints/*\r\n**/lightning_logs/\r\n**/results/*"
  },
  {
    "path": "LICENSE",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# SSL4EO-S12\nThe [SSL4EO-S12 dataset](https://arxiv.org/abs/2211.07044) is a large-scale multimodal multitemporal dataset for unsupervised/self-supervised pre-training in Earth observation. The dataset consists of unlabeled patch triplets (Sentinel-1 dual-pol SAR, Sentinel-2 top-of-atmosphere multispectral, Sentinel-2 surface reflectance multispectral) from 251079 locations across the globe, each patch covering 2640mx2640m and including four seasonal time stamps.\n\n![ssl4eo-s12](assets/hello.png)\n\n### Access the dataset\n- [x] **Raw dataset**: The full SSL4EO-S12 dataset (1.5TB, 500GB for each modality) is accessible at [mediaTUM](https://mediatum.ub.tum.de/1660427). There are some void IDs (gaps in folder names), see `data/void_ids.csv`. Center coordinates of all locations are available [here](https://drive.google.com/file/d/1RyJnGznSbMparS88BhHkXxETf0K-qYqI/view?usp=sharing).\n- [x] **Example subset**: An example 100-patch subset (600MB) is available at [Google Drive](https://drive.google.com/file/d/1sRWcYbaWs-efXza6kw03GlJQdZHq5iRN/view?usp=sharing).\n- [x] **Compressed dataset**: A compressed 8-bit version (20-50GB for each modality, including an RGB version) is available at [mediaTUM](https://mediatum.ub.tum.de/1702379). The raw 16/32-bit values are normalized by mean and std and converted to uint8, plus a default geotiff JPEG compression with quality 75. *Note: in our experiments, 8-bit input (without JPEG compression) performs comparably well as 16-bit.*\n- [ ] A 50k (random) RGB subset (18GB) is available here (link broken). Sample IDs see `data/50k_ids_random.csv`.\n\n**Updates**\n- For faster access in some regions, we have hosted a copy of the data in [HuggingFace](https://huggingface.co/datasets/wangyi111/SSL4EO-S12). Note that only the original data in mediaTUM has a proper DOI.\n- We've got some feedback that the compressed dataset (with JPEG compression) has a performance drop compared to the raw data, which could be because of the lossy compression. We plan to update it with a lossless version (yet the file size will increase). Also, do you have INode (number of single files) limit on your server? We could consider updating one resampled GeoTiff for all bands (as in [SSL4EO-L](https://arxiv.org/abs/2306.09424)). If you have any issues or wish for updates, let us know!\n\n### Collect your own data\nCheck [`src/download_data`](src/download_data) for instructions to download sentinel or other products from Google Earth Engine.\n\n\n### Pre-trained models\nThe pre-trained models with different SSL methods are provided as follows (13 bands of S2-L1C, 100 epochs, input clip to [0,1] by dividing 10000).\n\n\n| SSL method |   Arch   | BigEarthNet* | EuroSAT | So2Sat-LCZ42 |                                                   Download                                                  |          |      | Usage |\n|:----------:|:--------:|:-----------:|:-------:|:------------:|:-----------------------------------------------------------------------------------------------------------:|:--------:|:----:|:----:|\n|    [MoCo](https://github.com/facebookresearch/moco)    | ResNet50 |    [91.8%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_rn50_s2c_BE.sh)    |  [99.1%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_rn50_s2c_EU.sh)  |     [60.9%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_vits16_s2c_SS.sh)    |    [full ckpt](https://drive.google.com/file/d/1OrtPfG2wkO05bimstQ_T9Dza8z3zp8i-/view?usp=sharing)    | [backbone](https://drive.google.com/file/d/1MAe3dCW4hPasSaBMZAVkJVX80LONkrLY/view?usp=sharing) | [logs](https://drive.google.com/file/d/1G66pdvJmeD6Rc-OZdOKA1h2Vnvq_0nnt/view?usp=sharing) | [define model](https://github.com/zhu-xlab/SSL4EO-S12/blob/d2868adfada65e40910bfcedfc49bc3b20df2248/src/benchmark/transfer_classification/linear_BE_moco.py#L228-L236), [load weights](https://github.com/zhu-xlab/SSL4EO-S12/blob/d2868adfada65e40910bfcedfc49bc3b20df2248/src/benchmark/transfer_classification/linear_BE_moco.py#L248-L276) |\n|    [MoCo](https://github.com/facebookresearch/moco-v3)        | ViT-S/16 |    [89.9%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_vits16_s2c_BE.sh)    |  [98.6%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_vits16_s2c_EU.sh)  |     [61.6%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_vits16_s2c_SS.sh)    |   [full ckpt](https://drive.google.com/file/d/1Tx07L6OilkfcgE2HWiSXHRmRepCPdn6V/view?usp=sharing)   | [backbone](https://drive.google.com/file/d/1LREGuI6w7Gq6Xm0jFQdxxtp8QkmLvJWk/view?usp=sharing) | [logs](https://drive.google.com/file/d/1f05B85T4Y2-RntfAw42uICKm9mwilHXF/view?usp=sharing) | [define model](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/linear_BE_moco_v3.py#L182-L184), [load weights](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/linear_BE_moco_v3.py#L199-L220) |\n|    [DINO](https://github.com/facebookresearch/dino)    | ResNet50 |    [90.7%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_rn50_s2c_BE.sh)    |  [99.1%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_rn50_s2c_EU.sh)  |     [63.6%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_rn50_s2c_SS.sh)    |    [full ckpt](https://drive.google.com/file/d/1iSHHp_cudPjZlshqWXVZj5TK74P32a2q/view?usp=sharing)    | [backbone](https://drive.google.com/file/d/1B4o_NvY7O6fJrvsOUR-7QzLYNpRL1ieA/view?usp=sharing) | [logs](https://drive.google.com/file/d/1VxjT-3n1ckbvnlsF81jZwmm9Wvb3YX0H/view?usp=sharing) | [define model](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/linear_BE_dino.py#L57-L61), [load weights](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/models/dino/utils.py#L92-L103) |\n|   [DINO](https://github.com/facebookresearch/dino)         | ViT-S/16 |    [90.5%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_vits16_s2_BE.sh)    |  [99.0%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_vits16_s2c_EU.sh)  |     [62.2%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_vits16_s2c_SS.sh)    |   [full ckpt](https://drive.google.com/file/d/1CseO5vvMReGlAulm5o4ZgbjUgj8VlAH7/view?usp=sharing)   | [backbone](https://drive.google.com/file/d/1kjQWfPRI5z43EmRkw5fzgHU01hB7E_4H/view?usp=sharing) | [logs](https://drive.google.com/file/d/1eeKrKFMa6akGyXugBRF6-rJ7oTIeZAno/view?usp=sharing) | [define model](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/linear_BE_dino.py#L53-L55), [load weights](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/models/dino/utils.py#L92-L103) |\n|     [MAE](https://github.com/facebookresearch/mae)    | ViT-S/16 |    [88.9%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_mae_vits16_s2c_BE.sh)    |  [98.7%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_mae_vits16_s2c_EU.sh)  |     [63.9%](src/benchmark/transfer_classification/scripts/benchmark/srun_ft_mae_vits16_s2c_SS.sh)    |    [full ckpt](https://drive.google.com/file/d/1QTBKl1asxgQCNd6bO2azXZNPfoQ3Sazv/view?usp=sharing)   | [backbone](https://drive.google.com/file/d/1hdie-7orFnj5Q1E1C2BudqwQCvMk3Fza/view?usp=sharing) | [logs](https://drive.google.com/file/d/1uJojq9q_fKMdD6cO1YXCPguZYEmfj35s/view?usp=sharing) | [define model](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/linear_BE_mae.py#L232-L236), [load weights](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/linear_BE_mae.py#L238-L259) |\n|  [Data2vec](https://github.com/facebookresearch/fairseq/tree/main/examples/data2vec)  | ViT-S/16 |    [90.3%](src/benchmark/transfer_classification/scripts/benchmark/ft_data2vec_vit16_s2c_BE_100.sh)    |  [99.1%](src/benchmark/transfer_classification/scripts/benchmark/ft_data2vec_vits16_s2c_EU_100.sh)  |     [64.8%](src/benchmark/transfer_classification/scripts/benchmark/lc_data2vec_vits16_s2c_SS_100.sh)    | [full ckpt](https://drive.google.com/file/d/1VbIGBwzZYndv4v1vx9FiD6IP-YwsHEns/view?usp=sharing) | [backbone](https://drive.google.com/file/d/1YecuYPAxl1NIzLmsmdbUROjCb5g0t80l/view?usp=sharing) | logs | [define model](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/linear_BE_data2vec.py#L372-L390), [load weights](https://github.com/zhu-xlab/SSL4EO-S12/blob/1a668f76fd46762a19780293675a6e23e5204e72/src/benchmark/transfer_classification/linear_BE_data2vec.py#L406-L553) |\n\n\\* Note the results for BigEarthNet are based on the train/val split following [SeCo](https://github.com/ServiceNow/seasonal-contrast/blob/8285173ec205b64bc3e53b880344dd6c3f79fa7a/datasets/bigearthnet_dataset.py#L119) and [In-domain representation learning for RS](https://github.com/google-research/google-research/tree/master/remote_sensing_representations).\n\nOther pre-trained models:\n\n| SSL method |   Arch   | Input |                                                           Download                                                           |          |      |\n|:----------:|:--------:|:----------------:|:----------------------------------------------------------------------------------------------------------------------------:|:--------:|:----:|\n|    MoCo    | ResNet18 | S2-L1C 13 bands      |             [full ckpt](https://drive.google.com/file/d/1iWLm7ljQ6tKZiVp47pJUPDe3Un0BUd9o/view?usp=sharing)            | backbone | logs |\n|            | ResNet18 | S2-L1C RGB            | [full ckpt](https://drive.google.com/file/d/1HfgXS5VpQA39k8mFrWMbHvYwuT_j6Mbi/view?usp=sharing), [full ckpt ep200](https://drive.google.com/file/d/1U_m39Owahk15Vg1uL1MYbPAmAyUWBKfI/view?usp=sharing) | backbone | logs |\n|            | ResNet50 | S2-L1C RGB            |             [full ckpt](https://drive.google.com/file/d/1UEpA9sOcA47W0cmwQhkSeXfQxrL-EcJB/view?usp=sharing)            | backbone | logs |\n|            | ResNet50 | S1 SAR 2 bands            |             [full ckpt](https://drive.google.com/file/d/1gjTTWikf1qORJyFifWD1ksk9HzezqQ0b/view?usp=sharing)            | [backbone](https://drive.google.com/file/d/1E5MvVI1SnQneQXe37QAWx_B6aoTiSN24/view?usp=sharing) | logs |\n| MAE |        ViT-S/16 | S1 SAR 2 bands | [full ckpt](https://huggingface.co/wangyi111/SSL4EO-S12/resolve/main/B2_vits16_mae_ep99.pth) | backbone  |\n|     |        ViT-B/16 | S1 SAR 2 bands | [full ckpt](https://huggingface.co/wangyi111/SSL4EO-S12/resolve/main/B2_vitb16_mae_ep99.pth) | backbone  |\n|     |        ViT-L/16 | S1 SAR 2 bands | [full ckpt](https://huggingface.co/wangyi111/SSL4EO-S12/resolve/main/B2_vitl16_mae_ep99.pth) | backbone  |\n|     |        ViT-H/14 | S1 SAR 2 bands | [full ckpt](https://huggingface.co/wangyi111/SSL4EO-S12/resolve/main/B2_vith14_mae_ep199.pth) | backbone  |\n|     |        ViT-B/16 | S2-L1C 13 bands | [full ckpt](https://huggingface.co/wangyi111/SSL4EO-S12/resolve/main/B13_vitb16_mae_ep99.pth) | backbone |\n|     |        ViT-L/16 | S2-L1C 13 bands | [full ckpt](https://huggingface.co/wangyi111/SSL4EO-S12/resolve/main/B13_vitl16_mae_ep99.pth) | backbone |\n|     |        ViT-H/14 | S2-L1C 13 bands | [full ckpt](https://huggingface.co/wangyi111/SSL4EO-S12/resolve/main/B13_vith14_mae_ep199.pth) | backbone |\n\n**\\* The pretrained models are also available in [TorchGeo](https://github.com/microsoft/torchgeo).**\n\n### License\nThis repository is released under the Apache 2.0 license. The dataset and pretrained model weights are released under the CC-BY-4.0 license.\n\n\n### Citation\n```BibTeX\n@article{wang2022ssl4eo,\n  title={SSL4EO-S12: A Large-Scale Multi-Modal, Multi-Temporal Dataset for Self-Supervised Learning in Earth Observation},\n  author={Wang, Yi and Braham, Nassim Ait Ali and Xiong, Zhitong and Liu, Chenying and Albrecht, Conrad M and Zhu, Xiao Xiang},\n  journal={arXiv preprint arXiv:2211.07044},\n  year={2022}\n}\n```\n"
  },
  {
    "path": "data/50k_ids_random.csv",
    "content": "2\n9\n13\n15\n22\n24\n34\n44\n48\n51\n55\n64\n70\n75\n84\n89\n92\n106\n111\n121\n123\n129\n132\n138\n140\n142\n147\n148\n149\n150\n156\n165\n168\n170\n171\n173\n177\n179\n188\n189\n201\n203\n208\n215\n221\n222\n227\n239\n251\n256\n262\n263\n268\n284\n285\n287\n295\n301\n307\n312\n314\n316\n317\n319\n320\n324\n330\n335\n337\n343\n357\n366\n373\n376\n380\n381\n382\n383\n386\n390\n392\n395\n402\n410\n413\n414\n415\n417\n422\n424\n440\n443\n453\n465\n471\n493\n500\n510\n512\n518\n522\n528\n536\n540\n546\n547\n553\n558\n565\n571\n572\n575\n576\n583\n585\n589\n590\n602\n604\n607\n634\n640\n641\n644\n648\n650\n652\n660\n662\n672\n673\n677\n685\n694\n698\n699\n700\n701\n704\n705\n716\n717\n724\n727\n728\n731\n732\n738\n739\n743\n747\n751\n756\n765\n770\n783\n787\n790\n793\n800\n801\n805\n806\n808\n814\n820\n823\n830\n838\n842\n845\n850\n854\n856\n867\n871\n872\n874\n880\n883\n892\n896\n899\n903\n904\n907\n910\n919\n926\n929\n931\n941\n942\n943\n944\n946\n950\n956\n963\n968\n969\n970\n971\n972\n975\n981\n983\n990\n994\n1000\n1006\n1008\n1017\n1029\n1051\n1059\n1066\n1067\n1070\n1077\n1081\n1089\n1095\n1098\n1117\n1119\n1120\n1121\n1123\n1125\n1127\n1129\n1130\n1134\n1137\n1138\n1143\n1145\n1156\n1158\n1166\n1176\n1182\n1187\n1198\n1199\n1206\n1218\n1219\n1221\n1223\n1228\n1235\n1242\n1249\n1254\n1257\n1261\n1265\n1266\n1275\n1276\n1285\n1287\n1289\n1294\n1295\n1296\n1298\n1299\n1303\n1304\n1312\n1314\n1318\n1324\n1325\n1331\n1334\n1335\n1346\n1349\n1351\n1352\n1358\n1361\n1364\n1366\n1372\n1376\n1385\n1386\n1395\n1397\n1405\n1411\n1433\n1453\n1460\n1462\n1468\n1471\n1472\n1479\n1487\n1492\n1499\n1507\n1517\n1521\n1523\n1532\n1537\n1538\n1540\n1544\n1545\n1546\n1547\n1556\n1560\n1567\n1579\n1584\n1591\n1592\n1600\n1604\n1607\n1637\n1639\n1640\n1644\n1648\n1649\n1654\n1655\n1664\n1665\n1666\n1668\n1671\n1673\n1678\n1682\n1683\n1691\n1693\n1702\n1703\n1707\n1708\n1719\n1721\n1723\n1725\n1726\n1729\n1733\n1734\n1735\n1736\n1737\n1747\n1759\n1763\n1774\n1776\n1790\n1794\n1795\n1804\n1805\n1811\n1812\n1823\n1826\n1828\n1830\n1833\n1837\n1843\n1846\n1857\n1858\n1864\n1870\n1874\n1885\n1892\n1893\n1894\n1898\n1901\n1902\n1903\n1911\n1914\n1919\n1921\n1926\n1942\n1946\n1947\n1949\n1950\n1951\n1986\n1989\n1992\n1993\n1998\n2006\n2012\n2015\n2020\n2026\n2034\n2040\n2050\n2051\n2061\n2062\n2064\n2070\n2071\n2074\n2076\n2080\n2082\n2085\n2089\n2090\n2095\n2100\n2104\n2110\n2113\n2114\n2117\n2118\n2122\n2125\n2127\n2128\n2139\n2143\n2147\n2150\n2164\n2168\n2179\n2180\n2184\n2186\n2192\n2193\n2197\n2206\n2207\n2209\n2210\n2211\n2218\n2220\n2221\n2222\n2225\n2230\n2237\n2238\n2242\n2259\n2260\n2268\n2270\n2272\n2274\n2287\n2291\n2292\n2307\n2315\n2316\n2321\n2322\n2323\n2325\n2332\n2333\n2334\n2336\n2340\n2347\n2367\n2369\n2383\n2390\n2391\n2394\n2396\n2398\n2400\n2408\n2418\n2424\n2426\n2427\n2429\n2431\n2434\n2439\n2441\n2442\n2454\n2461\n2463\n2467\n2470\n2477\n2486\n2489\n2492\n2510\n2512\n2515\n2517\n2518\n2525\n2527\n2528\n2534\n2535\n2537\n2544\n2548\n2550\n2551\n2553\n2570\n2574\n2580\n2583\n2585\n2589\n2593\n2598\n2603\n2607\n2611\n2615\n2634\n2658\n2661\n2663\n2675\n2678\n2681\n2690\n2692\n2696\n2698\n2705\n2706\n2713\n2725\n2728\n2730\n2732\n2734\n2735\n2736\n2743\n2748\n2765\n2767\n2770\n2772\n2776\n2778\n2780\n2789\n2797\n2799\n2803\n2806\n2807\n2814\n2823\n2824\n2825\n2826\n2848\n2857\n2861\n2870\n2871\n2877\n2884\n2888\n2895\n2897\n2898\n2904\n2907\n2915\n2922\n2934\n2937\n2938\n2939\n2961\n2964\n2974\n2975\n2977\n2987\n2990\n2993\n2997\n3000\n3009\n3021\n3022\n3023\n3024\n3037\n3041\n3044\n3052\n3066\n3070\n3078\n3080\n3090\n3097\n3098\n3106\n3109\n3116\n3117\n3128\n3133\n3134\n3135\n3138\n3140\n3145\n3151\n3153\n3155\n3163\n3164\n3168\n3175\n3176\n3189\n3195\n3198\n3199\n3200\n3204\n3207\n3215\n3221\n3230\n3234\n3235\n3239\n3240\n3241\n3255\n3256\n3258\n3263\n3265\n3270\n3294\n3297\n3303\n3307\n3310\n3316\n3320\n3332\n3335\n3337\n3338\n3341\n3342\n3347\n3351\n3353\n3364\n3368\n3372\n3381\n3388\n3398\n3399\n3406\n3418\n3419\n3420\n3430\n3439\n3441\n3444\n3452\n3455\n3457\n3458\n3461\n3462\n3478\n3482\n3484\n3487\n3511\n3515\n3524\n3525\n3533\n3538\n3551\n3552\n3554\n3567\n3570\n3571\n3575\n3577\n3579\n3581\n3582\n3584\n3600\n3602\n3607\n3609\n3615\n3637\n3643\n3647\n3648\n3650\n3655\n3656\n3660\n3665\n3667\n3673\n3690\n3692\n3694\n3700\n3703\n3708\n3711\n3712\n3714\n3718\n3723\n3724\n3725\n3730\n3740\n3754\n3758\n3760\n3763\n3765\n3767\n3771\n3778\n3779\n3802\n3812\n3816\n3819\n3843\n3851\n3855\n3860\n3861\n3864\n3868\n3872\n3875\n3883\n3887\n3888\n3895\n3902\n3905\n3906\n3908\n3912\n3914\n3916\n3918\n3919\n3930\n3935\n3943\n3949\n3980\n3993\n3999\n4019\n4023\n4028\n4036\n4043\n4053\n4054\n4055\n4066\n4071\n4077\n4081\n4083\n4087\n4097\n4099\n4101\n4104\n4109\n4117\n4123\n4134\n4136\n4141\n4144\n4147\n4154\n4161\n4164\n4167\n4175\n4177\n4180\n4182\n4195\n4202\n4203\n4204\n4205\n4209\n4214\n4225\n4232\n4237\n4244\n4247\n4251\n4252\n4257\n4261\n4264\n4265\n4267\n4268\n4270\n4273\n4284\n4293\n4295\n4296\n4299\n4303\n4306\n4307\n4308\n4310\n4341\n4348\n4359\n4361\n4367\n4371\n4373\n4374\n4375\n4382\n4384\n4389\n4396\n4397\n4408\n4415\n4419\n4426\n4427\n4428\n4430\n4432\n4435\n4444\n4446\n4453\n4454\n4461\n4476\n4479\n4484\n4486\n4488\n4493\n4494\n4496\n4502\n4504\n4506\n4507\n4512\n4520\n4526\n4527\n4531\n4544\n4547\n4553\n4555\n4558\n4560\n4569\n4571\n4574\n4577\n4578\n4579\n4587\n4592\n4597\n4599\n4603\n4626\n4627\n4629\n4632\n4642\n4651\n4655\n4658\n4675\n4692\n4694\n4696\n4710\n4715\n4720\n4723\n4732\n4734\n4735\n4737\n4739\n4742\n4743\n4752\n4760\n4763\n4764\n4778\n4779\n4782\n4793\n4794\n4802\n4816\n4820\n4830\n4842\n4850\n4855\n4867\n4876\n4881\n4883\n4888\n4892\n4897\n4906\n4907\n4912\n4913\n4918\n4919\n4929\n4938\n4941\n4944\n4945\n4947\n4964\n4966\n4973\n4975\n4981\n4985\n4997\n5001\n5005\n5006\n5013\n5036\n5038\n5039\n5043\n5047\n5053\n5058\n5066\n5081\n5084\n5099\n5101\n5105\n5106\n5107\n5113\n5119\n5120\n5123\n5127\n5130\n5140\n5145\n5150\n5159\n5162\n5167\n5169\n5175\n5176\n5183\n5185\n5186\n5188\n5193\n5199\n5205\n5209\n5211\n5217\n5218\n5221\n5222\n5224\n5230\n5236\n5243\n5250\n5256\n5263\n5271\n5283\n5289\n5303\n5309\n5321\n5330\n5342\n5347\n5348\n5353\n5356\n5372\n5376\n5377\n5383\n5405\n5417\n5423\n5428\n5430\n5431\n5433\n5435\n5438\n5445\n5450\n5454\n5455\n5458\n5459\n5467\n5488\n5502\n5503\n5514\n5515\n5517\n5524\n5535\n5544\n5551\n5558\n5559\n5560\n5570\n5571\n5575\n5576\n5580\n5588\n5589\n5597\n5598\n5599\n5621\n5626\n5627\n5631\n5633\n5634\n5653\n5655\n5660\n5664\n5672\n5675\n5677\n5682\n5683\n5686\n5688\n5690\n5697\n5701\n5706\n5709\n5710\n5714\n5719\n5727\n5728\n5734\n5735\n5742\n5744\n5749\n5751\n5755\n5758\n5776\n5780\n5781\n5797\n5800\n5801\n5802\n5826\n5829\n5832\n5833\n5839\n5858\n5865\n5866\n5867\n5870\n5875\n5884\n5891\n5893\n5894\n5896\n5899\n5905\n5909\n5910\n5912\n5913\n5917\n5920\n5925\n5933\n5936\n5941\n5948\n5953\n5955\n5959\n5963\n5985\n5987\n5991\n6005\n6007\n6009\n6013\n6014\n6015\n6017\n6018\n6019\n6021\n6031\n6036\n6037\n6039\n6043\n6044\n6047\n6055\n6060\n6061\n6064\n6065\n6066\n6071\n6075\n6079\n6081\n6092\n6098\n6106\n6109\n6124\n6127\n6132\n6135\n6136\n6139\n6142\n6145\n6161\n6163\n6165\n6168\n6182\n6193\n6195\n6203\n6207\n6208\n6211\n6212\n6218\n6220\n6226\n6227\n6232\n6233\n6237\n6242\n6247\n6248\n6253\n6258\n6267\n6272\n6273\n6282\n6285\n6287\n6291\n6297\n6298\n6299\n6302\n6306\n6309\n6314\n6319\n6320\n6326\n6328\n6329\n6345\n6350\n6351\n6355\n6363\n6365\n6372\n6399\n6402\n6417\n6421\n6422\n6424\n6428\n6438\n6442\n6445\n6458\n6463\n6465\n6470\n6473\n6476\n6479\n6482\n6483\n6485\n6494\n6497\n6498\n6500\n6502\n6522\n6524\n6525\n6530\n6531\n6533\n6536\n6537\n6540\n6556\n6559\n6560\n6575\n6593\n6603\n6621\n6624\n6625\n6627\n6629\n6631\n6634\n6636\n6646\n6649\n6651\n6657\n6658\n6659\n6662\n6663\n6664\n6672\n6675\n6680\n6693\n6695\n6704\n6716\n6721\n6722\n6726\n6729\n6731\n6735\n6742\n6746\n6757\n6758\n6761\n6771\n6774\n6780\n6786\n6792\n6793\n6794\n6800\n6805\n6808\n6813\n6814\n6815\n6832\n6837\n6841\n6850\n6854\n6867\n6872\n6874\n6880\n6881\n6882\n6884\n6890\n6896\n6898\n6901\n6906\n6908\n6909\n6911\n6914\n6924\n6926\n6927\n6931\n6933\n6938\n6947\n6950\n6956\n6960\n6964\n6984\n6985\n6986\n6991\n7003\n7012\n7015\n7021\n7022\n7027\n7029\n7031\n7032\n7035\n7037\n7050\n7051\n7052\n7054\n7055\n7069\n7071\n7088\n7090\n7095\n7104\n7120\n7122\n7123\n7133\n7134\n7148\n7155\n7156\n7158\n7160\n7162\n7163\n7168\n7169\n7179\n7186\n7190\n7195\n7200\n7206\n7208\n7216\n7217\n7219\n7223\n7229\n7231\n7235\n7240\n7249\n7252\n7254\n7262\n7263\n7274\n7281\n7291\n7292\n7302\n7306\n7311\n7314\n7325\n7328\n7330\n7332\n7334\n7337\n7341\n7345\n7352\n7353\n7360\n7362\n7378\n7382\n7385\n7389\n7394\n7398\n7401\n7406\n7407\n7412\n7420\n7423\n7428\n7437\n7438\n7456\n7465\n7470\n7485\n7489\n7491\n7493\n7516\n7518\n7523\n7529\n7535\n7539\n7542\n7544\n7545\n7548\n7553\n7554\n7555\n7559\n7567\n7569\n7573\n7576\n7577\n7580\n7585\n7588\n7589\n7592\n7600\n7604\n7608\n7612\n7613\n7616\n7617\n7619\n7632\n7639\n7643\n7647\n7650\n7652\n7657\n7660\n7661\n7662\n7670\n7672\n7675\n7677\n7680\n7681\n7682\n7687\n7688\n7695\n7697\n7706\n7721\n7722\n7724\n7728\n7729\n7732\n7738\n7747\n7750\n7751\n7756\n7765\n7766\n7776\n7781\n7786\n7791\n7796\n7802\n7809\n7811\n7812\n7828\n7837\n7840\n7848\n7853\n7856\n7858\n7859\n7861\n7868\n7870\n7886\n7891\n7899\n7909\n7913\n7914\n7918\n7919\n7931\n7933\n7939\n7951\n7953\n7955\n7960\n7968\n7976\n7989\n7990\n7991\n7996\n8000\n8004\n8011\n8014\n8020\n8027\n8028\n8029\n8030\n8036\n8049\n8055\n8078\n8079\n8089\n8094\n8097\n8101\n8103\n8112\n8120\n8121\n8124\n8134\n8137\n8138\n8147\n8149\n8152\n8160\n8163\n8165\n8167\n8171\n8172\n8174\n8177\n8178\n8186\n8189\n8192\n8198\n8206\n8211\n8218\n8224\n8225\n8231\n8234\n8239\n8240\n8243\n8244\n8251\n8255\n8259\n8262\n8264\n8274\n8276\n8283\n8285\n8291\n8295\n8303\n8305\n8311\n8319\n8321\n8329\n8331\n8335\n8340\n8357\n8360\n8364\n8366\n8375\n8380\n8386\n8397\n8404\n8407\n8410\n8413\n8414\n8417\n8419\n8424\n8443\n8445\n8448\n8449\n8458\n8460\n8468\n8472\n8473\n8479\n8483\n8484\n8486\n8488\n8489\n8501\n8502\n8514\n8516\n8520\n8522\n8527\n8530\n8536\n8539\n8545\n8547\n8555\n8556\n8561\n8564\n8565\n8568\n8570\n8571\n8575\n8576\n8581\n8591\n8596\n8605\n8608\n8613\n8614\n8624\n8625\n8645\n8652\n8655\n8657\n8664\n8669\n8674\n8675\n8678\n8693\n8695\n8700\n8703\n8713\n8718\n8720\n8722\n8727\n8740\n8746\n8749\n8750\n8753\n8758\n8767\n8771\n8778\n8781\n8784\n8789\n8791\n8797\n8801\n8804\n8810\n8813\n8819\n8829\n8848\n8849\n8852\n8853\n8854\n8857\n8866\n8869\n8873\n8881\n8883\n8889\n8901\n8911\n8916\n8923\n8932\n8934\n8942\n8943\n8960\n8969\n8971\n8984\n9002\n9003\n9009\n9012\n9013\n9029\n9045\n9052\n9057\n9068\n9072\n9083\n9086\n9093\n9103\n9105\n9111\n9122\n9125\n9129\n9135\n9138\n9140\n9153\n9165\n9171\n9173\n9176\n9196\n9205\n9207\n9208\n9213\n9215\n9223\n9225\n9226\n9236\n9244\n9247\n9254\n9258\n9260\n9269\n9270\n9287\n9291\n9311\n9321\n9330\n9332\n9336\n9341\n9355\n9357\n9358\n9364\n9370\n9375\n9384\n9393\n9395\n9401\n9402\n9410\n9414\n9432\n9438\n9444\n9451\n9453\n9456\n9461\n9463\n9467\n9470\n9478\n9483\n9491\n9514\n9525\n9526\n9533\n9536\n9545\n9546\n9549\n9562\n9563\n9564\n9568\n9569\n9570\n9571\n9581\n9582\n9595\n9597\n9598\n9599\n9602\n9606\n9607\n9609\n9612\n9615\n9619\n9620\n9626\n9628\n9629\n9633\n9637\n9645\n9646\n9651\n9667\n9681\n9691\n9692\n9695\n9700\n9701\n9703\n9704\n9705\n9709\n9710\n9713\n9720\n9723\n9732\n9736\n9741\n9752\n9754\n9770\n9771\n9773\n9775\n9777\n9782\n9783\n9791\n9792\n9793\n9794\n9796\n9798\n9802\n9806\n9808\n9813\n9817\n9820\n9821\n9823\n9832\n9840\n9841\n9854\n9858\n9862\n9865\n9866\n9871\n9880\n9882\n9887\n9889\n9892\n9894\n9895\n9897\n9902\n9905\n9918\n9926\n9931\n9934\n9937\n9944\n9946\n9951\n9969\n9974\n9996\n10008\n10011\n10012\n10028\n10030\n10035\n10036\n10040\n10044\n10055\n10057\n10074\n10076\n10079\n10086\n10093\n10095\n10106\n10112\n10116\n10120\n10123\n10132\n10137\n10139\n10147\n10151\n10152\n10164\n10166\n10167\n10174\n10178\n10201\n10202\n10205\n10207\n10208\n10211\n10217\n10221\n10227\n10233\n10239\n10242\n10245\n10247\n10255\n10260\n10261\n10273\n10278\n10289\n10299\n10305\n10306\n10310\n10312\n10315\n10322\n10323\n10327\n10329\n10330\n10334\n10335\n10337\n10340\n10342\n10351\n10358\n10359\n10367\n10369\n10378\n10382\n10385\n10418\n10420\n10421\n10422\n10431\n10437\n10440\n10442\n10444\n10449\n10450\n10453\n10455\n10458\n10460\n10461\n10464\n10469\n10470\n10472\n10488\n10489\n10496\n10501\n10506\n10512\n10519\n10539\n10546\n10552\n10553\n10559\n10568\n10569\n10572\n10575\n10580\n10584\n10586\n10595\n10598\n10600\n10603\n10605\n10623\n10628\n10633\n10637\n10645\n10651\n10652\n10653\n10656\n10667\n10668\n10678\n10679\n10688\n10689\n10693\n10713\n10714\n10715\n10716\n10718\n10722\n10730\n10735\n10740\n10742\n10750\n10752\n10753\n10754\n10756\n10758\n10761\n10766\n10770\n10774\n10780\n10784\n10785\n10786\n10787\n10794\n10795\n10798\n10811\n10815\n10833\n10860\n10865\n10869\n10879\n10886\n10888\n10892\n10902\n10907\n10913\n10920\n10927\n10932\n10940\n10941\n10942\n10946\n10950\n10955\n10956\n10957\n10964\n10965\n10970\n10971\n10973\n10976\n10977\n10981\n10982\n10984\n10985\n10992\n10998\n11000\n11002\n11004\n11008\n11016\n11017\n11018\n11020\n11021\n11026\n11027\n11036\n11042\n11051\n11056\n11058\n11060\n11070\n11071\n11072\n11078\n11079\n11081\n11084\n11087\n11089\n11093\n11103\n11113\n11119\n11128\n11130\n11142\n11145\n11147\n11149\n11154\n11155\n11156\n11159\n11160\n11162\n11164\n11173\n11175\n11187\n11192\n11193\n11195\n11197\n11204\n11205\n11208\n11221\n11223\n11228\n11233\n11239\n11248\n11262\n11271\n11272\n11274\n11292\n11302\n11307\n11310\n11321\n11328\n11329\n11332\n11341\n11345\n11354\n11355\n11363\n11364\n11367\n11387\n11388\n11389\n11390\n11394\n11397\n11398\n11412\n11426\n11431\n11432\n11434\n11441\n11446\n11450\n11453\n11460\n11466\n11470\n11475\n11479\n11482\n11483\n11484\n11488\n11493\n11494\n11495\n11496\n11501\n11502\n11508\n11509\n11512\n11518\n11537\n11538\n11539\n11542\n11543\n11544\n11552\n11557\n11566\n11568\n11572\n11576\n11579\n11593\n11596\n11599\n11608\n11611\n11612\n11615\n11622\n11635\n11643\n11653\n11654\n11656\n11662\n11667\n11668\n11672\n11690\n11693\n11694\n11696\n11700\n11705\n11713\n11716\n11721\n11722\n11723\n11725\n11726\n11727\n11732\n11739\n11744\n11749\n11758\n11763\n11764\n11771\n11777\n11791\n11792\n11793\n11797\n11805\n11818\n11821\n11827\n11831\n11837\n11840\n11842\n11847\n11850\n11854\n11857\n11858\n11860\n11864\n11866\n11872\n11876\n11877\n11884\n11887\n11893\n11902\n11903\n11905\n11910\n11913\n11917\n11920\n11921\n11923\n11925\n11930\n11931\n11943\n11949\n11950\n11951\n11955\n11957\n11961\n11974\n11978\n11981\n11984\n11991\n11992\n11994\n12000\n12004\n12006\n12007\n12011\n12012\n12029\n12038\n12039\n12043\n12051\n12053\n12056\n12058\n12059\n12078\n12082\n12090\n12095\n12102\n12103\n12109\n12110\n12113\n12114\n12116\n12145\n12152\n12158\n12162\n12166\n12168\n12170\n12173\n12178\n12189\n12192\n12199\n12205\n12206\n12222\n12226\n12233\n12235\n12239\n12248\n12251\n12262\n12266\n12274\n12281\n12288\n12290\n12291\n12292\n12302\n12309\n12311\n12315\n12317\n12319\n12329\n12332\n12333\n12339\n12340\n12343\n12351\n12354\n12359\n12363\n12370\n12372\n12375\n12381\n12384\n12397\n12404\n12415\n12416\n12430\n12434\n12439\n12448\n12449\n12458\n12460\n12466\n12467\n12479\n12492\n12502\n12506\n12511\n12512\n12514\n12515\n12517\n12518\n12519\n12520\n12521\n12525\n12526\n12530\n12531\n12534\n12539\n12552\n12559\n12560\n12563\n12571\n12572\n12573\n12577\n12581\n12583\n12587\n12591\n12595\n12596\n12598\n12600\n12603\n12607\n12620\n12621\n12634\n12641\n12644\n12658\n12669\n12673\n12690\n12692\n12705\n12706\n12716\n12717\n12725\n12728\n12729\n12732\n12736\n12742\n12750\n12753\n12755\n12757\n12760\n12761\n12770\n12779\n12785\n12789\n12796\n12797\n12800\n12802\n12806\n12807\n12822\n12823\n12827\n12832\n12833\n12838\n12844\n12847\n12853\n12856\n12865\n12867\n12872\n12880\n12884\n12886\n12891\n12893\n12901\n12902\n12921\n12922\n12923\n12926\n12927\n12930\n12941\n12943\n12969\n12971\n12975\n12980\n12986\n12988\n12997\n13010\n13011\n13015\n13018\n13020\n13028\n13032\n13044\n13049\n13050\n13052\n13057\n13060\n13065\n13073\n13075\n13081\n13083\n13085\n13091\n13096\n13106\n13107\n13113\n13114\n13119\n13121\n13124\n13125\n13126\n13128\n13138\n13139\n13144\n13164\n13175\n13181\n13185\n13197\n13199\n13200\n13217\n13226\n13231\n13237\n13243\n13248\n13253\n13255\n13257\n13258\n13261\n13265\n13274\n13280\n13289\n13292\n13297\n13301\n13305\n13307\n13310\n13316\n13317\n13331\n13339\n13344\n13347\n13348\n13350\n13357\n13358\n13364\n13367\n13368\n13383\n13391\n13398\n13400\n13405\n13408\n13410\n13420\n13428\n13429\n13430\n13432\n13444\n13450\n13459\n13460\n13462\n13463\n13468\n13473\n13475\n13482\n13486\n13491\n13494\n13497\n13505\n13510\n13513\n13516\n13521\n13526\n13528\n13529\n13531\n13541\n13565\n13570\n13571\n13575\n13580\n13586\n13587\n13595\n13597\n13599\n13601\n13615\n13631\n13634\n13637\n13641\n13645\n13650\n13653\n13654\n13657\n13659\n13661\n13662\n13665\n13668\n13669\n13678\n13681\n13684\n13690\n13699\n13710\n13714\n13717\n13718\n13725\n13727\n13736\n13740\n13742\n13745\n13751\n13753\n13755\n13758\n13760\n13761\n13768\n13774\n13779\n13791\n13792\n13799\n13804\n13807\n13820\n13828\n13834\n13839\n13849\n13851\n13854\n13856\n13858\n13859\n13860\n13861\n13864\n13867\n13886\n13897\n13898\n13903\n13907\n13910\n13911\n13912\n13914\n13915\n13918\n13924\n13927\n13929\n13934\n13944\n13946\n13951\n13956\n13960\n13961\n13981\n13983\n13997\n13998\n14003\n14004\n14005\n14008\n14017\n14021\n14025\n14034\n14038\n14039\n14044\n14049\n14053\n14058\n14062\n14063\n14068\n14071\n14076\n14079\n14088\n14095\n14098\n14101\n14103\n14107\n14110\n14112\n14125\n14147\n14148\n14149\n14151\n14155\n14163\n14172\n14175\n14176\n14177\n14188\n14189\n14192\n14194\n14200\n14205\n14206\n14209\n14216\n14217\n14226\n14227\n14231\n14235\n14240\n14241\n14244\n14246\n14252\n14257\n14260\n14264\n14269\n14276\n14287\n14288\n14289\n14293\n14296\n14299\n14304\n14314\n14315\n14321\n14326\n14331\n14332\n14337\n14348\n14349\n14355\n14358\n14360\n14362\n14364\n14368\n14369\n14383\n14389\n14395\n14396\n14397\n14403\n14408\n14425\n14426\n14434\n14437\n14448\n14457\n14463\n14468\n14493\n14498\n14503\n14511\n14517\n14518\n14519\n14523\n14526\n14528\n14532\n14533\n14545\n14547\n14558\n14563\n14575\n14578\n14582\n14584\n14589\n14597\n14600\n14611\n14624\n14625\n14628\n14630\n14632\n14637\n14643\n14644\n14647\n14656\n14659\n14660\n14662\n14663\n14673\n14676\n14679\n14685\n14690\n14692\n14693\n14694\n14701\n14703\n14706\n14710\n14711\n14721\n14723\n14724\n14725\n14734\n14742\n14754\n14757\n14766\n14773\n14792\n14795\n14796\n14797\n14805\n14814\n14836\n14838\n14841\n14849\n14851\n14854\n14859\n14860\n14864\n14867\n14877\n14883\n14886\n14894\n14902\n14906\n14910\n14911\n14913\n14916\n14937\n14945\n14947\n14957\n14973\n14984\n14985\n14990\n14996\n15001\n15005\n15007\n15011\n15025\n15028\n15029\n15036\n15050\n15057\n15061\n15063\n15070\n15072\n15079\n15081\n15082\n15085\n15093\n15094\n15100\n15105\n15106\n15112\n15126\n15135\n15144\n15150\n15152\n15154\n15174\n15179\n15184\n15188\n15189\n15207\n15212\n15224\n15239\n15252\n15253\n15260\n15283\n15286\n15297\n15301\n15312\n15313\n15321\n15323\n15331\n15332\n15335\n15338\n15351\n15354\n15357\n15358\n15359\n15367\n15370\n15373\n15374\n15383\n15388\n15396\n15400\n15401\n15403\n15410\n15411\n15413\n15417\n15433\n15436\n15443\n15444\n15448\n15461\n15462\n15465\n15466\n15472\n15485\n15504\n15507\n15508\n15509\n15521\n15524\n15536\n15541\n15549\n15551\n15559\n15560\n15563\n15565\n15569\n15570\n15581\n15596\n15597\n15603\n15612\n15616\n15617\n15621\n15633\n15634\n15637\n15640\n15642\n15655\n15665\n15669\n15672\n15678\n15695\n15697\n15699\n15701\n15705\n15706\n15708\n15710\n15714\n15720\n15723\n15727\n15728\n15732\n15738\n15739\n15742\n15744\n15752\n15756\n15757\n15765\n15774\n15780\n15789\n15795\n15798\n15803\n15809\n15821\n15834\n15840\n15845\n15846\n15851\n15853\n15857\n15872\n15876\n15880\n15889\n15894\n15896\n15908\n15912\n15913\n15915\n15928\n15932\n15935\n15936\n15938\n15939\n15941\n15945\n15946\n15955\n15959\n15963\n15964\n15970\n15979\n15980\n15985\n15986\n15989\n15997\n16005\n16012\n16014\n16019\n16025\n16029\n16034\n16038\n16041\n16043\n16044\n16051\n16056\n16060\n16062\n16068\n16077\n16082\n16085\n16091\n16096\n16100\n16101\n16104\n16105\n16113\n16116\n16117\n16126\n16129\n16153\n16158\n16166\n16175\n16177\n16178\n16189\n16198\n16210\n16218\n16219\n16222\n16233\n16238\n16253\n16255\n16261\n16270\n16272\n16279\n16281\n16285\n16289\n16292\n16303\n16322\n16326\n16327\n16338\n16339\n16354\n16357\n16360\n16370\n16379\n16398\n16400\n16408\n16411\n16417\n16427\n16453\n16455\n16458\n16461\n16462\n16464\n16474\n16478\n16484\n16485\n16492\n16496\n16497\n16501\n16506\n16513\n16517\n16523\n16541\n16543\n16545\n16547\n16549\n16560\n16562\n16571\n16572\n16573\n16577\n16582\n16585\n16589\n16593\n16597\n16599\n16601\n16603\n16604\n16611\n16617\n16622\n16628\n16629\n16636\n16641\n16645\n16648\n16652\n16653\n16658\n16661\n16667\n16675\n16679\n16683\n16685\n16689\n16690\n16700\n16704\n16714\n16718\n16722\n16726\n16734\n16743\n16744\n16745\n16748\n16757\n16759\n16766\n16767\n16769\n16774\n16777\n16784\n16785\n16788\n16791\n16796\n16798\n16800\n16804\n16820\n16833\n16837\n16838\n16839\n16846\n16847\n16849\n16874\n16879\n16884\n16885\n16889\n16900\n16912\n16938\n16948\n16949\n16952\n16953\n16959\n16963\n16968\n16974\n16976\n16979\n16987\n16990\n16997\n17006\n17008\n17019\n17023\n17024\n17027\n17028\n17040\n17046\n17047\n17052\n17070\n17072\n17073\n17080\n17085\n17107\n17114\n17116\n17119\n17123\n17126\n17129\n17133\n17135\n17138\n17147\n17150\n17159\n17160\n17163\n17170\n17178\n17186\n17187\n17192\n17194\n17201\n17203\n17215\n17217\n17218\n17219\n17223\n17226\n17235\n17239\n17242\n17243\n17246\n17253\n17257\n17261\n17269\n17278\n17280\n17290\n17292\n17296\n17305\n17306\n17307\n17311\n17316\n17317\n17324\n17328\n17331\n17332\n17337\n17350\n17357\n17359\n17361\n17363\n17366\n17376\n17378\n17382\n17385\n17386\n17389\n17397\n17404\n17408\n17414\n17428\n17432\n17441\n17443\n17444\n17448\n17458\n17476\n17479\n17483\n17491\n17496\n17498\n17503\n17505\n17509\n17515\n17516\n17517\n17532\n17536\n17537\n17539\n17544\n17547\n17553\n17556\n17559\n17562\n17565\n17566\n17569\n17576\n17583\n17586\n17590\n17592\n17598\n17599\n17600\n17601\n17604\n17605\n17607\n17609\n17615\n17624\n17625\n17632\n17634\n17639\n17640\n17645\n17650\n17652\n17658\n17661\n17663\n17666\n17668\n17670\n17681\n17698\n17701\n17703\n17706\n17708\n17710\n17711\n17713\n17720\n17738\n17741\n17749\n17752\n17761\n17771\n17773\n17776\n17777\n17778\n17782\n17786\n17798\n17811\n17813\n17815\n17817\n17823\n17824\n17826\n17852\n17861\n17865\n17868\n17872\n17880\n17885\n17887\n17900\n17906\n17908\n17914\n17924\n17925\n17931\n17933\n17934\n17936\n17941\n17947\n17962\n17980\n17985\n17987\n17993\n17994\n17995\n17998\n18006\n18012\n18014\n18021\n18025\n18031\n18033\n18037\n18046\n18047\n18055\n18059\n18068\n18076\n18080\n18092\n18114\n18117\n18120\n18127\n18129\n18130\n18141\n18142\n18143\n18151\n18152\n18154\n18155\n18157\n18159\n18176\n18180\n18188\n18189\n18192\n18198\n18203\n18204\n18205\n18206\n18207\n18208\n18216\n18233\n18239\n18240\n18241\n18243\n18247\n18253\n18265\n18278\n18281\n18282\n18286\n18287\n18299\n18300\n18308\n18319\n18325\n18333\n18342\n18343\n18344\n18346\n18357\n18370\n18373\n18376\n18377\n18386\n18404\n18411\n18423\n18441\n18445\n18450\n18451\n18455\n18458\n18465\n18480\n18487\n18489\n18495\n18496\n18507\n18509\n18523\n18533\n18538\n18539\n18550\n18561\n18565\n18567\n18574\n18575\n18577\n18579\n18580\n18589\n18590\n18592\n18605\n18607\n18610\n18613\n18615\n18620\n18622\n18643\n18647\n18653\n18659\n18664\n18666\n18668\n18673\n18675\n18682\n18688\n18700\n18702\n18703\n18709\n18713\n18715\n18717\n18719\n18726\n18730\n18732\n18763\n18772\n18774\n18781\n18784\n18788\n18791\n18805\n18807\n18808\n18810\n18823\n18826\n18827\n18828\n18858\n18859\n18865\n18871\n18876\n18879\n18883\n18885\n18887\n18894\n18900\n18901\n18905\n18918\n18926\n18928\n18967\n18971\n18975\n18989\n18995\n18999\n19002\n19013\n19016\n19023\n19028\n19029\n19032\n19037\n19042\n19044\n19050\n19052\n19055\n19057\n19063\n19070\n19071\n19077\n19079\n19080\n19085\n19091\n19094\n19100\n19104\n19105\n19109\n19113\n19115\n19123\n19126\n19129\n19130\n19134\n19140\n19143\n19144\n19150\n19151\n19158\n19174\n19175\n19177\n19179\n19184\n19187\n19192\n19197\n19201\n19204\n19208\n19212\n19234\n19245\n19246\n19248\n19252\n19265\n19267\n19269\n19275\n19287\n19297\n19305\n19306\n19312\n19313\n19316\n19317\n19322\n19323\n19328\n19333\n19334\n19338\n19346\n19352\n19360\n19362\n19368\n19369\n19375\n19378\n19381\n19389\n19393\n19395\n19397\n19405\n19412\n19416\n19420\n19421\n19441\n19443\n19445\n19448\n19449\n19451\n19469\n19478\n19479\n19485\n19486\n19489\n19490\n19492\n19499\n19502\n19506\n19507\n19510\n19512\n19514\n19516\n19521\n19529\n19532\n19538\n19554\n19563\n19568\n19578\n19602\n19614\n19615\n19616\n19617\n19625\n19626\n19627\n19629\n19647\n19657\n19660\n19661\n19663\n19671\n19673\n19674\n19675\n19676\n19677\n19682\n19687\n19690\n19692\n19698\n19702\n19707\n19724\n19727\n19729\n19731\n19735\n19739\n19744\n19751\n19753\n19755\n19757\n19761\n19762\n19765\n19768\n19774\n19783\n19785\n19796\n19798\n19805\n19807\n19810\n19843\n19848\n19865\n19883\n19893\n19905\n19906\n19916\n19922\n19926\n19927\n19929\n19930\n19931\n19947\n19949\n19950\n19956\n19958\n19959\n19979\n19982\n19988\n19993\n19998\n20003\n20004\n20014\n20015\n20017\n20019\n20021\n20022\n20027\n20030\n20039\n20044\n20053\n20054\n20058\n20061\n20062\n20063\n20065\n20073\n20077\n20081\n20083\n20096\n20104\n20107\n20114\n20118\n20131\n20133\n20135\n20138\n20139\n20140\n20141\n20143\n20148\n20154\n20155\n20164\n20168\n20171\n20177\n20178\n20179\n20194\n20195\n20197\n20202\n20203\n20208\n20228\n20237\n20239\n20255\n20266\n20270\n20275\n20278\n20285\n20286\n20288\n20298\n20301\n20303\n20309\n20310\n20311\n20314\n20317\n20322\n20325\n20328\n20335\n20338\n20346\n20356\n20361\n20377\n20378\n20381\n20382\n20386\n20391\n20393\n20396\n20397\n20403\n20404\n20411\n20417\n20419\n20430\n20431\n20436\n20445\n20451\n20466\n20468\n20474\n20479\n20480\n20484\n20488\n20490\n20499\n20505\n20508\n20510\n20512\n20542\n20543\n20550\n20554\n20559\n20563\n20564\n20567\n20572\n20575\n20576\n20584\n20587\n20590\n20599\n20603\n20605\n20606\n20616\n20620\n20621\n20622\n20625\n20626\n20629\n20633\n20644\n20645\n20647\n20649\n20656\n20660\n20664\n20667\n20672\n20674\n20678\n20683\n20690\n20691\n20693\n20697\n20701\n20707\n20714\n20715\n20717\n20723\n20726\n20727\n20729\n20738\n20744\n20748\n20751\n20757\n20764\n20768\n20772\n20776\n20781\n20783\n20784\n20800\n20811\n20814\n20815\n20817\n20822\n20826\n20828\n20831\n20832\n20833\n20834\n20852\n20855\n20868\n20871\n20877\n20883\n20886\n20890\n20894\n20900\n20910\n20915\n20916\n20921\n20924\n20928\n20946\n20951\n20952\n20958\n20960\n20963\n20969\n20973\n20975\n20979\n20981\n20987\n20988\n20989\n20995\n20996\n20998\n21000\n21011\n21012\n21016\n21019\n21025\n21030\n21035\n21036\n21037\n21042\n21044\n21052\n21054\n21062\n21063\n21069\n21072\n21087\n21091\n21103\n21104\n21107\n21116\n21122\n21127\n21129\n21133\n21135\n21159\n21160\n21171\n21178\n21179\n21184\n21186\n21199\n21214\n21222\n21227\n21250\n21267\n21272\n21274\n21275\n21282\n21289\n21292\n21305\n21307\n21313\n21314\n21330\n21340\n21347\n21350\n21361\n21365\n21366\n21378\n21382\n21386\n21392\n21393\n21419\n21428\n21435\n21442\n21445\n21452\n21461\n21469\n21471\n21473\n21479\n21481\n21482\n21484\n21488\n21491\n21495\n21498\n21504\n21505\n21518\n21520\n21539\n21544\n21545\n21548\n21550\n21551\n21556\n21560\n21564\n21566\n21569\n21577\n21582\n21586\n21588\n21597\n21600\n21605\n21606\n21607\n21615\n21622\n21629\n21638\n21639\n21644\n21655\n21656\n21657\n21661\n21662\n21663\n21664\n21665\n21671\n21674\n21675\n21677\n21704\n21708\n21711\n21717\n21726\n21731\n21743\n21748\n21749\n21752\n21756\n21757\n21758\n21767\n21777\n21781\n21782\n21791\n21796\n21799\n21800\n21811\n21816\n21818\n21820\n21822\n21823\n21824\n21828\n21831\n21834\n21837\n21838\n21840\n21845\n21857\n21859\n21871\n21874\n21886\n21889\n21906\n21910\n21912\n21914\n21917\n21918\n21919\n21924\n21934\n21938\n21939\n21943\n21945\n21946\n21964\n21969\n21972\n21977\n21980\n21984\n21987\n21990\n21996\n22001\n22006\n22011\n22012\n22020\n22023\n22027\n22028\n22030\n22032\n22035\n22037\n22047\n22049\n22085\n22093\n22100\n22101\n22106\n22112\n22124\n22125\n22134\n22138\n22140\n22149\n22158\n22160\n22165\n22172\n22173\n22179\n22180\n22186\n22187\n22188\n22189\n22192\n22194\n22203\n22208\n22214\n22215\n22217\n22219\n22224\n22228\n22230\n22233\n22236\n22240\n22246\n22247\n22256\n22260\n22266\n22270\n22273\n22277\n22278\n22280\n22282\n22283\n22284\n22292\n22295\n22302\n22303\n22315\n22319\n22322\n22324\n22327\n22328\n22329\n22331\n22341\n22343\n22348\n22352\n22362\n22368\n22370\n22377\n22380\n22386\n22411\n22422\n22438\n22439\n22442\n22443\n22446\n22453\n22464\n22467\n22475\n22478\n22479\n22485\n22490\n22495\n22497\n22506\n22508\n22511\n22524\n22530\n22531\n22532\n22545\n22547\n22548\n22549\n22564\n22568\n22569\n22575\n22578\n22586\n22589\n22593\n22594\n22600\n22626\n22634\n22636\n22638\n22643\n22645\n22651\n22652\n22653\n22655\n22661\n22662\n22668\n22669\n22676\n22686\n22707\n22718\n22724\n22737\n22744\n22749\n22753\n22761\n22765\n22770\n22772\n22775\n22790\n22791\n22796\n22800\n22802\n22806\n22808\n22809\n22813\n22826\n22830\n22832\n22834\n22840\n22842\n22847\n22850\n22854\n22856\n22867\n22870\n22872\n22884\n22887\n22905\n22907\n22938\n22942\n22943\n22947\n22960\n22963\n22964\n22969\n22971\n22973\n22982\n22984\n22990\n22995\n22997\n23006\n23011\n23013\n23014\n23021\n23048\n23053\n23055\n23070\n23073\n23074\n23079\n23084\n23092\n23098\n23100\n23102\n23105\n23111\n23116\n23123\n23125\n23129\n23131\n23132\n23137\n23138\n23141\n23156\n23166\n23168\n23169\n23174\n23177\n23180\n23181\n23183\n23185\n23186\n23189\n23205\n23207\n23210\n23212\n23218\n23224\n23228\n23246\n23247\n23249\n23252\n23254\n23255\n23258\n23259\n23272\n23282\n23296\n23297\n23320\n23324\n23331\n23336\n23337\n23346\n23358\n23367\n23378\n23379\n23380\n23390\n23392\n23398\n23402\n23406\n23409\n23413\n23416\n23417\n23420\n23431\n23436\n23438\n23443\n23444\n23446\n23451\n23452\n23454\n23455\n23456\n23472\n23476\n23480\n23486\n23491\n23493\n23495\n23498\n23500\n23502\n23503\n23506\n23518\n23522\n23533\n23541\n23547\n23553\n23579\n23584\n23585\n23587\n23588\n23599\n23605\n23608\n23614\n23616\n23619\n23627\n23629\n23636\n23638\n23640\n23644\n23648\n23651\n23654\n23658\n23659\n23660\n23668\n23670\n23672\n23673\n23678\n23683\n23684\n23692\n23695\n23697\n23703\n23706\n23707\n23708\n23710\n23711\n23715\n23716\n23731\n23732\n23735\n23738\n23740\n23760\n23762\n23767\n23770\n23780\n23784\n23785\n23791\n23797\n23800\n23811\n23818\n23820\n23827\n23831\n23833\n23838\n23839\n23842\n23846\n23851\n23861\n23878\n23882\n23883\n23885\n23889\n23890\n23892\n23899\n23901\n23905\n23907\n23910\n23914\n23918\n23931\n23940\n23943\n23949\n23952\n23953\n23956\n23960\n23961\n23964\n23977\n23987\n23991\n24002\n24008\n24009\n24012\n24017\n24022\n24029\n24031\n24037\n24038\n24039\n24042\n24053\n24054\n24064\n24080\n24084\n24091\n24092\n24100\n24101\n24102\n24106\n24109\n24111\n24114\n24121\n24122\n24124\n24125\n24130\n24135\n24143\n24147\n24149\n24154\n24176\n24180\n24182\n24187\n24188\n24195\n24197\n24199\n24207\n24216\n24225\n24232\n24238\n24239\n24241\n24243\n24245\n24252\n24256\n24261\n24275\n24289\n24295\n24308\n24312\n24320\n24325\n24330\n24332\n24333\n24338\n24340\n24344\n24354\n24357\n24360\n24363\n24365\n24366\n24370\n24373\n24381\n24386\n24387\n24393\n24395\n24396\n24399\n24404\n24406\n24412\n24416\n24419\n24429\n24434\n24436\n24437\n24439\n24440\n24441\n24442\n24443\n24446\n24448\n24450\n24453\n24455\n24468\n24474\n24480\n24486\n24490\n24491\n24498\n24503\n24505\n24509\n24510\n24511\n24513\n24516\n24520\n24528\n24530\n24531\n24538\n24540\n24545\n24548\n24560\n24561\n24562\n24580\n24585\n24587\n24591\n24593\n24601\n24605\n24612\n24617\n24620\n24624\n24631\n24643\n24648\n24652\n24656\n24664\n24667\n24669\n24671\n24672\n24679\n24683\n24690\n24693\n24694\n24697\n24705\n24706\n24710\n24716\n24718\n24721\n24724\n24726\n24736\n24739\n24745\n24762\n24768\n24774\n24776\n24786\n24790\n24791\n24792\n24794\n24804\n24815\n24825\n24828\n24831\n24833\n24836\n24839\n24840\n24848\n24863\n24881\n24882\n24891\n24896\n24899\n24903\n24924\n24926\n24935\n24944\n24951\n24956\n24961\n24962\n24964\n24967\n24968\n24975\n24976\n24984\n24998\n24999\n25004\n25005\n25013\n25018\n25021\n25026\n25032\n25037\n25043\n25045\n25048\n25049\n25054\n25056\n25062\n25072\n25075\n25079\n25082\n25108\n25119\n25121\n25122\n25123\n25129\n25137\n25143\n25145\n25153\n25154\n25159\n25161\n25170\n25176\n25178\n25189\n25190\n25195\n25197\n25198\n25209\n25213\n25219\n25230\n25233\n25239\n25244\n25248\n25253\n25260\n25262\n25267\n25270\n25297\n25305\n25306\n25307\n25313\n25315\n25319\n25323\n25328\n25344\n25350\n25353\n25356\n25365\n25370\n25378\n25386\n25390\n25392\n25394\n25398\n25401\n25409\n25410\n25418\n25422\n25424\n25444\n25446\n25447\n25451\n25453\n25454\n25459\n25460\n25466\n25470\n25472\n25478\n25488\n25496\n25504\n25511\n25518\n25519\n25522\n25523\n25527\n25531\n25532\n25534\n25540\n25542\n25544\n25552\n25561\n25573\n25586\n25591\n25599\n25600\n25603\n25604\n25607\n25608\n25611\n25612\n25615\n25616\n25618\n25627\n25634\n25641\n25653\n25655\n25666\n25676\n25677\n25681\n25686\n25689\n25691\n25706\n25712\n25726\n25732\n25743\n25747\n25756\n25758\n25759\n25760\n25762\n25763\n25766\n25767\n25774\n25779\n25784\n25797\n25799\n25806\n25811\n25816\n25826\n25831\n25835\n25841\n25846\n25849\n25857\n25860\n25862\n25865\n25869\n25877\n25885\n25887\n25894\n25897\n25900\n25908\n25910\n25921\n25926\n25940\n25945\n25954\n25957\n25964\n25967\n25969\n25974\n25979\n25989\n25991\n25999\n26006\n26009\n26011\n26013\n26029\n26039\n26045\n26062\n26067\n26070\n26072\n26074\n26102\n26103\n26106\n26110\n26130\n26132\n26136\n26137\n26138\n26140\n26141\n26143\n26151\n26153\n26155\n26164\n26172\n26175\n26180\n26181\n26182\n26186\n26189\n26191\n26192\n26200\n26203\n26205\n26206\n26209\n26212\n26216\n26219\n26226\n26228\n26229\n26231\n26237\n26238\n26244\n26245\n26246\n26248\n26249\n26250\n26253\n26258\n26260\n26266\n26267\n26268\n26275\n26281\n26282\n26284\n26287\n26290\n26295\n26309\n26310\n26311\n26313\n26316\n26318\n26328\n26329\n26332\n26333\n26334\n26336\n26340\n26346\n26347\n26349\n26352\n26357\n26358\n26363\n26364\n26387\n26390\n26410\n26412\n26414\n26417\n26426\n26435\n26449\n26451\n26453\n26459\n26470\n26471\n26474\n26475\n26476\n26477\n26484\n26493\n26496\n26508\n26510\n26513\n26526\n26535\n26544\n26545\n26546\n26549\n26551\n26552\n26554\n26555\n26556\n26565\n26582\n26584\n26588\n26589\n26591\n26599\n26607\n26608\n26609\n26610\n26614\n26617\n26622\n26623\n26631\n26635\n26637\n26640\n26641\n26648\n26651\n26653\n26659\n26664\n26665\n26669\n26672\n26673\n26676\n26680\n26686\n26689\n26692\n26693\n26698\n26704\n26712\n26714\n26721\n26725\n26732\n26740\n26744\n26753\n26755\n26760\n26774\n26784\n26793\n26796\n26799\n26804\n26805\n26808\n26810\n26814\n26818\n26820\n26823\n26824\n26827\n26837\n26844\n26847\n26848\n26850\n26856\n26863\n26864\n26868\n26875\n26876\n26882\n26887\n26892\n26893\n26895\n26897\n26899\n26903\n26907\n26912\n26919\n26924\n26933\n26940\n26946\n26947\n26949\n26952\n26956\n26970\n26973\n26975\n26979\n26983\n26986\n26989\n26994\n26995\n27003\n27008\n27013\n27017\n27026\n27027\n27029\n27030\n27037\n27051\n27053\n27054\n27059\n27062\n27063\n27068\n27069\n27074\n27076\n27077\n27094\n27097\n27108\n27110\n27115\n27121\n27130\n27132\n27146\n27149\n27150\n27154\n27158\n27159\n27161\n27164\n27165\n27169\n27172\n27174\n27177\n27180\n27182\n27187\n27192\n27201\n27208\n27213\n27214\n27220\n27222\n27226\n27229\n27232\n27233\n27238\n27242\n27243\n27244\n27249\n27253\n27258\n27262\n27279\n27282\n27283\n27287\n27289\n27291\n27300\n27311\n27315\n27328\n27331\n27345\n27346\n27348\n27349\n27361\n27362\n27367\n27370\n27373\n27383\n27390\n27395\n27403\n27404\n27406\n27411\n27416\n27419\n27420\n27423\n27431\n27434\n27438\n27453\n27460\n27474\n27475\n27483\n27485\n27488\n27493\n27499\n27502\n27512\n27515\n27525\n27534\n27536\n27542\n27559\n27560\n27561\n27570\n27573\n27574\n27583\n27584\n27586\n27603\n27621\n27632\n27638\n27648\n27659\n27666\n27691\n27692\n27695\n27697\n27698\n27706\n27726\n27730\n27742\n27743\n27745\n27750\n27751\n27753\n27757\n27758\n27759\n27768\n27772\n27778\n27783\n27789\n27790\n27792\n27798\n27805\n27818\n27821\n27822\n27832\n27835\n27842\n27845\n27848\n27850\n27852\n27856\n27863\n27864\n27866\n27871\n27873\n27874\n27876\n27880\n27883\n27894\n27896\n27898\n27899\n27900\n27903\n27906\n27909\n27910\n27916\n27917\n27920\n27921\n27924\n27929\n27931\n27937\n27940\n27941\n27946\n27949\n27953\n27954\n27958\n27967\n27971\n27978\n27982\n27988\n27989\n28000\n28001\n28004\n28006\n28012\n28020\n28033\n28037\n28039\n28041\n28042\n28044\n28051\n28053\n28058\n28059\n28062\n28063\n28066\n28068\n28069\n28071\n28080\n28085\n28086\n28089\n28092\n28094\n28097\n28102\n28107\n28117\n28128\n28134\n28137\n28149\n28150\n28152\n28154\n28163\n28170\n28179\n28181\n28186\n28190\n28195\n28209\n28215\n28220\n28222\n28226\n28228\n28230\n28241\n28244\n28250\n28251\n28252\n28254\n28258\n28259\n28260\n28262\n28263\n28269\n28273\n28279\n28280\n28283\n28293\n28301\n28313\n28314\n28320\n28321\n28332\n28336\n28337\n28338\n28341\n28359\n28365\n28368\n28381\n28385\n28391\n28399\n28402\n28404\n28416\n28417\n28418\n28424\n28426\n28433\n28440\n28449\n28461\n28478\n28481\n28484\n28493\n28498\n28501\n28503\n28506\n28514\n28529\n28535\n28543\n28544\n28546\n28560\n28564\n28566\n28581\n28587\n28601\n28604\n28606\n28614\n28616\n28622\n28623\n28624\n28628\n28633\n28644\n28645\n28647\n28652\n28653\n28656\n28663\n28668\n28669\n28670\n28672\n28673\n28674\n28676\n28694\n28699\n28708\n28714\n28732\n28734\n28743\n28750\n28756\n28758\n28763\n28765\n28766\n28780\n28789\n28793\n28794\n28798\n28803\n28808\n28812\n28816\n28819\n28833\n28834\n28845\n28847\n28850\n28855\n28867\n28869\n28870\n28871\n28876\n28882\n28885\n28888\n28898\n28900\n28903\n28918\n28919\n28923\n28929\n28935\n28945\n28948\n28951\n28953\n28957\n28982\n28993\n28995\n29001\n29005\n29010\n29011\n29019\n29030\n29038\n29041\n29046\n29052\n29057\n29060\n29062\n29065\n29066\n29069\n29070\n29071\n29073\n29077\n29079\n29080\n29081\n29083\n29087\n29089\n29090\n29096\n29100\n29106\n29115\n29119\n29120\n29126\n29133\n29139\n29140\n29141\n29146\n29150\n29158\n29167\n29170\n29174\n29182\n29184\n29193\n29198\n29203\n29204\n29211\n29212\n29221\n29222\n29223\n29235\n29236\n29240\n29242\n29253\n29267\n29273\n29274\n29275\n29277\n29287\n29303\n29305\n29322\n29325\n29327\n29328\n29330\n29337\n29338\n29342\n29346\n29347\n29348\n29358\n29363\n29366\n29377\n29389\n29395\n29403\n29414\n29420\n29428\n29442\n29447\n29456\n29457\n29467\n29472\n29484\n29488\n29489\n29492\n29494\n29496\n29499\n29502\n29505\n29509\n29513\n29520\n29522\n29529\n29531\n29538\n29541\n29542\n29546\n29548\n29551\n29554\n29555\n29557\n29559\n29561\n29575\n29576\n29579\n29580\n29581\n29592\n29603\n29605\n29608\n29610\n29612\n29613\n29618\n29621\n29623\n29637\n29643\n29648\n29656\n29665\n29667\n29670\n29673\n29677\n29683\n29711\n29716\n29719\n29720\n29721\n29724\n29739\n29743\n29759\n29762\n29765\n29768\n29776\n29781\n29783\n29792\n29796\n29800\n29812\n29836\n29839\n29840\n29841\n29845\n29850\n29852\n29853\n29855\n29857\n29860\n29867\n29868\n29872\n29873\n29875\n29876\n29887\n29889\n29890\n29891\n29896\n29904\n29907\n29921\n29923\n29927\n29931\n29938\n29940\n29945\n29946\n29960\n29969\n29970\n29984\n29986\n29992\n29995\n29999\n30001\n30004\n30005\n30007\n30008\n30013\n30015\n30016\n30019\n30024\n30026\n30029\n30036\n30044\n30045\n30047\n30053\n30054\n30059\n30063\n30065\n30070\n30073\n30075\n30076\n30078\n30083\n30087\n30091\n30093\n30100\n30108\n30116\n30121\n30125\n30142\n30151\n30167\n30168\n30184\n30186\n30187\n30190\n30191\n30192\n30195\n30196\n30202\n30211\n30219\n30222\n30224\n30226\n30234\n30236\n30237\n30252\n30253\n30255\n30258\n30261\n30267\n30279\n30287\n30289\n30293\n30295\n30299\n30315\n30318\n30324\n30327\n30335\n30338\n30353\n30359\n30361\n30362\n30363\n30365\n30367\n30369\n30375\n30382\n30388\n30391\n30396\n30397\n30402\n30405\n30407\n30410\n30415\n30424\n30425\n30426\n30432\n30436\n30440\n30447\n30452\n30457\n30459\n30465\n30468\n30471\n30477\n30479\n30483\n30488\n30490\n30494\n30495\n30498\n30505\n30508\n30515\n30520\n30526\n30528\n30529\n30534\n30538\n30539\n30543\n30555\n30556\n30559\n30573\n30578\n30585\n30586\n30600\n30603\n30612\n30614\n30626\n30629\n30630\n30638\n30649\n30650\n30655\n30657\n30662\n30663\n30673\n30675\n30677\n30688\n30725\n30726\n30731\n30732\n30741\n30747\n30748\n30753\n30756\n30761\n30762\n30767\n30772\n30779\n30783\n30793\n30794\n30797\n30803\n30806\n30816\n30817\n30823\n30841\n30843\n30846\n30858\n30859\n30862\n30863\n30865\n30870\n30874\n30875\n30876\n30881\n30884\n30885\n30887\n30888\n30896\n30897\n30899\n30900\n30907\n30910\n30913\n30919\n30923\n30931\n30937\n30947\n30948\n30953\n30982\n30987\n30991\n30992\n31001\n31002\n31003\n31013\n31015\n31018\n31019\n31024\n31030\n31034\n31036\n31041\n31043\n31048\n31051\n31054\n31061\n31062\n31064\n31066\n31067\n31068\n31071\n31077\n31087\n31089\n31098\n31103\n31105\n31106\n31117\n31118\n31127\n31130\n31133\n31137\n31140\n31143\n31145\n31150\n31157\n31163\n31174\n31176\n31182\n31187\n31193\n31199\n31201\n31202\n31207\n31212\n31213\n31216\n31217\n31222\n31224\n31230\n31236\n31239\n31245\n31252\n31253\n31254\n31255\n31263\n31275\n31281\n31282\n31287\n31288\n31294\n31300\n31307\n31311\n31326\n31333\n31340\n31348\n31350\n31363\n31365\n31373\n31374\n31378\n31392\n31409\n31425\n31427\n31431\n31434\n31435\n31441\n31444\n31451\n31453\n31456\n31457\n31469\n31477\n31490\n31506\n31520\n31522\n31530\n31531\n31535\n31536\n31538\n31539\n31542\n31550\n31551\n31552\n31553\n31578\n31579\n31583\n31587\n31592\n31597\n31598\n31612\n31615\n31618\n31625\n31629\n31636\n31637\n31638\n31650\n31652\n31660\n31664\n31665\n31667\n31668\n31684\n31685\n31701\n31708\n31710\n31714\n31720\n31722\n31725\n31728\n31732\n31733\n31739\n31748\n31752\n31772\n31779\n31781\n31782\n31785\n31788\n31791\n31801\n31802\n31813\n31814\n31827\n31829\n31831\n31833\n31834\n31835\n31838\n31844\n31847\n31854\n31856\n31860\n31861\n31863\n31865\n31867\n31875\n31882\n31903\n31906\n31907\n31924\n31926\n31932\n31936\n31941\n31945\n31948\n31971\n31975\n31976\n31979\n31985\n31987\n31988\n31990\n31995\n32006\n32007\n32011\n32012\n32018\n32022\n32023\n32025\n32028\n32031\n32041\n32042\n32054\n32061\n32067\n32068\n32071\n32079\n32080\n32089\n32099\n32108\n32113\n32118\n32119\n32123\n32143\n32148\n32154\n32160\n32167\n32177\n32181\n32205\n32211\n32216\n32221\n32228\n32233\n32237\n32239\n32248\n32255\n32258\n32261\n32263\n32269\n32271\n32272\n32273\n32284\n32286\n32289\n32295\n32296\n32298\n32301\n32305\n32307\n32318\n32321\n32330\n32334\n32344\n32350\n32352\n32353\n32357\n32365\n32367\n32372\n32373\n32374\n32375\n32386\n32398\n32399\n32405\n32412\n32415\n32417\n32433\n32434\n32447\n32448\n32451\n32456\n32464\n32472\n32483\n32497\n32508\n32514\n32520\n32526\n32529\n32530\n32536\n32541\n32542\n32545\n32548\n32552\n32568\n32575\n32586\n32588\n32590\n32598\n32599\n32602\n32603\n32618\n32621\n32630\n32631\n32633\n32635\n32653\n32655\n32663\n32668\n32669\n32675\n32676\n32683\n32684\n32686\n32687\n32693\n32701\n32702\n32706\n32713\n32715\n32718\n32722\n32732\n32733\n32737\n32739\n32752\n32765\n32773\n32774\n32778\n32779\n32783\n32784\n32791\n32792\n32794\n32802\n32805\n32812\n32819\n32829\n32830\n32837\n32841\n32845\n32848\n32853\n32854\n32858\n32862\n32866\n32867\n32882\n32902\n32911\n32913\n32915\n32917\n32938\n32941\n32956\n32967\n32968\n32972\n32984\n32986\n32997\n33001\n33010\n33013\n33015\n33025\n33031\n33035\n33042\n33044\n33048\n33051\n33054\n33058\n33062\n33067\n33076\n33078\n33080\n33083\n33087\n33088\n33089\n33090\n33093\n33094\n33095\n33096\n33097\n33103\n33105\n33107\n33108\n33110\n33115\n33116\n33126\n33128\n33134\n33138\n33139\n33142\n33146\n33150\n33154\n33156\n33161\n33162\n33163\n33169\n33170\n33177\n33182\n33199\n33203\n33214\n33217\n33228\n33233\n33234\n33242\n33244\n33245\n33249\n33252\n33259\n33262\n33264\n33266\n33274\n33280\n33286\n33306\n33315\n33322\n33324\n33327\n33332\n33337\n33340\n33342\n33347\n33350\n33364\n33366\n33367\n33377\n33383\n33395\n33401\n33402\n33405\n33406\n33408\n33409\n33411\n33413\n33432\n33437\n33438\n33442\n33444\n33456\n33470\n33480\n33482\n33498\n33499\n33500\n33507\n33510\n33515\n33516\n33517\n33518\n33520\n33524\n33530\n33532\n33539\n33540\n33543\n33548\n33555\n33560\n33569\n33577\n33582\n33589\n33592\n33604\n33606\n33607\n33610\n33617\n33618\n33619\n33625\n33628\n33634\n33642\n33645\n33654\n33655\n33657\n33665\n33675\n33683\n33686\n33692\n33694\n33699\n33728\n33730\n33741\n33744\n33748\n33754\n33755\n33757\n33760\n33761\n33766\n33768\n33769\n33782\n33783\n33787\n33788\n33789\n33798\n33799\n33803\n33812\n33817\n33825\n33833\n33839\n33841\n33849\n33852\n33865\n33869\n33873\n33886\n33895\n33900\n33907\n33917\n33921\n33922\n33927\n33928\n33938\n33941\n33944\n33948\n33949\n33952\n33965\n33972\n33977\n33984\n34003\n34004\n34009\n34010\n34017\n34018\n34019\n34020\n34026\n34028\n34046\n34050\n34051\n34053\n34054\n34060\n34075\n34076\n34080\n34083\n34084\n34086\n34092\n34094\n34095\n34096\n34098\n34103\n34108\n34113\n34130\n34135\n34141\n34149\n34153\n34159\n34164\n34166\n34177\n34187\n34205\n34207\n34212\n34213\n34219\n34222\n34224\n34231\n34234\n34243\n34247\n34249\n34250\n34253\n34259\n34261\n34264\n34266\n34278\n34279\n34287\n34288\n34290\n34293\n34303\n34308\n34314\n34323\n34336\n34338\n34344\n34346\n34347\n34353\n34356\n34362\n34374\n34377\n34382\n34391\n34392\n34393\n34394\n34401\n34405\n34406\n34413\n34416\n34417\n34424\n34438\n34448\n34449\n34450\n34451\n34461\n34473\n34478\n34483\n34490\n34497\n34500\n34507\n34510\n34518\n34523\n34526\n34529\n34536\n34543\n34547\n34548\n34549\n34551\n34553\n34554\n34564\n34566\n34568\n34569\n34574\n34579\n34580\n34581\n34588\n34591\n34598\n34602\n34606\n34608\n34610\n34614\n34617\n34621\n34642\n34644\n34645\n34648\n34649\n34652\n34655\n34658\n34659\n34664\n34665\n34671\n34673\n34675\n34679\n34680\n34684\n34685\n34686\n34692\n34696\n34702\n34706\n34708\n34710\n34711\n34716\n34718\n34720\n34722\n34735\n34737\n34739\n34744\n34746\n34761\n34767\n34773\n34774\n34777\n34778\n34779\n34784\n34786\n34789\n34791\n34795\n34810\n34815\n34823\n34824\n34839\n34847\n34849\n34854\n34855\n34857\n34862\n34873\n34877\n34886\n34890\n34895\n34903\n34906\n34908\n34918\n34921\n34928\n34933\n34935\n34948\n34954\n34958\n34962\n34972\n34988\n34990\n34991\n34992\n34994\n34998\n34999\n35000\n35003\n35005\n35009\n35013\n35014\n35020\n35025\n35032\n35043\n35055\n35057\n35072\n35078\n35080\n35096\n35100\n35107\n35110\n35113\n35114\n35115\n35121\n35123\n35126\n35128\n35130\n35133\n35148\n35150\n35151\n35160\n35179\n35181\n35188\n35193\n35194\n35197\n35200\n35201\n35203\n35207\n35211\n35213\n35214\n35215\n35226\n35228\n35232\n35233\n35239\n35243\n35250\n35251\n35255\n35256\n35262\n35268\n35270\n35271\n35279\n35286\n35293\n35294\n35295\n35308\n35311\n35312\n35314\n35315\n35317\n35319\n35328\n35342\n35350\n35355\n35360\n35365\n35370\n35374\n35376\n35377\n35383\n35411\n35416\n35419\n35446\n35450\n35455\n35456\n35460\n35469\n35478\n35483\n35486\n35501\n35502\n35504\n35514\n35516\n35517\n35519\n35522\n35531\n35540\n35541\n35543\n35546\n35549\n35554\n35557\n35559\n35563\n35564\n35568\n35570\n35572\n35576\n35578\n35580\n35581\n35587\n35591\n35592\n35595\n35621\n35626\n35628\n35636\n35639\n35648\n35654\n35660\n35672\n35673\n35675\n35678\n35679\n35680\n35683\n35684\n35694\n35698\n35699\n35702\n35706\n35707\n35716\n35717\n35728\n35729\n35730\n35738\n35746\n35749\n35751\n35757\n35763\n35764\n35769\n35777\n35781\n35783\n35784\n35791\n35793\n35796\n35798\n35815\n35816\n35823\n35824\n35836\n35837\n35839\n35855\n35865\n35866\n35874\n35876\n35880\n35885\n35887\n35889\n35892\n35894\n35898\n35900\n35901\n35907\n35912\n35923\n35929\n35930\n35936\n35941\n35947\n35948\n35956\n35960\n35964\n35969\n35970\n35971\n35975\n35977\n35982\n35983\n35985\n35990\n35995\n36000\n36006\n36009\n36025\n36026\n36030\n36034\n36036\n36037\n36041\n36042\n36048\n36051\n36052\n36059\n36060\n36061\n36067\n36070\n36071\n36081\n36086\n36090\n36095\n36099\n36102\n36104\n36113\n36115\n36116\n36119\n36123\n36140\n36141\n36142\n36149\n36162\n36167\n36174\n36189\n36191\n36193\n36196\n36197\n36199\n36202\n36203\n36204\n36212\n36223\n36233\n36234\n36238\n36239\n36242\n36248\n36254\n36259\n36262\n36264\n36271\n36273\n36279\n36280\n36282\n36283\n36286\n36302\n36305\n36307\n36309\n36312\n36319\n36323\n36325\n36327\n36335\n36337\n36339\n36357\n36361\n36363\n36368\n36370\n36375\n36383\n36394\n36396\n36402\n36405\n36409\n36416\n36419\n36424\n36429\n36437\n36441\n36456\n36457\n36473\n36477\n36484\n36490\n36491\n36498\n36499\n36508\n36510\n36511\n36513\n36514\n36516\n36517\n36520\n36529\n36548\n36551\n36558\n36566\n36571\n36574\n36579\n36581\n36582\n36586\n36588\n36603\n36604\n36608\n36609\n36610\n36623\n36624\n36628\n36629\n36641\n36642\n36645\n36651\n36653\n36655\n36657\n36659\n36662\n36663\n36664\n36667\n36676\n36677\n36681\n36682\n36683\n36685\n36687\n36689\n36692\n36700\n36701\n36703\n36705\n36710\n36729\n36735\n36747\n36754\n36757\n36767\n36770\n36773\n36777\n36779\n36786\n36789\n36793\n36797\n36804\n36811\n36815\n36817\n36822\n36840\n36847\n36850\n36853\n36856\n36860\n36863\n36868\n36870\n36878\n36881\n36883\n36885\n36888\n36893\n36898\n36913\n36916\n36919\n36921\n36922\n36923\n36926\n36927\n36930\n36937\n36938\n36939\n36963\n37000\n37024\n37027\n37028\n37029\n37035\n37038\n37039\n37041\n37048\n37049\n37052\n37053\n37055\n37056\n37058\n37060\n37062\n37065\n37071\n37074\n37076\n37083\n37084\n37087\n37090\n37092\n37093\n37097\n37099\n37101\n37102\n37105\n37108\n37110\n37117\n37128\n37133\n37137\n37139\n37142\n37148\n37155\n37159\n37161\n37162\n37163\n37165\n37170\n37180\n37181\n37182\n37189\n37191\n37192\n37202\n37211\n37214\n37221\n37222\n37231\n37234\n37246\n37247\n37251\n37255\n37256\n37261\n37269\n37277\n37279\n37286\n37287\n37297\n37307\n37309\n37313\n37315\n37318\n37320\n37322\n37329\n37331\n37341\n37343\n37344\n37345\n37364\n37380\n37382\n37387\n37388\n37391\n37392\n37393\n37400\n37405\n37408\n37410\n37411\n37413\n37423\n37428\n37430\n37433\n37440\n37444\n37448\n37452\n37456\n37466\n37474\n37485\n37490\n37506\n37507\n37508\n37509\n37512\n37517\n37528\n37529\n37531\n37535\n37538\n37539\n37542\n37545\n37549\n37550\n37552\n37554\n37563\n37571\n37573\n37581\n37582\n37594\n37606\n37614\n37623\n37635\n37637\n37646\n37651\n37654\n37656\n37658\n37661\n37674\n37675\n37688\n37691\n37694\n37700\n37710\n37715\n37720\n37722\n37736\n37743\n37744\n37747\n37753\n37755\n37757\n37763\n37764\n37767\n37768\n37785\n37788\n37789\n37798\n37800\n37807\n37809\n37818\n37821\n37831\n37834\n37838\n37839\n37840\n37841\n37848\n37849\n37853\n37855\n37856\n37862\n37864\n37879\n37883\n37897\n37901\n37906\n37907\n37910\n37917\n37920\n37923\n37929\n37930\n37932\n37940\n37944\n37946\n37955\n37964\n37965\n37966\n37971\n37987\n37995\n38002\n38007\n38021\n38024\n38029\n38049\n38050\n38051\n38058\n38059\n38061\n38068\n38076\n38078\n38082\n38087\n38094\n38096\n38104\n38107\n38109\n38111\n38116\n38131\n38141\n38145\n38147\n38150\n38151\n38156\n38158\n38160\n38161\n38164\n38173\n38174\n38179\n38181\n38193\n38195\n38198\n38208\n38211\n38212\n38223\n38225\n38232\n38239\n38249\n38250\n38252\n38255\n38257\n38258\n38268\n38275\n38285\n38296\n38300\n38302\n38304\n38308\n38313\n38324\n38325\n38327\n38331\n38336\n38337\n38339\n38359\n38362\n38384\n38385\n38389\n38397\n38401\n38406\n38410\n38415\n38417\n38418\n38419\n38425\n38427\n38431\n38433\n38437\n38442\n38451\n38456\n38458\n38463\n38465\n38467\n38468\n38469\n38470\n38481\n38497\n38498\n38499\n38501\n38505\n38509\n38517\n38531\n38555\n38557\n38565\n38569\n38571\n38577\n38579\n38594\n38598\n38603\n38607\n38609\n38611\n38614\n38615\n38624\n38625\n38626\n38627\n38629\n38631\n38633\n38636\n38642\n38645\n38646\n38647\n38648\n38652\n38659\n38662\n38663\n38666\n38669\n38671\n38680\n38684\n38689\n38693\n38696\n38701\n38712\n38713\n38716\n38721\n38730\n38738\n38739\n38744\n38746\n38750\n38765\n38766\n38771\n38782\n38783\n38785\n38789\n38797\n38800\n38803\n38806\n38811\n38819\n38821\n38831\n38833\n38840\n38841\n38849\n38864\n38868\n38871\n38878\n38882\n38884\n38885\n38886\n38890\n38891\n38892\n38897\n38898\n38901\n38906\n38912\n38927\n38929\n38945\n38946\n38953\n38956\n38957\n38960\n38962\n38963\n38965\n38968\n38986\n38987\n39006\n39011\n39020\n39021\n39032\n39033\n39036\n39043\n39046\n39047\n39051\n39054\n39056\n39067\n39073\n39084\n39097\n39099\n39105\n39107\n39111\n39115\n39116\n39121\n39122\n39124\n39125\n39129\n39131\n39133\n39135\n39139\n39140\n39143\n39145\n39150\n39151\n39158\n39160\n39162\n39166\n39171\n39177\n39186\n39195\n39201\n39203\n39206\n39211\n39219\n39225\n39227\n39230\n39234\n39235\n39239\n39244\n39247\n39248\n39262\n39282\n39284\n39295\n39299\n39302\n39303\n39308\n39310\n39311\n39325\n39333\n39338\n39341\n39342\n39343\n39344\n39345\n39355\n39370\n39379\n39381\n39384\n39399\n39410\n39413\n39419\n39422\n39423\n39431\n39436\n39445\n39451\n39452\n39454\n39458\n39462\n39463\n39465\n39470\n39472\n39479\n39482\n39484\n39498\n39500\n39511\n39514\n39516\n39517\n39525\n39535\n39539\n39540\n39547\n39559\n39561\n39565\n39567\n39570\n39571\n39572\n39589\n39591\n39593\n39597\n39610\n39617\n39619\n39621\n39627\n39630\n39642\n39653\n39663\n39670\n39672\n39674\n39681\n39683\n39684\n39686\n39689\n39696\n39697\n39700\n39706\n39715\n39724\n39727\n39728\n39731\n39733\n39742\n39743\n39747\n39750\n39753\n39758\n39759\n39764\n39767\n39768\n39769\n39774\n39780\n39785\n39786\n39787\n39790\n39803\n39805\n39815\n39816\n39831\n39834\n39841\n39850\n39852\n39859\n39873\n39885\n39886\n39899\n39900\n39904\n39907\n39912\n39913\n39916\n39922\n39926\n39927\n39934\n39936\n39938\n39940\n39946\n39948\n39949\n39951\n39953\n39956\n39968\n39975\n39976\n39977\n39984\n40004\n40011\n40013\n40014\n40024\n40025\n40029\n40032\n40034\n40038\n40042\n40045\n40046\n40055\n40056\n40065\n40066\n40070\n40073\n40091\n40094\n40100\n40105\n40112\n40113\n40117\n40120\n40133\n40141\n40144\n40146\n40148\n40149\n40154\n40156\n40158\n40159\n40167\n40175\n40185\n40187\n40191\n40193\n40194\n40204\n40206\n40213\n40219\n40221\n40222\n40235\n40236\n40238\n40241\n40246\n40249\n40255\n40256\n40262\n40268\n40279\n40284\n40285\n40289\n40291\n40292\n40294\n40299\n40301\n40305\n40311\n40315\n40323\n40328\n40334\n40339\n40345\n40347\n40348\n40351\n40360\n40361\n40362\n40368\n40369\n40371\n40376\n40382\n40390\n40391\n40392\n40395\n40400\n40403\n40404\n40405\n40406\n40407\n40409\n40413\n40414\n40415\n40421\n40428\n40429\n40433\n40436\n40437\n40438\n40439\n40440\n40442\n40444\n40447\n40454\n40458\n40464\n40485\n40504\n40507\n40515\n40517\n40520\n40526\n40534\n40546\n40550\n40557\n40560\n40561\n40563\n40568\n40570\n40571\n40572\n40573\n40574\n40578\n40579\n40581\n40595\n40596\n40617\n40628\n40630\n40632\n40633\n40635\n40638\n40642\n40646\n40648\n40650\n40664\n40675\n40682\n40685\n40689\n40693\n40698\n40704\n40709\n40711\n40714\n40731\n40732\n40733\n40739\n40749\n40755\n40758\n40760\n40761\n40774\n40775\n40776\n40777\n40780\n40781\n40784\n40786\n40789\n40794\n40797\n40800\n40816\n40820\n40826\n40831\n40833\n40856\n40861\n40862\n40864\n40868\n40870\n40875\n40877\n40879\n40886\n40892\n40893\n40908\n40910\n40914\n40916\n40919\n40922\n40939\n40946\n40949\n40958\n40965\n40966\n40975\n40976\n40978\n40979\n40996\n41004\n41013\n41022\n41033\n41034\n41036\n41044\n41047\n41049\n41065\n41070\n41075\n41083\n41085\n41086\n41094\n41099\n41101\n41104\n41114\n41117\n41124\n41128\n41130\n41137\n41142\n41143\n41144\n41148\n41149\n41150\n41152\n41154\n41157\n41159\n41165\n41170\n41171\n41183\n41187\n41191\n41202\n41211\n41230\n41231\n41237\n41246\n41250\n41258\n41259\n41260\n41262\n41263\n41264\n41270\n41273\n41274\n41283\n41286\n41288\n41289\n41296\n41301\n41306\n41311\n41317\n41331\n41334\n41338\n41339\n41341\n41345\n41349\n41352\n41354\n41361\n41372\n41374\n41382\n41392\n41394\n41396\n41400\n41403\n41405\n41412\n41414\n41419\n41430\n41431\n41439\n41444\n41460\n41463\n41464\n41465\n41472\n41477\n41492\n41496\n41498\n41501\n41503\n41507\n41512\n41517\n41520\n41522\n41525\n41532\n41535\n41537\n41560\n41574\n41575\n41576\n41577\n41579\n41581\n41586\n41606\n41614\n41615\n41616\n41623\n41624\n41630\n41641\n41651\n41658\n41660\n41663\n41672\n41673\n41674\n41686\n41687\n41694\n41696\n41698\n41711\n41712\n41722\n41726\n41727\n41731\n41732\n41736\n41737\n41739\n41747\n41750\n41752\n41761\n41767\n41768\n41770\n41774\n41778\n41784\n41793\n41797\n41799\n41800\n41804\n41806\n41807\n41808\n41827\n41842\n41844\n41849\n41853\n41859\n41864\n41868\n41874\n41875\n41880\n41882\n41886\n41889\n41892\n41893\n41896\n41898\n41907\n41910\n41916\n41917\n41919\n41932\n41938\n41939\n41943\n41947\n41948\n41950\n41952\n41956\n41960\n41961\n41973\n41974\n41978\n41982\n41986\n42002\n42004\n42007\n42009\n42012\n42024\n42025\n42026\n42027\n42032\n42033\n42034\n42039\n42040\n42046\n42052\n42061\n42063\n42089\n42096\n42098\n42121\n42123\n42130\n42134\n42136\n42146\n42150\n42159\n42174\n42175\n42180\n42183\n42186\n42188\n42193\n42197\n42204\n42217\n42230\n42231\n42232\n42239\n42259\n42260\n42263\n42265\n42269\n42271\n42274\n42282\n42292\n42293\n42301\n42304\n42306\n42311\n42314\n42317\n42327\n42329\n42330\n42339\n42342\n42349\n42352\n42355\n42357\n42366\n42383\n42386\n42394\n42404\n42413\n42415\n42422\n42423\n42424\n42425\n42431\n42434\n42437\n42440\n42454\n42455\n42458\n42463\n42466\n42467\n42474\n42480\n42482\n42490\n42491\n42494\n42499\n42507\n42519\n42520\n42532\n42537\n42540\n42543\n42547\n42549\n42562\n42565\n42573\n42578\n42579\n42584\n42585\n42596\n42598\n42600\n42601\n42605\n42611\n42620\n42623\n42626\n42636\n42638\n42639\n42655\n42659\n42662\n42666\n42674\n42678\n42688\n42689\n42692\n42698\n42703\n42705\n42708\n42709\n42713\n42717\n42730\n42731\n42737\n42738\n42741\n42752\n42754\n42763\n42767\n42770\n42777\n42784\n42786\n42793\n42796\n42800\n42805\n42810\n42813\n42819\n42820\n42825\n42826\n42829\n42832\n42834\n42836\n42853\n42864\n42867\n42871\n42873\n42874\n42882\n42884\n42886\n42893\n42904\n42907\n42911\n42919\n42930\n42935\n42936\n42947\n42956\n42964\n42967\n42976\n42982\n42990\n42995\n42998\n43002\n43010\n43020\n43022\n43029\n43032\n43033\n43038\n43043\n43045\n43054\n43055\n43063\n43064\n43068\n43076\n43084\n43089\n43091\n43102\n43105\n43108\n43117\n43131\n43132\n43133\n43134\n43150\n43155\n43157\n43158\n43163\n43171\n43175\n43183\n43188\n43192\n43198\n43205\n43206\n43207\n43210\n43211\n43220\n43223\n43226\n43229\n43233\n43245\n43246\n43249\n43253\n43255\n43265\n43269\n43278\n43283\n43287\n43291\n43302\n43309\n43311\n43318\n43321\n43342\n43343\n43345\n43359\n43362\n43364\n43386\n43389\n43391\n43395\n43404\n43407\n43409\n43411\n43412\n43414\n43420\n43422\n43423\n43424\n43437\n43448\n43449\n43453\n43459\n43466\n43469\n43474\n43482\n43490\n43495\n43497\n43498\n43501\n43507\n43511\n43516\n43528\n43542\n43543\n43546\n43548\n43549\n43558\n43565\n43567\n43569\n43570\n43572\n43574\n43580\n43597\n43604\n43605\n43608\n43609\n43611\n43616\n43617\n43618\n43625\n43632\n43636\n43638\n43642\n43643\n43646\n43650\n43656\n43663\n43680\n43684\n43685\n43690\n43696\n43704\n43708\n43713\n43718\n43720\n43721\n43725\n43728\n43741\n43742\n43743\n43746\n43747\n43750\n43751\n43754\n43756\n43758\n43761\n43768\n43777\n43778\n43779\n43781\n43783\n43787\n43790\n43813\n43821\n43826\n43832\n43835\n43843\n43844\n43850\n43852\n43857\n43861\n43872\n43874\n43878\n43879\n43881\n43885\n43891\n43903\n43905\n43911\n43915\n43925\n43928\n43931\n43932\n43935\n43946\n43947\n43950\n43952\n43956\n43963\n43967\n43978\n43980\n43983\n43984\n43985\n43992\n43995\n44007\n44008\n44009\n44010\n44019\n44020\n44037\n44040\n44053\n44054\n44064\n44066\n44072\n44074\n44079\n44081\n44082\n44085\n44089\n44090\n44091\n44092\n44094\n44097\n44098\n44101\n44105\n44114\n44117\n44118\n44122\n44139\n44140\n44144\n44159\n44168\n44171\n44174\n44179\n44182\n44193\n44198\n44206\n44207\n44212\n44222\n44223\n44229\n44230\n44238\n44242\n44245\n44250\n44252\n44263\n44265\n44287\n44290\n44296\n44298\n44304\n44308\n44317\n44318\n44322\n44323\n44334\n44344\n44352\n44358\n44369\n44371\n44386\n44390\n44399\n44424\n44428\n44433\n44440\n44448\n44455\n44471\n44483\n44490\n44491\n44496\n44506\n44514\n44521\n44529\n44542\n44547\n44553\n44560\n44567\n44590\n44592\n44596\n44605\n44614\n44617\n44620\n44622\n44625\n44626\n44627\n44646\n44647\n44648\n44653\n44657\n44665\n44667\n44671\n44672\n44677\n44684\n44688\n44689\n44691\n44694\n44695\n44698\n44708\n44709\n44713\n44718\n44721\n44723\n44728\n44730\n44745\n44747\n44751\n44753\n44754\n44755\n44757\n44760\n44767\n44774\n44776\n44778\n44782\n44792\n44796\n44800\n44804\n44810\n44818\n44824\n44834\n44852\n44855\n44857\n44862\n44863\n44877\n44879\n44891\n44895\n44898\n44900\n44915\n44916\n44919\n44920\n44924\n44927\n44937\n44946\n44955\n44965\n44984\n44988\n44989\n44995\n44997\n45000\n45004\n45018\n45019\n45020\n45025\n45027\n45029\n45030\n45034\n45035\n45043\n45047\n45049\n45051\n45055\n45061\n45062\n45103\n45106\n45115\n45120\n45124\n45127\n45141\n45143\n45145\n45154\n45159\n45168\n45178\n45183\n45187\n45191\n45194\n45198\n45201\n45202\n45215\n45216\n45225\n45227\n45231\n45233\n45235\n45239\n45242\n45249\n45252\n45257\n45260\n45262\n45263\n45287\n45288\n45290\n45293\n45300\n45317\n45319\n45321\n45322\n45323\n45325\n45329\n45337\n45339\n45340\n45342\n45361\n45363\n45366\n45373\n45385\n45398\n45403\n45412\n45414\n45419\n45420\n45421\n45427\n45430\n45433\n45439\n45443\n45444\n45452\n45458\n45459\n45468\n45472\n45476\n45477\n45479\n45481\n45482\n45484\n45491\n45493\n45497\n45503\n45513\n45517\n45521\n45528\n45529\n45534\n45537\n45538\n45544\n45553\n45559\n45560\n45563\n45564\n45573\n45574\n45578\n45585\n45590\n45591\n45603\n45612\n45620\n45630\n45636\n45640\n45641\n45643\n45651\n45660\n45664\n45665\n45666\n45669\n45673\n45677\n45681\n45686\n45687\n45693\n45694\n45699\n45705\n45706\n45712\n45731\n45742\n45743\n45744\n45745\n45748\n45754\n45756\n45765\n45773\n45780\n45797\n45800\n45802\n45805\n45822\n45824\n45826\n45830\n45840\n45847\n45851\n45862\n45870\n45872\n45876\n45878\n45881\n45882\n45884\n45888\n45892\n45893\n45896\n45898\n45900\n45907\n45908\n45910\n45913\n45914\n45915\n45924\n45925\n45930\n45932\n45935\n45936\n45945\n45946\n45950\n45961\n45967\n45969\n45976\n45979\n45987\n45990\n45993\n46004\n46006\n46007\n46008\n46013\n46019\n46021\n46033\n46039\n46040\n46042\n46044\n46057\n46058\n46059\n46064\n46065\n46066\n46077\n46079\n46081\n46088\n46095\n46098\n46107\n46111\n46113\n46122\n46133\n46140\n46142\n46144\n46146\n46154\n46157\n46161\n46162\n46163\n46165\n46166\n46173\n46176\n46182\n46188\n46194\n46205\n46222\n46233\n46241\n46242\n46251\n46276\n46293\n46296\n46297\n46299\n46302\n46306\n46317\n46318\n46326\n46330\n46341\n46345\n46353\n46355\n46365\n46367\n46369\n46372\n46375\n46378\n46380\n46384\n46406\n46407\n46408\n46409\n46411\n46413\n46414\n46415\n46419\n46421\n46422\n46427\n46428\n46432\n46437\n46438\n46443\n46448\n46449\n46452\n46456\n46461\n46480\n46481\n46484\n46490\n46493\n46507\n46509\n46510\n46511\n46512\n46516\n46519\n46520\n46528\n46534\n46547\n46549\n46551\n46552\n46563\n46565\n46566\n46572\n46576\n46584\n46585\n46591\n46602\n46612\n46613\n46620\n46635\n46637\n46643\n46645\n46646\n46647\n46659\n46661\n46662\n46663\n46664\n46677\n46679\n46685\n46687\n46691\n46703\n46709\n46712\n46714\n46716\n46726\n46729\n46730\n46737\n46742\n46744\n46746\n46770\n46777\n46780\n46785\n46788\n46803\n46810\n46813\n46824\n46828\n46829\n46830\n46832\n46839\n46848\n46850\n46852\n46853\n46863\n46867\n46870\n46874\n46881\n46888\n46891\n46897\n46903\n46904\n46913\n46916\n46919\n46923\n46925\n46929\n46934\n46935\n46945\n46948\n46960\n46961\n46963\n46968\n46971\n46972\n46977\n46982\n46987\n46988\n46993\n47001\n47008\n47012\n47013\n47014\n47016\n47018\n47021\n47026\n47032\n47039\n47044\n47055\n47059\n47068\n47072\n47075\n47089\n47103\n47105\n47110\n47118\n47125\n47131\n47132\n47134\n47135\n47137\n47141\n47153\n47154\n47155\n47156\n47160\n47161\n47163\n47164\n47166\n47169\n47181\n47186\n47194\n47195\n47200\n47201\n47202\n47215\n47233\n47248\n47253\n47254\n47257\n47259\n47262\n47263\n47265\n47268\n47273\n47277\n47279\n47282\n47284\n47289\n47292\n47294\n47295\n47297\n47303\n47305\n47306\n47311\n47319\n47320\n47334\n47335\n47338\n47341\n47343\n47345\n47350\n47357\n47360\n47362\n47368\n47369\n47371\n47379\n47392\n47395\n47398\n47407\n47408\n47412\n47426\n47429\n47430\n47433\n47434\n47443\n47459\n47460\n47465\n47470\n47473\n47475\n47480\n47483\n47489\n47493\n47497\n47509\n47510\n47516\n47522\n47541\n47543\n47554\n47568\n47572\n47576\n47582\n47584\n47588\n47589\n47599\n47601\n47603\n47606\n47609\n47619\n47620\n47624\n47628\n47634\n47637\n47638\n47639\n47643\n47645\n47652\n47654\n47656\n47665\n47666\n47668\n47676\n47679\n47681\n47691\n47700\n47706\n47708\n47709\n47726\n47731\n47749\n47755\n47757\n47761\n47764\n47767\n47769\n47773\n47776\n47783\n47788\n47794\n47804\n47809\n47812\n47813\n47816\n47821\n47828\n47841\n47855\n47868\n47870\n47872\n47875\n47877\n47880\n47882\n47885\n47887\n47889\n47895\n47901\n47907\n47911\n47912\n47915\n47938\n47940\n47942\n47958\n47969\n47976\n47978\n47981\n47982\n47984\n47990\n47992\n47996\n47999\n48001\n48009\n48014\n48018\n48019\n48031\n48037\n48043\n48059\n48064\n48066\n48069\n48078\n48079\n48088\n48090\n48100\n48108\n48113\n48115\n48120\n48121\n48138\n48141\n48147\n48152\n48154\n48165\n48166\n48171\n48172\n48174\n48183\n48187\n48194\n48195\n48200\n48202\n48203\n48204\n48206\n48210\n48211\n48216\n48219\n48222\n48224\n48228\n48231\n48232\n48246\n48247\n48251\n48254\n48255\n48269\n48271\n48283\n48284\n48288\n48295\n48296\n48298\n48301\n48303\n48314\n48319\n48325\n48328\n48329\n48335\n48346\n48352\n48353\n48359\n48364\n48370\n48382\n48387\n48390\n48398\n48405\n48406\n48414\n48420\n48430\n48431\n48435\n48437\n48439\n48445\n48446\n48451\n48452\n48453\n48454\n48460\n48464\n48465\n48467\n48477\n48482\n48484\n48489\n48493\n48494\n48499\n48501\n48503\n48517\n48519\n48525\n48526\n48529\n48530\n48535\n48576\n48592\n48594\n48630\n48633\n48636\n48638\n48639\n48645\n48646\n48647\n48656\n48663\n48664\n48669\n48672\n48677\n48681\n48683\n48689\n48690\n48694\n48704\n48712\n48736\n48738\n48740\n48741\n48742\n48757\n48760\n48764\n48770\n48771\n48773\n48775\n48776\n48797\n48798\n48800\n48803\n48809\n48810\n48817\n48820\n48828\n48834\n48839\n48840\n48842\n48852\n48860\n48863\n48868\n48870\n48882\n48883\n48886\n48889\n48890\n48899\n48900\n48904\n48906\n48908\n48910\n48911\n48913\n48916\n48923\n48928\n48931\n48935\n48940\n48952\n48958\n48960\n48961\n48966\n48967\n48970\n48973\n48976\n48977\n48984\n48992\n48996\n49009\n49010\n49014\n49028\n49033\n49046\n49048\n49050\n49060\n49064\n49068\n49071\n49089\n49096\n49097\n49103\n49111\n49118\n49120\n49123\n49129\n49134\n49135\n49149\n49157\n49160\n49163\n49165\n49173\n49185\n49192\n49193\n49197\n49200\n49215\n49217\n49227\n49229\n49236\n49238\n49242\n49243\n49248\n49256\n49261\n49265\n49266\n49270\n49272\n49273\n49275\n49277\n49280\n49283\n49296\n49301\n49302\n49303\n49304\n49306\n49324\n49325\n49330\n49334\n49335\n49341\n49342\n49344\n49345\n49347\n49350\n49361\n49367\n49369\n49371\n49372\n49375\n49377\n49379\n49381\n49392\n49394\n49398\n49406\n49409\n49420\n49427\n49431\n49432\n49442\n49450\n49452\n49454\n49457\n49458\n49467\n49488\n49489\n49498\n49505\n49508\n49512\n49518\n49521\n49522\n49524\n49526\n49537\n49550\n49553\n49557\n49561\n49565\n49568\n49571\n49574\n49582\n49585\n49617\n49623\n49635\n49637\n49638\n49640\n49648\n49649\n49663\n49665\n49666\n49667\n49675\n49678\n49688\n49692\n49693\n49698\n49700\n49702\n49709\n49713\n49716\n49747\n49748\n49752\n49757\n49763\n49767\n49768\n49770\n49773\n49774\n49775\n49780\n49785\n49793\n49795\n49798\n49803\n49811\n49813\n49828\n49834\n49841\n49843\n49845\n49851\n49855\n49857\n49862\n49875\n49882\n49889\n49905\n49908\n49911\n49912\n49914\n49917\n49918\n49921\n49923\n49933\n49935\n49936\n49950\n49957\n49958\n49959\n49967\n49975\n49998\n50003\n50005\n50012\n50013\n50017\n50037\n50040\n50045\n50047\n50051\n50059\n50060\n50064\n50065\n50070\n50071\n50083\n50084\n50092\n50096\n50111\n50112\n50124\n50136\n50138\n50139\n50140\n50152\n50167\n50172\n50197\n50203\n50211\n50213\n50222\n50224\n50231\n50234\n50238\n50241\n50245\n50248\n50249\n50254\n50289\n50291\n50292\n50298\n50301\n50306\n50309\n50313\n50333\n50337\n50342\n50359\n50360\n50364\n50371\n50377\n50378\n50382\n50384\n50394\n50396\n50400\n50407\n50409\n50425\n50437\n50441\n50443\n50446\n50447\n50448\n50453\n50454\n50455\n50457\n50464\n50465\n50468\n50469\n50474\n50477\n50479\n50483\n50484\n50485\n50486\n50490\n50496\n50499\n50502\n50504\n50514\n50519\n50521\n50527\n50531\n50540\n50544\n50553\n50554\n50561\n50568\n50574\n50577\n50578\n50584\n50591\n50594\n50602\n50608\n50611\n50614\n50618\n50621\n50622\n50625\n50627\n50634\n50635\n50636\n50641\n50644\n50650\n50658\n50661\n50673\n50674\n50679\n50681\n50691\n50692\n50694\n50696\n50703\n50714\n50719\n50724\n50728\n50732\n50735\n50737\n50738\n50739\n50749\n50754\n50760\n50761\n50763\n50765\n50767\n50777\n50782\n50792\n50795\n50807\n50811\n50814\n50815\n50816\n50818\n50830\n50838\n50846\n50852\n50854\n50860\n50874\n50877\n50886\n50896\n50897\n50900\n50903\n50909\n50915\n50918\n50930\n50935\n50939\n50941\n50942\n50944\n50950\n50954\n50961\n50970\n50973\n50974\n50979\n50985\n50993\n50995\n50998\n51003\n51004\n51013\n51015\n51018\n51025\n51026\n51027\n51036\n51038\n51040\n51043\n51047\n51051\n51058\n51065\n51067\n51083\n51086\n51087\n51088\n51092\n51098\n51103\n51112\n51114\n51124\n51138\n51142\n51151\n51152\n51155\n51157\n51159\n51178\n51179\n51180\n51188\n51196\n51219\n51224\n51226\n51228\n51236\n51245\n51249\n51261\n51264\n51266\n51274\n51289\n51292\n51295\n51304\n51305\n51306\n51316\n51320\n51321\n51330\n51337\n51339\n51342\n51344\n51347\n51349\n51353\n51359\n51376\n51377\n51384\n51396\n51399\n51400\n51402\n51406\n51408\n51412\n51419\n51420\n51425\n51426\n51430\n51450\n51452\n51454\n51455\n51458\n51459\n51467\n51471\n51472\n51477\n51491\n51493\n51498\n51500\n51503\n51510\n51515\n51520\n51523\n51525\n51535\n51544\n51548\n51549\n51553\n51560\n51565\n51570\n51572\n51574\n51592\n51610\n51627\n51638\n51651\n51653\n51661\n51664\n51674\n51676\n51712\n51713\n51719\n51720\n51727\n51738\n51739\n51742\n51746\n51751\n51768\n51771\n51782\n51785\n51787\n51795\n51803\n51806\n51811\n51826\n51831\n51832\n51839\n51840\n51847\n51854\n51857\n51858\n51867\n51872\n51877\n51878\n51884\n51886\n51889\n51891\n51895\n51897\n51901\n51905\n51909\n51915\n51927\n51931\n51932\n51934\n51938\n51939\n51943\n51964\n51968\n51974\n51976\n51979\n51982\n51988\n51990\n52012\n52014\n52015\n52019\n52023\n52024\n52025\n52026\n52029\n52050\n52051\n52054\n52063\n52066\n52068\n52071\n52074\n52078\n52082\n52083\n52088\n52094\n52101\n52124\n52133\n52143\n52155\n52157\n52158\n52162\n52163\n52164\n52166\n52179\n52181\n52189\n52195\n52196\n52198\n52200\n52205\n52209\n52213\n52216\n52220\n52223\n52225\n52228\n52234\n52236\n52245\n52261\n52263\n52274\n52275\n52281\n52285\n52286\n52289\n52290\n52293\n52296\n52299\n52303\n52316\n52326\n52332\n52335\n52341\n52343\n52346\n52348\n52349\n52353\n52355\n52359\n52363\n52372\n52375\n52376\n52395\n52398\n52403\n52410\n52417\n52425\n52427\n52432\n52435\n52436\n52441\n52444\n52445\n52448\n52451\n52459\n52461\n52466\n52475\n52476\n52496\n52497\n52500\n52503\n52505\n52506\n52508\n52509\n52510\n52515\n52520\n52524\n52526\n52535\n52549\n52560\n52562\n52574\n52578\n52587\n52598\n52599\n52603\n52604\n52611\n52612\n52619\n52627\n52631\n52635\n52636\n52637\n52652\n52661\n52671\n52673\n52675\n52685\n52694\n52701\n52723\n52730\n52740\n52741\n52753\n52759\n52760\n52764\n52771\n52777\n52779\n52796\n52798\n52800\n52812\n52813\n52832\n52834\n52840\n52844\n52845\n52848\n52859\n52864\n52867\n52874\n52875\n52876\n52877\n52878\n52881\n52884\n52889\n52896\n52924\n52931\n52935\n52943\n52950\n52951\n52952\n52956\n52968\n52970\n52973\n52978\n52986\n52992\n52994\n53001\n53004\n53008\n53020\n53030\n53032\n53033\n53034\n53036\n53037\n53044\n53046\n53056\n53070\n53079\n53090\n53092\n53096\n53099\n53107\n53115\n53119\n53121\n53127\n53136\n53139\n53142\n53154\n53160\n53163\n53171\n53176\n53193\n53208\n53210\n53215\n53217\n53219\n53220\n53221\n53238\n53240\n53246\n53247\n53248\n53252\n53253\n53254\n53260\n53262\n53264\n53267\n53272\n53284\n53288\n53295\n53299\n53303\n53318\n53334\n53335\n53356\n53360\n53361\n53365\n53366\n53369\n53371\n53374\n53375\n53397\n53404\n53407\n53412\n53415\n53421\n53425\n53429\n53435\n53437\n53448\n53456\n53463\n53466\n53472\n53477\n53483\n53487\n53488\n53489\n53496\n53497\n53501\n53510\n53514\n53520\n53528\n53530\n53531\n53535\n53538\n53539\n53540\n53544\n53545\n53554\n53569\n53575\n53578\n53584\n53585\n53587\n53588\n53598\n53599\n53607\n53610\n53611\n53624\n53627\n53632\n53645\n53646\n53651\n53657\n53658\n53661\n53663\n53664\n53670\n53677\n53685\n53707\n53710\n53711\n53717\n53728\n53747\n53756\n53767\n53769\n53770\n53771\n53773\n53774\n53780\n53788\n53790\n53793\n53804\n53814\n53818\n53822\n53834\n53840\n53844\n53846\n53849\n53856\n53862\n53869\n53879\n53882\n53883\n53891\n53892\n53893\n53905\n53907\n53912\n53916\n53924\n53927\n53930\n53931\n53942\n53945\n53950\n53952\n53953\n53957\n53965\n53972\n53973\n53977\n53979\n53984\n53987\n53999\n54002\n54003\n54009\n54010\n54021\n54023\n54030\n54035\n54039\n54043\n54051\n54052\n54054\n54056\n54061\n54065\n54066\n54069\n54075\n54077\n54082\n54087\n54089\n54091\n54094\n54098\n54114\n54120\n54127\n54139\n54144\n54153\n54154\n54160\n54164\n54171\n54186\n54193\n54194\n54200\n54204\n54205\n54206\n54213\n54220\n54222\n54223\n54224\n54229\n54230\n54235\n54236\n54244\n54248\n54251\n54265\n54268\n54279\n54286\n54295\n54296\n54298\n54299\n54300\n54302\n54305\n54310\n54311\n54316\n54317\n54318\n54321\n54323\n54328\n54330\n54336\n54343\n54346\n54350\n54351\n54353\n54361\n54363\n54380\n54385\n54387\n54388\n54391\n54404\n54408\n54430\n54439\n54442\n54445\n54446\n54454\n54455\n54456\n54469\n54470\n54483\n54488\n54502\n54504\n54515\n54518\n54522\n54523\n54524\n54527\n54530\n54552\n54554\n54561\n54565\n54576\n54580\n54583\n54584\n54588\n54589\n54590\n54594\n54595\n54598\n54600\n54607\n54616\n54624\n54625\n54629\n54631\n54638\n54643\n54649\n54665\n54669\n54679\n54685\n54688\n54690\n54699\n54703\n54706\n54707\n54710\n54719\n54723\n54724\n54730\n54731\n54734\n54737\n54741\n54744\n54745\n54748\n54752\n54759\n54771\n54779\n54780\n54784\n54789\n54790\n54801\n54806\n54807\n54810\n54814\n54818\n54827\n54837\n54841\n54846\n54848\n54850\n54852\n54866\n54868\n54877\n54887\n54888\n54901\n54907\n54912\n54921\n54925\n54926\n54941\n54942\n54947\n54955\n54957\n54958\n54963\n54967\n54973\n54974\n54976\n54981\n54983\n54988\n54990\n54994\n54996\n54998\n55003\n55004\n55008\n55009\n55012\n55017\n55018\n55019\n55024\n55028\n55029\n55041\n55043\n55058\n55060\n55063\n55064\n55065\n55070\n55072\n55073\n55075\n55084\n55098\n55103\n55107\n55112\n55114\n55119\n55126\n55127\n55131\n55136\n55137\n55151\n55159\n55163\n55171\n55183\n55185\n55189\n55193\n55200\n55203\n55209\n55210\n55211\n55212\n55213\n55215\n55217\n55223\n55228\n55234\n55239\n55243\n55247\n55251\n55254\n55255\n55262\n55265\n55273\n55274\n55275\n55295\n55307\n55309\n55314\n55315\n55318\n55328\n55329\n55330\n55342\n55361\n55362\n55369\n55373\n55376\n55380\n55383\n55384\n55387\n55388\n55392\n55407\n55408\n55414\n55421\n55422\n55423\n55426\n55427\n55438\n55441\n55447\n55448\n55462\n55480\n55481\n55485\n55490\n55505\n55518\n55521\n55524\n55535\n55538\n55540\n55541\n55543\n55545\n55550\n55564\n55568\n55577\n55591\n55598\n55602\n55605\n55616\n55620\n55621\n55631\n55639\n55644\n55647\n55655\n55663\n55668\n55678\n55684\n55699\n55703\n55706\n55709\n55724\n55729\n55738\n55741\n55742\n55752\n55758\n55759\n55768\n55772\n55773\n55775\n55778\n55798\n55809\n55824\n55827\n55839\n55844\n55848\n55851\n55853\n55869\n55872\n55877\n55882\n55883\n55891\n55892\n55893\n55897\n55911\n55921\n55924\n55925\n55926\n55929\n55938\n55942\n55945\n55946\n55947\n55953\n55959\n55965\n55971\n55983\n55987\n56001\n56002\n56003\n56008\n56020\n56029\n56032\n56033\n56039\n56041\n56044\n56054\n56065\n56071\n56072\n56079\n56086\n56094\n56095\n56097\n56102\n56106\n56119\n56122\n56124\n56126\n56127\n56130\n56137\n56144\n56148\n56149\n56160\n56170\n56182\n56187\n56188\n56203\n56214\n56216\n56217\n56218\n56221\n56227\n56228\n56233\n56238\n56244\n56248\n56255\n56260\n56275\n56276\n56286\n56300\n56304\n56307\n56310\n56311\n56314\n56318\n56326\n56332\n56347\n56352\n56355\n56359\n56366\n56367\n56370\n56374\n56378\n56384\n56388\n56390\n56395\n56398\n56400\n56409\n56414\n56415\n56416\n56421\n56441\n56443\n56449\n56477\n56478\n56480\n56483\n56485\n56490\n56494\n56498\n56509\n56510\n56513\n56514\n56515\n56522\n56523\n56526\n56530\n56532\n56537\n56543\n56545\n56555\n56563\n56568\n56579\n56596\n56598\n56609\n56610\n56614\n56632\n56633\n56644\n56658\n56659\n56666\n56672\n56676\n56683\n56684\n56696\n56697\n56703\n56710\n56716\n56717\n56718\n56723\n56724\n56728\n56734\n56738\n56739\n56741\n56742\n56748\n56756\n56757\n56765\n56767\n56768\n56772\n56774\n56778\n56779\n56782\n56788\n56799\n56804\n56808\n56816\n56818\n56820\n56828\n56834\n56839\n56852\n56874\n56883\n56884\n56888\n56889\n56893\n56903\n56931\n56934\n56936\n56942\n56947\n56948\n56949\n56952\n56955\n56956\n56970\n56975\n56994\n56997\n56999\n57001\n57006\n57018\n57021\n57023\n57027\n57038\n57039\n57045\n57046\n57049\n57052\n57056\n57061\n57068\n57071\n57075\n57082\n57087\n57091\n57093\n57096\n57102\n57103\n57106\n57114\n57118\n57121\n57124\n57126\n57128\n57138\n57149\n57152\n57155\n57160\n57168\n57182\n57183\n57189\n57191\n57195\n57199\n57202\n57213\n57214\n57215\n57227\n57232\n57234\n57237\n57243\n57245\n57248\n57249\n57252\n57255\n57256\n57262\n57263\n57264\n57265\n57267\n57270\n57274\n57285\n57289\n57294\n57295\n57303\n57305\n57310\n57312\n57314\n57329\n57336\n57346\n57347\n57353\n57359\n57362\n57366\n57367\n57372\n57374\n57375\n57376\n57384\n57385\n57391\n57395\n57397\n57403\n57405\n57409\n57410\n57414\n57415\n57417\n57426\n57428\n57434\n57440\n57443\n57445\n57455\n57460\n57481\n57482\n57491\n57493\n57497\n57498\n57504\n57515\n57517\n57518\n57520\n57526\n57530\n57547\n57555\n57561\n57568\n57570\n57593\n57595\n57606\n57608\n57609\n57614\n57629\n57633\n57636\n57638\n57642\n57650\n57657\n57659\n57661\n57674\n57688\n57696\n57718\n57720\n57726\n57728\n57729\n57733\n57738\n57746\n57747\n57753\n57757\n57759\n57760\n57761\n57767\n57769\n57770\n57771\n57774\n57775\n57786\n57787\n57788\n57804\n57805\n57807\n57810\n57812\n57815\n57817\n57819\n57820\n57821\n57826\n57829\n57830\n57835\n57839\n57843\n57845\n57847\n57848\n57857\n57861\n57863\n57864\n57877\n57878\n57880\n57887\n57894\n57906\n57909\n57926\n57936\n57939\n57942\n57945\n57946\n57948\n57950\n57963\n57969\n57972\n57985\n58005\n58009\n58010\n58015\n58016\n58018\n58025\n58030\n58033\n58035\n58040\n58049\n58070\n58071\n58077\n58082\n58083\n58090\n58097\n58104\n58115\n58129\n58131\n58135\n58137\n58138\n58141\n58143\n58144\n58153\n58158\n58160\n58164\n58166\n58174\n58175\n58181\n58190\n58196\n58199\n58205\n58211\n58218\n58220\n58229\n58230\n58233\n58246\n58247\n58250\n58255\n58259\n58260\n58262\n58264\n58265\n58266\n58271\n58272\n58276\n58287\n58289\n58291\n58293\n58302\n58309\n58311\n58312\n58322\n58324\n58341\n58343\n58364\n58367\n58371\n58376\n58379\n58381\n58389\n58398\n58405\n58411\n58413\n58415\n58426\n58429\n58431\n58436\n58438\n58440\n58449\n58451\n58464\n58465\n58467\n58471\n58472\n58503\n58506\n58513\n58514\n58520\n58523\n58529\n58530\n58538\n58544\n58545\n58546\n58548\n58563\n58568\n58574\n58575\n58577\n58589\n58593\n58600\n58602\n58603\n58622\n58624\n58636\n58650\n58657\n58659\n58664\n58665\n58666\n58667\n58669\n58676\n58678\n58679\n58687\n58695\n58696\n58701\n58703\n58710\n58716\n58720\n58724\n58725\n58736\n58745\n58754\n58758\n58770\n58771\n58774\n58778\n58780\n58783\n58784\n58787\n58800\n58801\n58802\n58803\n58804\n58807\n58822\n58835\n58837\n58838\n58839\n58843\n58847\n58855\n58856\n58857\n58858\n58861\n58863\n58872\n58874\n58878\n58886\n58888\n58890\n58903\n58908\n58909\n58928\n58932\n58936\n58941\n58947\n58958\n58959\n58965\n58986\n58988\n58989\n59000\n59001\n59008\n59011\n59016\n59027\n59041\n59042\n59044\n59046\n59057\n59068\n59072\n59073\n59084\n59085\n59097\n59105\n59111\n59112\n59113\n59118\n59122\n59123\n59126\n59127\n59135\n59142\n59143\n59146\n59147\n59152\n59155\n59158\n59162\n59164\n59170\n59176\n59180\n59183\n59191\n59195\n59200\n59203\n59204\n59207\n59209\n59211\n59214\n59215\n59226\n59234\n59245\n59251\n59252\n59254\n59267\n59269\n59286\n59293\n59294\n59296\n59303\n59308\n59312\n59314\n59316\n59322\n59324\n59334\n59338\n59339\n59345\n59347\n59353\n59355\n59356\n59366\n59368\n59374\n59386\n59392\n59395\n59411\n59412\n59421\n59424\n59425\n59427\n59430\n59432\n59441\n59444\n59446\n59449\n59459\n59461\n59464\n59465\n59481\n59487\n59500\n59502\n59507\n59510\n59522\n59524\n59525\n59528\n59539\n59540\n59542\n59579\n59580\n59589\n59596\n59600\n59605\n59608\n59610\n59611\n59614\n59616\n59618\n59624\n59633\n59634\n59641\n59649\n59651\n59652\n59654\n59656\n59658\n59660\n59662\n59675\n59676\n59685\n59694\n59700\n59701\n59704\n59711\n59722\n59726\n59727\n59728\n59729\n59736\n59740\n59742\n59747\n59749\n59756\n59757\n59759\n59762\n59763\n59764\n59768\n59783\n59797\n59798\n59799\n59805\n59814\n59816\n59821\n59825\n59838\n59839\n59844\n59854\n59857\n59866\n59868\n59874\n59878\n59898\n59914\n59917\n59920\n59922\n59934\n59936\n59937\n59948\n59950\n59954\n59956\n59958\n59960\n59967\n59969\n59980\n59981\n59989\n59995\n60005\n60006\n60011\n60015\n60017\n60029\n60033\n60043\n60051\n60054\n60061\n60062\n60070\n60080\n60085\n60088\n60093\n60098\n60116\n60117\n60118\n60119\n60124\n60125\n60127\n60131\n60145\n60153\n60154\n60158\n60163\n60166\n60169\n60170\n60173\n60181\n60199\n60205\n60206\n60215\n60220\n60224\n60231\n60232\n60233\n60236\n60240\n60243\n60244\n60254\n60256\n60261\n60271\n60274\n60290\n60293\n60294\n60298\n60309\n60310\n60312\n60320\n60322\n60323\n60324\n60332\n60339\n60364\n60377\n60383\n60384\n60396\n60397\n60404\n60414\n60419\n60421\n60422\n60433\n60434\n60443\n60450\n60454\n60457\n60461\n60474\n60482\n60496\n60500\n60504\n60505\n60508\n60510\n60517\n60525\n60526\n60527\n60532\n60535\n60536\n60540\n60546\n60547\n60552\n60559\n60568\n60578\n60597\n60599\n60607\n60610\n60611\n60623\n60624\n60635\n60640\n60646\n60651\n60664\n60667\n60668\n60674\n60679\n60680\n60691\n60695\n60701\n60704\n60712\n60718\n60720\n60724\n60731\n60732\n60737\n60739\n60742\n60744\n60751\n60754\n60765\n60769\n60772\n60773\n60779\n60780\n60789\n60791\n60792\n60814\n60817\n60826\n60831\n60834\n60840\n60844\n60845\n60847\n60848\n60849\n60850\n60855\n60856\n60864\n60865\n60866\n60875\n60882\n60885\n60886\n60903\n60912\n60924\n60928\n60930\n60933\n60951\n60959\n60961\n60964\n60965\n60966\n60972\n60976\n60980\n60982\n60986\n60987\n60990\n60991\n60993\n60994\n60998\n61006\n61017\n61022\n61024\n61029\n61032\n61036\n61039\n61045\n61057\n61074\n61075\n61078\n61079\n61089\n61099\n61108\n61115\n61124\n61125\n61126\n61138\n61149\n61150\n61156\n61157\n61164\n61173\n61175\n61179\n61190\n61191\n61194\n61207\n61211\n61216\n61218\n61219\n61224\n61225\n61226\n61229\n61239\n61252\n61253\n61269\n61270\n61273\n61274\n61275\n61277\n61282\n61286\n61291\n61295\n61299\n61306\n61307\n61329\n61342\n61346\n61351\n61352\n61362\n61377\n61379\n61384\n61396\n61399\n61409\n61421\n61428\n61430\n61442\n61451\n61452\n61460\n61461\n61465\n61467\n61471\n61474\n61480\n61481\n61504\n61506\n61507\n61522\n61524\n61526\n61529\n61530\n61534\n61543\n61546\n61550\n61551\n61552\n61556\n61560\n61562\n61565\n61567\n61569\n61570\n61571\n61584\n61588\n61600\n61603\n61606\n61607\n61609\n61617\n61629\n61631\n61633\n61636\n61643\n61645\n61654\n61657\n61658\n61659\n61661\n61664\n61667\n61677\n61680\n61682\n61686\n61697\n61703\n61704\n61724\n61725\n61731\n61740\n61752\n61761\n61765\n61770\n61771\n61772\n61782\n61788\n61797\n61807\n61814\n61826\n61842\n61849\n61852\n61853\n61857\n61864\n61870\n61876\n61878\n61891\n61895\n61898\n61900\n61906\n61914\n61915\n61917\n61919\n61930\n61935\n61936\n61937\n61938\n61941\n61943\n61945\n61947\n61948\n61951\n61953\n61957\n61960\n61961\n61965\n61966\n61969\n61976\n61982\n61985\n61994\n61998\n61999\n62010\n62013\n62022\n62027\n62040\n62051\n62057\n62058\n62059\n62060\n62061\n62062\n62064\n62068\n62074\n62083\n62090\n62102\n62113\n62117\n62122\n62132\n62154\n62159\n62162\n62164\n62182\n62183\n62188\n62190\n62195\n62202\n62216\n62227\n62229\n62234\n62239\n62245\n62250\n62254\n62267\n62271\n62274\n62279\n62280\n62284\n62295\n62296\n62298\n62299\n62303\n62320\n62322\n62328\n62334\n62336\n62345\n62358\n62362\n62365\n62366\n62367\n62372\n62376\n62379\n62383\n62389\n62391\n62400\n62407\n62410\n62424\n62429\n62434\n62441\n62447\n62448\n62449\n62456\n62460\n62462\n62468\n62478\n62483\n62484\n62485\n62505\n62516\n62517\n62531\n62533\n62535\n62540\n62541\n62544\n62551\n62552\n62556\n62557\n62570\n62575\n62583\n62591\n62592\n62596\n62601\n62604\n62611\n62621\n62624\n62647\n62652\n62657\n62668\n62670\n62681\n62692\n62694\n62696\n62697\n62699\n62709\n62716\n62718\n62719\n62721\n62723\n62726\n62730\n62734\n62735\n62739\n62741\n62746\n62749\n62759\n62761\n62763\n62764\n62770\n62791\n62796\n62799\n62808\n62809\n62815\n62821\n62829\n62834\n62840\n62841\n62879\n62895\n62910\n62912\n62920\n62921\n62924\n62931\n62933\n62935\n62939\n62941\n62942\n62951\n62953\n62954\n62966\n62973\n62983\n62985\n62993\n62999\n63002\n63003\n63005\n63009\n63011\n63012\n63016\n63017\n63019\n63038\n63041\n63045\n63048\n63050\n63051\n63058\n63062\n63069\n63072\n63078\n63089\n63092\n63093\n63098\n63102\n63103\n63105\n63108\n63116\n63117\n63132\n63138\n63143\n63146\n63148\n63150\n63156\n63168\n63174\n63188\n63198\n63200\n63201\n63209\n63211\n63216\n63220\n63229\n63231\n63235\n63239\n63248\n63253\n63261\n63265\n63270\n63272\n63275\n63281\n63288\n63290\n63292\n63293\n63306\n63322\n63343\n63351\n63357\n63367\n63370\n63373\n63381\n63385\n63392\n63394\n63395\n63396\n63401\n63402\n63408\n63411\n63419\n63422\n63426\n63427\n63430\n63431\n63436\n63437\n63441\n63444\n63445\n63453\n63459\n63465\n63481\n63482\n63490\n63498\n63502\n63504\n63513\n63515\n63518\n63521\n63531\n63532\n63533\n63537\n63544\n63550\n63554\n63558\n63560\n63561\n63568\n63569\n63570\n63574\n63578\n63580\n63591\n63592\n63594\n63598\n63603\n63608\n63615\n63617\n63625\n63626\n63627\n63629\n63633\n63638\n63640\n63661\n63663\n63671\n63673\n63683\n63690\n63694\n63700\n63705\n63707\n63708\n63713\n63718\n63719\n63720\n63724\n63737\n63740\n63742\n63753\n63755\n63761\n63762\n63765\n63767\n63768\n63772\n63776\n63780\n63783\n63792\n63794\n63804\n63807\n63828\n63836\n63844\n63850\n63854\n63855\n63858\n63866\n63867\n63869\n63871\n63876\n63878\n63879\n63880\n63882\n63884\n63885\n63892\n63898\n63911\n63913\n63915\n63917\n63918\n63925\n63926\n63927\n63930\n63931\n63940\n63947\n63953\n63954\n63959\n63970\n63972\n63980\n63982\n63989\n64006\n64014\n64017\n64022\n64023\n64027\n64032\n64034\n64037\n64040\n64046\n64057\n64058\n64059\n64064\n64065\n64076\n64088\n64092\n64096\n64099\n64103\n64105\n64107\n64111\n64117\n64121\n64124\n64131\n64133\n64141\n64144\n64150\n64154\n64155\n64159\n64175\n64177\n64179\n64183\n64184\n64189\n64193\n64194\n64196\n64205\n64209\n64210\n64225\n64226\n64228\n64237\n64241\n64243\n64248\n64254\n64258\n64264\n64267\n64284\n64285\n64291\n64300\n64302\n64303\n64307\n64308\n64315\n64317\n64319\n64321\n64327\n64332\n64343\n64348\n64355\n64360\n64362\n64365\n64371\n64373\n64379\n64381\n64383\n64385\n64391\n64394\n64397\n64400\n64404\n64408\n64414\n64416\n64424\n64428\n64431\n64432\n64442\n64449\n64459\n64461\n64462\n64463\n64464\n64468\n64478\n64487\n64488\n64489\n64495\n64497\n64506\n64512\n64513\n64516\n64521\n64528\n64532\n64533\n64536\n64538\n64543\n64545\n64551\n64559\n64562\n64563\n64568\n64570\n64574\n64578\n64579\n64587\n64591\n64596\n64604\n64605\n64607\n64615\n64619\n64623\n64640\n64642\n64644\n64645\n64651\n64658\n64679\n64692\n64694\n64696\n64707\n64722\n64726\n64731\n64733\n64736\n64741\n64754\n64756\n64765\n64767\n64784\n64785\n64789\n64792\n64794\n64803\n64812\n64819\n64823\n64830\n64842\n64844\n64852\n64853\n64855\n64858\n64864\n64867\n64871\n64880\n64883\n64885\n64888\n64894\n64900\n64901\n64910\n64915\n64944\n64945\n64946\n64955\n64962\n64964\n64967\n64974\n64986\n64987\n64990\n64996\n64998\n65004\n65006\n65015\n65024\n65031\n65040\n65043\n65055\n65061\n65063\n65064\n65068\n65069\n65071\n65072\n65074\n65075\n65079\n65080\n65082\n65086\n65093\n65095\n65098\n65100\n65101\n65147\n65152\n65156\n65161\n65162\n65164\n65174\n65175\n65176\n65180\n65183\n65184\n65186\n65188\n65195\n65196\n65201\n65202\n65203\n65205\n65211\n65212\n65213\n65216\n65221\n65227\n65241\n65249\n65259\n65263\n65265\n65267\n65273\n65275\n65277\n65279\n65281\n65284\n65285\n65294\n65297\n65299\n65301\n65303\n65306\n65309\n65312\n65320\n65325\n65329\n65338\n65347\n65350\n65370\n65371\n65376\n65383\n65394\n65396\n65401\n65402\n65405\n65412\n65415\n65432\n65434\n65443\n65451\n65456\n65457\n65474\n65476\n65478\n65485\n65486\n65494\n65495\n65496\n65497\n65498\n65508\n65515\n65516\n65518\n65520\n65527\n65531\n65532\n65534\n65536\n65541\n65542\n65547\n65548\n65551\n65556\n65557\n65560\n65561\n65565\n65569\n65571\n65573\n65580\n65581\n65583\n65588\n65593\n65602\n65608\n65610\n65619\n65632\n65636\n65638\n65643\n65662\n65670\n65675\n65676\n65677\n65683\n65688\n65692\n65693\n65694\n65695\n65700\n65707\n65711\n65712\n65716\n65718\n65738\n65746\n65769\n65784\n65791\n65800\n65810\n65814\n65816\n65824\n65829\n65842\n65850\n65852\n65854\n65858\n65860\n65863\n65867\n65871\n65880\n65883\n65884\n65887\n65893\n65895\n65898\n65903\n65906\n65910\n65911\n65921\n65923\n65951\n65953\n65954\n65961\n65967\n65973\n65978\n65981\n65994\n66009\n66012\n66013\n66020\n66027\n66033\n66036\n66042\n66044\n66047\n66050\n66059\n66063\n66066\n66071\n66073\n66077\n66078\n66086\n66089\n66092\n66099\n66101\n66107\n66120\n66128\n66129\n66131\n66143\n66145\n66147\n66159\n66162\n66164\n66169\n66185\n66190\n66198\n66200\n66210\n66216\n66226\n66230\n66234\n66238\n66241\n66247\n66249\n66253\n66254\n66255\n66261\n66264\n66273\n66283\n66286\n66288\n66291\n66301\n66305\n66317\n66325\n66332\n66338\n66339\n66343\n66351\n66355\n66362\n66373\n66374\n66375\n66379\n66393\n66395\n66404\n66409\n66410\n66419\n66421\n66422\n66423\n66433\n66436\n66444\n66453\n66457\n66463\n66485\n66488\n66489\n66492\n66494\n66511\n66513\n66519\n66520\n66521\n66526\n66530\n66533\n66534\n66554\n66557\n66565\n66578\n66591\n66595\n66600\n66607\n66611\n66621\n66627\n66631\n66642\n66647\n66660\n66662\n66664\n66682\n66685\n66687\n66689\n66690\n66694\n66704\n66706\n66711\n66715\n66718\n66720\n66722\n66723\n66731\n66734\n66743\n66765\n66772\n66773\n66774\n66775\n66777\n66781\n66785\n66786\n66796\n66797\n66808\n66810\n66817\n66823\n66827\n66828\n66838\n66845\n66846\n66850\n66858\n66873\n66877\n66884\n66885\n66889\n66910\n66914\n66920\n66921\n66925\n66926\n66932\n66934\n66936\n66938\n66939\n66940\n66947\n66956\n66965\n66966\n66974\n66975\n66982\n66983\n66985\n66986\n66992\n66999\n67019\n67028\n67033\n67037\n67045\n67051\n67053\n67054\n67061\n67065\n67067\n67068\n67080\n67088\n67089\n67090\n67091\n67092\n67100\n67105\n67115\n67117\n67127\n67133\n67135\n67168\n67172\n67181\n67183\n67200\n67215\n67220\n67222\n67225\n67228\n67239\n67258\n67263\n67281\n67284\n67289\n67293\n67308\n67312\n67327\n67333\n67334\n67343\n67353\n67358\n67359\n67363\n67365\n67389\n67394\n67395\n67412\n67416\n67417\n67426\n67439\n67440\n67447\n67451\n67456\n67457\n67459\n67460\n67461\n67463\n67468\n67470\n67475\n67476\n67487\n67503\n67512\n67535\n67539\n67549\n67551\n67552\n67558\n67572\n67577\n67582\n67585\n67586\n67590\n67595\n67602\n67603\n67609\n67610\n67612\n67615\n67618\n67628\n67634\n67636\n67640\n67646\n67647\n67655\n67656\n67658\n67669\n67676\n67681\n67683\n67685\n67686\n67687\n67689\n67695\n67701\n67704\n67706\n67708\n67715\n67718\n67725\n67730\n67737\n67747\n67754\n67758\n67772\n67777\n67787\n67794\n67795\n67796\n67803\n67804\n67805\n67806\n67813\n67814\n67826\n67832\n67847\n67848\n67851\n67856\n67860\n67880\n67888\n67892\n67894\n67902\n67907\n67909\n67911\n67915\n67919\n67925\n67931\n67938\n67945\n67950\n67954\n67960\n67978\n67987\n67988\n67993\n68005\n68007\n68012\n68019\n68023\n68024\n68026\n68032\n68036\n68037\n68042\n68046\n68047\n68048\n68051\n68056\n68058\n68060\n68066\n68067\n68068\n68071\n68075\n68078\n68080\n68093\n68094\n68096\n68098\n68106\n68107\n68110\n68120\n68132\n68146\n68152\n68157\n68159\n68160\n68165\n68166\n68167\n68183\n68186\n68190\n68196\n68198\n68201\n68202\n68204\n68213\n68216\n68217\n68228\n68230\n68233\n68246\n68247\n68263\n68264\n68273\n68275\n68283\n68289\n68304\n68307\n68319\n68333\n68334\n68335\n68340\n68343\n68344\n68345\n68348\n68351\n68355\n68356\n68358\n68360\n68363\n68368\n68369\n68379\n68383\n68385\n68388\n68400\n68411\n68413\n68416\n68417\n68424\n68428\n68429\n68435\n68443\n68445\n68447\n68451\n68453\n68454\n68455\n68456\n68458\n68475\n68476\n68485\n68487\n68494\n68498\n68506\n68514\n68548\n68550\n68564\n68566\n68573\n68578\n68580\n68590\n68591\n68593\n68597\n68600\n68602\n68604\n68609\n68621\n68623\n68624\n68626\n68628\n68629\n68633\n68638\n68642\n68652\n68658\n68661\n68663\n68670\n68672\n68678\n68679\n68680\n68681\n68701\n68702\n68716\n68718\n68719\n68720\n68724\n68729\n68730\n68747\n68750\n68751\n68754\n68758\n68774\n68776\n68779\n68784\n68785\n68786\n68790\n68796\n68800\n68801\n68804\n68808\n68810\n68812\n68815\n68821\n68827\n68844\n68845\n68848\n68853\n68858\n68859\n68863\n68867\n68871\n68876\n68883\n68885\n68891\n68892\n68895\n68898\n68899\n68904\n68905\n68908\n68927\n68930\n68936\n68938\n68942\n68945\n68957\n68958\n68963\n68967\n68973\n68975\n68989\n69000\n69005\n69008\n69012\n69016\n69021\n69026\n69028\n69035\n69040\n69042\n69045\n69046\n69048\n69049\n69050\n69058\n69072\n69073\n69074\n69082\n69086\n69089\n69093\n69094\n69113\n69119\n69125\n69126\n69129\n69134\n69142\n69149\n69152\n69156\n69162\n69164\n69167\n69171\n69176\n69180\n69182\n69201\n69213\n69216\n69221\n69233\n69235\n69238\n69241\n69256\n69257\n69258\n69262\n69264\n69268\n69276\n69280\n69282\n69293\n69299\n69300\n69309\n69315\n69326\n69328\n69329\n69334\n69336\n69337\n69339\n69341\n69342\n69348\n69351\n69353\n69362\n69375\n69377\n69380\n69384\n69388\n69389\n69396\n69402\n69408\n69409\n69421\n69423\n69436\n69442\n69444\n69459\n69465\n69469\n69470\n69472\n69474\n69475\n69483\n69487\n69500\n69504\n69508\n69515\n69520\n69521\n69523\n69526\n69537\n69538\n69543\n69547\n69549\n69559\n69562\n69564\n69573\n69574\n69590\n69591\n69601\n69605\n69607\n69619\n69625\n69629\n69631\n69633\n69637\n69650\n69651\n69664\n69665\n69668\n69677\n69681\n69687\n69697\n69699\n69700\n69702\n69708\n69719\n69725\n69731\n69732\n69734\n69740\n69751\n69763\n69767\n69775\n69777\n69783\n69788\n69797\n69798\n69801\n69835\n69844\n69847\n69862\n69868\n69875\n69887\n69889\n69892\n69897\n69906\n69919\n69920\n69923\n69928\n69930\n69932\n69934\n69941\n69946\n69956\n69966\n69975\n69982\n69986\n69990\n69991\n69994\n70004\n70006\n70007\n70012\n70015\n70020\n70027\n70036\n70037\n70054\n70062\n70067\n70072\n70076\n70077\n70079\n70082\n70086\n70089\n70109\n70112\n70116\n70121\n70126\n70132\n70147\n70152\n70155\n70160\n70164\n70167\n70169\n70171\n70183\n70185\n70186\n70191\n70197\n70202\n70204\n70212\n70214\n70225\n70226\n70232\n70234\n70237\n70247\n70248\n70250\n70256\n70262\n70267\n70285\n70292\n70307\n70308\n70310\n70312\n70320\n70324\n70335\n70337\n70339\n70342\n70347\n70349\n70358\n70361\n70363\n70365\n70367\n70373\n70375\n70380\n70389\n70390\n70393\n70395\n70401\n70402\n70406\n70407\n70421\n70425\n70428\n70429\n70430\n70442\n70444\n70445\n70450\n70454\n70462\n70464\n70470\n70481\n70495\n70503\n70513\n70515\n70520\n70522\n70524\n70528\n70529\n70532\n70536\n70538\n70546\n70548\n70551\n70553\n70558\n70560\n70564\n70567\n70578\n70580\n70581\n70582\n70592\n70600\n70601\n70602\n70605\n70609\n70611\n70617\n70621\n70623\n70624\n70626\n70630\n70638\n70643\n70650\n70662\n70664\n70676\n70677\n70679\n70684\n70698\n70702\n70707\n70717\n70718\n70723\n70739\n70741\n70746\n70755\n70757\n70762\n70765\n70772\n70778\n70792\n70793\n70796\n70800\n70802\n70810\n70811\n70818\n70820\n70824\n70834\n70837\n70844\n70848\n70853\n70857\n70864\n70870\n70874\n70876\n70887\n70888\n70892\n70893\n70905\n70912\n70925\n70933\n70954\n70962\n70968\n70972\n70973\n70975\n70987\n71002\n71006\n71012\n71016\n71019\n71023\n71027\n71031\n71038\n71044\n71045\n71054\n71055\n71061\n71063\n71065\n71069\n71075\n71106\n71108\n71114\n71122\n71139\n71141\n71152\n71159\n71161\n71164\n71165\n71170\n71171\n71186\n71195\n71197\n71203\n71204\n71217\n71219\n71228\n71230\n71241\n71253\n71257\n71259\n71266\n71267\n71270\n71276\n71277\n71287\n71288\n71291\n71293\n71297\n71298\n71330\n71331\n71332\n71338\n71349\n71352\n71355\n71367\n71378\n71380\n71381\n71389\n71391\n71394\n71407\n71411\n71416\n71423\n71436\n71441\n71451\n71456\n71457\n71463\n71464\n71470\n71474\n71478\n71481\n71489\n71495\n71496\n71501\n71510\n71512\n71520\n71522\n71525\n71531\n71538\n71544\n71548\n71558\n71567\n71568\n71570\n71572\n71577\n71600\n71602\n71609\n71616\n71622\n71631\n71636\n71644\n71647\n71649\n71651\n71653\n71658\n71660\n71661\n71665\n71676\n71682\n71683\n71685\n71688\n71691\n71695\n71703\n71710\n71721\n71722\n71730\n71731\n71732\n71734\n71740\n71755\n71765\n71768\n71771\n71774\n71787\n71791\n71793\n71799\n71800\n71802\n71805\n71807\n71817\n71818\n71819\n71820\n71821\n71832\n71836\n71837\n71840\n71845\n71852\n71864\n71866\n71870\n71873\n71881\n71888\n71890\n71895\n71898\n71909\n71911\n71913\n71918\n71930\n71936\n71937\n71942\n71945\n71946\n71949\n71953\n71968\n71970\n71973\n71979\n71981\n71983\n71984\n71999\n72004\n72009\n72015\n72019\n72021\n72028\n72029\n72033\n72034\n72051\n72060\n72063\n72073\n72076\n72079\n72080\n72084\n72089\n72093\n72094\n72097\n72098\n72105\n72106\n72110\n72115\n72116\n72118\n72129\n72137\n72146\n72151\n72157\n72165\n72167\n72174\n72188\n72192\n72197\n72198\n72201\n72203\n72205\n72210\n72212\n72227\n72233\n72236\n72244\n72249\n72250\n72259\n72267\n72288\n72292\n72293\n72296\n72299\n72301\n72305\n72316\n72319\n72320\n72327\n72330\n72332\n72335\n72336\n72337\n72338\n72340\n72341\n72349\n72357\n72363\n72367\n72372\n72375\n72377\n72380\n72387\n72389\n72396\n72399\n72404\n72406\n72408\n72411\n72416\n72422\n72428\n72433\n72442\n72446\n72447\n72452\n72459\n72463\n72465\n72468\n72470\n72478\n72482\n72484\n72486\n72495\n72517\n72522\n72529\n72530\n72533\n72535\n72542\n72551\n72574\n72575\n72578\n72583\n72588\n72596\n72605\n72613\n72626\n72635\n72637\n72638\n72641\n72651\n72659\n72660\n72662\n72670\n72673\n72675\n72676\n72685\n72689\n72695\n72698\n72700\n72702\n72704\n72707\n72712\n72715\n72717\n72725\n72727\n72730\n72736\n72738\n72739\n72758\n72762\n72780\n72788\n72789\n72793\n72802\n72806\n72807\n72812\n72813\n72816\n72819\n72822\n72833\n72836\n72838\n72839\n72842\n72843\n72845\n72856\n72857\n72858\n72859\n72867\n72868\n72869\n72870\n72874\n72884\n72888\n72898\n72905\n72909\n72910\n72912\n72917\n72926\n72933\n72935\n72938\n72943\n72954\n72955\n72958\n72965\n72966\n72974\n72976\n72985\n72986\n72992\n72993\n72994\n72995\n73000\n73001\n73010\n73011\n73012\n73014\n73016\n73018\n73022\n73024\n73033\n73034\n73040\n73043\n73048\n73054\n73056\n73059\n73071\n73075\n73080\n73085\n73099\n73106\n73109\n73112\n73119\n73124\n73128\n73129\n73139\n73145\n73150\n73162\n73167\n73170\n73175\n73179\n73182\n73184\n73194\n73202\n73210\n73216\n73218\n73221\n73224\n73232\n73248\n73254\n73258\n73260\n73261\n73267\n73268\n73272\n73278\n73279\n73294\n73299\n73303\n73308\n73310\n73311\n73319\n73327\n73329\n73332\n73341\n73342\n73343\n73344\n73347\n73348\n73351\n73354\n73362\n73380\n73382\n73384\n73387\n73394\n73396\n73399\n73411\n73419\n73431\n73437\n73441\n73442\n73443\n73448\n73451\n73453\n73464\n73470\n73479\n73487\n73491\n73492\n73493\n73494\n73495\n73496\n73498\n73504\n73508\n73516\n73520\n73539\n73542\n73546\n73549\n73552\n73558\n73560\n73561\n73574\n73575\n73580\n73583\n73590\n73598\n73600\n73601\n73602\n73605\n73612\n73614\n73616\n73618\n73623\n73629\n73635\n73637\n73644\n73645\n73655\n73658\n73662\n73674\n73684\n73697\n73698\n73717\n73723\n73730\n73736\n73744\n73755\n73762\n73765\n73767\n73768\n73771\n73779\n73780\n73793\n73797\n73798\n73799\n73806\n73811\n73817\n73826\n73830\n73844\n73849\n73854\n73858\n73860\n73864\n73869\n73871\n73875\n73880\n73882\n73884\n73887\n73897\n73902\n73908\n73920\n73923\n73931\n73936\n73942\n73949\n73950\n73954\n73963\n73975\n73978\n73979\n73983\n73992\n73997\n74000\n74003\n74005\n74006\n74010\n74020\n74030\n74035\n74044\n74045\n74047\n74049\n74051\n74060\n74061\n74071\n74080\n74081\n74094\n74102\n74109\n74112\n74114\n74131\n74137\n74141\n74144\n74158\n74162\n74167\n74174\n74178\n74184\n74185\n74186\n74191\n74197\n74201\n74202\n74208\n74210\n74216\n74220\n74231\n74237\n74245\n74250\n74251\n74256\n74261\n74264\n74267\n74286\n74287\n74289\n74291\n74293\n74297\n74300\n74303\n74305\n74312\n74313\n74335\n74342\n74345\n74347\n74352\n74356\n74364\n74367\n74369\n74371\n74378\n74384\n74392\n74401\n74419\n74424\n74425\n74429\n74438\n74439\n74452\n74461\n74463\n74471\n74473\n74475\n74479\n74485\n74487\n74494\n74498\n74504\n74508\n74510\n74512\n74519\n74521\n74522\n74533\n74537\n74539\n74544\n74548\n74549\n74559\n74563\n74565\n74566\n74575\n74576\n74578\n74583\n74587\n74589\n74596\n74597\n74608\n74619\n74626\n74632\n74633\n74643\n74648\n74656\n74659\n74660\n74661\n74668\n74674\n74675\n74683\n74684\n74688\n74690\n74691\n74692\n74694\n74701\n74706\n74707\n74712\n74718\n74720\n74721\n74722\n74725\n74727\n74729\n74734\n74746\n74751\n74765\n74771\n74773\n74774\n74775\n74776\n74778\n74779\n74793\n74794\n74800\n74803\n74811\n74816\n74819\n74830\n74833\n74835\n74839\n74851\n74855\n74862\n74882\n74895\n74901\n74902\n74907\n74911\n74913\n74928\n74930\n74931\n74934\n74938\n74950\n74954\n74974\n74983\n74985\n74990\n74992\n74996\n74997\n75002\n75024\n75032\n75043\n75047\n75063\n75080\n75088\n75095\n75096\n75101\n75103\n75108\n75110\n75119\n75121\n75131\n75133\n75134\n75135\n75137\n75144\n75151\n75153\n75160\n75171\n75173\n75174\n75181\n75187\n75188\n75189\n75192\n75195\n75197\n75199\n75202\n75203\n75205\n75212\n75219\n75227\n75236\n75243\n75247\n75252\n75255\n75256\n75259\n75283\n75284\n75286\n75288\n75290\n75299\n75305\n75306\n75311\n75315\n75321\n75328\n75334\n75338\n75345\n75347\n75358\n75359\n75363\n75366\n75372\n75381\n75385\n75399\n75400\n75402\n75409\n75414\n75415\n75418\n75420\n75425\n75428\n75442\n75445\n75446\n75453\n75454\n75456\n75457\n75474\n75481\n75487\n75489\n75491\n75493\n75495\n75500\n75505\n75506\n75514\n75515\n75524\n75535\n75554\n75561\n75565\n75568\n75570\n75577\n75580\n75586\n75595\n75604\n75610\n75616\n75620\n75622\n75639\n75641\n75643\n75647\n75655\n75657\n75658\n75660\n75663\n75673\n75678\n75697\n75701\n75702\n75705\n75708\n75716\n75741\n75745\n75746\n75753\n75755\n75760\n75765\n75775\n75778\n75784\n75787\n75799\n75802\n75809\n75814\n75825\n75828\n75829\n75831\n75835\n75843\n75845\n75846\n75851\n75854\n75860\n75861\n75876\n75877\n75881\n75882\n75893\n75894\n75906\n75914\n75915\n75920\n75923\n75926\n75927\n75931\n75935\n75942\n75953\n75960\n75964\n75976\n75978\n75980\n75981\n75984\n75985\n75989\n75994\n75996\n76003\n76010\n76016\n76021\n76025\n76031\n76036\n76038\n76040\n76047\n76053\n76054\n76061\n76068\n76070\n76071\n76072\n76073\n76077\n76078\n76091\n76096\n76114\n76116\n76121\n76122\n76126\n76137\n76140\n76149\n76154\n76155\n76169\n76170\n76172\n76173\n76176\n76177\n76179\n76181\n76182\n76192\n76194\n76199\n76206\n76212\n76224\n76228\n76231\n76232\n76238\n76242\n76243\n76250\n76259\n76265\n76277\n76283\n76296\n76300\n76304\n76305\n76311\n76314\n76318\n76319\n76328\n76330\n76337\n76341\n76346\n76351\n76355\n76364\n76370\n76375\n76377\n76382\n76393\n76394\n76396\n76397\n76401\n76404\n76413\n76415\n76419\n76434\n76439\n76447\n76450\n76457\n76461\n76464\n76472\n76481\n76486\n76495\n76496\n76499\n76504\n76506\n76509\n76511\n76517\n76519\n76525\n76529\n76540\n76541\n76550\n76551\n76555\n76569\n76576\n76578\n76580\n76581\n76582\n76587\n76592\n76609\n76615\n76618\n76629\n76633\n76637\n76639\n76653\n76654\n76663\n76674\n76675\n76685\n76686\n76691\n76704\n76707\n76712\n76721\n76722\n76725\n76731\n76734\n76743\n76751\n76756\n76764\n76765\n76768\n76787\n76797\n76798\n76799\n76802\n76803\n76811\n76817\n76825\n76830\n76839\n76841\n76843\n76848\n76850\n76852\n76853\n76854\n76859\n76871\n76891\n76896\n76898\n76904\n76910\n76911\n76912\n76918\n76924\n76926\n76931\n76932\n76939\n76940\n76951\n76955\n76958\n76965\n76968\n76977\n76978\n76979\n76984\n76998\n77000\n77008\n77009\n77013\n77021\n77026\n77034\n77047\n77050\n77056\n77057\n77065\n77071\n77074\n77083\n77085\n77086\n77099\n77108\n77113\n77115\n77116\n77118\n77120\n77123\n77128\n77132\n77136\n77154\n77177\n77180\n77182\n77183\n77205\n77206\n77208\n77212\n77213\n77214\n77218\n77219\n77229\n77232\n77243\n77250\n77253\n77257\n77260\n77279\n77282\n77288\n77300\n77305\n77306\n77308\n77309\n77310\n77313\n77314\n77317\n77326\n77328\n77332\n77336\n77338\n77342\n77345\n77360\n77361\n77369\n77372\n77374\n77382\n77385\n77392\n77394\n77395\n77402\n77404\n77409\n77417\n77424\n77431\n77436\n77441\n77442\n77445\n77456\n77458\n77461\n77468\n77469\n77472\n77474\n77476\n77478\n77490\n77491\n77494\n77496\n77499\n77500\n77504\n77508\n77518\n77519\n77520\n77521\n77522\n77531\n77538\n77539\n77540\n77541\n77546\n77548\n77555\n77556\n77561\n77571\n77586\n77590\n77593\n77595\n77600\n77603\n77605\n77613\n77621\n77622\n77632\n77645\n77648\n77656\n77658\n77659\n77664\n77681\n77689\n77695\n77702\n77708\n77713\n77724\n77727\n77733\n77735\n77749\n77751\n77755\n77758\n77767\n77771\n77780\n77783\n77785\n77788\n77791\n77796\n77802\n77803\n77810\n77811\n77812\n77817\n77819\n77831\n77836\n77839\n77845\n77862\n77874\n77888\n77898\n77906\n77910\n77940\n77944\n77948\n77949\n77954\n77961\n77967\n77970\n77973\n77974\n77979\n77985\n77990\n77998\n77999\n78002\n78004\n78010\n78013\n78017\n78021\n78026\n78035\n78042\n78045\n78051\n78061\n78069\n78070\n78079\n78082\n78087\n78096\n78105\n78106\n78108\n78113\n78125\n78128\n78130\n78131\n78133\n78154\n78161\n78165\n78168\n78169\n78171\n78178\n78183\n78184\n78186\n78189\n78190\n78197\n78207\n78209\n78210\n78212\n78214\n78215\n78221\n78224\n78234\n78235\n78239\n78240\n78243\n78249\n78252\n78259\n78262\n78264\n78270\n78278\n78279\n78284\n78289\n78305\n78312\n78316\n78326\n78330\n78332\n78334\n78339\n78342\n78343\n78347\n78353\n78357\n78358\n78364\n78388\n78400\n78403\n78404\n78407\n78419\n78421\n78427\n78433\n78441\n78442\n78443\n78446\n78447\n78453\n78455\n78457\n78458\n78465\n78469\n78471\n78477\n78480\n78503\n78505\n78514\n78515\n78516\n78517\n78526\n78531\n78536\n78541\n78546\n78548\n78556\n78566\n78567\n78568\n78573\n78578\n78585\n78588\n78591\n78596\n78597\n78602\n78604\n78605\n78610\n78613\n78614\n78616\n78619\n78623\n78631\n78632\n78636\n78638\n78641\n78642\n78646\n78652\n78659\n78664\n78665\n78669\n78670\n78671\n78681\n78687\n78688\n78691\n78694\n78696\n78699\n78703\n78705\n78707\n78710\n78712\n78715\n78716\n78717\n78722\n78725\n78727\n78730\n78732\n78733\n78738\n78742\n78746\n78750\n78751\n78752\n78757\n78763\n78769\n78774\n78775\n78779\n78792\n78793\n78795\n78796\n78800\n78804\n78810\n78816\n78824\n78825\n78836\n78844\n78846\n78867\n78874\n78876\n78877\n78881\n78883\n78892\n78904\n78921\n78924\n78933\n78935\n78937\n78939\n78940\n78944\n78945\n78947\n78952\n78955\n78956\n78957\n78959\n78972\n78979\n78982\n78993\n78996\n78997\n78999\n79001\n79013\n79015\n79017\n79024\n79027\n79028\n79030\n79031\n79044\n79045\n79052\n79053\n79058\n79070\n79074\n79075\n79079\n79092\n79105\n79107\n79125\n79127\n79132\n79143\n79148\n79151\n79152\n79153\n79154\n79160\n79163\n79165\n79172\n79173\n79176\n79178\n79180\n79185\n79190\n79192\n79193\n79194\n79198\n79199\n79205\n79207\n79217\n79218\n79225\n79235\n79237\n79240\n79246\n79250\n79253\n79262\n79269\n79284\n79295\n79298\n79300\n79301\n79303\n79308\n79310\n79312\n79313\n79325\n79332\n79339\n79346\n79348\n79352\n79353\n79355\n79357\n79363\n79364\n79366\n79367\n79374\n79377\n79382\n79383\n79384\n79385\n79392\n79406\n79411\n79415\n79417\n79418\n79427\n79433\n79439\n79441\n79444\n79450\n79455\n79456\n79476\n79478\n79480\n79481\n79482\n79490\n79492\n79497\n79498\n79510\n79519\n79520\n79526\n79537\n79539\n79544\n79546\n79548\n79551\n79552\n79559\n79566\n79579\n79580\n79583\n79591\n79597\n79598\n79600\n79605\n79619\n79632\n79635\n79636\n79648\n79658\n79666\n79668\n79669\n79673\n79674\n79676\n79693\n79700\n79703\n79708\n79710\n79711\n79713\n79715\n79721\n79724\n79733\n79740\n79742\n79748\n79753\n79759\n79764\n79767\n79770\n79776\n79785\n79787\n79793\n79804\n79806\n79826\n79833\n79835\n79837\n79848\n79849\n79852\n79859\n79860\n79864\n79865\n79870\n79871\n79872\n79876\n79881\n79883\n79886\n79897\n79906\n79911\n79919\n79925\n79930\n79934\n79937\n79943\n79952\n79966\n79971\n79972\n79973\n79977\n79984\n79985\n79991\n79992\n79996\n80003\n80025\n80035\n80036\n80038\n80046\n80053\n80054\n80065\n80071\n80074\n80077\n80079\n80085\n80087\n80090\n80096\n80097\n80103\n80106\n80109\n80111\n80114\n80119\n80121\n80127\n80130\n80141\n80145\n80150\n80157\n80169\n80172\n80176\n80177\n80189\n80194\n80202\n80215\n80224\n80232\n80233\n80234\n80235\n80246\n80251\n80260\n80261\n80269\n80270\n80276\n80283\n80285\n80288\n80298\n80304\n80307\n80319\n80320\n80324\n80332\n80345\n80346\n80360\n80361\n80368\n80378\n80379\n80382\n80387\n80389\n80392\n80405\n80411\n80414\n80422\n80424\n80427\n80430\n80431\n80432\n80436\n80450\n80451\n80456\n80463\n80469\n80476\n80486\n80500\n80503\n80509\n80516\n80522\n80530\n80534\n80540\n80545\n80557\n80559\n80566\n80570\n80576\n80579\n80580\n80582\n80590\n80604\n80608\n80612\n80616\n80625\n80630\n80633\n80635\n80638\n80642\n80648\n80649\n80652\n80655\n80665\n80669\n80680\n80683\n80690\n80691\n80705\n80730\n80734\n80742\n80744\n80749\n80750\n80752\n80756\n80757\n80761\n80762\n80766\n80773\n80777\n80784\n80785\n80808\n80810\n80814\n80821\n80825\n80826\n80829\n80832\n80837\n80841\n80850\n80851\n80866\n80869\n80874\n80875\n80877\n80882\n80889\n80891\n80898\n80917\n80940\n80941\n80951\n80962\n80967\n80974\n80983\n80984\n80988\n80998\n80999\n81002\n81007\n81014\n81016\n81029\n81031\n81033\n81035\n81046\n81051\n81063\n81072\n81074\n81077\n81078\n81082\n81083\n81087\n81089\n81091\n81099\n81115\n81117\n81125\n81126\n81131\n81133\n81134\n81136\n81138\n81144\n81150\n81155\n81158\n81165\n81175\n81180\n81186\n81187\n81188\n81189\n81190\n81191\n81196\n81200\n81202\n81203\n81205\n81215\n81218\n81226\n81227\n81235\n81238\n81240\n81249\n81259\n81265\n81271\n81280\n81284\n81289\n81291\n81297\n81306\n81307\n81309\n81321\n81323\n81325\n81336\n81341\n81346\n81354\n81358\n81363\n81367\n81371\n81372\n81374\n81388\n81392\n81396\n81398\n81402\n81406\n81422\n81424\n81425\n81426\n81443\n81447\n81457\n81458\n81459\n81461\n81465\n81472\n81474\n81475\n81478\n81488\n81491\n81498\n81513\n81515\n81521\n81524\n81527\n81531\n81536\n81538\n81539\n81550\n81557\n81559\n81562\n81568\n81569\n81573\n81576\n81578\n81579\n81586\n81622\n81625\n81639\n81646\n81648\n81653\n81654\n81657\n81671\n81675\n81677\n81680\n81683\n81685\n81687\n81688\n81693\n81697\n81701\n81706\n81714\n81725\n81726\n81727\n81741\n81743\n81747\n81759\n81760\n81777\n81778\n81790\n81794\n81802\n81803\n81804\n81813\n81815\n81817\n81826\n81834\n81835\n81838\n81846\n81851\n81855\n81856\n81880\n81889\n81892\n81896\n81904\n81906\n81909\n81914\n81919\n81926\n81929\n81930\n81932\n81941\n81946\n81953\n81954\n81960\n81962\n81963\n81964\n81974\n81976\n81982\n81994\n82010\n82014\n82017\n82024\n82030\n82031\n82034\n82036\n82037\n82038\n82048\n82053\n82055\n82056\n82064\n82065\n82066\n82070\n82072\n82078\n82088\n82093\n82096\n82099\n82100\n82101\n82103\n82105\n82107\n82109\n82119\n82121\n82124\n82128\n82138\n82143\n82145\n82148\n82151\n82157\n82158\n82159\n82168\n82171\n82175\n82177\n82178\n82192\n82196\n82198\n82201\n82203\n82204\n82209\n82220\n82221\n82222\n82228\n82232\n82233\n82239\n82240\n82246\n82248\n82258\n82264\n82268\n82272\n82279\n82280\n82288\n82289\n82291\n82299\n82300\n82301\n82302\n82303\n82316\n82317\n82320\n82321\n82328\n82332\n82336\n82337\n82343\n82346\n82357\n82361\n82365\n82368\n82372\n82375\n82384\n82386\n82390\n82406\n82407\n82409\n82414\n82416\n82422\n82431\n82433\n82437\n82440\n82444\n82445\n82448\n82456\n82459\n82465\n82490\n82497\n82505\n82509\n82519\n82524\n82525\n82527\n82539\n82548\n82549\n82550\n82552\n82571\n82573\n82577\n82585\n82587\n82591\n82594\n82604\n82608\n82614\n82615\n82619\n82622\n82624\n82631\n82634\n82642\n82645\n82660\n82661\n82663\n82666\n82681\n82684\n82687\n82694\n82695\n82706\n82707\n82717\n82718\n82719\n82721\n82731\n82738\n82746\n82755\n82765\n82766\n82771\n82786\n82797\n82798\n82811\n82817\n82818\n82822\n82829\n82838\n82846\n82847\n82853\n82856\n82863\n82873\n82883\n82885\n82892\n82893\n82900\n82916\n82924\n82931\n82933\n82934\n82938\n82940\n82943\n82944\n82961\n82963\n82965\n82966\n82972\n82977\n82994\n83001\n83009\n83010\n83012\n83015\n83025\n83027\n83030\n83031\n83051\n83064\n83067\n83068\n83083\n83084\n83092\n83095\n83096\n83102\n83105\n83106\n83110\n83117\n83122\n83123\n83129\n83147\n83149\n83168\n83173\n83174\n83177\n83182\n83183\n83185\n83187\n83188\n83198\n83199\n83220\n83223\n83229\n83231\n83237\n83240\n83244\n83256\n83261\n83280\n83295\n83297\n83298\n83299\n83302\n83304\n83305\n83308\n83322\n83324\n83331\n83340\n83341\n83349\n83353\n83358\n83359\n83360\n83362\n83374\n83376\n83382\n83387\n83394\n83395\n83403\n83408\n83418\n83426\n83428\n83434\n83435\n83438\n83441\n83442\n83443\n83449\n83450\n83451\n83452\n83455\n83466\n83471\n83472\n83477\n83485\n83488\n83493\n83500\n83502\n83508\n83510\n83513\n83516\n83522\n83530\n83533\n83541\n83542\n83549\n83554\n83558\n83563\n83586\n83591\n83593\n83598\n83599\n83600\n83606\n83607\n83610\n83613\n83629\n83630\n83634\n83640\n83654\n83657\n83660\n83663\n83678\n83686\n83689\n83702\n83706\n83707\n83709\n83711\n83713\n83728\n83729\n83736\n83738\n83744\n83745\n83748\n83756\n83759\n83761\n83762\n83764\n83775\n83777\n83778\n83788\n83789\n83792\n83799\n83802\n83809\n83812\n83820\n83822\n83824\n83830\n83844\n83853\n83860\n83864\n83869\n83873\n83886\n83890\n83892\n83895\n83896\n83901\n83907\n83916\n83917\n83922\n83926\n83935\n83938\n83939\n83943\n83946\n83947\n83953\n83956\n83967\n83968\n83969\n83983\n83985\n83992\n83999\n84000\n84001\n84007\n84008\n84010\n84012\n84013\n84016\n84017\n84031\n84033\n84047\n84052\n84053\n84054\n84060\n84067\n84068\n84069\n84072\n84076\n84078\n84079\n84080\n84085\n84108\n84113\n84116\n84130\n84131\n84135\n84137\n84143\n84144\n84145\n84158\n84163\n84167\n84169\n84173\n84178\n84185\n84188\n84189\n84192\n84194\n84203\n84205\n84208\n84213\n84218\n84223\n84224\n84236\n84240\n84251\n84252\n84254\n84264\n84281\n84283\n84286\n84291\n84295\n84302\n84306\n84309\n84315\n84316\n84319\n84320\n84321\n84323\n84326\n84330\n84346\n84348\n84352\n84358\n84364\n84366\n84367\n84369\n84372\n84375\n84379\n84387\n84389\n84416\n84431\n84435\n84439\n84441\n84450\n84451\n84452\n84458\n84466\n84470\n84472\n84475\n84479\n84480\n84481\n84490\n84494\n84507\n84509\n84510\n84511\n84516\n84520\n84534\n84536\n84540\n84549\n84562\n84567\n84568\n84569\n84575\n84581\n84583\n84586\n84588\n84594\n84597\n84598\n84600\n84609\n84620\n84621\n84625\n84635\n84637\n84639\n84640\n84646\n84647\n84659\n84661\n84662\n84670\n84672\n84677\n84678\n84680\n84683\n84686\n84689\n84692\n84697\n84700\n84703\n84715\n84717\n84718\n84722\n84727\n84732\n84736\n84743\n84744\n84745\n84746\n84755\n84758\n84761\n84768\n84771\n84778\n84780\n84782\n84790\n84792\n84793\n84813\n84824\n84826\n84830\n84831\n84841\n84843\n84845\n84848\n84850\n84862\n84863\n84864\n84873\n84874\n84891\n84893\n84904\n84912\n84914\n84915\n84916\n84919\n84920\n84923\n84928\n84929\n84930\n84934\n84938\n84946\n84953\n84954\n84974\n84975\n84977\n84981\n84982\n84986\n84988\n84989\n84991\n84996\n85003\n85004\n85008\n85013\n85016\n85017\n85027\n85031\n85032\n85033\n85035\n85047\n85051\n85053\n85068\n85069\n85077\n85079\n85081\n85083\n85084\n85091\n85094\n85098\n85100\n85101\n85106\n85116\n85122\n85124\n85134\n85136\n85141\n85161\n85166\n85167\n85169\n85174\n85175\n85177\n85196\n85200\n85202\n85209\n85220\n85221\n85222\n85223\n85226\n85232\n85233\n85245\n85249\n85253\n85256\n85261\n85273\n85292\n85295\n85300\n85310\n85311\n85315\n85322\n85323\n85324\n85334\n85337\n85344\n85375\n85376\n85400\n85403\n85404\n85412\n85420\n85424\n85429\n85451\n85453\n85454\n85455\n85461\n85462\n85466\n85468\n85475\n85479\n85486\n85489\n85492\n85493\n85496\n85498\n85506\n85511\n85523\n85524\n85526\n85530\n85536\n85539\n85555\n85557\n85559\n85563\n85574\n85576\n85590\n85598\n85599\n85600\n85601\n85613\n85618\n85621\n85624\n85626\n85630\n85633\n85643\n85646\n85647\n85653\n85655\n85657\n85660\n85661\n85674\n85676\n85677\n85680\n85684\n85688\n85697\n85709\n85718\n85736\n85739\n85744\n85750\n85751\n85758\n85760\n85777\n85780\n85781\n85783\n85788\n85794\n85796\n85797\n85798\n85799\n85801\n85803\n85806\n85809\n85813\n85815\n85816\n85818\n85819\n85820\n85823\n85825\n85828\n85835\n85836\n85841\n85844\n85858\n85862\n85864\n85873\n85885\n85892\n85893\n85895\n85899\n85902\n85915\n85918\n85921\n85925\n85929\n85941\n85943\n85948\n85951\n85954\n85957\n85962\n85964\n85968\n85974\n85984\n86006\n86007\n86009\n86013\n86014\n86015\n86019\n86023\n86026\n86032\n86034\n86050\n86051\n86060\n86071\n86073\n86077\n86101\n86103\n86108\n86116\n86120\n86123\n86127\n86129\n86130\n86131\n86132\n86137\n86138\n86145\n86146\n86147\n86150\n86153\n86155\n86156\n86162\n86164\n86172\n86174\n86180\n86186\n86192\n86197\n86200\n86203\n86206\n86211\n86216\n86232\n86235\n86270\n86278\n86297\n86300\n86304\n86305\n86308\n86315\n86316\n86320\n86331\n86339\n86344\n86347\n86356\n86357\n86373\n86378\n86380\n86387\n86388\n86394\n86405\n86409\n86414\n86418\n86424\n86426\n86435\n86439\n86442\n86447\n86456\n86462\n86463\n86472\n86476\n86480\n86489\n86493\n86496\n86506\n86514\n86520\n86533\n86544\n86547\n86549\n86552\n86553\n86557\n86559\n86566\n86572\n86573\n86574\n86576\n86584\n86587\n86593\n86594\n86600\n86614\n86617\n86619\n86620\n86622\n86633\n86642\n86647\n86650\n86655\n86662\n86663\n86664\n86665\n86667\n86671\n86676\n86680\n86682\n86686\n86691\n86702\n86704\n86708\n86714\n86723\n86729\n86730\n86738\n86741\n86742\n86743\n86748\n86766\n86768\n86773\n86775\n86777\n86778\n86785\n86787\n86794\n86798\n86803\n86804\n86807\n86808\n86813\n86817\n86820\n86825\n86831\n86832\n86837\n86840\n86842\n86843\n86845\n86850\n86852\n86853\n86855\n86863\n86869\n86870\n86874\n86876\n86878\n86881\n86888\n86899\n86900\n86901\n86902\n86904\n86913\n86914\n86916\n86917\n86922\n86926\n86952\n86957\n86958\n86960\n86962\n86967\n86975\n86976\n86979\n86996\n86999\n87000\n87001\n87012\n87014\n87024\n87030\n87035\n87036\n87042\n87044\n87051\n87054\n87061\n87064\n87068\n87072\n87080\n87088\n87107\n87109\n87114\n87118\n87120\n87145\n87147\n87149\n87166\n87167\n87190\n87195\n87196\n87203\n87206\n87221\n87222\n87230\n87237\n87241\n87242\n87249\n87251\n87253\n87257\n87260\n87266\n87269\n87272\n87284\n87285\n87297\n87298\n87299\n87300\n87301\n87304\n87311\n87312\n87331\n87332\n87341\n87347\n87355\n87361\n87363\n87368\n87369\n87374\n87377\n87380\n87383\n87388\n87390\n87406\n87409\n87415\n87420\n87427\n87429\n87431\n87433\n87435\n87436\n87439\n87443\n87448\n87455\n87462\n87483\n87487\n87491\n87492\n87493\n87494\n87499\n87501\n87504\n87516\n87517\n87520\n87538\n87541\n87554\n87556\n87558\n87566\n87570\n87572\n87574\n87577\n87601\n87605\n87620\n87626\n87630\n87633\n87635\n87637\n87654\n87658\n87683\n87685\n87690\n87692\n87693\n87697\n87701\n87706\n87710\n87715\n87725\n87726\n87728\n87730\n87733\n87736\n87741\n87742\n87745\n87749\n87755\n87776\n87777\n87780\n87784\n87791\n87799\n87804\n87809\n87814\n87817\n87821\n87822\n87829\n87831\n87832\n87833\n87834\n87839\n87841\n87845\n87846\n87850\n87854\n87857\n87867\n87868\n87876\n87877\n87881\n87893\n87894\n87896\n87906\n87922\n87927\n87940\n87941\n87950\n87953\n87958\n87965\n87967\n87968\n87972\n87979\n87984\n87991\n87995\n88000\n88014\n88015\n88034\n88040\n88048\n88051\n88060\n88067\n88071\n88077\n88087\n88109\n88114\n88119\n88124\n88127\n88137\n88138\n88149\n88153\n88154\n88155\n88157\n88167\n88170\n88175\n88178\n88184\n88213\n88224\n88227\n88236\n88246\n88248\n88251\n88253\n88256\n88258\n88269\n88280\n88281\n88283\n88285\n88292\n88293\n88296\n88298\n88300\n88303\n88332\n88342\n88346\n88350\n88362\n88371\n88372\n88373\n88377\n88383\n88384\n88388\n88389\n88399\n88409\n88410\n88417\n88424\n88425\n88430\n88432\n88434\n88437\n88440\n88442\n88444\n88446\n88449\n88450\n88463\n88471\n88473\n88476\n88478\n88481\n88482\n88488\n88490\n88494\n88498\n88501\n88504\n88506\n88511\n88516\n88519\n88521\n88524\n88525\n88530\n88531\n88535\n88539\n88540\n88545\n88552\n88558\n88561\n88566\n88569\n88570\n88572\n88575\n88583\n88584\n88587\n88588\n88590\n88591\n88593\n88609\n88614\n88616\n88621\n88623\n88627\n88638\n88643\n88646\n88672\n88683\n88684\n88688\n88693\n88694\n88700\n88705\n88706\n88715\n88717\n88719\n88728\n88729\n88732\n88736\n88746\n88748\n88751\n88756\n88758\n88767\n88770\n88777\n88784\n88789\n88792\n88794\n88798\n88802\n88823\n88826\n88833\n88835\n88841\n88848\n88855\n88857\n88858\n88861\n88866\n88867\n88872\n88876\n88880\n88888\n88889\n88896\n88897\n88906\n88913\n88941\n88943\n88946\n88980\n88992\n89001\n89007\n89008\n89019\n89020\n89024\n89028\n89035\n89039\n89040\n89042\n89055\n89058\n89070\n89072\n89079\n89081\n89082\n89085\n89087\n89089\n89092\n89096\n89099\n89101\n89107\n89110\n89113\n89117\n89120\n89123\n89124\n89135\n89140\n89145\n89146\n89147\n89157\n89159\n89165\n89171\n89174\n89176\n89177\n89179\n89187\n89191\n89194\n89198\n89203\n89205\n89211\n89213\n89217\n89228\n89230\n89246\n89251\n89263\n89268\n89284\n89285\n89293\n89297\n89301\n89313\n89314\n89315\n89316\n89319\n89321\n89327\n89328\n89339\n89342\n89345\n89352\n89360\n89361\n89363\n89366\n89372\n89376\n89383\n89386\n89393\n89397\n89408\n89416\n89421\n89426\n89428\n89451\n89454\n89458\n89468\n89475\n89478\n89480\n89482\n89484\n89485\n89487\n89489\n89495\n89499\n89501\n89505\n89509\n89510\n89517\n89519\n89535\n89540\n89546\n89548\n89556\n89561\n89562\n89572\n89573\n89579\n89582\n89583\n89586\n89597\n89602\n89626\n89630\n89641\n89651\n89655\n89658\n89659\n89665\n89678\n89679\n89685\n89686\n89690\n89692\n89693\n89698\n89700\n89701\n89705\n89711\n89716\n89728\n89737\n89738\n89749\n89751\n89755\n89760\n89764\n89766\n89769\n89783\n89796\n89811\n89812\n89818\n89819\n89821\n89828\n89829\n89834\n89838\n89841\n89842\n89844\n89845\n89846\n89860\n89865\n89875\n89878\n89884\n89888\n89889\n89891\n89899\n89900\n89902\n89905\n89932\n89935\n89939\n89940\n89945\n89948\n89956\n89959\n89974\n89978\n89981\n89982\n89983\n89986\n89987\n89991\n89992\n90000\n90007\n90009\n90010\n90018\n90021\n90024\n90027\n90030\n90034\n90045\n90047\n90052\n90053\n90058\n90065\n90066\n90076\n90079\n90081\n90087\n90091\n90106\n90109\n90113\n90122\n90129\n90132\n90137\n90138\n90143\n90147\n90151\n90163\n90165\n90169\n90180\n90182\n90186\n90190\n90191\n90208\n90209\n90211\n90213\n90214\n90218\n90228\n90233\n90236\n90242\n90243\n90246\n90247\n90259\n90269\n90270\n90280\n90286\n90291\n90292\n90293\n90301\n90303\n90312\n90315\n90316\n90321\n90329\n90335\n90338\n90342\n90354\n90356\n90361\n90364\n90365\n90371\n90374\n90376\n90387\n90410\n90416\n90418\n90424\n90425\n90428\n90430\n90431\n90432\n90434\n90441\n90448\n90452\n90455\n90459\n90462\n90472\n90474\n90477\n90478\n90481\n90482\n90484\n90485\n90487\n90493\n90499\n90502\n90504\n90505\n90507\n90508\n90516\n90518\n90528\n90531\n90533\n90536\n90538\n90540\n90544\n90546\n90551\n90587\n90619\n90628\n90636\n90642\n90647\n90655\n90656\n90661\n90664\n90665\n90680\n90689\n90699\n90703\n90707\n90728\n90729\n90730\n90743\n90745\n90759\n90764\n90769\n90774\n90777\n90784\n90797\n90812\n90834\n90845\n90862\n90867\n90868\n90872\n90873\n90879\n90885\n90886\n90889\n90899\n90900\n90902\n90906\n90907\n90908\n90914\n90916\n90922\n90925\n90927\n90929\n90934\n90943\n90944\n90953\n90957\n90963\n90970\n90971\n90993\n91008\n91017\n91039\n91043\n91046\n91047\n91052\n91054\n91061\n91067\n91075\n91078\n91085\n91088\n91090\n91110\n91115\n91119\n91122\n91127\n91129\n91138\n91142\n91146\n91152\n91159\n91165\n91167\n91174\n91182\n91183\n91184\n91187\n91189\n91191\n91194\n91206\n91207\n91208\n91210\n91215\n91221\n91222\n91230\n91234\n91241\n91242\n91248\n91251\n91273\n91281\n91286\n91291\n91304\n91306\n91309\n91312\n91313\n91315\n91318\n91327\n91356\n91360\n91362\n91364\n91367\n91371\n91373\n91375\n91377\n91387\n91391\n91396\n91400\n91404\n91410\n91412\n91433\n91435\n91436\n91440\n91444\n91447\n91449\n91451\n91455\n91462\n91470\n91471\n91477\n91479\n91487\n91490\n91493\n91494\n91502\n91515\n91516\n91546\n91556\n91560\n91564\n91565\n91566\n91567\n91570\n91574\n91579\n91582\n91586\n91588\n91593\n91612\n91616\n91624\n91635\n91640\n91641\n91646\n91648\n91658\n91660\n91663\n91676\n91677\n91679\n91687\n91688\n91696\n91703\n91708\n91715\n91725\n91735\n91740\n91743\n91752\n91766\n91773\n91775\n91780\n91781\n91807\n91817\n91823\n91833\n91838\n91843\n91845\n91852\n91854\n91857\n91869\n91871\n91876\n91882\n91886\n91895\n91905\n91906\n91908\n91911\n91915\n91916\n91929\n91942\n91948\n91955\n91958\n91964\n91972\n91991\n92002\n92018\n92022\n92026\n92029\n92034\n92036\n92037\n92038\n92047\n92050\n92055\n92058\n92061\n92065\n92073\n92080\n92083\n92105\n92112\n92118\n92122\n92125\n92128\n92142\n92147\n92152\n92155\n92157\n92163\n92176\n92177\n92181\n92189\n92191\n92194\n92197\n92203\n92211\n92213\n92219\n92220\n92223\n92225\n92237\n92239\n92247\n92251\n92256\n92259\n92263\n92267\n92270\n92281\n92291\n92302\n92305\n92312\n92320\n92327\n92330\n92337\n92339\n92340\n92341\n92343\n92347\n92353\n92357\n92358\n92359\n92364\n92373\n92378\n92379\n92382\n92383\n92389\n92400\n92401\n92411\n92421\n92424\n92430\n92434\n92438\n92449\n92458\n92461\n92469\n92474\n92475\n92488\n92492\n92509\n92510\n92513\n92514\n92521\n92535\n92537\n92539\n92542\n92562\n92568\n92570\n92574\n92582\n92583\n92594\n92597\n92598\n92599\n92606\n92613\n92618\n92620\n92624\n92625\n92633\n92655\n92663\n92677\n92681\n92689\n92691\n92692\n92693\n92697\n92702\n92704\n92714\n92717\n92725\n92726\n92730\n92739\n92746\n92753\n92755\n92760\n92762\n92763\n92770\n92772\n92773\n92776\n92781\n92782\n92784\n92795\n92799\n92803\n92809\n92810\n92836\n92842\n92849\n92856\n92874\n92875\n92876\n92878\n92881\n92883\n92887\n92890\n92895\n92897\n92907\n92908\n92910\n92914\n92923\n92926\n92938\n92944\n92958\n92963\n92964\n92967\n92968\n92971\n92972\n92976\n92977\n92980\n92985\n92989\n93001\n93003\n93009\n93014\n93015\n93024\n93048\n93050\n93058\n93063\n93077\n93078\n93081\n93089\n93097\n93099\n93101\n93102\n93124\n93132\n93134\n93135\n93141\n93148\n93150\n93151\n93160\n93163\n93171\n93181\n93187\n93188\n93195\n93196\n93210\n93214\n93216\n93224\n93233\n93253\n93255\n93256\n93263\n93269\n93273\n93280\n93281\n93284\n93286\n93294\n93296\n93309\n93317\n93319\n93327\n93330\n93331\n93335\n93336\n93341\n93348\n93349\n93367\n93378\n93385\n93386\n93388\n93391\n93393\n93396\n93409\n93417\n93429\n93441\n93450\n93452\n93454\n93456\n93459\n93464\n93474\n93482\n93486\n93492\n93493\n93496\n93499\n93505\n93507\n93516\n93539\n93540\n93543\n93554\n93555\n93559\n93563\n93568\n93569\n93574\n93576\n93578\n93596\n93603\n93604\n93606\n93610\n93614\n93618\n93621\n93627\n93636\n93649\n93651\n93652\n93658\n93666\n93671\n93675\n93676\n93680\n93681\n93686\n93688\n93693\n93694\n93698\n93699\n93710\n93711\n93720\n93721\n93723\n93725\n93731\n93740\n93742\n93753\n93768\n93772\n93780\n93781\n93782\n93797\n93800\n93815\n93817\n93822\n93825\n93827\n93832\n93837\n93838\n93839\n93848\n93849\n93869\n93870\n93872\n93874\n93875\n93877\n93879\n93882\n93888\n93891\n93897\n93905\n93911\n93922\n93924\n93931\n93939\n93943\n93949\n93953\n93954\n93969\n93971\n93977\n93978\n93980\n93981\n93996\n94001\n94002\n94004\n94008\n94021\n94022\n94024\n94026\n94029\n94036\n94037\n94041\n94042\n94044\n94052\n94053\n94055\n94056\n94066\n94079\n94080\n94088\n94092\n94098\n94104\n94105\n94110\n94113\n94119\n94121\n94126\n94133\n94134\n94139\n94147\n94155\n94157\n94169\n94171\n94173\n94175\n94177\n94178\n94182\n94184\n94210\n94219\n94221\n94231\n94237\n94246\n94248\n94254\n94256\n94262\n94278\n94289\n94303\n94309\n94334\n94340\n94346\n94348\n94350\n94356\n94374\n94399\n94404\n94407\n94408\n94421\n94422\n94425\n94428\n94429\n94433\n94438\n94447\n94452\n94454\n94458\n94465\n94470\n94474\n94483\n94485\n94490\n94493\n94500\n94501\n94508\n94514\n94519\n94520\n94527\n94530\n94534\n94540\n94555\n94559\n94562\n94580\n94589\n94595\n94596\n94602\n94606\n94614\n94617\n94624\n94630\n94631\n94635\n94649\n94650\n94659\n94665\n94666\n94667\n94675\n94676\n94680\n94685\n94688\n94689\n94694\n94699\n94704\n94714\n94716\n94718\n94721\n94724\n94734\n94738\n94742\n94746\n94755\n94756\n94757\n94759\n94761\n94763\n94766\n94773\n94791\n94792\n94797\n94799\n94800\n94801\n94803\n94805\n94807\n94809\n94810\n94814\n94816\n94819\n94823\n94833\n94836\n94838\n94839\n94840\n94844\n94845\n94846\n94847\n94849\n94851\n94855\n94857\n94864\n94866\n94870\n94886\n94888\n94895\n94899\n94903\n94906\n94909\n94911\n94919\n94921\n94924\n94926\n94927\n94928\n94935\n94945\n94949\n94954\n94955\n94966\n94969\n94972\n94973\n94991\n94994\n94996\n95000\n95004\n95012\n95033\n95035\n95040\n95045\n95046\n95047\n95052\n95068\n95075\n95080\n95085\n95086\n95092\n95106\n95110\n95120\n95142\n95143\n95153\n95156\n95157\n95158\n95163\n95201\n95202\n95204\n95207\n95229\n95232\n95235\n95237\n95239\n95244\n95245\n95247\n95248\n95252\n95254\n95256\n95259\n95267\n95271\n95272\n95276\n95277\n95282\n95283\n95284\n95304\n95305\n95309\n95310\n95313\n95319\n95320\n95327\n95337\n95339\n95344\n95351\n95363\n95364\n95366\n95377\n95385\n95387\n95393\n95412\n95414\n95417\n95429\n95436\n95440\n95442\n95444\n95455\n95462\n95469\n95471\n95474\n95475\n95478\n95479\n95481\n95492\n95496\n95498\n95500\n95533\n95542\n95544\n95549\n95550\n95555\n95559\n95564\n95570\n95591\n95593\n95596\n95597\n95598\n95599\n95611\n95615\n95618\n95620\n95621\n95638\n95639\n95646\n95647\n95653\n95661\n95677\n95686\n95688\n95700\n95703\n95705\n95725\n95726\n95730\n95735\n95739\n95746\n95752\n95756\n95758\n95760\n95761\n95775\n95778\n95780\n95790\n95793\n95795\n95798\n95802\n95812\n95832\n95835\n95837\n95841\n95845\n95848\n95849\n95851\n95859\n95862\n95864\n95868\n95877\n95885\n95886\n95887\n95890\n95893\n95895\n95896\n95897\n95903\n95907\n95924\n95928\n95931\n95936\n95937\n95938\n95947\n95955\n95958\n95973\n95976\n95985\n95992\n95999\n96008\n96011\n96014\n96021\n96030\n96032\n96037\n96046\n96052\n96058\n96060\n96066\n96067\n96081\n96095\n96099\n96100\n96105\n96113\n96119\n96121\n96125\n96132\n96133\n96135\n96136\n96145\n96152\n96160\n96163\n96164\n96170\n96177\n96178\n96189\n96193\n96195\n96198\n96199\n96204\n96211\n96220\n96228\n96234\n96236\n96251\n96256\n96263\n96278\n96281\n96284\n96291\n96294\n96295\n96297\n96318\n96322\n96326\n96332\n96334\n96338\n96341\n96349\n96353\n96354\n96364\n96366\n96373\n96375\n96385\n96387\n96392\n96400\n96401\n96427\n96428\n96431\n96433\n96437\n96444\n96448\n96452\n96453\n96460\n96462\n96470\n96472\n96474\n96482\n96483\n96489\n96492\n96499\n96506\n96507\n96516\n96530\n96532\n96536\n96540\n96543\n96544\n96547\n96548\n96561\n96562\n96563\n96566\n96581\n96591\n96598\n96600\n96611\n96617\n96618\n96619\n96620\n96622\n96634\n96636\n96639\n96647\n96660\n96662\n96667\n96678\n96684\n96686\n96687\n96694\n96696\n96697\n96699\n96701\n96703\n96707\n96709\n96710\n96712\n96721\n96725\n96736\n96743\n96747\n96749\n96760\n96765\n96781\n96787\n96789\n96791\n96795\n96808\n96809\n96818\n96824\n96829\n96830\n96836\n96845\n96846\n96848\n96855\n96867\n96869\n96871\n96872\n96879\n96884\n96886\n96893\n96896\n96898\n96899\n96907\n96919\n96920\n96923\n96932\n96935\n96939\n96943\n96946\n96959\n96960\n96974\n96977\n96984\n96986\n96995\n96998\n97004\n97006\n97007\n97008\n97013\n97032\n97040\n97044\n97049\n97053\n97054\n97060\n97070\n97078\n97090\n97092\n97099\n97103\n97109\n97116\n97119\n97128\n97132\n97134\n97135\n97139\n97140\n97142\n97154\n97178\n97179\n97181\n97186\n97197\n97198\n97199\n97200\n97209\n97211\n97212\n97216\n97217\n97221\n97223\n97226\n97229\n97236\n97238\n97242\n97245\n97246\n97247\n97248\n97249\n97251\n97253\n97254\n97258\n97260\n97262\n97273\n97275\n97277\n97301\n97306\n97311\n97315\n97316\n97320\n97321\n97322\n97325\n97326\n97337\n97343\n97349\n97359\n97361\n97367\n97377\n97379\n97380\n97394\n97396\n97404\n97405\n97408\n97410\n97421\n97428\n97434\n97437\n97439\n97444\n97451\n97460\n97465\n97476\n97480\n97483\n97491\n97503\n97504\n97505\n97508\n97509\n97521\n97538\n97546\n97547\n97548\n97554\n97561\n97568\n97576\n97580\n97584\n97586\n97591\n97592\n97596\n97598\n97609\n97612\n97613\n97616\n97619\n97631\n97632\n97633\n97638\n97639\n97642\n97645\n97646\n97649\n97651\n97658\n97668\n97675\n97680\n97687\n97693\n97695\n97710\n97718\n97726\n97729\n97730\n97732\n97733\n97735\n97739\n97740\n97743\n97744\n97748\n97757\n97761\n97769\n97774\n97777\n97783\n97785\n97786\n97793\n97800\n97806\n97808\n97811\n97813\n97816\n97817\n97818\n97821\n97825\n97827\n97830\n97831\n97832\n97836\n97840\n97849\n97854\n97858\n97859\n97862\n97864\n97872\n97881\n97889\n97904\n97906\n97915\n97918\n97926\n97931\n97934\n97943\n97946\n97948\n97954\n97955\n97958\n97979\n97987\n97989\n97993\n97994\n97998\n98005\n98010\n98011\n98012\n98013\n98017\n98018\n98019\n98024\n98031\n98034\n98035\n98048\n98051\n98066\n98069\n98073\n98085\n98091\n98094\n98095\n98098\n98100\n98102\n98103\n98104\n98108\n98109\n98110\n98111\n98120\n98121\n98122\n98126\n98129\n98136\n98148\n98162\n98165\n98179\n98180\n98182\n98186\n98195\n98197\n98210\n98212\n98225\n98226\n98229\n98232\n98243\n98247\n98250\n98255\n98261\n98262\n98281\n98284\n98290\n98293\n98295\n98303\n98308\n98311\n98315\n98317\n98320\n98332\n98333\n98341\n98342\n98349\n98350\n98354\n98367\n98370\n98378\n98381\n98384\n98389\n98395\n98401\n98402\n98415\n98417\n98418\n98424\n98426\n98438\n98441\n98443\n98454\n98455\n98468\n98473\n98478\n98482\n98483\n98500\n98506\n98519\n98520\n98531\n98543\n98545\n98546\n98551\n98555\n98557\n98559\n98561\n98568\n98578\n98580\n98582\n98584\n98591\n98596\n98597\n98600\n98617\n98618\n98620\n98631\n98638\n98642\n98648\n98652\n98654\n98664\n98665\n98668\n98686\n98690\n98703\n98705\n98711\n98713\n98716\n98718\n98725\n98739\n98744\n98751\n98754\n98755\n98758\n98761\n98771\n98773\n98782\n98786\n98787\n98788\n98794\n98796\n98797\n98800\n98802\n98803\n98809\n98816\n98822\n98823\n98825\n98830\n98835\n98836\n98837\n98842\n98843\n98845\n98849\n98850\n98856\n98857\n98859\n98862\n98869\n98872\n98880\n98883\n98885\n98888\n98893\n98897\n98899\n98902\n98904\n98908\n98909\n98912\n98913\n98925\n98928\n98929\n98931\n98934\n98939\n98949\n98958\n98961\n98964\n98965\n98970\n98973\n98974\n98975\n98983\n98988\n98992\n98993\n98996\n99000\n99002\n99014\n99016\n99017\n99019\n99021\n99029\n99032\n99037\n99045\n99050\n99052\n99057\n99063\n99066\n99069\n99070\n99082\n99084\n99090\n99109\n99112\n99113\n99118\n99121\n99126\n99141\n99145\n99168\n99184\n99186\n99191\n99196\n99199\n99202\n99204\n99208\n99221\n99226\n99228\n99230\n99233\n99234\n99240\n99246\n99256\n99257\n99268\n99277\n99278\n99280\n99291\n99300\n99306\n99308\n99310\n99326\n99328\n99329\n99330\n99331\n99332\n99336\n99337\n99339\n99341\n99345\n99348\n99349\n99363\n99364\n99374\n99377\n99379\n99382\n99385\n99390\n99401\n99402\n99414\n99416\n99421\n99425\n99433\n99436\n99438\n99449\n99450\n99454\n99458\n99464\n99468\n99469\n99471\n99479\n99485\n99494\n99498\n99504\n99512\n99513\n99534\n99549\n99555\n99562\n99570\n99572\n99574\n99575\n99578\n99581\n99584\n99585\n99594\n99595\n99606\n99611\n99614\n99617\n99619\n99622\n99623\n99633\n99640\n99641\n99644\n99647\n99651\n99654\n99655\n99657\n99662\n99664\n99665\n99669\n99673\n99680\n99681\n99682\n99684\n99689\n99690\n99694\n99707\n99712\n99713\n99714\n99723\n99727\n99732\n99737\n99744\n99747\n99754\n99755\n99762\n99765\n99773\n99784\n99788\n99790\n99791\n99798\n99806\n99819\n99828\n99829\n99842\n99846\n99851\n99855\n99860\n99863\n99869\n99878\n99883\n99884\n99895\n99897\n99900\n99911\n99917\n99918\n99919\n99926\n99931\n99932\n99936\n99937\n99938\n99942\n99945\n99952\n99953\n99960\n99965\n99972\n99974\n99978\n99979\n99985\n99986\n99987\n99989\n99990\n99993\n99996\n99997\n100003\n100004\n100005\n100008\n100012\n100020\n100024\n100026\n100028\n100029\n100035\n100038\n100039\n100043\n100047\n100052\n100055\n100065\n100078\n100081\n100089\n100095\n100105\n100116\n100124\n100134\n100135\n100139\n100140\n100141\n100144\n100151\n100158\n100165\n100168\n100174\n100180\n100188\n100192\n100193\n100197\n100199\n100202\n100208\n100219\n100223\n100236\n100241\n100245\n100246\n100247\n100250\n100252\n100255\n100256\n100258\n100264\n100266\n100269\n100270\n100275\n100280\n100281\n100288\n100289\n100291\n100292\n100293\n100300\n100301\n100302\n100304\n100315\n100321\n100328\n100330\n100343\n100345\n100346\n100348\n100353\n100362\n100363\n100383\n100387\n100389\n100393\n100395\n100405\n100410\n100412\n100413\n100418\n100419\n100421\n100426\n100444\n100449\n100458\n100462\n100471\n100472\n100480\n100484\n100485\n100487\n100493\n100505\n100524\n100529\n100531\n100539\n100545\n100551\n100552\n100554\n100558\n100566\n100571\n100587\n100588\n100589\n100590\n100592\n100596\n100597\n100599\n100615\n100619\n100622\n100634\n100642\n100645\n100646\n100648\n100649\n100652\n100657\n100660\n100670\n100671\n100673\n100676\n100680\n100681\n100685\n100686\n100689\n100700\n100702\n100706\n100708\n100709\n100713\n100715\n100722\n100728\n100735\n100739\n100742\n100748\n100754\n100757\n100759\n100769\n100773\n100774\n100779\n100781\n100786\n100787\n100789\n100815\n100819\n100827\n100837\n100844\n100845\n100850\n100853\n100858\n100860\n100864\n100868\n100872\n100874\n100879\n100888\n100893\n100897\n100899\n100915\n100930\n100933\n100938\n100940\n100941\n100943\n100950\n100972\n100973\n100976\n100987\n100988\n100996\n100998\n101006\n101008\n101012\n101014\n101020\n101021\n101025\n101033\n101046\n101050\n101058\n101063\n101064\n101067\n101073\n101076\n101080\n101083\n101093\n101097\n101103\n101113\n101127\n101140\n101141\n101144\n101153\n101154\n101155\n101157\n101159\n101162\n101165\n101170\n101171\n101179\n101186\n101201\n101208\n101212\n101217\n101218\n101219\n101231\n101240\n101248\n101250\n101260\n101262\n101270\n101279\n101283\n101287\n101290\n101296\n101301\n101324\n101333\n101335\n101343\n101344\n101345\n101348\n101356\n101360\n101371\n101373\n101377\n101380\n101384\n101388\n101401\n101402\n101407\n101412\n101416\n101418\n101419\n101423\n101424\n101437\n101440\n101446\n101454\n101456\n101475\n101476\n101477\n101481\n101482\n101494\n101498\n101500\n101504\n101511\n101521\n101526\n101529\n101536\n101538\n101546\n101554\n101555\n101556\n101558\n101561\n101567\n101568\n101570\n101577\n101578\n101580\n101587\n101588\n101589\n101595\n101600\n101603\n101611\n101612\n101615\n101632\n101633\n101637\n101645\n101652\n101659\n101662\n101668\n101672\n101674\n101680\n101682\n101684\n101685\n101686\n101691\n101693\n101694\n101699\n101717\n101718\n101720\n101728\n101735\n101736\n101737\n101740\n101741\n101742\n101744\n101747\n101750\n101758\n101765\n101770\n101776\n101779\n101780\n101781\n101783\n101790\n101791\n101801\n101806\n101811\n101815\n101820\n101821\n101822\n101827\n101830\n101833\n101835\n101842\n101843\n101844\n101845\n101852\n101855\n101860\n101861\n101864\n101866\n101868\n101869\n101879\n101880\n101881\n101883\n101900\n101913\n101915\n101920\n101923\n101930\n101933\n101934\n101936\n101939\n101944\n101955\n101956\n101972\n101975\n101978\n101980\n101984\n101988\n101990\n101991\n101994\n101995\n101997\n102001\n102006\n102010\n102015\n102017\n102022\n102026\n102029\n102037\n102042\n102046\n102049\n102050\n102062\n102063\n102066\n102079\n102086\n102095\n102099\n102101\n102105\n102114\n102120\n102121\n102122\n102125\n102134\n102137\n102139\n102153\n102161\n102163\n102164\n102176\n102177\n102183\n102190\n102192\n102195\n102196\n102200\n102204\n102214\n102218\n102219\n102220\n102222\n102223\n102231\n102232\n102234\n102252\n102254\n102258\n102263\n102265\n102273\n102276\n102281\n102284\n102300\n102315\n102325\n102333\n102335\n102341\n102342\n102344\n102345\n102346\n102347\n102348\n102355\n102362\n102366\n102371\n102390\n102392\n102393\n102395\n102398\n102399\n102402\n102404\n102412\n102415\n102417\n102420\n102422\n102423\n102427\n102429\n102433\n102436\n102439\n102443\n102444\n102445\n102449\n102456\n102457\n102458\n102462\n102468\n102474\n102477\n102478\n102488\n102491\n102493\n102494\n102496\n102498\n102505\n102514\n102519\n102521\n102525\n102530\n102533\n102538\n102541\n102547\n102555\n102560\n102566\n102574\n102580\n102584\n102593\n102597\n102599\n102607\n102609\n102630\n102632\n102633\n102655\n102657\n102662\n102663\n102665\n102675\n102689\n102690\n102692\n102695\n102697\n102704\n102705\n102710\n102723\n102729\n102733\n102736\n102737\n102738\n102749\n102750\n102756\n102763\n102780\n102787\n102797\n102802\n102805\n102809\n102814\n102815\n102821\n102826\n102827\n102835\n102836\n102839\n102841\n102847\n102865\n102868\n102871\n102890\n102891\n102903\n102905\n102913\n102914\n102925\n102926\n102933\n102936\n102944\n102967\n102970\n102975\n102976\n102977\n102982\n102991\n102992\n102993\n102995\n102996\n103001\n103005\n103008\n103009\n103010\n103011\n103016\n103019\n103029\n103032\n103037\n103040\n103043\n103044\n103060\n103068\n103070\n103075\n103086\n103087\n103089\n103092\n103093\n103100\n103105\n103108\n103113\n103116\n103119\n103123\n103125\n103126\n103127\n103146\n103149\n103152\n103154\n103155\n103164\n103165\n103167\n103184\n103185\n103186\n103191\n103193\n103194\n103210\n103217\n103225\n103231\n103233\n103234\n103243\n103245\n103259\n103260\n103266\n103270\n103285\n103290\n103297\n103302\n103306\n103314\n103324\n103325\n103329\n103333\n103336\n103337\n103347\n103355\n103367\n103368\n103369\n103375\n103376\n103378\n103382\n103386\n103389\n103394\n103395\n103396\n103415\n103420\n103423\n103424\n103427\n103432\n103435\n103442\n103443\n103449\n103455\n103459\n103467\n103470\n103473\n103481\n103489\n103490\n103495\n103497\n103516\n103518\n103522\n103529\n103536\n103539\n103546\n103551\n103563\n103569\n103571\n103576\n103578\n103581\n103584\n103590\n103592\n103596\n103610\n103615\n103617\n103626\n103628\n103630\n103640\n103650\n103654\n103658\n103659\n103665\n103666\n103668\n103669\n103670\n103677\n103683\n103684\n103687\n103693\n103699\n103701\n103703\n103707\n103712\n103715\n103728\n103743\n103747\n103752\n103754\n103758\n103759\n103763\n103775\n103782\n103789\n103795\n103805\n103806\n103807\n103809\n103816\n103821\n103823\n103830\n103831\n103852\n103856\n103865\n103868\n103871\n103873\n103889\n103897\n103898\n103899\n103900\n103902\n103903\n103905\n103908\n103911\n103912\n103920\n103922\n103928\n103935\n103937\n103943\n103952\n103956\n103960\n103966\n103974\n103978\n103980\n103985\n103993\n103994\n104007\n104009\n104014\n104023\n104028\n104034\n104041\n104043\n104044\n104045\n104052\n104056\n104062\n104065\n104069\n104071\n104074\n104083\n104088\n104089\n104090\n104092\n104094\n104096\n104098\n104105\n104111\n104118\n104127\n104139\n104144\n104152\n104162\n104164\n104179\n104190\n104193\n104197\n104199\n104200\n104203\n104207\n104210\n104212\n104216\n104217\n104223\n104237\n104241\n104245\n104252\n104254\n104258\n104272\n104276\n104284\n104285\n104288\n104296\n104298\n104299\n104301\n104302\n104306\n104313\n104315\n104316\n104325\n104326\n104331\n104332\n104342\n104343\n104356\n104361\n104366\n104367\n104369\n104371\n104373\n104374\n104375\n104380\n104386\n104389\n104392\n104394\n104395\n104396\n104397\n104410\n104413\n104417\n104424\n104427\n104430\n104437\n104438\n104440\n104444\n104445\n104455\n104456\n104462\n104464\n104471\n104488\n104489\n104500\n104501\n104508\n104509\n104511\n104514\n104521\n104524\n104528\n104532\n104549\n104550\n104558\n104564\n104565\n104568\n104571\n104573\n104577\n104579\n104593\n104595\n104614\n104621\n104622\n104625\n104630\n104631\n104634\n104642\n104645\n104653\n104654\n104657\n104658\n104661\n104668\n104672\n104673\n104682\n104684\n104685\n104688\n104691\n104700\n104701\n104705\n104708\n104709\n104757\n104762\n104766\n104770\n104773\n104781\n104786\n104787\n104794\n104796\n104804\n104806\n104809\n104818\n104825\n104827\n104830\n104842\n104850\n104859\n104863\n104871\n104873\n104874\n104879\n104885\n104891\n104900\n104904\n104907\n104910\n104911\n104913\n104917\n104918\n104919\n104921\n104923\n104925\n104937\n104938\n104939\n104942\n104947\n104958\n104963\n104965\n104974\n104975\n104976\n104977\n104978\n104983\n105002\n105004\n105010\n105012\n105013\n105016\n105017\n105018\n105019\n105021\n105026\n105031\n105035\n105042\n105043\n105051\n105054\n105058\n105061\n105062\n105063\n105065\n105068\n105070\n105071\n105076\n105080\n105085\n105086\n105090\n105091\n105097\n105100\n105103\n105104\n105105\n105128\n105130\n105133\n105144\n105147\n105150\n105155\n105159\n105162\n105181\n105191\n105192\n105193\n105194\n105195\n105196\n105201\n105203\n105205\n105207\n105208\n105212\n105218\n105221\n105229\n105231\n105235\n105237\n105240\n105241\n105243\n105247\n105250\n105255\n105256\n105258\n105265\n105267\n105271\n105281\n105284\n105290\n105291\n105298\n105304\n105308\n105309\n105310\n105324\n105326\n105327\n105328\n105330\n105331\n105346\n105349\n105353\n105369\n105371\n105372\n105382\n105384\n105389\n105396\n105398\n105399\n105410\n105411\n105416\n105418\n105426\n105432\n105439\n105440\n105442\n105451\n105454\n105460\n105465\n105485\n105486\n105492\n105497\n105500\n105502\n105510\n105512\n105514\n105515\n105522\n105525\n105533\n105537\n105544\n105548\n105552\n105554\n105561\n105563\n105564\n105579\n105586\n105594\n105598\n105604\n105606\n105617\n105622\n105627\n105628\n105635\n105637\n105639\n105641\n105644\n105675\n105689\n105695\n105701\n105704\n105707\n105710\n105714\n105716\n105717\n105721\n105723\n105724\n105726\n105740\n105744\n105746\n105747\n105752\n105753\n105759\n105783\n105785\n105789\n105802\n105814\n105815\n105818\n105827\n105830\n105831\n105846\n105847\n105856\n105863\n105879\n105883\n105889\n105894\n105897\n105904\n105907\n105909\n105912\n105927\n105931\n105936\n105940\n105945\n105952\n105957\n105958\n105960\n105961\n105963\n105968\n105970\n105978\n105979\n105980\n105981\n105989\n105990\n106008\n106011\n106016\n106017\n106020\n106022\n106023\n106027\n106030\n106034\n106036\n106038\n106042\n106045\n106050\n106051\n106052\n106053\n106061\n106063\n106064\n106067\n106073\n106090\n106092\n106106\n106108\n106115\n106121\n106125\n106130\n106133\n106134\n106136\n106142\n106146\n106151\n106164\n106166\n106175\n106176\n106180\n106186\n106190\n106192\n106194\n106195\n106203\n106208\n106216\n106217\n106220\n106226\n106227\n106235\n106241\n106243\n106251\n106254\n106262\n106270\n106277\n106286\n106287\n106288\n106291\n106296\n106301\n106303\n106308\n106309\n106311\n106332\n106333\n106340\n106343\n106348\n106349\n106360\n106365\n106367\n106375\n106376\n106382\n106389\n106394\n106395\n106402\n106410\n106426\n106427\n106437\n106439\n106442\n106446\n106447\n106450\n106451\n106454\n106456\n106457\n106461\n106462\n106468\n106481\n106485\n106488\n106491\n106496\n106498\n106500\n106505\n106506\n106517\n106521\n106522\n106529\n106530\n106531\n106533\n106535\n106539\n106542\n106545\n106564\n106565\n106566\n106569\n106570\n106573\n106580\n106581\n106582\n106590\n106592\n106595\n106597\n106600\n106613\n106615\n106619\n106622\n106623\n106626\n106631\n106634\n106635\n106639\n106657\n106658\n106659\n106660\n106668\n106672\n106691\n106693\n106694\n106708\n106712\n106724\n106727\n106729\n106733\n106734\n106736\n106737\n106740\n106743\n106744\n106746\n106749\n106757\n106762\n106763\n106765\n106766\n106767\n106770\n106780\n106792\n106796\n106797\n106809\n106812\n106816\n106822\n106826\n106827\n106828\n106838\n106840\n106843\n106844\n106849\n106854\n106858\n106860\n106861\n106864\n106867\n106870\n106881\n106882\n106889\n106899\n106907\n106908\n106909\n106925\n106931\n106937\n106940\n106952\n106954\n106956\n106961\n106966\n106974\n106977\n106985\n106990\n107000\n107002\n107005\n107009\n107021\n107022\n107031\n107032\n107044\n107046\n107049\n107053\n107056\n107057\n107059\n107066\n107083\n107086\n107089\n107090\n107092\n107093\n107094\n107098\n107107\n107108\n107109\n107110\n107113\n107114\n107117\n107124\n107129\n107136\n107155\n107156\n107157\n107160\n107161\n107162\n107164\n107174\n107176\n107179\n107182\n107184\n107204\n107206\n107210\n107218\n107225\n107227\n107252\n107253\n107254\n107260\n107263\n107267\n107270\n107271\n107272\n107274\n107282\n107287\n107290\n107297\n107330\n107337\n107338\n107349\n107368\n107371\n107372\n107373\n107381\n107395\n107408\n107413\n107415\n107417\n107427\n107428\n107429\n107432\n107435\n107442\n107447\n107455\n107457\n107459\n107463\n107473\n107476\n107478\n107481\n107488\n107504\n107508\n107518\n107527\n107530\n107534\n107536\n107546\n107547\n107556\n107560\n107561\n107562\n107573\n107575\n107576\n107577\n107580\n107599\n107613\n107614\n107615\n107617\n107621\n107627\n107638\n107652\n107667\n107670\n107671\n107673\n107680\n107682\n107683\n107686\n107687\n107690\n107691\n107695\n107697\n107698\n107704\n107711\n107712\n107714\n107720\n107724\n107728\n107731\n107747\n107756\n107760\n107766\n107767\n107769\n107771\n107774\n107776\n107790\n107791\n107792\n107796\n107801\n107806\n107807\n107812\n107814\n107815\n107817\n107829\n107833\n107870\n107878\n107882\n107883\n107894\n107897\n107900\n107903\n107904\n107910\n107913\n107918\n107922\n107923\n107927\n107928\n107930\n107934\n107940\n107949\n107953\n107964\n107966\n107976\n107984\n107987\n108001\n108004\n108006\n108011\n108015\n108016\n108017\n108034\n108036\n108041\n108047\n108056\n108058\n108073\n108077\n108080\n108088\n108092\n108093\n108097\n108106\n108111\n108114\n108118\n108122\n108148\n108153\n108155\n108158\n108159\n108171\n108172\n108173\n108174\n108180\n108184\n108195\n108198\n108206\n108208\n108212\n108217\n108219\n108232\n108237\n108240\n108248\n108251\n108254\n108255\n108258\n108270\n108277\n108280\n108282\n108293\n108298\n108308\n108309\n108316\n108319\n108320\n108325\n108330\n108332\n108335\n108337\n108338\n108342\n108344\n108347\n108358\n108369\n108371\n108372\n108375\n108381\n108386\n108390\n108398\n108403\n108406\n108411\n108412\n108418\n108419\n108425\n108427\n108429\n108433\n108448\n108451\n108460\n108464\n108466\n108469\n108477\n108478\n108481\n108482\n108489\n108491\n108493\n108506\n108509\n108513\n108515\n108523\n108524\n108528\n108532\n108538\n108539\n108541\n108546\n108549\n108552\n108555\n108557\n108571\n108575\n108578\n108586\n108602\n108609\n108611\n108612\n108625\n108637\n108643\n108644\n108650\n108651\n108657\n108662\n108665\n108673\n108678\n108688\n108689\n108693\n108712\n108713\n108715\n108717\n108738\n108755\n108757\n108759\n108761\n108762\n108770\n108773\n108774\n108777\n108792\n108795\n108803\n108809\n108810\n108823\n108830\n108838\n108842\n108861\n108862\n108863\n108864\n108877\n108886\n108889\n108892\n108901\n108903\n108904\n108909\n108917\n108918\n108921\n108923\n108924\n108929\n108932\n108938\n108940\n108942\n108949\n108951\n108952\n108955\n108956\n108962\n108968\n108969\n108973\n108976\n108981\n108986\n108992\n108999\n109004\n109011\n109014\n109022\n109033\n109038\n109039\n109040\n109043\n109045\n109047\n109049\n109050\n109054\n109059\n109061\n109073\n109077\n109097\n109103\n109110\n109114\n109117\n109119\n109126\n109131\n109133\n109137\n109142\n109144\n109151\n109154\n109161\n109180\n109181\n109185\n109188\n109190\n109192\n109193\n109197\n109200\n109202\n109205\n109214\n109219\n109232\n109249\n109254\n109255\n109257\n109269\n109270\n109272\n109277\n109286\n109290\n109293\n109299\n109301\n109302\n109307\n109312\n109314\n109329\n109337\n109346\n109350\n109355\n109361\n109374\n109375\n109378\n109381\n109391\n109397\n109401\n109404\n109419\n109439\n109440\n109441\n109446\n109447\n109451\n109463\n109464\n109465\n109468\n109470\n109492\n109493\n109494\n109495\n109498\n109504\n109507\n109516\n109534\n109538\n109542\n109543\n109544\n109546\n109547\n109550\n109557\n109568\n109572\n109581\n109595\n109597\n109599\n109601\n109602\n109607\n109611\n109614\n109617\n109623\n109631\n109634\n109638\n109640\n109642\n109646\n109655\n109656\n109662\n109665\n109667\n109670\n109673\n109674\n109678\n109683\n109684\n109700\n109709\n109716\n109719\n109721\n109724\n109731\n109739\n109740\n109741\n109749\n109750\n109752\n109754\n109758\n109768\n109775\n109778\n109780\n109782\n109787\n109792\n109794\n109799\n109808\n109824\n109825\n109828\n109832\n109835\n109838\n109839\n109840\n109843\n109849\n109853\n109855\n109859\n109860\n109862\n109864\n109865\n109871\n109872\n109876\n109894\n109897\n109899\n109901\n109902\n109907\n109910\n109914\n109918\n109930\n109935\n109954\n109965\n109973\n109974\n109988\n109990\n109994\n110007\n110009\n110017\n110018\n110019\n110021\n110027\n110028\n110041\n110043\n110045\n110046\n110047\n110052\n110054\n110056\n110065\n110066\n110069\n110072\n110076\n110093\n110097\n110100\n110104\n110107\n110115\n110116\n110134\n110138\n110145\n110146\n110152\n110159\n110164\n110165\n110175\n110183\n110193\n110195\n110199\n110207\n110217\n110222\n110224\n110229\n110233\n110260\n110265\n110268\n110275\n110277\n110279\n110289\n110290\n110293\n110300\n110312\n110318\n110324\n110326\n110327\n110328\n110341\n110352\n110355\n110356\n110357\n110358\n110364\n110366\n110368\n110377\n110380\n110382\n110386\n110387\n110388\n110389\n110399\n110407\n110421\n110424\n110427\n110428\n110431\n110435\n110437\n110441\n110448\n110450\n110464\n110468\n110469\n110471\n110473\n110483\n110493\n110499\n110510\n110517\n110519\n110528\n110539\n110540\n110541\n110546\n110548\n110551\n110555\n110556\n110558\n110559\n110560\n110561\n110569\n110576\n110578\n110580\n110583\n110586\n110593\n110598\n110603\n110604\n110607\n110608\n110611\n110615\n110620\n110622\n110625\n110628\n110629\n110630\n110631\n110640\n110646\n110656\n110657\n110666\n110673\n110674\n110682\n110687\n110689\n110691\n110693\n110704\n110707\n110711\n110716\n110718\n110720\n110723\n110726\n110728\n110731\n110739\n110744\n110745\n110748\n110751\n110753\n110763\n110765\n110772\n110778\n110779\n110785\n110799\n110807\n110808\n110814\n110820\n110837\n110845\n110847\n110850\n110852\n110853\n110857\n110866\n110868\n110869\n110870\n110872\n110876\n110882\n110884\n110888\n110897\n110900\n110901\n110905\n110911\n110913\n110919\n110920\n110923\n110928\n110930\n110933\n110936\n110946\n110949\n110951\n110953\n110954\n110956\n110960\n110963\n110985\n110993\n110997\n110998\n111003\n111011\n111017\n111023\n111028\n111031\n111033\n111034\n111037\n111038\n111041\n111047\n111049\n111059\n111062\n111069\n111070\n111080\n111083\n111084\n111091\n111098\n111101\n111102\n111105\n111109\n111112\n111117\n111118\n111121\n111134\n111139\n111144\n111152\n111153\n111159\n111166\n111169\n111172\n111173\n111181\n111182\n111183\n111185\n111196\n111203\n111206\n111207\n111213\n111217\n111221\n111223\n111225\n111227\n111230\n111231\n111254\n111257\n111273\n111276\n111280\n111283\n111286\n111304\n111316\n111319\n111331\n111333\n111334\n111346\n111351\n111360\n111363\n111366\n111367\n111371\n111373\n111375\n111381\n111388\n111391\n111405\n111406\n111407\n111408\n111417\n111424\n111433\n111441\n111447\n111449\n111450\n111451\n111455\n111463\n111470\n111475\n111478\n111485\n111489\n111495\n111501\n111505\n111516\n111517\n111521\n111530\n111533\n111534\n111539\n111541\n111543\n111558\n111560\n111564\n111568\n111571\n111579\n111583\n111590\n111592\n111593\n111594\n111595\n111597\n111599\n111600\n111620\n111621\n111633\n111636\n111645\n111647\n111649\n111652\n111654\n111661\n111672\n111677\n111678\n111684\n111692\n111693\n111695\n111700\n111703\n111713\n111716\n111725\n111728\n111736\n111737\n111738\n111744\n111745\n111752\n111757\n111762\n111765\n111768\n111770\n111774\n111776\n111791\n111795\n111796\n111797\n111805\n111808\n111810\n111821\n111827\n111828\n111837\n111838\n111847\n111854\n111865\n111867\n111870\n111871\n111872\n111873\n111874\n111888\n111891\n111900\n111901\n111912\n111914\n111931\n111949\n111954\n111955\n111960\n111961\n111963\n111964\n111965\n111967\n111970\n111971\n111972\n111974\n111986\n111988\n111992\n112000\n112007\n112020\n112022\n112024\n112030\n112039\n112041\n112054\n112060\n112065\n112066\n112069\n112071\n112079\n112081\n112085\n112087\n112094\n112103\n112110\n112115\n112119\n112120\n112124\n112126\n112127\n112133\n112136\n112138\n112141\n112145\n112148\n112153\n112160\n112166\n112168\n112173\n112175\n112177\n112187\n112189\n112199\n112200\n112204\n112225\n112226\n112228\n112236\n112237\n112241\n112245\n112249\n112267\n112278\n112287\n112293\n112296\n112297\n112298\n112302\n112303\n112304\n112305\n112311\n112312\n112321\n112328\n112330\n112334\n112336\n112337\n112339\n112346\n112351\n112357\n112358\n112362\n112367\n112373\n112378\n112381\n112382\n112395\n112405\n112413\n112415\n112417\n112434\n112438\n112442\n112447\n112448\n112449\n112459\n112466\n112468\n112476\n112483\n112486\n112489\n112495\n112499\n112501\n112502\n112503\n112510\n112513\n112520\n112521\n112522\n112529\n112531\n112534\n112540\n112541\n112544\n112553\n112554\n112560\n112561\n112564\n112567\n112576\n112578\n112586\n112590\n112599\n112601\n112604\n112628\n112634\n112639\n112643\n112648\n112649\n112657\n112664\n112666\n112667\n112670\n112679\n112684\n112687\n112689\n112690\n112692\n112694\n112699\n112702\n112711\n112714\n112715\n112720\n112721\n112724\n112727\n112734\n112738\n112739\n112740\n112743\n112744\n112746\n112749\n112750\n112771\n112774\n112785\n112797\n112802\n112806\n112816\n112822\n112828\n112832\n112836\n112839\n112841\n112862\n112872\n112874\n112876\n112881\n112882\n112883\n112884\n112885\n112893\n112900\n112901\n112910\n112912\n112928\n112932\n112937\n112939\n112944\n112954\n112958\n112959\n112965\n112970\n112971\n112978\n112994\n112997\n113005\n113006\n113007\n113010\n113012\n113022\n113025\n113042\n113045\n113046\n113048\n113050\n113056\n113062\n113064\n113066\n113068\n113073\n113077\n113086\n113092\n113094\n113101\n113105\n113108\n113111\n113113\n113114\n113119\n113123\n113144\n113146\n113158\n113165\n113170\n113171\n113177\n113184\n113189\n113190\n113193\n113199\n113204\n113206\n113212\n113213\n113222\n113229\n113231\n113232\n113236\n113243\n113244\n113246\n113247\n113250\n113253\n113259\n113266\n113281\n113287\n113290\n113297\n113298\n113302\n113303\n113309\n113313\n113315\n113321\n113331\n113338\n113340\n113350\n113351\n113352\n113362\n113371\n113373\n113374\n113376\n113378\n113389\n113397\n113401\n113408\n113409\n113416\n113421\n113426\n113440\n113451\n113453\n113458\n113462\n113465\n113468\n113469\n113470\n113471\n113473\n113484\n113489\n113494\n113495\n113500\n113510\n113514\n113538\n113543\n113547\n113549\n113568\n113576\n113584\n113585\n113598\n113607\n113608\n113615\n113621\n113622\n113626\n113628\n113631\n113645\n113656\n113672\n113675\n113680\n113682\n113692\n113694\n113696\n113698\n113700\n113709\n113717\n113719\n113723\n113725\n113727\n113728\n113732\n113737\n113738\n113745\n113746\n113760\n113762\n113763\n113764\n113784\n113787\n113789\n113790\n113798\n113804\n113808\n113809\n113812\n113816\n113818\n113823\n113834\n113835\n113838\n113844\n113849\n113850\n113854\n113856\n113868\n113870\n113879\n113897\n113899\n113902\n113913\n113917\n113918\n113926\n113932\n113934\n113936\n113942\n113946\n113947\n113951\n113961\n113962\n113964\n113971\n113974\n113975\n113978\n113993\n113997\n114003\n114004\n114008\n114016\n114017\n114023\n114024\n114026\n114027\n114028\n114034\n114054\n114057\n114060\n114063\n114067\n114069\n114071\n114073\n114074\n114082\n114083\n114086\n114091\n114094\n114100\n114104\n114120\n114122\n114125\n114129\n114131\n114134\n114135\n114137\n114138\n114141\n114143\n114148\n114149\n114158\n114160\n114161\n114165\n114173\n114183\n114185\n114196\n114203\n114209\n114211\n114213\n114227\n114235\n114239\n114243\n114246\n114247\n114249\n114250\n114251\n114254\n114259\n114262\n114264\n114266\n114267\n114270\n114271\n114275\n114276\n114281\n114292\n114309\n114311\n114312\n114325\n114327\n114329\n114331\n114333\n114337\n114341\n114343\n114344\n114352\n114355\n114357\n114371\n114372\n114382\n114389\n114398\n114404\n114405\n114407\n114416\n114420\n114427\n114430\n114432\n114433\n114438\n114448\n114465\n114467\n114473\n114481\n114486\n114487\n114500\n114501\n114506\n114518\n114522\n114528\n114529\n114538\n114540\n114542\n114544\n114547\n114561\n114569\n114576\n114579\n114580\n114584\n114602\n114604\n114611\n114620\n114626\n114643\n114649\n114650\n114651\n114662\n114666\n114667\n114675\n114680\n114681\n114684\n114686\n114688\n114691\n114697\n114698\n114700\n114714\n114722\n114723\n114726\n114731\n114733\n114734\n114735\n114741\n114744\n114745\n114746\n114750\n114752\n114755\n114758\n114767\n114773\n114779\n114785\n114795\n114800\n114804\n114806\n114814\n114829\n114834\n114835\n114844\n114845\n114847\n114848\n114849\n114851\n114852\n114859\n114861\n114862\n114864\n114867\n114876\n114887\n114890\n114891\n114903\n114905\n114913\n114916\n114920\n114923\n114928\n114938\n114955\n114957\n114960\n114962\n114964\n114969\n114972\n114985\n114992\n114995\n114997\n115007\n115025\n115027\n115040\n115047\n115049\n115053\n115056\n115059\n115068\n115070\n115071\n115073\n115074\n115075\n115083\n115085\n115088\n115089\n115099\n115109\n115115\n115121\n115128\n115130\n115131\n115138\n115142\n115153\n115155\n115158\n115167\n115172\n115174\n115189\n115191\n115205\n115206\n115210\n115221\n115226\n115232\n115238\n115239\n115242\n115249\n115255\n115261\n115273\n115274\n115275\n115276\n115281\n115292\n115307\n115309\n115316\n115319\n115333\n115335\n115336\n115337\n115340\n115341\n115348\n115351\n115353\n115354\n115355\n115364\n115369\n115370\n115380\n115383\n115391\n115401\n115407\n115416\n115423\n115424\n115425\n115426\n115434\n115436\n115450\n115452\n115458\n115464\n115466\n115474\n115482\n115485\n115492\n115494\n115497\n115499\n115500\n115505\n115513\n115515\n115523\n115526\n115528\n115530\n115534\n115555\n115556\n115557\n115559\n115560\n115566\n115576\n115588\n115592\n115598\n115599\n115610\n115615\n115622\n115629\n115633\n115635\n115662\n115679\n115680\n115694\n115701\n115703\n115704\n115705\n115710\n115711\n115741\n115744\n115747\n115753\n115757\n115767\n115770\n115775\n115785\n115793\n115796\n115811\n115814\n115824\n115825\n115831\n115834\n115837\n115840\n115841\n115846\n115849\n115851\n115854\n115855\n115864\n115867\n115873\n115878\n115879\n115882\n115886\n115887\n115888\n115895\n115905\n115907\n115909\n115916\n115917\n115920\n115922\n115927\n115931\n115935\n115936\n115937\n115938\n115946\n115956\n115958\n115959\n115962\n115966\n115968\n115973\n115994\n115999\n116002\n116003\n116005\n116008\n116013\n116015\n116017\n116019\n116021\n116029\n116030\n116033\n116035\n116038\n116049\n116055\n116056\n116069\n116072\n116076\n116080\n116082\n116090\n116092\n116096\n116103\n116107\n116114\n116116\n116117\n116119\n116124\n116128\n116130\n116132\n116146\n116154\n116155\n116158\n116159\n116164\n116171\n116178\n116181\n116206\n116212\n116226\n116228\n116229\n116230\n116234\n116235\n116237\n116242\n116246\n116248\n116256\n116271\n116277\n116287\n116295\n116297\n116299\n116301\n116307\n116320\n116329\n116332\n116337\n116341\n116342\n116343\n116345\n116353\n116355\n116363\n116367\n116373\n116375\n116376\n116377\n116379\n116380\n116383\n116385\n116388\n116397\n116402\n116405\n116409\n116410\n116415\n116419\n116424\n116426\n116428\n116431\n116433\n116441\n116444\n116446\n116449\n116452\n116472\n116474\n116477\n116478\n116479\n116480\n116492\n116498\n116504\n116509\n116511\n116515\n116517\n116522\n116524\n116527\n116538\n116543\n116546\n116547\n116555\n116557\n116566\n116568\n116573\n116574\n116577\n116584\n116594\n116605\n116607\n116608\n116613\n116627\n116628\n116629\n116632\n116633\n116636\n116638\n116656\n116667\n116668\n116669\n116671\n116673\n116674\n116681\n116683\n116684\n116685\n116691\n116693\n116698\n116699\n116700\n116702\n116710\n116721\n116723\n116724\n116731\n116737\n116738\n116739\n116747\n116756\n116767\n116770\n116774\n116780\n116789\n116796\n116800\n116805\n116815\n116824\n116828\n116829\n116838\n116845\n116855\n116857\n116858\n116866\n116873\n116874\n116885\n116893\n116894\n116898\n116901\n116909\n116911\n116918\n116919\n116930\n116934\n116936\n116940\n116942\n116943\n116946\n116949\n116954\n116957\n116959\n116965\n116974\n116983\n116986\n116987\n116991\n117004\n117007\n117022\n117023\n117031\n117035\n117041\n117044\n117047\n117050\n117059\n117072\n117077\n117080\n117081\n117082\n117087\n117095\n117098\n117105\n117109\n117112\n117118\n117120\n117129\n117131\n117132\n117135\n117140\n117160\n117183\n117187\n117196\n117197\n117198\n117200\n117212\n117220\n117223\n117232\n117235\n117236\n117239\n117252\n117254\n117259\n117261\n117264\n117265\n117277\n117285\n117290\n117291\n117296\n117304\n117306\n117309\n117321\n117330\n117345\n117347\n117372\n117377\n117389\n117392\n117393\n117394\n117403\n117405\n117415\n117423\n117437\n117446\n117448\n117466\n117476\n117483\n117486\n117491\n117492\n117497\n117502\n117507\n117511\n117512\n117525\n117534\n117538\n117551\n117552\n117559\n117563\n117566\n117569\n117571\n117581\n117585\n117589\n117592\n117598\n117601\n117604\n117606\n117607\n117611\n117618\n117622\n117633\n117641\n117649\n117654\n117655\n117656\n117659\n117661\n117665\n117666\n117675\n117677\n117678\n117679\n117681\n117683\n117684\n117694\n117698\n117703\n117704\n117709\n117713\n117715\n117718\n117720\n117722\n117736\n117747\n117752\n117755\n117757\n117758\n117768\n117773\n117775\n117783\n117786\n117788\n117792\n117800\n117803\n117807\n117808\n117811\n117818\n117822\n117825\n117829\n117832\n117835\n117836\n117837\n117841\n117842\n117851\n117853\n117858\n117863\n117864\n117870\n117871\n117878\n117879\n117888\n117894\n117898\n117900\n117903\n117906\n117907\n117908\n117919\n117922\n117925\n117926\n117930\n117931\n117944\n117946\n117949\n117951\n117955\n117957\n117958\n117976\n117980\n117983\n117988\n117995\n118001\n118002\n118019\n118025\n118030\n118035\n118040\n118046\n118052\n118057\n118059\n118063\n118074\n118077\n118079\n118080\n118093\n118096\n118097\n118099\n118101\n118109\n118111\n118116\n118127\n118129\n118134\n118138\n118155\n118161\n118164\n118166\n118171\n118175\n118190\n118192\n118195\n118197\n118198\n118206\n118210\n118211\n118220\n118227\n118244\n118253\n118259\n118260\n118265\n118266\n118267\n118276\n118279\n118284\n118287\n118302\n118303\n118306\n118318\n118321\n118323\n118324\n118336\n118337\n118342\n118350\n118351\n118353\n118354\n118355\n118357\n118359\n118366\n118367\n118372\n118386\n118397\n118400\n118409\n118417\n118420\n118421\n118428\n118435\n118450\n118453\n118460\n118462\n118463\n118464\n118466\n118467\n118469\n118483\n118486\n118490\n118500\n118503\n118510\n118516\n118518\n118521\n118535\n118541\n118553\n118559\n118570\n118572\n118578\n118580\n118582\n118586\n118587\n118594\n118596\n118599\n118602\n118604\n118606\n118622\n118628\n118636\n118637\n118643\n118644\n118646\n118650\n118652\n118655\n118657\n118677\n118687\n118690\n118694\n118700\n118701\n118704\n118710\n118727\n118729\n118741\n118742\n118744\n118752\n118754\n118763\n118765\n118766\n118767\n118777\n118779\n118785\n118787\n118789\n118801\n118803\n118811\n118812\n118819\n118825\n118826\n118838\n118848\n118858\n118859\n118864\n118865\n118867\n118872\n118874\n118882\n118885\n118887\n118889\n118890\n118891\n118893\n118894\n118896\n118901\n118909\n118912\n118913\n118919\n118920\n118922\n118928\n118929\n118936\n118938\n118940\n118943\n118944\n118946\n118949\n118950\n118951\n118956\n118959\n118965\n118973\n118976\n118978\n118988\n118994\n119002\n119010\n119019\n119021\n119022\n119025\n119027\n119031\n119033\n119034\n119041\n119045\n119048\n119050\n119065\n119069\n119070\n119071\n119081\n119091\n119092\n119094\n119103\n119104\n119109\n119110\n119116\n119119\n119122\n119124\n119125\n119126\n119127\n119132\n119133\n119136\n119139\n119158\n119165\n119178\n119179\n119182\n119187\n119188\n119192\n119193\n119194\n119195\n119196\n119201\n119208\n119212\n119219\n119225\n119228\n119229\n119233\n119237\n119242\n119260\n119263\n119269\n119271\n119272\n119273\n119274\n119275\n119277\n119279\n119281\n119282\n119287\n119327\n119329\n119332\n119339\n119343\n119361\n119362\n119364\n119365\n119373\n119383\n119384\n119388\n119391\n119398\n119405\n119428\n119435\n119440\n119450\n119455\n119462\n119481\n119490\n119502\n119506\n119509\n119515\n119518\n119522\n119536\n119537\n119540\n119544\n119545\n119550\n119554\n119555\n119559\n119562\n119565\n119586\n119590\n119591\n119592\n119594\n119604\n119605\n119610\n119613\n119614\n119618\n119620\n119632\n119652\n119654\n119655\n119658\n119666\n119673\n119678\n119680\n119686\n119699\n119701\n119703\n119704\n119714\n119715\n119727\n119733\n119734\n119743\n119746\n119756\n119770\n119772\n119773\n119778\n119780\n119782\n119785\n119787\n119795\n119796\n119808\n119809\n119811\n119820\n119821\n119824\n119829\n119835\n119843\n119847\n119851\n119858\n119860\n119861\n119874\n119884\n119892\n119896\n119901\n119913\n119932\n119935\n119939\n119941\n119942\n119944\n119949\n119950\n119968\n119974\n119977\n119986\n119989\n119993\n119997\n119998\n120001\n120006\n120010\n120015\n120016\n120023\n120025\n120028\n120031\n120033\n120035\n120037\n120038\n120041\n120058\n120061\n120063\n120064\n120070\n120072\n120073\n120083\n120084\n120088\n120100\n120102\n120103\n120104\n120114\n120115\n120125\n120126\n120135\n120136\n120149\n120153\n120159\n120162\n120171\n120179\n120180\n120182\n120186\n120194\n120200\n120202\n120213\n120215\n120217\n120219\n120228\n120230\n120233\n120234\n120240\n120248\n120250\n120257\n120258\n120259\n120262\n120264\n120265\n120277\n120281\n120284\n120285\n120288\n120296\n120299\n120301\n120312\n120323\n120329\n120344\n120348\n120353\n120354\n120357\n120374\n120383\n120384\n120386\n120388\n120398\n120408\n120417\n120420\n120422\n120423\n120426\n120435\n120445\n120450\n120452\n120456\n120473\n120476\n120481\n120483\n120487\n120491\n120496\n120498\n120500\n120502\n120506\n120507\n120517\n120521\n120525\n120530\n120533\n120541\n120542\n120543\n120557\n120568\n120587\n120588\n120589\n120592\n120604\n120611\n120616\n120628\n120629\n120630\n120635\n120639\n120642\n120644\n120647\n120648\n120649\n120651\n120657\n120658\n120662\n120665\n120676\n120677\n120679\n120683\n120686\n120688\n120715\n120718\n120719\n120735\n120738\n120740\n120744\n120748\n120750\n120755\n120757\n120766\n120767\n120768\n120772\n120773\n120774\n120775\n120780\n120781\n120786\n120788\n120796\n120797\n120803\n120805\n120808\n120810\n120821\n120822\n120824\n120830\n120831\n120836\n120841\n120844\n120847\n120854\n120856\n120858\n120859\n120871\n120873\n120876\n120887\n120888\n120895\n120901\n120904\n120911\n120912\n120917\n120922\n120923\n120929\n120936\n120939\n120941\n120945\n120951\n120953\n120954\n120965\n120966\n120971\n120973\n120974\n120976\n120992\n120994\n121011\n121016\n121020\n121026\n121031\n121035\n121038\n121043\n121050\n121064\n121065\n121073\n121085\n121095\n121096\n121101\n121104\n121115\n121116\n121117\n121119\n121121\n121124\n121126\n121141\n121142\n121149\n121154\n121166\n121170\n121178\n121183\n121184\n121198\n121200\n121207\n121208\n121209\n121216\n121221\n121225\n121226\n121233\n121238\n121243\n121251\n121255\n121259\n121261\n121265\n121275\n121286\n121288\n121291\n121292\n121293\n121297\n121300\n121309\n121310\n121311\n121312\n121320\n121322\n121332\n121340\n121341\n121348\n121373\n121374\n121376\n121379\n121380\n121387\n121389\n121393\n121400\n121402\n121419\n121421\n121426\n121432\n121437\n121444\n121451\n121454\n121455\n121463\n121466\n121468\n121470\n121471\n121484\n121491\n121492\n121495\n121498\n121499\n121504\n121508\n121510\n121515\n121524\n121525\n121528\n121529\n121532\n121536\n121540\n121543\n121549\n121551\n121552\n121555\n121569\n121572\n121577\n121582\n121585\n121588\n121594\n121603\n121612\n121614\n121615\n121616\n121620\n121622\n121625\n121632\n121633\n121637\n121638\n121640\n121644\n121676\n121689\n121691\n121692\n121699\n121701\n121703\n121704\n121705\n121707\n121712\n121715\n121725\n121729\n121737\n121740\n121748\n121750\n121767\n121778\n121779\n121798\n121803\n121804\n121805\n121806\n121807\n121812\n121818\n121820\n121827\n121832\n121834\n121841\n121848\n121850\n121856\n121858\n121862\n121863\n121866\n121876\n121880\n121881\n121882\n121886\n121889\n121893\n121900\n121905\n121912\n121920\n121921\n121950\n121961\n121963\n121972\n121974\n121984\n121989\n121995\n122000\n122021\n122033\n122037\n122054\n122058\n122059\n122075\n122078\n122079\n122080\n122084\n122088\n122100\n122110\n122115\n122121\n122127\n122133\n122135\n122139\n122146\n122151\n122160\n122163\n122164\n122173\n122178\n122187\n122195\n122212\n122214\n122224\n122225\n122242\n122245\n122247\n122250\n122266\n122267\n122274\n122277\n122281\n122282\n122296\n122299\n122301\n122303\n122304\n122305\n122306\n122312\n122321\n122325\n122328\n122331\n122342\n122358\n122369\n122372\n122379\n122385\n122388\n122396\n122402\n122409\n122427\n122432\n122440\n122442\n122444\n122451\n122456\n122471\n122479\n122485\n122491\n122492\n122498\n122499\n122503\n122508\n122510\n122514\n122515\n122520\n122523\n122526\n122527\n122529\n122536\n122541\n122548\n122549\n122562\n122565\n122570\n122576\n122581\n122601\n122604\n122612\n122614\n122616\n122659\n122669\n122673\n122678\n122684\n122686\n122688\n122691\n122696\n122698\n122705\n122708\n122709\n122710\n122714\n122716\n122722\n122740\n122754\n122755\n122761\n122763\n122768\n122770\n122782\n122784\n122786\n122790\n122794\n122797\n122800\n122805\n122811\n122817\n122823\n122831\n122835\n122852\n122857\n122865\n122866\n122868\n122870\n122872\n122873\n122876\n122877\n122883\n122885\n122895\n122898\n122911\n122912\n122914\n122924\n122926\n122934\n122940\n122949\n122963\n122967\n122974\n122982\n122987\n122997\n123000\n123004\n123006\n123008\n123013\n123014\n123017\n123018\n123021\n123031\n123049\n123059\n123073\n123074\n123082\n123084\n123087\n123094\n123095\n123096\n123116\n123122\n123129\n123132\n123135\n123142\n123146\n123147\n123158\n123159\n123160\n123162\n123163\n123171\n123173\n123174\n123179\n123184\n123195\n123197\n123199\n123202\n123208\n123210\n123213\n123219\n123227\n123233\n123235\n123237\n123239\n123243\n123246\n123250\n123256\n123261\n123262\n123268\n123272\n123275\n123276\n123284\n123288\n123290\n123292\n123308\n123309\n123312\n123321\n123324\n123330\n123333\n123337\n123338\n123339\n123340\n123348\n123350\n123361\n123374\n123378\n123382\n123387\n123388\n123390\n123394\n123398\n123400\n123404\n123412\n123414\n123417\n123419\n123421\n123424\n123437\n123440\n123443\n123451\n123452\n123454\n123455\n123464\n123467\n123469\n123470\n123471\n123473\n123480\n123485\n123493\n123498\n123513\n123518\n123519\n123521\n123524\n123526\n123527\n123534\n123543\n123547\n123560\n123562\n123564\n123569\n123570\n123574\n123578\n123594\n123598\n123607\n123608\n123610\n123628\n123631\n123634\n123643\n123645\n123646\n123649\n123650\n123654\n123656\n123667\n123670\n123690\n123693\n123699\n123705\n123706\n123709\n123715\n123718\n123725\n123727\n123730\n123733\n123747\n123750\n123759\n123760\n123773\n123776\n123779\n123781\n123788\n123789\n123796\n123803\n123807\n123810\n123812\n123813\n123817\n123818\n123835\n123837\n123841\n123850\n123851\n123852\n123856\n123857\n123873\n123875\n123880\n123892\n123893\n123899\n123904\n123905\n123907\n123923\n123931\n123940\n123945\n123948\n123964\n123972\n123987\n123988\n123990\n123991\n124001\n124006\n124028\n124029\n124036\n124039\n124040\n124042\n124053\n124054\n124055\n124057\n124062\n124066\n124074\n124082\n124087\n124091\n124094\n124098\n124100\n124101\n124104\n124106\n124111\n124112\n124122\n124129\n124130\n124131\n124132\n124137\n124139\n124141\n124143\n124144\n124145\n124147\n124150\n124160\n124162\n124166\n124168\n124172\n124174\n124184\n124185\n124186\n124188\n124189\n124192\n124197\n124204\n124211\n124216\n124219\n124222\n124223\n124227\n124228\n124231\n124232\n124236\n124242\n124246\n124252\n124253\n124256\n124268\n124281\n124291\n124292\n124299\n124300\n124308\n124317\n124325\n124326\n124336\n124337\n124348\n124353\n124360\n124363\n124364\n124370\n124371\n124376\n124381\n124382\n124387\n124391\n124404\n124408\n124409\n124410\n124413\n124416\n124420\n124431\n124433\n124443\n124448\n124449\n124452\n124455\n124460\n124471\n124472\n124476\n124477\n124478\n124480\n124484\n124489\n124490\n124491\n124503\n124519\n124541\n124547\n124548\n124554\n124558\n124565\n124566\n124569\n124570\n124573\n124575\n124576\n124578\n124588\n124589\n124592\n124593\n124602\n124606\n124616\n124617\n124623\n124632\n124640\n124648\n124649\n124676\n124681\n124682\n124683\n124689\n124695\n124699\n124701\n124705\n124708\n124711\n124727\n124735\n124737\n124742\n124746\n124751\n124757\n124768\n124781\n124783\n124789\n124791\n124792\n124793\n124804\n124812\n124818\n124821\n124822\n124823\n124829\n124832\n124838\n124841\n124842\n124843\n124844\n124845\n124846\n124849\n124850\n124851\n124855\n124859\n124874\n124877\n124888\n124892\n124895\n124909\n124912\n124919\n124921\n124923\n124925\n124926\n124938\n124940\n124942\n124943\n124944\n124947\n124955\n124957\n124964\n124979\n124982\n124984\n124987\n125078\n125098\n125116\n125124\n125126\n125132\n125133\n125147\n125149\n125151\n125160\n125161\n125163\n125173\n125181\n125193\n125198\n125200\n125202\n125205\n125222\n125223\n125224\n125226\n125232\n125233\n125241\n125249\n125258\n125259\n125273\n125277\n125285\n125296\n125299\n125301\n125308\n125319\n125323\n125341\n125342\n125352\n125356\n125362\n125366\n125367\n125369\n125370\n125375\n125377\n125378\n125383\n125386\n125388\n125389\n125400\n125402\n125406\n125414\n125418\n125420\n125423\n125425\n125429\n125434\n125440\n125443\n125444\n125449\n125470\n125475\n125479\n125485\n125486\n125488\n125492\n125494\n125497\n125498\n125500\n125501\n125507\n125511\n125518\n125519\n125520\n125534\n125536\n125541\n125542\n125543\n125546\n125548\n125550\n125558\n125562\n125563\n125564\n125568\n125569\n125572\n125575\n125582\n125584\n125587\n125595\n125600\n125602\n125609\n125610\n125611\n125616\n125618\n125628\n125637\n125644\n125648\n125651\n125656\n125662\n125670\n125687\n125693\n125695\n125697\n125701\n125702\n125704\n125708\n125716\n125722\n125723\n125725\n125726\n125732\n125738\n125742\n125745\n125746\n125748\n125757\n125767\n125772\n125777\n125780\n125790\n125791\n125793\n125800\n125807\n125812\n125817\n125820\n125833\n125836\n125840\n125849\n125875\n125879\n125883\n125894\n125900\n125903\n125905\n125915\n125917\n125918\n125920\n125926\n125929\n125931\n125933\n125934\n125940\n125943\n125944\n125946\n125949\n125951\n125952\n125956\n125959\n125967\n125968\n125969\n125973\n125977\n125983\n125991\n125992\n125994\n125997\n125999\n126000\n126003\n126005\n126006\n126008\n126008\n126010\n126011\n126013\n126020\n126024\n126029\n126030\n126031\n126032\n126033\n126035\n126035\n126036\n126037\n126040\n126050\n126050\n126051\n126052\n126059\n126060\n126069\n126070\n126070\n126071\n126073\n126074\n126079\n126080\n126084\n126096\n126099\n126103\n126120\n126121\n126123\n126131\n126136\n126137\n126138\n126143\n126148\n126151\n126154\n126165\n126166\n126169\n126185\n126191\n126195\n126196\n126198\n126213\n126214\n126217\n126221\n126226\n126230\n126241\n126242\n126247\n126249\n126253\n126255\n126262\n126266\n126270\n126277\n126284\n126295\n126308\n126313\n126314\n126334\n126345\n126346\n126347\n126351\n126353\n126361\n126367\n126370\n126372\n126382\n126385\n126387\n126390\n126391\n126395\n126397\n126398\n126402\n126403\n126406\n126416\n126420\n126426\n126429\n126451\n126456\n126469\n126475\n126476\n126484\n126493\n126498\n126499\n126507\n126508\n126518\n126527\n126530\n126538\n126542\n126546\n126555\n126557\n126562\n126568\n126575\n126586\n126590\n126596\n126597\n126601\n126607\n126614\n126622\n126625\n126627\n126636\n126642\n126646\n126648\n126659\n126663\n126669\n126670\n126685\n126686\n126687\n126688\n126693\n126694\n126699\n126707\n126713\n126717\n126719\n126726\n126727\n126734\n126739\n126745\n126747\n126780\n126784\n126785\n126786\n126789\n126804\n126807\n126809\n126810\n126813\n126814\n126820\n126827\n126834\n126837\n126842\n126844\n126854\n126864\n126877\n126887\n126889\n126905\n126908\n126918\n126922\n126924\n126927\n126929\n126938\n126940\n126941\n126942\n126943\n126944\n126948\n126950\n126967\n126970\n126983\n126984\n126990\n126998\n127001\n127003\n127010\n127017\n127018\n127022\n127023\n127029\n127034\n127035\n127037\n127045\n127051\n127055\n127060\n127064\n127069\n127076\n127078\n127085\n127107\n127113\n127118\n127128\n127145\n127152\n127155\n127169\n127183\n127190\n127192\n127204\n127210\n127217\n127219\n127228\n127236\n127237\n127240\n127241\n127248\n127251\n127255\n127262\n127264\n127272\n127273\n127283\n127288\n127293\n127295\n127296\n127307\n127308\n127311\n127313\n127323\n127336\n127355\n127360\n127363\n127365\n127371\n127375\n127376\n127379\n127380\n127382\n127383\n127384\n127393\n127394\n127397\n127399\n127401\n127426\n127428\n127429\n127438\n127440\n127443\n127444\n127454\n127456\n127461\n127466\n127469\n127473\n127477\n127479\n127484\n127495\n127497\n127512\n127525\n127531\n127533\n127537\n127538\n127542\n127543\n127544\n127548\n127560\n127564\n127567\n127568\n127574\n127577\n127579\n127581\n127585\n127591\n127605\n127612\n127613\n127618\n127621\n127624\n127625\n127627\n127631\n127636\n127655\n127656\n127658\n127674\n127678\n127679\n127714\n127716\n127720\n127722\n127724\n127736\n127739\n127741\n127742\n127743\n127749\n127753\n127754\n127757\n127764\n127772\n127781\n127783\n127788\n127793\n127794\n127796\n127799\n127808\n127816\n127830\n127832\n127833\n127839\n127865\n127870\n127872\n127873\n127882\n127885\n127887\n127888\n127889\n127890\n127900\n127906\n127912\n127927\n127937\n127958\n127967\n127976\n127983\n127984\n127986\n127988\n127994\n127996\n127997\n127998\n127999\n128006\n128007\n128009\n128012\n128020\n128022\n128027\n128045\n128064\n128065\n128066\n128069\n128073\n128077\n128080\n128085\n128087\n128089\n128090\n128109\n128116\n128117\n128132\n128134\n128137\n128143\n128144\n128151\n128152\n128154\n128157\n128159\n128160\n128164\n128165\n128174\n128177\n128182\n128184\n128185\n128189\n128190\n128198\n128201\n128203\n128206\n128211\n128213\n128214\n128215\n128216\n128225\n128233\n128234\n128235\n128244\n128245\n128249\n128254\n128263\n128277\n128279\n128286\n128295\n128308\n128315\n128329\n128330\n128332\n128335\n128339\n128348\n128349\n128350\n128351\n128354\n128356\n128365\n128373\n128378\n128398\n128401\n128410\n128420\n128426\n128427\n128432\n128435\n128439\n128456\n128458\n128465\n128474\n128475\n128477\n128497\n128500\n128503\n128508\n128516\n128521\n128523\n128529\n128531\n128536\n128537\n128544\n128558\n128559\n128564\n128566\n128572\n128582\n128583\n128586\n128591\n128594\n128595\n128597\n128603\n128604\n128606\n128608\n128615\n128624\n128628\n128631\n128632\n128647\n128648\n128651\n128654\n128661\n128662\n128665\n128668\n128672\n128675\n128680\n128683\n128691\n128697\n128699\n128701\n128702\n128711\n128713\n128714\n128722\n128730\n128737\n128738\n128739\n128749\n128757\n128765\n128775\n128779\n128784\n128787\n128792\n128800\n128802\n128815\n128816\n128819\n128823\n128824\n128829\n128831\n128834\n128836\n128838\n128848\n128854\n128863\n128875\n128881\n128882\n128887\n128891\n128892\n128894\n128901\n128902\n128908\n128913\n128916\n128927\n128938\n128945\n128947\n128956\n128964\n128973\n128977\n128982\n128983\n128986\n128989\n128990\n128999\n129010\n129012\n129023\n129024\n129034\n129035\n129047\n129056\n129064\n129073\n129085\n129094\n129098\n129105\n129107\n129110\n129127\n129132\n129133\n129138\n129139\n129142\n129144\n129145\n129149\n129152\n129156\n129158\n129160\n129161\n129170\n129174\n129179\n129185\n129190\n129191\n129194\n129195\n129197\n129207\n129222\n129223\n129227\n129231\n129233\n129234\n129235\n129236\n129239\n129242\n129250\n129252\n129258\n129261\n129263\n129269\n129276\n129297\n129303\n129304\n129313\n129321\n129325\n129327\n129329\n129331\n129337\n129343\n129344\n129346\n129348\n129349\n129355\n129359\n129363\n129364\n129372\n129376\n129382\n129386\n129388\n129398\n129400\n129423\n129427\n129434\n129444\n129445\n129448\n129451\n129460\n129474\n129476\n129478\n129481\n129496\n129502\n129504\n129517\n129525\n129526\n129528\n129529\n129538\n129543\n129551\n129553\n129559\n129561\n129563\n129576\n129579\n129589\n129592\n129595\n129597\n129598\n129607\n129608\n129622\n129628\n129633\n129636\n129638\n129639\n129657\n129666\n129667\n129670\n129680\n129686\n129695\n129705\n129706\n129713\n129717\n129723\n129731\n129733\n129734\n129737\n129742\n129743\n129753\n129754\n129755\n129759\n129767\n129768\n129772\n129775\n129795\n129803\n129806\n129809\n129811\n129814\n129816\n129824\n129831\n129833\n129836\n129839\n129840\n129841\n129842\n129843\n129845\n129847\n129850\n129854\n129855\n129861\n129868\n129874\n129880\n129884\n129886\n129894\n129895\n129904\n129910\n129911\n129916\n129920\n129922\n129924\n129940\n129945\n129946\n129957\n129963\n129967\n129969\n129971\n129975\n129980\n129982\n129988\n129996\n129999\n130003\n130005\n130009\n130013\n130016\n130017\n130024\n130025\n130033\n130038\n130056\n130057\n130061\n130062\n130069\n130071\n130073\n130076\n130078\n130109\n130112\n130115\n130116\n130118\n130122\n130123\n130124\n130127\n130128\n130129\n130131\n130132\n130139\n130141\n130145\n130162\n130169\n130171\n130172\n130179\n130190\n130194\n130195\n130198\n130199\n130200\n130213\n130214\n130215\n130242\n130245\n130253\n130254\n130259\n130260\n130267\n130270\n130271\n130272\n130273\n130286\n130294\n130295\n130298\n130299\n130302\n130312\n130318\n130320\n130323\n130336\n130341\n130343\n130344\n130357\n130358\n130370\n130377\n130382\n130383\n130386\n130396\n130406\n130411\n130417\n130420\n130422\n130427\n130429\n130431\n130446\n130447\n130450\n130456\n130460\n130463\n130469\n130471\n130474\n130479\n130482\n130484\n130496\n130502\n130503\n130504\n130521\n130528\n130539\n130542\n130549\n130554\n130555\n130557\n130562\n130563\n130576\n130578\n130583\n130588\n130600\n130605\n130617\n130622\n130623\n130646\n130650\n130651\n130655\n130657\n130664\n130667\n130672\n130676\n130683\n130701\n130707\n130716\n130718\n130719\n130723\n130734\n130738\n130746\n130748\n130749\n130754\n130757\n130764\n130776\n130781\n130782\n130784\n130785\n130786\n130790\n130797\n130803\n130806\n130809\n130818\n130819\n130821\n130834\n130838\n130844\n130845\n130863\n130865\n130867\n130870\n130875\n130878\n130888\n130889\n130892\n130909\n130919\n130923\n130926\n130930\n130941\n130943\n130960\n130962\n130963\n130964\n130965\n130966\n130969\n130982\n130988\n130989\n130992\n130994\n130999\n131000\n131019\n131022\n131023\n131027\n131028\n131029\n131034\n131036\n131038\n131042\n131050\n131058\n131063\n131070\n131072\n131082\n131084\n131086\n131092\n131096\n131101\n131104\n131115\n131122\n131124\n131127\n131128\n131137\n131140\n131155\n131157\n131161\n131170\n131175\n131185\n131186\n131188\n131193\n131194\n131195\n131196\n131197\n131198\n131203\n131204\n131225\n131228\n131235\n131238\n131239\n131241\n131242\n131243\n131244\n131251\n131255\n131275\n131279\n131280\n131291\n131294\n131297\n131311\n131322\n131326\n131327\n131329\n131335\n131340\n131346\n131347\n131354\n131357\n131359\n131366\n131383\n131395\n131399\n131400\n131403\n131415\n131428\n131430\n131434\n131443\n131452\n131453\n131465\n131471\n131481\n131487\n131491\n131496\n131522\n131525\n131531\n131534\n131538\n131542\n131546\n131548\n131549\n131553\n131559\n131560\n131562\n131581\n131594\n131595\n131598\n131604\n131607\n131608\n131612\n131615\n131617\n131618\n131622\n131640\n131642\n131646\n131649\n131652\n131656\n131671\n131672\n131676\n131681\n131682\n131683\n131685\n131689\n131695\n131696\n131699\n131701\n131710\n131720\n131721\n131727\n131732\n131735\n131746\n131750\n131757\n131763\n131767\n131773\n131777\n131797\n131800\n131803\n131804\n131815\n131819\n131822\n131833\n131843\n131844\n131858\n131869\n131874\n131884\n131893\n131894\n131896\n131898\n131902\n131912\n131914\n131920\n131921\n131925\n131929\n131935\n131941\n131944\n131946\n131947\n131952\n131953\n131957\n131958\n131960\n131968\n131969\n131974\n131975\n131978\n131979\n131983\n131985\n131988\n131995\n132006\n132010\n132020\n132028\n132042\n132045\n132054\n132059\n132063\n132072\n132075\n132078\n132086\n132088\n132092\n132093\n132094\n132099\n132107\n132108\n132112\n132124\n132125\n132138\n132149\n132154\n132165\n132167\n132171\n132172\n132176\n132177\n132187\n132197\n132203\n132214\n132224\n132231\n132234\n132240\n132246\n132254\n132262\n132264\n132265\n132275\n132286\n132287\n132288\n132300\n132302\n132310\n132311\n132320\n132324\n132328\n132335\n132347\n132349\n132352\n132358\n132377\n132379\n132388\n132389\n132398\n132415\n132419\n132423\n132430\n132431\n132432\n132439\n132444\n132454\n132459\n132475\n132476\n132489\n132494\n132497\n132499\n132504\n132509\n132510\n132519\n132521\n132527\n132530\n132531\n132537\n132538\n132547\n132551\n132554\n132555\n132557\n132562\n132574\n132588\n132589\n132591\n132593\n132597\n132603\n132605\n132606\n132614\n132617\n132622\n132629\n132631\n132633\n132634\n132643\n132652\n132653\n132661\n132667\n132676\n132683\n132684\n132691\n132705\n132707\n132718\n132722\n132732\n132733\n132737\n132755\n132760\n132771\n132787\n132790\n132791\n132793\n132796\n132800\n132804\n132805\n132816\n132822\n132824\n132825\n132829\n132832\n132833\n132834\n132839\n132853\n132865\n132867\n132883\n132888\n132890\n132896\n132899\n132901\n132905\n132922\n132924\n132935\n132936\n132937\n132939\n132941\n132944\n132953\n132966\n132967\n132974\n132979\n132980\n132983\n132984\n132987\n132989\n132992\n132993\n132995\n133001\n133007\n133011\n133014\n133015\n133016\n133018\n133025\n133030\n133034\n133037\n133040\n133047\n133048\n133053\n133054\n133060\n133064\n133065\n133070\n133073\n133075\n133080\n133085\n133087\n133098\n133100\n133122\n133124\n133132\n133140\n133146\n133149\n133155\n133157\n133181\n133184\n133191\n133195\n133210\n133212\n133216\n133226\n133227\n133228\n133232\n133236\n133239\n133256\n133257\n133259\n133262\n133263\n133264\n133267\n133278\n133297\n133305\n133310\n133318\n133319\n133324\n133330\n133332\n133341\n133344\n133348\n133351\n133352\n133357\n133361\n133362\n133364\n133367\n133369\n133376\n133385\n133388\n133397\n133398\n133400\n133404\n133415\n133423\n133439\n133442\n133446\n133448\n133451\n133454\n133457\n133460\n133463\n133467\n133469\n133470\n133472\n133478\n133482\n133492\n133495\n133504\n133514\n133529\n133532\n133537\n133540\n133546\n133564\n133568\n133569\n133574\n133581\n133590\n133603\n133610\n133614\n133618\n133627\n133657\n133658\n133674\n133677\n133680\n133681\n133693\n133698\n133704\n133713\n133744\n133748\n133758\n133761\n133763\n133767\n133779\n133781\n133791\n133801\n133804\n133807\n133809\n133811\n133820\n133823\n133828\n133833\n133834\n133836\n133837\n133848\n133860\n133864\n133865\n133870\n133874\n133883\n133888\n133897\n133898\n133902\n133904\n133908\n133909\n133924\n133928\n133930\n133931\n133935\n133936\n133940\n133945\n133956\n133962\n133964\n133967\n133976\n133981\n133986\n133987\n133990\n133998\n134000\n134001\n134010\n134018\n134026\n134028\n134035\n134036\n134043\n134049\n134050\n134055\n134064\n134066\n134067\n134070\n134073\n134085\n134090\n134097\n134101\n134102\n134108\n134112\n134126\n134130\n134131\n134133\n134134\n134139\n134140\n134141\n134144\n134146\n134148\n134150\n134162\n134166\n134177\n134180\n134187\n134191\n134204\n134209\n134213\n134216\n134217\n134225\n134244\n134255\n134256\n134271\n134277\n134286\n134292\n134294\n134299\n134308\n134310\n134316\n134319\n134327\n134333\n134343\n134346\n134347\n134348\n134355\n134356\n134362\n134364\n134370\n134382\n134383\n134386\n134387\n134388\n134389\n134391\n134399\n134406\n134423\n134425\n134426\n134431\n134439\n134446\n134451\n134468\n134474\n134477\n134491\n134502\n134512\n134515\n134517\n134526\n134528\n134539\n134542\n134544\n134550\n134551\n134553\n134555\n134557\n134568\n134569\n134572\n134573\n134575\n134580\n134582\n134588\n134590\n134596\n134600\n134601\n134605\n134607\n134611\n134614\n134615\n134627\n134628\n134637\n134642\n134654\n134659\n134660\n134662\n134674\n134688\n134698\n134701\n134707\n134714\n134715\n134719\n134722\n134727\n134728\n134734\n134746\n134752\n134756\n134757\n134771\n134772\n134774\n134777\n134782\n134784\n134789\n134791\n134794\n134804\n134807\n134809\n134812\n134821\n134823\n134825\n134829\n134839\n134846\n134850\n134855\n134856\n134870\n134871\n134883\n134898\n134899\n134917\n134921\n134922\n134926\n134931\n134932\n134934\n134935\n134939\n134941\n134943\n134957\n134972\n134975\n134976\n134977\n134978\n134981\n134986\n134998\n135006\n135007\n135013\n135017\n135030\n135074\n135077\n135082\n135085\n135086\n135100\n135102\n135104\n135105\n135107\n135118\n135119\n135122\n135136\n135137\n135142\n135153\n135164\n135170\n135178\n135179\n135192\n135194\n135204\n135207\n135210\n135217\n135220\n135237\n135242\n135248\n135252\n135255\n135264\n135268\n135296\n135299\n135304\n135307\n135317\n135321\n135322\n135325\n135335\n135337\n135339\n135345\n135346\n135350\n135355\n135356\n135359\n135362\n135363\n135370\n135384\n135388\n135392\n135396\n135397\n135398\n135417\n135419\n135426\n135430\n135434\n135440\n135450\n135452\n135459\n135466\n135471\n135480\n135489\n135493\n135495\n135503\n135511\n135515\n135520\n135521\n135527\n135530\n135531\n135534\n135536\n135539\n135543\n135546\n135549\n135560\n135562\n135572\n135584\n135586\n135593\n135595\n135596\n135601\n135605\n135607\n135619\n135620\n135622\n135631\n135639\n135659\n135667\n135679\n135680\n135681\n135688\n135704\n135706\n135723\n135724\n135727\n135730\n135746\n135753\n135760\n135778\n135779\n135788\n135789\n135792\n135802\n135811\n135816\n135817\n135830\n135835\n135843\n135844\n135849\n135863\n135867\n135872\n135905\n135907\n135911\n135913\n135918\n135928\n135929\n135931\n135935\n135938\n135940\n135945\n135946\n135947\n135952\n135953\n135954\n135960\n135962\n135969\n135974\n135986\n135990\n135999\n136005\n136006\n136007\n136017\n136021\n136024\n136025\n136026\n136029\n136035\n136038\n136043\n136044\n136048\n136049\n136051\n136065\n136071\n136078\n136088\n136090\n136115\n136125\n136133\n136139\n136141\n136152\n136156\n136158\n136164\n136168\n136169\n136175\n136179\n136196\n136201\n136207\n136215\n136224\n136227\n136229\n136231\n136233\n136237\n136243\n136246\n136249\n136251\n136252\n136253\n136256\n136264\n136268\n136273\n136288\n136292\n136293\n136298\n136301\n136302\n136313\n136314\n136318\n136325\n136327\n136329\n136334\n136335\n136336\n136344\n136356\n136359\n136369\n136372\n136376\n136382\n136383\n136388\n136390\n136395\n136397\n136402\n136404\n136427\n136428\n136438\n136448\n136449\n136466\n136468\n136470\n136471\n136473\n136477\n136482\n136485\n136488\n136495\n136496\n136503\n136509\n136512\n136517\n136519\n136543\n136549\n136557\n136560\n136567\n136575\n136578\n136582\n136587\n136591\n136596\n136600\n136601\n136604\n136607\n136613\n136620\n136631\n136639\n136642\n136644\n136654\n136655\n136659\n136665\n136674\n136695\n136698\n136700\n136708\n136719\n136753\n136757\n136761\n136766\n136772\n136773\n136774\n136777\n136778\n136781\n136783\n136788\n136804\n136813\n136818\n136825\n136828\n136833\n136834\n136835\n136844\n136846\n136850\n136856\n136861\n136880\n136894\n136897\n136898\n136905\n136909\n136917\n136922\n136926\n136929\n136936\n136940\n136954\n136957\n136965\n136974\n136980\n136983\n136985\n136986\n136989\n136991\n136992\n137008\n137012\n137013\n137017\n137025\n137027\n137030\n137032\n137035\n137039\n137042\n137043\n137044\n137046\n137058\n137059\n137062\n137068\n137071\n137079\n137087\n137089\n137093\n137094\n137099\n137102\n137110\n137112\n137117\n137120\n137122\n137124\n137125\n137128\n137132\n137133\n137139\n137145\n137150\n137153\n137158\n137167\n137168\n137171\n137176\n137182\n137184\n137189\n137194\n137195\n137198\n137203\n137207\n137221\n137224\n137228\n137232\n137236\n137246\n137247\n137251\n137254\n137258\n137265\n137283\n137290\n137301\n137304\n137309\n137312\n137315\n137325\n137328\n137329\n137332\n137343\n137346\n137348\n137353\n137358\n137359\n137364\n137367\n137368\n137381\n137385\n137394\n137410\n137413\n137424\n137426\n137428\n137437\n137438\n137446\n137448\n137462\n137463\n137464\n137467\n137472\n137476\n137477\n137480\n137484\n137487\n137490\n137492\n137495\n137499\n137501\n137511\n137517\n137520\n137524\n137530\n137532\n137541\n137550\n137556\n137560\n137563\n137567\n137571\n137572\n137577\n137580\n137581\n137599\n137613\n137615\n137618\n137637\n137638\n137640\n137644\n137645\n137651\n137658\n137671\n137675\n137676\n137679\n137680\n137686\n137687\n137692\n137693\n137694\n137696\n137704\n137713\n137720\n137728\n137729\n137739\n137750\n137758\n137761\n137766\n137771\n137776\n137778\n137794\n137796\n137807\n137812\n137814\n137818\n137839\n137840\n137841\n137842\n137845\n137850\n137874\n137877\n137878\n137880\n137883\n137888\n137890\n137891\n137901\n137903\n137910\n137922\n137927\n137938\n137943\n137952\n137954\n137958\n137965\n137972\n137980\n137990\n137994\n138001\n138002\n138005\n138007\n138012\n138027\n138033\n138034\n138035\n138036\n138037\n138039\n138052\n138066\n138073\n138078\n138082\n138085\n138091\n138093\n138097\n138100\n138109\n138111\n138119\n138125\n138130\n138132\n138134\n138135\n138141\n138145\n138149\n138163\n138168\n138180\n138199\n138203\n138204\n138209\n138218\n138222\n138226\n138238\n138251\n138265\n138267\n138270\n138277\n138284\n138294\n138304\n138318\n138326\n138331\n138334\n138337\n138348\n138352\n138354\n138355\n138357\n138360\n138362\n138371\n138380\n138383\n138386\n138400\n138408\n138432\n138441\n138444\n138452\n138453\n138454\n138457\n138473\n138487\n138488\n138492\n138496\n138497\n138500\n138505\n138516\n138523\n138539\n138544\n138550\n138557\n138562\n138571\n138593\n138600\n138604\n138611\n138612\n138626\n138631\n138632\n138638\n138639\n138641\n138646\n138654\n138657\n138658\n138660\n138663\n138674\n138677\n138678\n138679\n138683\n138694\n138696\n138698\n138699\n138704\n138705\n138710\n138711\n138714\n138722\n138723\n138729\n138733\n138735\n138741\n138748\n138750\n138755\n138761\n138775\n138777\n138780\n138783\n138787\n138794\n138821\n138829\n138834\n138839\n138841\n138844\n138857\n138868\n138876\n138887\n138888\n138891\n138893\n138897\n138907\n138915\n138919\n138920\n138934\n138945\n138956\n138959\n138964\n138979\n138987\n138988\n139002\n139016\n139028\n139029\n139031\n139036\n139041\n139042\n139045\n139047\n139052\n139053\n139057\n139062\n139066\n139067\n139069\n139072\n139080\n139082\n139083\n139090\n139091\n139092\n139094\n139095\n139096\n139101\n139105\n139116\n139118\n139123\n139130\n139131\n139138\n139151\n139153\n139156\n139157\n139159\n139160\n139163\n139164\n139166\n139168\n139172\n139173\n139176\n139177\n139180\n139181\n139186\n139188\n139202\n139205\n139207\n139209\n139210\n139212\n139214\n139215\n139229\n139230\n139231\n139233\n139234\n139242\n139249\n139265\n139268\n139274\n139275\n139311\n139321\n139330\n139334\n139335\n139336\n139344\n139345\n139348\n139363\n139365\n139371\n139377\n139379\n139380\n139384\n139385\n139391\n139398\n139414\n139423\n139425\n139427\n139431\n139433\n139435\n139441\n139442\n139443\n139445\n139455\n139463\n139485\n139495\n139497\n139510\n139512\n139513\n139516\n139523\n139530\n139532\n139534\n139536\n139538\n139540\n139545\n139549\n139552\n139556\n139567\n139568\n139583\n139584\n139588\n139589\n139593\n139595\n139597\n139606\n139613\n139615\n139621\n139627\n139635\n139644\n139645\n139649\n139654\n139655\n139656\n139667\n139676\n139677\n139682\n139684\n139688\n139690\n139707\n139712\n139726\n139730\n139733\n139734\n139756\n139757\n139763\n139769\n139775\n139776\n139779\n139785\n139797\n139798\n139809\n139829\n139833\n139839\n139845\n139848\n139849\n139863\n139865\n139868\n139871\n139872\n139873\n139884\n139885\n139888\n139891\n139892\n139893\n139895\n139897\n139903\n139907\n139924\n139926\n139927\n139928\n139929\n139932\n139936\n139940\n139949\n139956\n139958\n139959\n139969\n139971\n139972\n139976\n139979\n139980\n139987\n140008\n140011\n140015\n140017\n140019\n140020\n140021\n140026\n140029\n140031\n140032\n140033\n140045\n140052\n140056\n140061\n140062\n140067\n140069\n140070\n140081\n140083\n140085\n140092\n140095\n140096\n140098\n140109\n140113\n140119\n140120\n140125\n140127\n140130\n140136\n140140\n140142\n140147\n140149\n140151\n140153\n140156\n140157\n140161\n140177\n140182\n140183\n140184\n140185\n140193\n140197\n140203\n140210\n140223\n140225\n140233\n140239\n140241\n140243\n140244\n140250\n140253\n140254\n140255\n140268\n140272\n140274\n140277\n140286\n140291\n140293\n140296\n140303\n140305\n140314\n140316\n140323\n140326\n140330\n140334\n140341\n140344\n140355\n140356\n140364\n140367\n140369\n140370\n140371\n140374\n140379\n140381\n140384\n140386\n140390\n140394\n140396\n140405\n140411\n140413\n140417\n140419\n140420\n140430\n140440\n140444\n140452\n140465\n140472\n140473\n140479\n140484\n140486\n140489\n140494\n140497\n140512\n140522\n140523\n140526\n140527\n140536\n140548\n140550\n140556\n140564\n140565\n140566\n140568\n140569\n140573\n140577\n140584\n140587\n140588\n140589\n140590\n140599\n140601\n140607\n140611\n140615\n140618\n140621\n140623\n140626\n140627\n140628\n140629\n140632\n140633\n140635\n140642\n140645\n140655\n140656\n140657\n140659\n140661\n140674\n140680\n140682\n140690\n140699\n140724\n140729\n140732\n140733\n140742\n140743\n140746\n140753\n140755\n140756\n140762\n140763\n140773\n140777\n140780\n140782\n140786\n140792\n140801\n140804\n140811\n140823\n140828\n140832\n140833\n140839\n140841\n140842\n140860\n140865\n140870\n140873\n140874\n140877\n140878\n140884\n140885\n140889\n140894\n140902\n140905\n140907\n140911\n140913\n140914\n140917\n140919\n140925\n140926\n140929\n140930\n140932\n140937\n140938\n140943\n140951\n140961\n140962\n140963\n140964\n140969\n140971\n140972\n140974\n140985\n140986\n140999\n141000\n141006\n141008\n141011\n141014\n141019\n141020\n141024\n141026\n141034\n141043\n141067\n141078\n141081\n141084\n141088\n141089\n141091\n141092\n141095\n141096\n141100\n141105\n141110\n141112\n141114\n141119\n141120\n141129\n141132\n141137\n141138\n141139\n141141\n141142\n141143\n141148\n141151\n141154\n141184\n141185\n141186\n141188\n141192\n141195\n141203\n141218\n141223\n141225\n141228\n141229\n141234\n141235\n141237\n141241\n141242\n141245\n141246\n141260\n141267\n141268\n141273\n141278\n141284\n141287\n141289\n141290\n141296\n141299\n141300\n141302\n141303\n141315\n141321\n141326\n141335\n141336\n141347\n141351\n141355\n141356\n141358\n141366\n141370\n141371\n141373\n141374\n141377\n141389\n141394\n141398\n141402\n141405\n141406\n141407\n141415\n141420\n141446\n141447\n141449\n141456\n141459\n141460\n141461\n141463\n141470\n141473\n141479\n141485\n141494\n141496\n141497\n141513\n141515\n141519\n141522\n141524\n141539\n141540\n141543\n141544\n141552\n141554\n141561\n141563\n141570\n141577\n141582\n141590\n141591\n141596\n141597\n141600\n141605\n141608\n141613\n141614\n141619\n141625\n141629\n141634\n141637\n141644\n141654\n141661\n141673\n141674\n141675\n141684\n141686\n141696\n141698\n141702\n141703\n141705\n141709\n141710\n141711\n141720\n141723\n141732\n141758\n141759\n141764\n141773\n141777\n141778\n141780\n141782\n141785\n141789\n141791\n141798\n141818\n141820\n141821\n141823\n141824\n141825\n141830\n141839\n141857\n141862\n141865\n141868\n141875\n141887\n141889\n141894\n141900\n141911\n141912\n141914\n141925\n141929\n141933\n141937\n141939\n141942\n141944\n141947\n141949\n141950\n141962\n141963\n141968\n141970\n141971\n141978\n141983\n141991\n141999\n142002\n142004\n142006\n142013\n142018\n142019\n142020\n142021\n142023\n142024\n142032\n142037\n142038\n142044\n142056\n142066\n142072\n142073\n142075\n142081\n142082\n142092\n142093\n142098\n142114\n142115\n142117\n142122\n142126\n142133\n142136\n142138\n142142\n142143\n142146\n142151\n142152\n142156\n142165\n142168\n142178\n142179\n142196\n142204\n142210\n142220\n142237\n142242\n142244\n142255\n142263\n142273\n142274\n142275\n142278\n142281\n142282\n142285\n142288\n142292\n142296\n142299\n142303\n142305\n142318\n142343\n142345\n142352\n142354\n142365\n142372\n142377\n142380\n142394\n142395\n142400\n142401\n142402\n142414\n142422\n142424\n142427\n142429\n142439\n142452\n142456\n142459\n142465\n142467\n142471\n142475\n142478\n142482\n142487\n142492\n142493\n142503\n142504\n142506\n142513\n142516\n142519\n142520\n142528\n142530\n142535\n142536\n142542\n142558\n142574\n142580\n142598\n142602\n142603\n142605\n142619\n142627\n142628\n142639\n142663\n142679\n142682\n142685\n142698\n142699\n142701\n142702\n142704\n142705\n142712\n142717\n142718\n142723\n142727\n142728\n142729\n142737\n142742\n142744\n142745\n142751\n142753\n142761\n142763\n142765\n142774\n142775\n142786\n142788\n142790\n142798\n142802\n142804\n142807\n142808\n142823\n142846\n142853\n142855\n142873\n142877\n142885\n142889\n142897\n142899\n142905\n142917\n142920\n142930\n142935\n142948\n142952\n142964\n142976\n142981\n142984\n142992\n142997\n142998\n143019\n143021\n143022\n143023\n143025\n143032\n143033\n143036\n143044\n143049\n143055\n143058\n143063\n143064\n143066\n143071\n143072\n143086\n143099\n143100\n143108\n143109\n143112\n143115\n143132\n143134\n143136\n143137\n143140\n143147\n143153\n143156\n143157\n143160\n143163\n143165\n143168\n143171\n143174\n143178\n143202\n143205\n143223\n143224\n143226\n143229\n143230\n143237\n143241\n143252\n143257\n143273\n143275\n143277\n143282\n143283\n143284\n143286\n143287\n143291\n143292\n143293\n143300\n143301\n143302\n143309\n143314\n143315\n143317\n143319\n143320\n143321\n143323\n143334\n143336\n143339\n143346\n143356\n143357\n143367\n143373\n143376\n143379\n143400\n143401\n143404\n143406\n143407\n143415\n143417\n143424\n143425\n143428\n143433\n143434\n143435\n143440\n143465\n143466\n143474\n143482\n143508\n143512\n143517\n143520\n143523\n143524\n143525\n143530\n143533\n143539\n143540\n143543\n143553\n143554\n143561\n143562\n143572\n143573\n143583\n143584\n143587\n143603\n143604\n143617\n143618\n143620\n143621\n143632\n143635\n143638\n143639\n143641\n143642\n143647\n143649\n143651\n143652\n143653\n143657\n143661\n143668\n143670\n143680\n143684\n143691\n143694\n143696\n143697\n143708\n143710\n143715\n143716\n143719\n143720\n143748\n143751\n143753\n143767\n143768\n143773\n143777\n143780\n143783\n143786\n143787\n143793\n143797\n143802\n143803\n143818\n143821\n143833\n143850\n143853\n143862\n143864\n143865\n143876\n143878\n143886\n143891\n143892\n143894\n143900\n143904\n143909\n143912\n143922\n143924\n143927\n143928\n143942\n143974\n143978\n143983\n143988\n143989\n144002\n144003\n144005\n144012\n144015\n144034\n144037\n144046\n144059\n144061\n144069\n144070\n144072\n144090\n144091\n144094\n144099\n144102\n144106\n144107\n144111\n144127\n144134\n144135\n144139\n144141\n144160\n144164\n144166\n144170\n144176\n144177\n144178\n144187\n144190\n144192\n144197\n144200\n144204\n144205\n144206\n144208\n144210\n144211\n144212\n144217\n144221\n144224\n144233\n144241\n144249\n144254\n144255\n144257\n144258\n144261\n144264\n144266\n144269\n144271\n144278\n144281\n144284\n144286\n144287\n144292\n144296\n144301\n144302\n144304\n144308\n144309\n144319\n144323\n144326\n144330\n144336\n144337\n144340\n144347\n144348\n144349\n144351\n144358\n144359\n144363\n144364\n144370\n144374\n144376\n144378\n144398\n144399\n144409\n144430\n144434\n144439\n144444\n144447\n144458\n144470\n144471\n144481\n144493\n144495\n144500\n144502\n144510\n144511\n144513\n144520\n144525\n144528\n144529\n144535\n144547\n144552\n144555\n144557\n144558\n144563\n144568\n144571\n144572\n144583\n144595\n144597\n144599\n144600\n144601\n144610\n144613\n144614\n144615\n144617\n144618\n144619\n144622\n144623\n144637\n144641\n144642\n144647\n144653\n144654\n144660\n144663\n144679\n144681\n144697\n144701\n144712\n144714\n144716\n144717\n144718\n144719\n144722\n144724\n144730\n144735\n144736\n144742\n144743\n144746\n144747\n144753\n144758\n144759\n144769\n144776\n144785\n144787\n144797\n144799\n144803\n144813\n144826\n144831\n144833\n144841\n144845\n144847\n144854\n144864\n144865\n144867\n144880\n144883\n144886\n144887\n144894\n144899\n144901\n144912\n144919\n144925\n144926\n144930\n144933\n144937\n144940\n144941\n144952\n144956\n144959\n144974\n144975\n144977\n144989\n144997\n145001\n145005\n145021\n145024\n145030\n145032\n145038\n145040\n145042\n145043\n145047\n145050\n145052\n145059\n145069\n145072\n145080\n145084\n145085\n145089\n145101\n145103\n145107\n145108\n145109\n145110\n145118\n145119\n145123\n145125\n145128\n145139\n145146\n145151\n145156\n145160\n145168\n145171\n145175\n145186\n145192\n145194\n145199\n145201\n145202\n145205\n145207\n145217\n145221\n145227\n145229\n145233\n145246\n145247\n145254\n145255\n145256\n145257\n145265\n145267\n145268\n145269\n145282\n145285\n145291\n145298\n145302\n145307\n145310\n145313\n145328\n145335\n145348\n145352\n145354\n145360\n145364\n145366\n145369\n145372\n145379\n145385\n145406\n145409\n145413\n145416\n145421\n145424\n145431\n145438\n145439\n145447\n145451\n145452\n145453\n145466\n145467\n145474\n145477\n145488\n145489\n145490\n145493\n145508\n145512\n145513\n145529\n145531\n145536\n145544\n145552\n145559\n145560\n145563\n145567\n145574\n145577\n145579\n145581\n145588\n145592\n145600\n145607\n145611\n145617\n145621\n145627\n145632\n145633\n145639\n145650\n145659\n145665\n145666\n145669\n145683\n145688\n145691\n145695\n145697\n145702\n145703\n145712\n145734\n145737\n145739\n145741\n145744\n145746\n145752\n145755\n145762\n145766\n145767\n145769\n145775\n145785\n145791\n145795\n145820\n145821\n145823\n145825\n145827\n145829\n145832\n145836\n145847\n145848\n145849\n145867\n145870\n145874\n145877\n145878\n145883\n145888\n145889\n145894\n145907\n145908\n145911\n145920\n145926\n145928\n145937\n145940\n145945\n145947\n145949\n145962\n145966\n145969\n145971\n145975\n145981\n145998\n146001\n146009\n146010\n146014\n146020\n146025\n146026\n146035\n146047\n146048\n146061\n146064\n146069\n146084\n146088\n146089\n146090\n146096\n146103\n146106\n146109\n146110\n146120\n146129\n146130\n146134\n146137\n146142\n146143\n146152\n146158\n146160\n146161\n146164\n146171\n146184\n146186\n146193\n146197\n146200\n146207\n146225\n146230\n146231\n146232\n146234\n146251\n146252\n146254\n146259\n146265\n146266\n146274\n146281\n146284\n146294\n146295\n146298\n146299\n146304\n146305\n146313\n146316\n146320\n146325\n146326\n146341\n146345\n146348\n146352\n146357\n146358\n146363\n146366\n146368\n146371\n146374\n146377\n146378\n146387\n146393\n146401\n146404\n146410\n146411\n146415\n146425\n146437\n146438\n146440\n146441\n146447\n146448\n146455\n146459\n146466\n146468\n146474\n146483\n146485\n146493\n146499\n146500\n146502\n146509\n146514\n146518\n146523\n146530\n146537\n146544\n146545\n146546\n146556\n146560\n146563\n146568\n146577\n146578\n146579\n146593\n146594\n146597\n146602\n146606\n146612\n146613\n146615\n146616\n146630\n146646\n146652\n146654\n146656\n146663\n146679\n146684\n146685\n146686\n146693\n146702\n146711\n146713\n146719\n146723\n146746\n146754\n146760\n146761\n146770\n146779\n146783\n146787\n146789\n146793\n146798\n146804\n146808\n146817\n146831\n146837\n146838\n146840\n146841\n146846\n146848\n146849\n146852\n146856\n146857\n146858\n146867\n146869\n146872\n146891\n146892\n146895\n146909\n146920\n146921\n146927\n146928\n146938\n146945\n146947\n146965\n146976\n146979\n146980\n146989\n146997\n146998\n146999\n147008\n147010\n147015\n147018\n147019\n147024\n147030\n147032\n147033\n147038\n147040\n147051\n147053\n147060\n147061\n147071\n147072\n147073\n147074\n147078\n147092\n147102\n147106\n147109\n147111\n147112\n147113\n147127\n147129\n147130\n147131\n147132\n147133\n147138\n147148\n147150\n147156\n147159\n147160\n147169\n147170\n147175\n147182\n147188\n147190\n147208\n147210\n147215\n147216\n147217\n147230\n147233\n147235\n147236\n147239\n147241\n147242\n147245\n147265\n147270\n147276\n147278\n147282\n147285\n147286\n147292\n147294\n147295\n147298\n147306\n147318\n147320\n147329\n147330\n147335\n147337\n147339\n147350\n147361\n147362\n147371\n147384\n147391\n147392\n147398\n147401\n147410\n147412\n147416\n147420\n147423\n147425\n147426\n147430\n147432\n147439\n147443\n147445\n147448\n147452\n147455\n147462\n147475\n147476\n147480\n147488\n147491\n147504\n147511\n147513\n147526\n147531\n147536\n147540\n147545\n147548\n147556\n147566\n147567\n147580\n147585\n147586\n147587\n147597\n147602\n147608\n147609\n147613\n147615\n147620\n147625\n147627\n147631\n147635\n147639\n147642\n147644\n147647\n147651\n147662\n147663\n147665\n147668\n147679\n147680\n147682\n147699\n147720\n147723\n147726\n147728\n147740\n147744\n147745\n147746\n147749\n147754\n147755\n147760\n147764\n147772\n147774\n147775\n147779\n147780\n147788\n147798\n147799\n147810\n147811\n147813\n147824\n147825\n147826\n147829\n147838\n147841\n147845\n147854\n147855\n147883\n147893\n147904\n147910\n147913\n147927\n147928\n147932\n147934\n147935\n147951\n147953\n147961\n147970\n147976\n147978\n147986\n147991\n147994\n147995\n147998\n148000\n148001\n148006\n148014\n148018\n148024\n148058\n148070\n148079\n148083\n148088\n148094\n148096\n148097\n148111\n148114\n148118\n148121\n148123\n148124\n148138\n148145\n148148\n148153\n148167\n148170\n148172\n148183\n148191\n148193\n148197\n148198\n148200\n148202\n148210\n148215\n148216\n148221\n148224\n148227\n148235\n148240\n148241\n148243\n148244\n148248\n148253\n148255\n148256\n148259\n148261\n148263\n148266\n148267\n148268\n148270\n148273\n148275\n148281\n148282\n148296\n148298\n148301\n148308\n148311\n148324\n148335\n148336\n148344\n148354\n148355\n148373\n148377\n148391\n148392\n148398\n148404\n148410\n148414\n148419\n148423\n148432\n148442\n148443\n148457\n148465\n148467\n148470\n148475\n148476\n148485\n148488\n148512\n148522\n148523\n148525\n148529\n148541\n148543\n148547\n148553\n148555\n148557\n148578\n148579\n148595\n148599\n148602\n148605\n148609\n148617\n148621\n148623\n148646\n148654\n148657\n148659\n148672\n148673\n148676\n148679\n148682\n148688\n148691\n148693\n148697\n148698\n148699\n148701\n148702\n148705\n148712\n148729\n148732\n148736\n148738\n148754\n148758\n148762\n148763\n148779\n148780\n148782\n148787\n148791\n148795\n148799\n148803\n148806\n148811\n148815\n148816\n148818\n148823\n148825\n148838\n148839\n148840\n148842\n148844\n148850\n148854\n148861\n148862\n148863\n148871\n148875\n148878\n148884\n148887\n148894\n148901\n148905\n148909\n148910\n148918\n148920\n148923\n148926\n148931\n148934\n148937\n148943\n148945\n148946\n148947\n148951\n148958\n148962\n148965\n148975\n148977\n148988\n148989\n148990\n148997\n148998\n148999\n149001\n149008\n149013\n149019\n149021\n149023\n149036\n149038\n149059\n149062\n149065\n149072\n149074\n149075\n149076\n149082\n149084\n149090\n149094\n149097\n149107\n149118\n149121\n149125\n149139\n149145\n149153\n149163\n149176\n149177\n149181\n149186\n149187\n149193\n149199\n149201\n149205\n149207\n149210\n149211\n149212\n149213\n149214\n149219\n149237\n149240\n149241\n149243\n149246\n149249\n149251\n149260\n149263\n149265\n149266\n149272\n149273\n149285\n149286\n149291\n149294\n149295\n149300\n149310\n149332\n149334\n149336\n149341\n149351\n149357\n149366\n149369\n149382\n149384\n149389\n149396\n149400\n149410\n149418\n149426\n149429\n149433\n149436\n149441\n149450\n149454\n149457\n149464\n149476\n149477\n149481\n149483\n149486\n149493\n149494\n149495\n149505\n149508\n149514\n149517\n149519\n149521\n149524\n149532\n149537\n149541\n149549\n149557\n149563\n149566\n149575\n149583\n149584\n149589\n149592\n149596\n149597\n149614\n149617\n149628\n149656\n149659\n149660\n149668\n149677\n149678\n149679\n149684\n149686\n149687\n149688\n149689\n149695\n149704\n149705\n149707\n149722\n149724\n149727\n149734\n149739\n149741\n149747\n149749\n149750\n149756\n149757\n149759\n149766\n149767\n149770\n149774\n149777\n149780\n149781\n149785\n149791\n149794\n149795\n149799\n149801\n149804\n149811\n149813\n149817\n149824\n149831\n149832\n149834\n149835\n149844\n149846\n149851\n149856\n149858\n149860\n149868\n149877\n149884\n149886\n149892\n149893\n149899\n149912\n149915\n149916\n149918\n149919\n149921\n149922\n149926\n149929\n149930\n149935\n149945\n149952\n149957\n149963\n149966\n149967\n149969\n149982\n149987\n149989\n149993\n149995\n150001\n150010\n150014\n150016\n150018\n150019\n150020\n150023\n150025\n150050\n150051\n150057\n150060\n150062\n150078\n150082\n150083\n150087\n150095\n150100\n150101\n150102\n150103\n150104\n150106\n150111\n150114\n150118\n150120\n150121\n150123\n150125\n150126\n150130\n150131\n150133\n150134\n150138\n150139\n150147\n150150\n150152\n150165\n150166\n150168\n150169\n150171\n150173\n150176\n150181\n150185\n150191\n150198\n150200\n150203\n150211\n150217\n150218\n150224\n150230\n150241\n150242\n150243\n150246\n150263\n150264\n150270\n150295\n150296\n150298\n150309\n150312\n150313\n150314\n150320\n150322\n150333\n150336\n150340\n150345\n150370\n150379\n150382\n150385\n150390\n150392\n150395\n150399\n150401\n150405\n150412\n150428\n150431\n150435\n150436\n150438\n150440\n150443\n150447\n150450\n150451\n150452\n150457\n150459\n150461\n150462\n150463\n150466\n150467\n150471\n150487\n150492\n150493\n150495\n150496\n150502\n150505\n150510\n150514\n150520\n150527\n150531\n150536\n150538\n150550\n150553\n150558\n150565\n150579\n150585\n150587\n150595\n150603\n150606\n150607\n150608\n150610\n150616\n150619\n150621\n150622\n150626\n150634\n150637\n150638\n150640\n150648\n150649\n150664\n150666\n150668\n150681\n150683\n150684\n150688\n150691\n150704\n150706\n150708\n150709\n150711\n150712\n150720\n150722\n150725\n150740\n150745\n150750\n150754\n150755\n150756\n150760\n150763\n150767\n150768\n150770\n150784\n150787\n150791\n150792\n150793\n150794\n150796\n150799\n150801\n150815\n150823\n150824\n150826\n150829\n150832\n150846\n150849\n150852\n150854\n150859\n150863\n150871\n150872\n150884\n150887\n150889\n150891\n150893\n150895\n150896\n150904\n150908\n150909\n150911\n150913\n150914\n150918\n150920\n150929\n150931\n150941\n150944\n150957\n150962\n150963\n150966\n150967\n150972\n150974\n150983\n150985\n150986\n150987\n150998\n150999\n151005\n151008\n151022\n151023\n151026\n151029\n151047\n151050\n151052\n151055\n151059\n151062\n151067\n151068\n151069\n151087\n151095\n151100\n151102\n151103\n151105\n151107\n151109\n151114\n151127\n151129\n151138\n151139\n151141\n151142\n151146\n151148\n151149\n151155\n151156\n151164\n151165\n151166\n151169\n151175\n151176\n151194\n151197\n151198\n151204\n151205\n151211\n151214\n151216\n151218\n151219\n151221\n151224\n151235\n151236\n151239\n151247\n151262\n151268\n151275\n151277\n151281\n151289\n151290\n151298\n151300\n151301\n151306\n151309\n151314\n151316\n151320\n151329\n151336\n151338\n151339\n151345\n151348\n151349\n151351\n151361\n151363\n151366\n151368\n151371\n151372\n151380\n151381\n151385\n151390\n151403\n151407\n151410\n151413\n151414\n151415\n151416\n151419\n151423\n151427\n151437\n151443\n151453\n151455\n151458\n151477\n151478\n151480\n151486\n151487\n151489\n151494\n151497\n151501\n151503\n151513\n151515\n151516\n151528\n151533\n151536\n151538\n151543\n151546\n151551\n151554\n151556\n151559\n151563\n151566\n151568\n151569\n151576\n151598\n151600\n151602\n151606\n151608\n151618\n151620\n151622\n151626\n151643\n151647\n151650\n151664\n151672\n151675\n151684\n151691\n151692\n151698\n151701\n151703\n151722\n151730\n151741\n151747\n151755\n151760\n151764\n151770\n151772\n151775\n151776\n151783\n151784\n151811\n151818\n151828\n151851\n151852\n151854\n151858\n151868\n151872\n151874\n151877\n151883\n151898\n151900\n151903\n151904\n151916\n151926\n151929\n151930\n151931\n151932\n151933\n151936\n151944\n151946\n151948\n151950\n151970\n151975\n151978\n151981\n151985\n151987\n151994\n151998\n152014\n152016\n152023\n152031\n152035\n152039\n152042\n152055\n152071\n152072\n152074\n152075\n152081\n152084\n152085\n152089\n152097\n152099\n152100\n152111\n152112\n152113\n152118\n152125\n152128\n152129\n152138\n152144\n152153\n152171\n152179\n152184\n152190\n152195\n152198\n152199\n152200\n152207\n152209\n152212\n152217\n152230\n152233\n152236\n152243\n152244\n152245\n152248\n152264\n152278\n152284\n152285\n152296\n152299\n152307\n152313\n152314\n152319\n152322\n152325\n152353\n152354\n152361\n152366\n152369\n152376\n152398\n152401\n152411\n152417\n152421\n152430\n152433\n152443\n152444\n152450\n152451\n152453\n152458\n152461\n152464\n152472\n152474\n152477\n152479\n152492\n152494\n152502\n152506\n152507\n152524\n152527\n152537\n152538\n152539\n152542\n152546\n152556\n152560\n152561\n152564\n152568\n152569\n152578\n152586\n152596\n152597\n152599\n152608\n152627\n152631\n152636\n152637\n152644\n152645\n152652\n152659\n152664\n152670\n152684\n152688\n152689\n152701\n152713\n152715\n152716\n152733\n152734\n152737\n152745\n152747\n152754\n152758\n152761\n152764\n152765\n152770\n152772\n152779\n152783\n152787\n152790\n152794\n152798\n152803\n152804\n152805\n152812\n152821\n152828\n152831\n152836\n152850\n152852\n152868\n152871\n152872\n152875\n152878\n152880\n152890\n152898\n152901\n152909\n152919\n152920\n152931\n152932\n152936\n152943\n152947\n152948\n152950\n152966\n152967\n152969\n152973\n152974\n152978\n152979\n152980\n152982\n152989\n152999\n153000\n153002\n153004\n153006\n153007\n153014\n153021\n153026\n153034\n153041\n153047\n153057\n153059\n153060\n153061\n153065\n153082\n153083\n153087\n153088\n153089\n153092\n153095\n153096\n153100\n153112\n153113\n153123\n153126\n153129\n153136\n153138\n153153\n153155\n153165\n153171\n153172\n153177\n153182\n153190\n153203\n153211\n153214\n153217\n153219\n153221\n153223\n153226\n153229\n153230\n153235\n153237\n153238\n153239\n153245\n153249\n153253\n153263\n153274\n153277\n153278\n153281\n153290\n153296\n153297\n153325\n153331\n153336\n153337\n153343\n153348\n153363\n153364\n153375\n153378\n153380\n153385\n153391\n153392\n153395\n153396\n153400\n153402\n153406\n153408\n153412\n153413\n153419\n153421\n153434\n153440\n153449\n153451\n153453\n153464\n153471\n153482\n153483\n153502\n153503\n153504\n153506\n153512\n153513\n153516\n153517\n153523\n153527\n153528\n153531\n153534\n153543\n153556\n153557\n153559\n153573\n153574\n153583\n153597\n153605\n153615\n153620\n153624\n153637\n153640\n153646\n153647\n153652\n153655\n153658\n153660\n153661\n153662\n153665\n153666\n153668\n153701\n153703\n153706\n153707\n153709\n153710\n153713\n153716\n153717\n153728\n153730\n153731\n153738\n153742\n153743\n153746\n153762\n153763\n153776\n153784\n153786\n153796\n153798\n153802\n153811\n153815\n153831\n153833\n153834\n153838\n153839\n153842\n153844\n153845\n153846\n153847\n153857\n153862\n153866\n153879\n153887\n153898\n153906\n153910\n153911\n153914\n153916\n153920\n153924\n153925\n153933\n153938\n153943\n153960\n153961\n153963\n153967\n153973\n153978\n153979\n153992\n153995\n154001\n154004\n154007\n154009\n154020\n154025\n154028\n154029\n154030\n154031\n154034\n154036\n154038\n154043\n154044\n154048\n154051\n154054\n154056\n154057\n154065\n154074\n154076\n154077\n154079\n154084\n154091\n154095\n154096\n154106\n154118\n154120\n154123\n154137\n154140\n154157\n154161\n154170\n154174\n154177\n154183\n154184\n154191\n154193\n154201\n154203\n154215\n154220\n154221\n154224\n154226\n154232\n154235\n154241\n154243\n154251\n154256\n154272\n154275\n154278\n154282\n154289\n154290\n154295\n154300\n154302\n154304\n154306\n154309\n154316\n154319\n154324\n154330\n154331\n154335\n154340\n154352\n154353\n154356\n154357\n154361\n154363\n154364\n154366\n154369\n154374\n154379\n154386\n154389\n154398\n154401\n154414\n154415\n154425\n154434\n154435\n154441\n154443\n154462\n154470\n154472\n154475\n154485\n154486\n154489\n154490\n154501\n154502\n154504\n154517\n154528\n154530\n154549\n154551\n154553\n154556\n154560\n154566\n154568\n154572\n154573\n154578\n154581\n154583\n154584\n154593\n154607\n154609\n154614\n154626\n154630\n154635\n154655\n154656\n154659\n154667\n154674\n154680\n154688\n154689\n154692\n154697\n154699\n154705\n154707\n154709\n154710\n154712\n154721\n154725\n154727\n154734\n154741\n154743\n154747\n154748\n154749\n154753\n154754\n154758\n154777\n154786\n154788\n154790\n154792\n154794\n154799\n154802\n154805\n154811\n154821\n154830\n154834\n154842\n154848\n154856\n154858\n154861\n154866\n154868\n154869\n154870\n154871\n154872\n154874\n154877\n154882\n154887\n154888\n154899\n154909\n154911\n154916\n154919\n154920\n154924\n154930\n154937\n154938\n154941\n154943\n154949\n154954\n154962\n154966\n154969\n154971\n154978\n154982\n154986\n155000\n155005\n155011\n155021\n155032\n155035\n155036\n155037\n155041\n155052\n155053\n155055\n155074\n155075\n155076\n155078\n155079\n155101\n155104\n155106\n155108\n155119\n155128\n155129\n155132\n155139\n155153\n155154\n155159\n155161\n155163\n155167\n155183\n155202\n155205\n155214\n155218\n155221\n155225\n155229\n155232\n155233\n155234\n155241\n155242\n155247\n155248\n155253\n155261\n155270\n155277\n155280\n155282\n155284\n155291\n155292\n155297\n155300\n155302\n155313\n155317\n155321\n155323\n155325\n155327\n155328\n155334\n155354\n155356\n155374\n155385\n155387\n155405\n155408\n155414\n155419\n155421\n155425\n155434\n155435\n155437\n155451\n155453\n155456\n155464\n155470\n155471\n155473\n155474\n155475\n155477\n155480\n155486\n155492\n155497\n155519\n155521\n155526\n155534\n155535\n155539\n155542\n155545\n155548\n155553\n155554\n155558\n155561\n155563\n155568\n155578\n155596\n155599\n155602\n155607\n155617\n155621\n155625\n155629\n155635\n155640\n155641\n155642\n155643\n155645\n155646\n155653\n155662\n155663\n155664\n155666\n155669\n155672\n155674\n155676\n155681\n155686\n155687\n155693\n155694\n155695\n155698\n155709\n155713\n155714\n155717\n155719\n155721\n155724\n155726\n155729\n155731\n155734\n155744\n155749\n155758\n155767\n155775\n155784\n155788\n155802\n155803\n155804\n155805\n155809\n155816\n155823\n155825\n155827\n155830\n155831\n155832\n155844\n155849\n155856\n155859\n155875\n155881\n155883\n155890\n155897\n155938\n155939\n155941\n155947\n155950\n155965\n155967\n155969\n155976\n155978\n155981\n155984\n155986\n155987\n155988\n156005\n156007\n156009\n156010\n156021\n156022\n156023\n156025\n156035\n156036\n156039\n156046\n156051\n156053\n156055\n156074\n156089\n156094\n156099\n156105\n156111\n156113\n156118\n156119\n156127\n156135\n156138\n156145\n156154\n156164\n156170\n156173\n156175\n156179\n156183\n156189\n156195\n156206\n156207\n156208\n156210\n156220\n156223\n156229\n156233\n156235\n156239\n156256\n156257\n156269\n156271\n156275\n156278\n156279\n156285\n156290\n156291\n156293\n156296\n156305\n156306\n156308\n156309\n156319\n156322\n156324\n156332\n156334\n156336\n156344\n156345\n156349\n156353\n156356\n156359\n156377\n156387\n156390\n156401\n156409\n156413\n156416\n156427\n156431\n156440\n156445\n156450\n156460\n156462\n156464\n156468\n156476\n156480\n156483\n156492\n156500\n156501\n156510\n156516\n156517\n156519\n156522\n156526\n156527\n156529\n156530\n156533\n156538\n156551\n156555\n156556\n156560\n156564\n156572\n156575\n156593\n156600\n156602\n156619\n156620\n156623\n156635\n156646\n156647\n156653\n156662\n156666\n156670\n156683\n156684\n156686\n156692\n156693\n156696\n156699\n156705\n156708\n156710\n156713\n156720\n156722\n156723\n156727\n156728\n156731\n156732\n156740\n156744\n156745\n156749\n156754\n156757\n156771\n156773\n156774\n156781\n156796\n156800\n156803\n156808\n156815\n156818\n156819\n156820\n156822\n156823\n156824\n156830\n156831\n156833\n156838\n156839\n156843\n156846\n156856\n156864\n156870\n156878\n156879\n156895\n156908\n156940\n156943\n156948\n156953\n156955\n156956\n156957\n156959\n156961\n156968\n156969\n156970\n156971\n156975\n156981\n156985\n156989\n156992\n156995\n157009\n157018\n157024\n157036\n157041\n157044\n157045\n157051\n157052\n157054\n157059\n157062\n157064\n157068\n157079\n157082\n157089\n157099\n157102\n157103\n157109\n157110\n157113\n157117\n157123\n157125\n157127\n157139\n157141\n157144\n157151\n157152\n157153\n157156\n157158\n157159\n157167\n157168\n157173\n157175\n157177\n157180\n157184\n157191\n157192\n157205\n157207\n157208\n157212\n157224\n157228\n157229\n157233\n157237\n157239\n157244\n157248\n157251\n157259\n157260\n157264\n157272\n157273\n157277\n157284\n157288\n157295\n157296\n157307\n157308\n157309\n157311\n157313\n157318\n157320\n157322\n157338\n157339\n157342\n157347\n157348\n157350\n157356\n157367\n157368\n157375\n157377\n157378\n157388\n157389\n157390\n157393\n157394\n157400\n157408\n157416\n157429\n157438\n157445\n157448\n157453\n157464\n157466\n157475\n157476\n157491\n157492\n157500\n157503\n157506\n157515\n157528\n157530\n157531\n157532\n157533\n157536\n157539\n157548\n157555\n157563\n157568\n157570\n157580\n157585\n157586\n157605\n157609\n157624\n157630\n157638\n157641\n157647\n157655\n157658\n157661\n157667\n157670\n157676\n157680\n157686\n157690\n157693\n157698\n157705\n157709\n157710\n157714\n157717\n157721\n157722\n157742\n157743\n157756\n157757\n157758\n157761\n157765\n157767\n157781\n157786\n157790\n157795\n157801\n157815\n157816\n157824\n157828\n157836\n157837\n157841\n157842\n157848\n157849\n157850\n157868\n157870\n157883\n157886\n157887\n157889\n157893\n157900\n157912\n157915\n157919\n157926\n157929\n157932\n157942\n157948\n157949\n157952\n157957\n157967\n157972\n157973\n157975\n157976\n157988\n157994\n158005\n158011\n158015\n158023\n158046\n158048\n158052\n158053\n158065\n158068\n158069\n158073\n158081\n158084\n158101\n158104\n158114\n158116\n158117\n158122\n158125\n158128\n158138\n158139\n158141\n158143\n158147\n158149\n158152\n158155\n158159\n158164\n158168\n158169\n158174\n158175\n158179\n158195\n158196\n158197\n158198\n158199\n158204\n158205\n158206\n158207\n158230\n158232\n158234\n158236\n158237\n158238\n158239\n158243\n158245\n158246\n158254\n158256\n158257\n158258\n158259\n158263\n158267\n158271\n158280\n158284\n158288\n158301\n158304\n158314\n158316\n158330\n158336\n158338\n158343\n158346\n158348\n158358\n158367\n158368\n158380\n158386\n158388\n158389\n158390\n158391\n158405\n158409\n158410\n158413\n158418\n158423\n158424\n158428\n158431\n158432\n158437\n158438\n158440\n158441\n158447\n158450\n158467\n158468\n158470\n158485\n158488\n158491\n158492\n158498\n158505\n158507\n158508\n158514\n158521\n158522\n158525\n158530\n158532\n158537\n158538\n158552\n158553\n158557\n158563\n158571\n158574\n158578\n158582\n158585\n158586\n158589\n158590\n158591\n158597\n158598\n158600\n158601\n158608\n158610\n158615\n158617\n158618\n158621\n158623\n158626\n158628\n158633\n158638\n158640\n158641\n158648\n158650\n158651\n158654\n158663\n158664\n158674\n158686\n158689\n158693\n158696\n158698\n158709\n158711\n158712\n158716\n158717\n158718\n158724\n158726\n158729\n158730\n158731\n158732\n158740\n158748\n158753\n158755\n158763\n158775\n158777\n158778\n158782\n158783\n158784\n158786\n158790\n158793\n158810\n158816\n158817\n158820\n158831\n158835\n158847\n158851\n158855\n158858\n158862\n158865\n158866\n158887\n158888\n158891\n158897\n158901\n158903\n158904\n158914\n158927\n158931\n158933\n158940\n158942\n158954\n158957\n158958\n158965\n158973\n158978\n158986\n158988\n158996\n158997\n158999\n159001\n159004\n159007\n159008\n159011\n159013\n159014\n159023\n159027\n159029\n159030\n159031\n159032\n159033\n159041\n159042\n159044\n159050\n159053\n159055\n159059\n159062\n159072\n159075\n159083\n159089\n159095\n159102\n159103\n159111\n159112\n159115\n159118\n159138\n159141\n159148\n159151\n159153\n159156\n159160\n159166\n159176\n159178\n159186\n159188\n159189\n159191\n159193\n159198\n159204\n159210\n159219\n159221\n159226\n159233\n159238\n159239\n159242\n159243\n159245\n159259\n159261\n159264\n159265\n159269\n159271\n159276\n159283\n159314\n159326\n159332\n159335\n159336\n159338\n159340\n159345\n159358\n159363\n159365\n159367\n159379\n159382\n159383\n159385\n159400\n159404\n159411\n159414\n159419\n159423\n159435\n159446\n159452\n159453\n159461\n159462\n159464\n159473\n159491\n159493\n159497\n159503\n159510\n159520\n159521\n159522\n159523\n159528\n159543\n159549\n159551\n159555\n159566\n159567\n159570\n159572\n159577\n159582\n159586\n159587\n159589\n159593\n159601\n159604\n159606\n159607\n159612\n159614\n159627\n159628\n159632\n159634\n159635\n159637\n159642\n159644\n159646\n159653\n159655\n159658\n159680\n159681\n159685\n159696\n159697\n159698\n159704\n159725\n159728\n159737\n159738\n159747\n159748\n159749\n159750\n159752\n159753\n159754\n159759\n159772\n159773\n159774\n159777\n159779\n159783\n159800\n159801\n159804\n159811\n159817\n159819\n159820\n159821\n159826\n159830\n159837\n159840\n159841\n159842\n159843\n159844\n159856\n159858\n159861\n159865\n159877\n159885\n159897\n159908\n159909\n159916\n159917\n159919\n159923\n159926\n159927\n159929\n159932\n159940\n159971\n159975\n159976\n159979\n159986\n159991\n159993\n159994\n160001\n160006\n160009\n160010\n160012\n160017\n160021\n160024\n160035\n160037\n160042\n160044\n160045\n160048\n160051\n160054\n160056\n160057\n160063\n160090\n160101\n160103\n160104\n160110\n160119\n160120\n160122\n160131\n160147\n160153\n160156\n160158\n160160\n160176\n160181\n160193\n160196\n160197\n160225\n160226\n160228\n160229\n160232\n160234\n160241\n160243\n160246\n160248\n160250\n160254\n160263\n160268\n160269\n160271\n160291\n160295\n160296\n160298\n160299\n160300\n160302\n160308\n160320\n160327\n160328\n160333\n160334\n160336\n160347\n160358\n160359\n160360\n160362\n160372\n160380\n160399\n160400\n160403\n160406\n160418\n160424\n160427\n160428\n160432\n160445\n160446\n160449\n160451\n160452\n160453\n160456\n160481\n160488\n160489\n160490\n160504\n160509\n160513\n160516\n160517\n160521\n160525\n160527\n160528\n160530\n160545\n160547\n160549\n160552\n160553\n160560\n160563\n160580\n160587\n160590\n160591\n160603\n160609\n160612\n160625\n160628\n160630\n160631\n160636\n160647\n160660\n160661\n160667\n160671\n160672\n160673\n160674\n160676\n160682\n160685\n160698\n160701\n160704\n160708\n160712\n160713\n160715\n160716\n160725\n160727\n160729\n160735\n160744\n160750\n160761\n160763\n160765\n160766\n160770\n160773\n160784\n160793\n160794\n160796\n160804\n160805\n160806\n160807\n160808\n160810\n160812\n160837\n160844\n160846\n160850\n160854\n160863\n160864\n160868\n160877\n160878\n160880\n160882\n160898\n160911\n160917\n160921\n160923\n160927\n160933\n160935\n160943\n160947\n160956\n160957\n160962\n160963\n160965\n160977\n160984\n160985\n160987\n160991\n161004\n161006\n161011\n161022\n161026\n161029\n161032\n161035\n161037\n161051\n161052\n161056\n161057\n161064\n161067\n161068\n161076\n161078\n161081\n161082\n161083\n161089\n161092\n161093\n161103\n161120\n161131\n161152\n161155\n161158\n161160\n161163\n161166\n161168\n161171\n161173\n161179\n161184\n161186\n161188\n161191\n161192\n161198\n161202\n161204\n161208\n161216\n161217\n161220\n161222\n161228\n161229\n161232\n161237\n161241\n161244\n161246\n161253\n161255\n161264\n161268\n161273\n161290\n161299\n161302\n161306\n161309\n161315\n161316\n161317\n161323\n161332\n161336\n161343\n161348\n161353\n161357\n161361\n161362\n161367\n161368\n161370\n161371\n161378\n161383\n161385\n161389\n161396\n161398\n161401\n161404\n161406\n161421\n161423\n161427\n161443\n161451\n161457\n161459\n161466\n161467\n161471\n161478\n161479\n161488\n161493\n161500\n161503\n161507\n161509\n161513\n161516\n161520\n161533\n161538\n161548\n161550\n161554\n161555\n161558\n161563\n161570\n161572\n161576\n161577\n161581\n161586\n161600\n161603\n161604\n161608\n161611\n161612\n161615\n161616\n161619\n161637\n161641\n161645\n161648\n161656\n161671\n161675\n161685\n161687\n161689\n161691\n161695\n161699\n161700\n161702\n161709\n161712\n161715\n161718\n161724\n161725\n161727\n161728\n161736\n161740\n161749\n161758\n161768\n161784\n161790\n161792\n161794\n161795\n161800\n161804\n161806\n161808\n161822\n161824\n161832\n161837\n161849\n161854\n161863\n161867\n161870\n161876\n161879\n161888\n161890\n161896\n161903\n161909\n161921\n161925\n161926\n161934\n161935\n161939\n161945\n161946\n161954\n161961\n161962\n161970\n161981\n161983\n161987\n161991\n161995\n161998\n162006\n162013\n162023\n162028\n162031\n162033\n162037\n162053\n162054\n162055\n162067\n162069\n162078\n162079\n162080\n162086\n162090\n162096\n162097\n162102\n162104\n162114\n162121\n162125\n162127\n162128\n162130\n162135\n162141\n162147\n162149\n162158\n162161\n162165\n162166\n162170\n162174\n162177\n162181\n162183\n162187\n162189\n162197\n162201\n162210\n162216\n162219\n162221\n162228\n162234\n162246\n162265\n162269\n162278\n162284\n162286\n162302\n162307\n162313\n162316\n162318\n162327\n162330\n162331\n162333\n162334\n162335\n162339\n162366\n162367\n162371\n162374\n162378\n162401\n162402\n162408\n162410\n162415\n162417\n162421\n162439\n162443\n162446\n162449\n162453\n162456\n162459\n162460\n162462\n162465\n162467\n162471\n162479\n162488\n162496\n162498\n162506\n162508\n162519\n162530\n162540\n162552\n162556\n162579\n162581\n162583\n162584\n162587\n162590\n162600\n162609\n162618\n162627\n162639\n162644\n162645\n162648\n162654\n162676\n162677\n162682\n162690\n162699\n162700\n162702\n162704\n162720\n162729\n162731\n162736\n162741\n162747\n162750\n162752\n162757\n162758\n162762\n162764\n162776\n162778\n162781\n162786\n162790\n162792\n162798\n162806\n162811\n162813\n162820\n162824\n162825\n162827\n162833\n162835\n162838\n162850\n162873\n162879\n162892\n162896\n162904\n162905\n162912\n162921\n162930\n162937\n162957\n162958\n162961\n162963\n162974\n162981\n162983\n162991\n162993\n163001\n163002\n163009\n163012\n163016\n163017\n163019\n163030\n163031\n163040\n163044\n163046\n163051\n163053\n163057\n163063\n163064\n163069\n163075\n163079\n163084\n163088\n163108\n163110\n163120\n163131\n163135\n163141\n163149\n163154\n163164\n163167\n163181\n163197\n163200\n163206\n163215\n163219\n163220\n163224\n163234\n163236\n163239\n163241\n163250\n163251\n163256\n163261\n163262\n163266\n163278\n163288\n163291\n163292\n163301\n163305\n163308\n163326\n163329\n163330\n163333\n163351\n163352\n163356\n163362\n163363\n163369\n163371\n163376\n163378\n163379\n163380\n163383\n163389\n163423\n163428\n163430\n163431\n163434\n163439\n163443\n163447\n163455\n163458\n163470\n163471\n163472\n163474\n163475\n163483\n163489\n163492\n163496\n163516\n163519\n163520\n163524\n163528\n163532\n163537\n163552\n163554\n163555\n163556\n163570\n163579\n163586\n163591\n163595\n163611\n163615\n163621\n163622\n163647\n163651\n163660\n163661\n163672\n163674\n163682\n163684\n163688\n163699\n163703\n163704\n163707\n163709\n163714\n163723\n163727\n163739\n163740\n163743\n163754\n163762\n163771\n163776\n163779\n163786\n163798\n163804\n163813\n163821\n163825\n163826\n163830\n163832\n163838\n163844\n163845\n163848\n163855\n163856\n163862\n163863\n163866\n163869\n163874\n163880\n163892\n163896\n163900\n163902\n163910\n163911\n163915\n163917\n163918\n163921\n163924\n163925\n163931\n163936\n163942\n163947\n163949\n163953\n163958\n163960\n163963\n163964\n163969\n163973\n163975\n163977\n163982\n163987\n163991\n163998\n164003\n164017\n164018\n164047\n164052\n164054\n164055\n164073\n164081\n164089\n164090\n164091\n164092\n164100\n164111\n164112\n164117\n164118\n164119\n164123\n164132\n164135\n164145\n164149\n164150\n164152\n164156\n164157\n164162\n164180\n164191\n164198\n164201\n164207\n164211\n164220\n164222\n164223\n164228\n164229\n164233\n164235\n164236\n164242\n164243\n164256\n164259\n164264\n164265\n164266\n164267\n164279\n164282\n164284\n164290\n164298\n164300\n164308\n164309\n164311\n164314\n164319\n164321\n164327\n164335\n164337\n164341\n164346\n164348\n164357\n164358\n164361\n164365\n164372\n164375\n164393\n164395\n164398\n164402\n164407\n164413\n164414\n164416\n164417\n164418\n164420\n164421\n164423\n164427\n164431\n164436\n164439\n164442\n164443\n164444\n164447\n164463\n164465\n164469\n164479\n164481\n164484\n164491\n164500\n164501\n164503\n164507\n164511\n164528\n164542\n164544\n164550\n164556\n164557\n164559\n164566\n164567\n164570\n164571\n164577\n164578\n164585\n164609\n164612\n164613\n164625\n164627\n164634\n164644\n164647\n164648\n164651\n164655\n164657\n164659\n164660\n164689\n164691\n164693\n164696\n164698\n164699\n164700\n164701\n164704\n164710\n164716\n164719\n164723\n164729\n164739\n164751\n164759\n164769\n164776\n164793\n164794\n164801\n164805\n164806\n164812\n164813\n164838\n164841\n164848\n164853\n164858\n164859\n164860\n164864\n164868\n164873\n164882\n164895\n164897\n164907\n164915\n164916\n164918\n164920\n164921\n164927\n164928\n164931\n164934\n164937\n164939\n164940\n164941\n164949\n164954\n164956\n164958\n164961\n164967\n164980\n165004\n165005\n165008\n165011\n165012\n165023\n165027\n165029\n165030\n165034\n165035\n165037\n165055\n165062\n165070\n165087\n165089\n165093\n165096\n165098\n165108\n165114\n165115\n165117\n165128\n165131\n165141\n165145\n165156\n165157\n165170\n165179\n165187\n165191\n165193\n165196\n165206\n165207\n165220\n165222\n165228\n165232\n165233\n165235\n165239\n165240\n165243\n165258\n165271\n165276\n165278\n165287\n165306\n165310\n165312\n165313\n165314\n165320\n165321\n165324\n165327\n165330\n165334\n165348\n165363\n165366\n165368\n165370\n165372\n165376\n165379\n165383\n165385\n165393\n165400\n165403\n165413\n165418\n165419\n165421\n165425\n165428\n165432\n165433\n165438\n165439\n165440\n165442\n165446\n165455\n165456\n165459\n165464\n165465\n165468\n165484\n165489\n165490\n165491\n165493\n165500\n165503\n165505\n165508\n165512\n165513\n165524\n165528\n165544\n165546\n165550\n165553\n165554\n165556\n165558\n165562\n165569\n165572\n165577\n165578\n165599\n165605\n165609\n165610\n165623\n165624\n165632\n165633\n165637\n165643\n165654\n165663\n165675\n165680\n165684\n165705\n165706\n165707\n165720\n165724\n165725\n165726\n165729\n165737\n165746\n165759\n165762\n165780\n165827\n165835\n165838\n165840\n165848\n165853\n165854\n165857\n165858\n165877\n165882\n165889\n165893\n165902\n165906\n165911\n165913\n165916\n165921\n165935\n165936\n165938\n165939\n165955\n165957\n165968\n165969\n165982\n165996\n166000\n166012\n166013\n166014\n166017\n166018\n166025\n166029\n166030\n166041\n166042\n166046\n166051\n166053\n166064\n166065\n166074\n166076\n166078\n166079\n166080\n166081\n166085\n166086\n166094\n166099\n166101\n166110\n166117\n166122\n166124\n166131\n166133\n166136\n166138\n166140\n166143\n166144\n166158\n166161\n166165\n166167\n166169\n166171\n166173\n166174\n166180\n166185\n166196\n166202\n166203\n166210\n166211\n166212\n166218\n166227\n166230\n166231\n166234\n166237\n166244\n166257\n166261\n166269\n166273\n166275\n166276\n166279\n166281\n166285\n166295\n166296\n166297\n166303\n166308\n166320\n166324\n166329\n166330\n166347\n166354\n166358\n166364\n166372\n166376\n166393\n166401\n166405\n166406\n166410\n166411\n166412\n166417\n166419\n166423\n166426\n166431\n166436\n166437\n166443\n166444\n166455\n166456\n166458\n166461\n166466\n166467\n166474\n166476\n166478\n166485\n166490\n166505\n166511\n166512\n166514\n166515\n166519\n166527\n166534\n166539\n166540\n166551\n166554\n166563\n166567\n166568\n166574\n166577\n166592\n166607\n166610\n166612\n166614\n166619\n166623\n166626\n166627\n166635\n166637\n166640\n166641\n166652\n166655\n166660\n166670\n166684\n166691\n166694\n166703\n166708\n166713\n166717\n166719\n166730\n166731\n166736\n166739\n166753\n166758\n166761\n166762\n166764\n166770\n166771\n166772\n166775\n166779\n166784\n166787\n166788\n166793\n166795\n166798\n166813\n166832\n166837\n166841\n166844\n166849\n166856\n166865\n166870\n166881\n166883\n166885\n166894\n166895\n166898\n166900\n166906\n166909\n166915\n166917\n166919\n166921\n166923\n166927\n166933\n166938\n166941\n166942\n166945\n166947\n166953\n166957\n166959\n166960\n166963\n166965\n166968\n166979\n166996\n166997\n167010\n167015\n167025\n167031\n167037\n167039\n167042\n167044\n167070\n167081\n167083\n167089\n167091\n167096\n167097\n167111\n167113\n167115\n167117\n167120\n167126\n167127\n167136\n167142\n167147\n167148\n167151\n167155\n167159\n167164\n167168\n167169\n167172\n167173\n167176\n167180\n167185\n167196\n167199\n167213\n167217\n167222\n167228\n167233\n167235\n167240\n167247\n167254\n167257\n167262\n167263\n167267\n167268\n167269\n167275\n167283\n167287\n167292\n167295\n167297\n167299\n167313\n167321\n167326\n167330\n167331\n167349\n167362\n167366\n167384\n167391\n167403\n167404\n167411\n167412\n167414\n167417\n167434\n167438\n167440\n167448\n167451\n167452\n167459\n167460\n167470\n167475\n167478\n167486\n167487\n167488\n167489\n167493\n167495\n167496\n167497\n167507\n167510\n167515\n167523\n167526\n167531\n167534\n167536\n167538\n167539\n167546\n167551\n167552\n167553\n167560\n167579\n167585\n167588\n167589\n167592\n167604\n167619\n167621\n167628\n167633\n167634\n167638\n167639\n167648\n167655\n167662\n167668\n167671\n167674\n167679\n167681\n167683\n167685\n167702\n167705\n167716\n167718\n167719\n167724\n167726\n167729\n167732\n167740\n167755\n167771\n167772\n167773\n167774\n167777\n167778\n167781\n167794\n167796\n167797\n167802\n167807\n167809\n167810\n167818\n167828\n167829\n167834\n167837\n167841\n167844\n167848\n167852\n167854\n167856\n167860\n167863\n167865\n167882\n167895\n167897\n167913\n167917\n167922\n167924\n167927\n167928\n167934\n167935\n167954\n167957\n167959\n167987\n167988\n167991\n167992\n168006\n168009\n168012\n168016\n168022\n168024\n168025\n168031\n168037\n168047\n168052\n168056\n168059\n168060\n168064\n168074\n168080\n168081\n168091\n168096\n168103\n168112\n168116\n168119\n168125\n168132\n168133\n168135\n168137\n168139\n168140\n168141\n168143\n168145\n168153\n168156\n168160\n168169\n168171\n168176\n168179\n168180\n168185\n168187\n168189\n168191\n168211\n168216\n168218\n168228\n168230\n168231\n168232\n168240\n168244\n168246\n168248\n168250\n168259\n168261\n168266\n168267\n168271\n168272\n168273\n168275\n168276\n168279\n168284\n168296\n168304\n168305\n168306\n168307\n168315\n168323\n168347\n168357\n168359\n168360\n168363\n168364\n168365\n168370\n168373\n168377\n168378\n168379\n168382\n168385\n168391\n168392\n168394\n168398\n168404\n168410\n168412\n168415\n168421\n168423\n168424\n168431\n168432\n168434\n168436\n168437\n168439\n168443\n168445\n168449\n168460\n168466\n168467\n168474\n168479\n168480\n168482\n168490\n168492\n168505\n168510\n168511\n168512\n168515\n168518\n168519\n168533\n168535\n168536\n168548\n168551\n168554\n168555\n168556\n168559\n168563\n168592\n168596\n168598\n168599\n168610\n168623\n168624\n168638\n168639\n168640\n168641\n168647\n168650\n168663\n168665\n168676\n168680\n168681\n168683\n168687\n168689\n168702\n168709\n168710\n168711\n168716\n168721\n168722\n168727\n168728\n168730\n168733\n168741\n168744\n168754\n168762\n168773\n168776\n168781\n168785\n168787\n168789\n168794\n168795\n168798\n168810\n168816\n168817\n168820\n168822\n168828\n168845\n168853\n168856\n168860\n168886\n168889\n168897\n168901\n168902\n168903\n168909\n168924\n168930\n168932\n168933\n168934\n168947\n168957\n168971\n168977\n168979\n168981\n168983\n168989\n168990\n168995\n168996\n168997\n169000\n169010\n169019\n169024\n169026\n169027\n169032\n169037\n169038\n169042\n169046\n169050\n169058\n169062\n169073\n169077\n169080\n169085\n169091\n169095\n169097\n169099\n169101\n169108\n169111\n169114\n169118\n169119\n169121\n169124\n169125\n169128\n169131\n169135\n169140\n169145\n169151\n169156\n169170\n169175\n169184\n169187\n169189\n169193\n169199\n169204\n169207\n169209\n169214\n169221\n169227\n169228\n169232\n169234\n169242\n169244\n169253\n169262\n169263\n169267\n169269\n169273\n169280\n169282\n169283\n169285\n169290\n169295\n169298\n169302\n169303\n169308\n169313\n169314\n169315\n169318\n169319\n169323\n169325\n169327\n169329\n169341\n169342\n169347\n169351\n169355\n169356\n169357\n169358\n169363\n169367\n169371\n169376\n169378\n169388\n169389\n169392\n169397\n169398\n169415\n169423\n169425\n169428\n169431\n169433\n169434\n169435\n169461\n169492\n169498\n169505\n169511\n169514\n169529\n169530\n169537\n169539\n169561\n169566\n169580\n169581\n169586\n169601\n169607\n169611\n169615\n169616\n169617\n169618\n169626\n169630\n169631\n169635\n169638\n169639\n169642\n169647\n169651\n169659\n169664\n169665\n169666\n169668\n169671\n169675\n169676\n169678\n169679\n169680\n169687\n169696\n169698\n169699\n169701\n169704\n169706\n169723\n169732\n169742\n169749\n169750\n169755\n169761\n169763\n169767\n169769\n169772\n169773\n169774\n169778\n169793\n169801\n169804\n169809\n169814\n169824\n169827\n169838\n169841\n169844\n169845\n169846\n169848\n169853\n169855\n169856\n169859\n169861\n169870\n169873\n169876\n169877\n169878\n169881\n169887\n169891\n169896\n169899\n169910\n169914\n169915\n169940\n169943\n169944\n169948\n169957\n169966\n169968\n169969\n169971\n169979\n169986\n169989\n169996\n170003\n170006\n170010\n170019\n170020\n170032\n170037\n170038\n170052\n170053\n170057\n170058\n170065\n170067\n170073\n170075\n170078\n170082\n170086\n170091\n170093\n170095\n170108\n170113\n170122\n170133\n170138\n170140\n170141\n170145\n170150\n170151\n170156\n170159\n170165\n170178\n170187\n170192\n170194\n170201\n170210\n170237\n170238\n170239\n170249\n170278\n170280\n170287\n170295\n170296\n170303\n170322\n170324\n170325\n170333\n170344\n170350\n170351\n170358\n170361\n170362\n170363\n170365\n170369\n170379\n170381\n170383\n170392\n170398\n170401\n170410\n170412\n170416\n170418\n170419\n170422\n170431\n170434\n170437\n170439\n170441\n170443\n170449\n170451\n170454\n170458\n170466\n170468\n170470\n170472\n170475\n170481\n170491\n170494\n170504\n170507\n170509\n170510\n170513\n170514\n170521\n170522\n170534\n170535\n170538\n170542\n170554\n170557\n170559\n170562\n170567\n170570\n170605\n170612\n170616\n170626\n170629\n170631\n170632\n170633\n170635\n170645\n170647\n170665\n170679\n170688\n170689\n170710\n170718\n170720\n170725\n170729\n170734\n170741\n170742\n170759\n170760\n170762\n170778\n170783\n170789\n170794\n170796\n170798\n170800\n170806\n170809\n170822\n170836\n170838\n170839\n170840\n170849\n170853\n170855\n170872\n170875\n170879\n170891\n170895\n170898\n170904\n170907\n170911\n170912\n170918\n170920\n170922\n170925\n170926\n170927\n170932\n170934\n170935\n170942\n170952\n170955\n170958\n170972\n170974\n170978\n170980\n170983\n170985\n170996\n171002\n171006\n171014\n171015\n171041\n171049\n171054\n171079\n171080\n171085\n171101\n171102\n171112\n171122\n171126\n171127\n171133\n171137\n171144\n171151\n171152\n171163\n171183\n171184\n171188\n171195\n171198\n171202\n171207\n171215\n171221\n171225\n171231\n171232\n171240\n171252\n171263\n171266\n171268\n171277\n171287\n171293\n171299\n171304\n171308\n171320\n171328\n171340\n171342\n171344\n171346\n171348\n171349\n171356\n171357\n171359\n171364\n171372\n171377\n171380\n171393\n171394\n171396\n171398\n171400\n171402\n171408\n171418\n171421\n171426\n171429\n171430\n171435\n171440\n171453\n171455\n171459\n171466\n171472\n171473\n171491\n171492\n171493\n171496\n171497\n171499\n171508\n171510\n171531\n171532\n171533\n171535\n171538\n171556\n171560\n171578\n171581\n171585\n171596\n171598\n171599\n171601\n171605\n171608\n171619\n171624\n171626\n171627\n171629\n171636\n171640\n171646\n171648\n171652\n171660\n171662\n171668\n171670\n171679\n171681\n171683\n171686\n171697\n171705\n171708\n171709\n171718\n171726\n171728\n171731\n171736\n171743\n171745\n171755\n171757\n171759\n171776\n171780\n171785\n171787\n171799\n171808\n171809\n171811\n171819\n171823\n171825\n171828\n171831\n171837\n171859\n171878\n171888\n171896\n171900\n171903\n171908\n171910\n171914\n171919\n171928\n171932\n171937\n171939\n171945\n171949\n171957\n171959\n171960\n171963\n171972\n171973\n171979\n171980\n171981\n171983\n171988\n171989\n171993\n171997\n172001\n172007\n172010\n172011\n172012\n172014\n172016\n172018\n172022\n172027\n172028\n172035\n172039\n172046\n172050\n172060\n172064\n172069\n172082\n172100\n172107\n172109\n172114\n172121\n172125\n172126\n172132\n172134\n172135\n172136\n172147\n172148\n172156\n172159\n172161\n172168\n172173\n172181\n172189\n172192\n172193\n172196\n172198\n172199\n172200\n172210\n172212\n172213\n172216\n172217\n172226\n172234\n172235\n172243\n172244\n172255\n172263\n172270\n172272\n172278\n172281\n172284\n172287\n172289\n172292\n172293\n172296\n172297\n172300\n172306\n172307\n172308\n172309\n172311\n172318\n172320\n172322\n172325\n172326\n172328\n172333\n172336\n172338\n172341\n172348\n172350\n172361\n172365\n172368\n172376\n172378\n172381\n172382\n172386\n172389\n172391\n172393\n172401\n172405\n172406\n172410\n172416\n172425\n172429\n172432\n172434\n172445\n172446\n172454\n172462\n172463\n172464\n172470\n172471\n172473\n172475\n172480\n172492\n172493\n172494\n172499\n172504\n172519\n172527\n172532\n172534\n172535\n172539\n172543\n172549\n172550\n172557\n172565\n172566\n172567\n172570\n172577\n172579\n172596\n172597\n172598\n172607\n172610\n172611\n172618\n172619\n172622\n172626\n172634\n172643\n172645\n172648\n172650\n172656\n172660\n172663\n172664\n172665\n172666\n172669\n172671\n172675\n172682\n172709\n172713\n172714\n172720\n172721\n172724\n172727\n172728\n172729\n172745\n172748\n172753\n172762\n172766\n172772\n172773\n172781\n172782\n172784\n172793\n172794\n172800\n172804\n172807\n172813\n172814\n172818\n172820\n172821\n172822\n172824\n172825\n172827\n172830\n172838\n172844\n172849\n172855\n172860\n172861\n172862\n172863\n172870\n172872\n172876\n172878\n172889\n172891\n172892\n172894\n172898\n172902\n172908\n172910\n172911\n172922\n172923\n172925\n172927\n172933\n172942\n172948\n172949\n172955\n172959\n172972\n172973\n172974\n172978\n172990\n172995\n172999\n173011\n173012\n173021\n173023\n173024\n173025\n173028\n173033\n173035\n173041\n173058\n173061\n173062\n173066\n173070\n173074\n173076\n173081\n173092\n173099\n173102\n173103\n173109\n173112\n173120\n173123\n173125\n173127\n173130\n173139\n173140\n173149\n173150\n173154\n173160\n173167\n173171\n173175\n173176\n173186\n173187\n173189\n173191\n173195\n173196\n173198\n173204\n173207\n173209\n173211\n173213\n173218\n173226\n173232\n173234\n173239\n173246\n173249\n173253\n173255\n173256\n173257\n173264\n173279\n173287\n173292\n173295\n173298\n173302\n173305\n173311\n173322\n173324\n173325\n173330\n173340\n173343\n173346\n173347\n173352\n173361\n173362\n173364\n173369\n173380\n173382\n173385\n173402\n173404\n173406\n173413\n173425\n173428\n173430\n173434\n173442\n173450\n173451\n173464\n173465\n173468\n173472\n173479\n173484\n173487\n173495\n173497\n173505\n173506\n173509\n173510\n173514\n173517\n173519\n173520\n173523\n173531\n173533\n173540\n173544\n173545\n173549\n173552\n173553\n173563\n173574\n173575\n173579\n173586\n173588\n173594\n173595\n173597\n173598\n173611\n173618\n173621\n173632\n173633\n173641\n173648\n173651\n173655\n173665\n173666\n173667\n173680\n173681\n173682\n173688\n173689\n173692\n173694\n173697\n173699\n173701\n173702\n173707\n173712\n173713\n173715\n173717\n173722\n173734\n173735\n173736\n173740\n173741\n173750\n173753\n173769\n173770\n173777\n173779\n173791\n173796\n173800\n173801\n173829\n173832\n173837\n173845\n173851\n173857\n173864\n173865\n173866\n173868\n173876\n173883\n173886\n173889\n173891\n173894\n173903\n173906\n173908\n173912\n173921\n173929\n173933\n173935\n173939\n173941\n173945\n173950\n173951\n173954\n173956\n173961\n173970\n173974\n173981\n173982\n173987\n173994\n173996\n174006\n174017\n174025\n174029\n174032\n174047\n174053\n174054\n174055\n174060\n174061\n174062\n174065\n174073\n174080\n174082\n174084\n174088\n174092\n174101\n174103\n174114\n174120\n174125\n174127\n174147\n174160\n174169\n174178\n174187\n174193\n174194\n174195\n174196\n174215\n174216\n174222\n174230\n174231\n174245\n174247\n174255\n174269\n174271\n174273\n174276\n174279\n174283\n174284\n174291\n174294\n174300\n174302\n174305\n174307\n174309\n174310\n174311\n174316\n174322\n174324\n174326\n174327\n174328\n174333\n174346\n174353\n174354\n174358\n174363\n174366\n174373\n174375\n174389\n174394\n174395\n174407\n174410\n174411\n174415\n174417\n174419\n174423\n174425\n174431\n174433\n174447\n174450\n174459\n174460\n174462\n174465\n174470\n174472\n174473\n174478\n174490\n174498\n174502\n174515\n174517\n174532\n174537\n174545\n174549\n174550\n174554\n174557\n174562\n174564\n174565\n174570\n174586\n174589\n174590\n174596\n174603\n174608\n174609\n174637\n174641\n174645\n174646\n174654\n174655\n174667\n174671\n174674\n174681\n174685\n174687\n174694\n174699\n174701\n174727\n174728\n174729\n174739\n174741\n174760\n174761\n174765\n174770\n174774\n174776\n174785\n174786\n174788\n174789\n174800\n174808\n174813\n174819\n174820\n174821\n174829\n174832\n174837\n174838\n174840\n174844\n174848\n174849\n174853\n174856\n174864\n174871\n174878\n174883\n174884\n174891\n174906\n174907\n174908\n174910\n174919\n174921\n174922\n174928\n174932\n174941\n174951\n174954\n174958\n174972\n174986\n174990\n174996\n174998\n175001\n175003\n175016\n175019\n175032\n175033\n175036\n175037\n175039\n175045\n175047\n175051\n175054\n175056\n175059\n175069\n175070\n175075\n175076\n175079\n175086\n175102\n175105\n175107\n175111\n175115\n175124\n175143\n175146\n175149\n175152\n175158\n175161\n175168\n175173\n175180\n175182\n175189\n175192\n175193\n175194\n175205\n175210\n175225\n175226\n175228\n175229\n175233\n175242\n175247\n175251\n175265\n175267\n175284\n175286\n175287\n175293\n175297\n175299\n175300\n175304\n175307\n175310\n175312\n175319\n175327\n175331\n175341\n175345\n175349\n175355\n175357\n175358\n175360\n175361\n175368\n175374\n175376\n175380\n175383\n175392\n175394\n175395\n175408\n175413\n175425\n175441\n175447\n175455\n175456\n175468\n175476\n175479\n175483\n175485\n175489\n175494\n175501\n175504\n175510\n175514\n175532\n175534\n175535\n175540\n175542\n175543\n175547\n175548\n175553\n175555\n175564\n175566\n175579\n175586\n175592\n175593\n175595\n175596\n175604\n175612\n175616\n175634\n175639\n175641\n175642\n175643\n175646\n175653\n175657\n175666\n175671\n175673\n175674\n175682\n175687\n175703\n175704\n175705\n175708\n175713\n175722\n175724\n175729\n175744\n175752\n175756\n175763\n175767\n175774\n175781\n175788\n175793\n175794\n175801\n175820\n175829\n175831\n175832\n175835\n175843\n175864\n175873\n175883\n175889\n175891\n175892\n175904\n175908\n175911\n175924\n175926\n175931\n175932\n175940\n175941\n175944\n175946\n175950\n175951\n175954\n175962\n175964\n175967\n175973\n175975\n175976\n175977\n175987\n175988\n175989\n175990\n175993\n176000\n176001\n176009\n176013\n176015\n176016\n176022\n176044\n176045\n176055\n176059\n176060\n176064\n176066\n176070\n176074\n176078\n176079\n176087\n176094\n176095\n176098\n176110\n176111\n176114\n176118\n176120\n176126\n176131\n176135\n176142\n176150\n176158\n176163\n176166\n176182\n176184\n176185\n176189\n176190\n176191\n176197\n176203\n176204\n176206\n176207\n176209\n176212\n176218\n176222\n176223\n176225\n176226\n176234\n176243\n176248\n176250\n176258\n176274\n176284\n176296\n176297\n176300\n176306\n176314\n176320\n176321\n176328\n176333\n176335\n176345\n176362\n176369\n176370\n176371\n176377\n176397\n176413\n176416\n176417\n176419\n176422\n176425\n176429\n176439\n176449\n176451\n176456\n176461\n176468\n176473\n176483\n176489\n176495\n176500\n176501\n176503\n176504\n176508\n176510\n176514\n176518\n176530\n176532\n176536\n176537\n176540\n176553\n176555\n176560\n176565\n176574\n176577\n176582\n176583\n176589\n176595\n176599\n176600\n176603\n176605\n176608\n176611\n176615\n176633\n176634\n176635\n176643\n176646\n176654\n176660\n176670\n176676\n176691\n176693\n176694\n176703\n176712\n176716\n176720\n176724\n176726\n176735\n176739\n176748\n176754\n176763\n176767\n176774\n176775\n176778\n176784\n176790\n176791\n176793\n176795\n176800\n176806\n176814\n176816\n176819\n176821\n176826\n176828\n176834\n176837\n176850\n176856\n176860\n176864\n176873\n176881\n176894\n176898\n176904\n176917\n176934\n176941\n176944\n176946\n176953\n176958\n176972\n176974\n176975\n176976\n176982\n176983\n176992\n176996\n177000\n177002\n177005\n177007\n177010\n177017\n177018\n177020\n177023\n177026\n177029\n177051\n177053\n177055\n177059\n177077\n177078\n177085\n177093\n177110\n177111\n177116\n177119\n177125\n177129\n177133\n177138\n177144\n177150\n177160\n177162\n177174\n177180\n177185\n177203\n177208\n177215\n177224\n177225\n177235\n177240\n177251\n177252\n177258\n177270\n177275\n177279\n177283\n177284\n177286\n177293\n177294\n177300\n177304\n177305\n177320\n177322\n177324\n177337\n177345\n177347\n177349\n177351\n177354\n177362\n177372\n177373\n177388\n177392\n177394\n177397\n177402\n177405\n177408\n177410\n177412\n177420\n177424\n177427\n177431\n177432\n177433\n177438\n177443\n177444\n177447\n177448\n177452\n177471\n177473\n177475\n177480\n177488\n177489\n177504\n177507\n177508\n177509\n177515\n177518\n177519\n177520\n177521\n177522\n177547\n177554\n177562\n177569\n177571\n177573\n177580\n177583\n177590\n177595\n177599\n177609\n177611\n177612\n177613\n177619\n177625\n177631\n177638\n177646\n177649\n177653\n177659\n177664\n177671\n177673\n177681\n177682\n177683\n177684\n177692\n177695\n177707\n177708\n177714\n177715\n177725\n177728\n177732\n177735\n177738\n177742\n177754\n177756\n177761\n177765\n177784\n177785\n177786\n177787\n177788\n177790\n177804\n177806\n177809\n177810\n177812\n177814\n177816\n177822\n177831\n177833\n177835\n177836\n177837\n177861\n177862\n177864\n177869\n177879\n177880\n177893\n177908\n177920\n177926\n177927\n177929\n177930\n177935\n177937\n177938\n177943\n177949\n177954\n177956\n177968\n177972\n177975\n178006\n178012\n178013\n178026\n178029\n178030\n178032\n178042\n178048\n178049\n178051\n178067\n178074\n178076\n178080\n178097\n178098\n178099\n178103\n178105\n178106\n178109\n178110\n178112\n178113\n178126\n178131\n178132\n178141\n178142\n178147\n178149\n178160\n178168\n178171\n178177\n178180\n178182\n178183\n178189\n178193\n178232\n178240\n178247\n178251\n178252\n178253\n178257\n178258\n178260\n178270\n178271\n178279\n178284\n178286\n178289\n178303\n178315\n178317\n178330\n178331\n178332\n178335\n178336\n178340\n178346\n178347\n178351\n178361\n178362\n178365\n178377\n178380\n178384\n178385\n178396\n178401\n178403\n178408\n178411\n178416\n178420\n178423\n178424\n178425\n178431\n178433\n178436\n178440\n178448\n178453\n178454\n178456\n178471\n178482\n178486\n178488\n178491\n178492\n178495\n178497\n178499\n178505\n178509\n178512\n178524\n178526\n178534\n178537\n178541\n178547\n178555\n178562\n178565\n178569\n178570\n178587\n178588\n178590\n178601\n178603\n178604\n178608\n178610\n178620\n178627\n178636\n178640\n178653\n178655\n178659\n178667\n178675\n178706\n178711\n178713\n178729\n178732\n178737\n178739\n178741\n178745\n178746\n178748\n178750\n178763\n178766\n178771\n178773\n178776\n178780\n178784\n178786\n178788\n178794\n178799\n178808\n178813\n178815\n178816\n178821\n178827\n178829\n178830\n178831\n178832\n178834\n178845\n178871\n178876\n178880\n178882\n178887\n178889\n178891\n178898\n178899\n178910\n178926\n178927\n178936\n178939\n178942\n178948\n178949\n178954\n178959\n178965\n178968\n178973\n178975\n178983\n178990\n178992\n178999\n179004\n179011\n179013\n179014\n179021\n179029\n179031\n179033\n179034\n179047\n179052\n179053\n179055\n179067\n179068\n179072\n179074\n179076\n179077\n179079\n179091\n179092\n179094\n179097\n179100\n179103\n179114\n179117\n179121\n179128\n179135\n179136\n179143\n179146\n179178\n179181\n179182\n179183\n179185\n179187\n179200\n179220\n179221\n179222\n179239\n179243\n179248\n179250\n179252\n179260\n179281\n179282\n179288\n179294\n179301\n179304\n179309\n179317\n179319\n179320\n179321\n179324\n179325\n179326\n179329\n179342\n179348\n179349\n179358\n179374\n179375\n179376\n179377\n179384\n179388\n179389\n179397\n179399\n179401\n179402\n179405\n179407\n179409\n179411\n179414\n179415\n179418\n179419\n179420\n179421\n179422\n179424\n179428\n179429\n179431\n179435\n179436\n179449\n179454\n179464\n179467\n179474\n179480\n179485\n179486\n179488\n179489\n179492\n179493\n179498\n179499\n179502\n179506\n179509\n179520\n179525\n179527\n179528\n179529\n179531\n179544\n179552\n179558\n179560\n179561\n179566\n179574\n179582\n179583\n179590\n179591\n179594\n179600\n179605\n179607\n179609\n179611\n179632\n179633\n179634\n179642\n179649\n179651\n179654\n179661\n179662\n179665\n179666\n179674\n179677\n179679\n179684\n179685\n179697\n179699\n179701\n179702\n179706\n179715\n179721\n179726\n179728\n179729\n179730\n179732\n179739\n179742\n179744\n179745\n179746\n179762\n179766\n179768\n179771\n179774\n179775\n179778\n179784\n179785\n179786\n179787\n179788\n179795\n179798\n179803\n179807\n179816\n179825\n179831\n179833\n179834\n179837\n179842\n179845\n179847\n179850\n179851\n179852\n179856\n179879\n179889\n179892\n179893\n179898\n179900\n179905\n179909\n179914\n179919\n179931\n179932\n179933\n179934\n179940\n179945\n179946\n179949\n179959\n179967\n179979\n179987\n179991\n179992\n179997\n180003\n180004\n180005\n180008\n180013\n180016\n180020\n180021\n180023\n180024\n180026\n180029\n180031\n180033\n180035\n180036\n180042\n180046\n180047\n180052\n180054\n180055\n180082\n180083\n180096\n180097\n180103\n180105\n180106\n180107\n180110\n180113\n180115\n180120\n180132\n180134\n180135\n180151\n180156\n180172\n180181\n180184\n180189\n180191\n180193\n180195\n180211\n180215\n180219\n180223\n180227\n180232\n180235\n180249\n180256\n180267\n180283\n180293\n180294\n180296\n180299\n180302\n180305\n180313\n180319\n180333\n180334\n180336\n180337\n180338\n180343\n180350\n180352\n180353\n180366\n180367\n180371\n180373\n180379\n180380\n180385\n180386\n180392\n180397\n180404\n180408\n180411\n180418\n180422\n180428\n180431\n180441\n180442\n180445\n180448\n180449\n180454\n180459\n180461\n180468\n180473\n180483\n180485\n180489\n180494\n180499\n180501\n180508\n180510\n180512\n180515\n180521\n180522\n180526\n180532\n180535\n180542\n180543\n180549\n180556\n180563\n180571\n180572\n180575\n180577\n180578\n180581\n180586\n180588\n180615\n180616\n180621\n180623\n180625\n180628\n180646\n180650\n180652\n180653\n180655\n180668\n180671\n180672\n180681\n180682\n180685\n180698\n180714\n180719\n180722\n180723\n180731\n180739\n180740\n180746\n180748\n180754\n180756\n180761\n180766\n180767\n180773\n180777\n180784\n180788\n180794\n180795\n180800\n180802\n180805\n180807\n180808\n180811\n180813\n180817\n180820\n180822\n180834\n180842\n180844\n180853\n180855\n180867\n180869\n180872\n180883\n180885\n180886\n180887\n180890\n180891\n180900\n180901\n180903\n180904\n180912\n180914\n180916\n180920\n180922\n180925\n180932\n180933\n180942\n180947\n180949\n180952\n180953\n180955\n180956\n180961\n180970\n180973\n180978\n180983\n180993\n181004\n181005\n181009\n181010\n181012\n181014\n181015\n181021\n181034\n181035\n181036\n181039\n181040\n181043\n181050\n181052\n181058\n181062\n181071\n181076\n181084\n181093\n181102\n181105\n181106\n181108\n181110\n181121\n181123\n181130\n181137\n181146\n181154\n181155\n181163\n181169\n181175\n181176\n181191\n181208\n181212\n181220\n181230\n181234\n181241\n181248\n181252\n181256\n181265\n181272\n181275\n181276\n181287\n181299\n181306\n181309\n181313\n181315\n181318\n181320\n181327\n181329\n181335\n181347\n181349\n181351\n181352\n181355\n181358\n181360\n181361\n181363\n181377\n181378\n181382\n181405\n181414\n181416\n181418\n181421\n181439\n181440\n181458\n181461\n181471\n181479\n181482\n181489\n181496\n181497\n181511\n181512\n181514\n181515\n181522\n181538\n181540\n181546\n181557\n181558\n181563\n181580\n181581\n181588\n181595\n181601\n181605\n181607\n181618\n181622\n181625\n181628\n181639\n181649\n181657\n181660\n181662\n181671\n181684\n181692\n181699\n181704\n181707\n181711\n181712\n181713\n181714\n181717\n181721\n181722\n181723\n181724\n181739\n181742\n181743\n181747\n181749\n181761\n181763\n181774\n181776\n181779\n181780\n181785\n181786\n181789\n181793\n181794\n181796\n181797\n181803\n181805\n181807\n181812\n181819\n181822\n181827\n181829\n181839\n181842\n181845\n181847\n181849\n181853\n181854\n181856\n181859\n181866\n181874\n181876\n181877\n181878\n181894\n181900\n181905\n181907\n181908\n181910\n181912\n181914\n181917\n181919\n181922\n181926\n181928\n181929\n181936\n181939\n181943\n181944\n181948\n181949\n181961\n181962\n181969\n181978\n181984\n181989\n181991\n181992\n181993\n181995\n182001\n182005\n182007\n182009\n182020\n182021\n182029\n182031\n182044\n182045\n182048\n182050\n182051\n182055\n182058\n182060\n182061\n182063\n182064\n182074\n182081\n182084\n182090\n182095\n182112\n182115\n182117\n182119\n182128\n182130\n182132\n182135\n182144\n182147\n182149\n182152\n182153\n182157\n182164\n182166\n182168\n182173\n182179\n182180\n182183\n182192\n182195\n182199\n182203\n182208\n182210\n182211\n182216\n182227\n182235\n182240\n182245\n182246\n182254\n182255\n182263\n182265\n182266\n182272\n182284\n182288\n182289\n182292\n182299\n182301\n182305\n182308\n182309\n182320\n182321\n182327\n182346\n182349\n182350\n182354\n182356\n182361\n182388\n182390\n182392\n182394\n182401\n182407\n182411\n182417\n182420\n182421\n182427\n182429\n182434\n182436\n182437\n182440\n182441\n182449\n182452\n182459\n182460\n182471\n182472\n182474\n182482\n182484\n182485\n182496\n182497\n182498\n182500\n182502\n182508\n182510\n182525\n182526\n182528\n182529\n182533\n182534\n182535\n182539\n182545\n182550\n182551\n182561\n182566\n182567\n182569\n182571\n182572\n182575\n182577\n182579\n182580\n182589\n182590\n182601\n182607\n182614\n182621\n182623\n182629\n182631\n182632\n182633\n182637\n182638\n182641\n182646\n182652\n182662\n182671\n182676\n182678\n182682\n182685\n182695\n182697\n182699\n182702\n182705\n182706\n182709\n182711\n182718\n182722\n182724\n182729\n182735\n182747\n182748\n182756\n182764\n182765\n182766\n182767\n182768\n182769\n182776\n182781\n182789\n182790\n182791\n182796\n182801\n182807\n182812\n182814\n182820\n182821\n182823\n182837\n182841\n182845\n182846\n182847\n182849\n182850\n182852\n182860\n182866\n182877\n182878\n182879\n182882\n182885\n182897\n182899\n182904\n182908\n182915\n182916\n182927\n182928\n182935\n182939\n182942\n182943\n182945\n182952\n182961\n182967\n182968\n182980\n182988\n182990\n182996\n183006\n183010\n183011\n183013\n183025\n183033\n183035\n183040\n183042\n183045\n183050\n183051\n183053\n183057\n183062\n183066\n183072\n183080\n183081\n183089\n183094\n183102\n183113\n183115\n183117\n183124\n183133\n183134\n183142\n183145\n183146\n183150\n183153\n183164\n183166\n183167\n183171\n183172\n183174\n183179\n183180\n183183\n183203\n183207\n183209\n183212\n183217\n183220\n183225\n183234\n183239\n183241\n183243\n183246\n183251\n183258\n183266\n183271\n183286\n183300\n183304\n183305\n183306\n183308\n183311\n183312\n183315\n183317\n183320\n183321\n183334\n183340\n183346\n183350\n183353\n183354\n183360\n183362\n183363\n183369\n183372\n183385\n183398\n183399\n183400\n183403\n183405\n183410\n183413\n183416\n183417\n183418\n183424\n183430\n183434\n183446\n183449\n183458\n183459\n183460\n183462\n183464\n183476\n183477\n183483\n183485\n183492\n183496\n183502\n183504\n183505\n183506\n183515\n183518\n183530\n183542\n183551\n183555\n183558\n183560\n183570\n183571\n183574\n183577\n183578\n183583\n183587\n183594\n183601\n183605\n183606\n183607\n183608\n183611\n183612\n183614\n183620\n183624\n183635\n183637\n183647\n183648\n183652\n183657\n183662\n183664\n183666\n183670\n183674\n183683\n183687\n183688\n183691\n183695\n183699\n183703\n183705\n183707\n183709\n183715\n183721\n183722\n183732\n183739\n183744\n183751\n183783\n183789\n183791\n183797\n183798\n183800\n183809\n183811\n183815\n183819\n183820\n183823\n183831\n183835\n183838\n183840\n183845\n183848\n183849\n183851\n183863\n183868\n183871\n183874\n183884\n183887\n183892\n183893\n183898\n183905\n183907\n183909\n183913\n183915\n183919\n183929\n183942\n183953\n183959\n183967\n183975\n183977\n183979\n183982\n183990\n183996\n184009\n184022\n184027\n184037\n184049\n184050\n184051\n184062\n184065\n184068\n184074\n184077\n184079\n184083\n184085\n184094\n184101\n184108\n184111\n184136\n184137\n184139\n184143\n184144\n184148\n184151\n184160\n184164\n184169\n184180\n184181\n184187\n184197\n184207\n184208\n184218\n184219\n184239\n184240\n184242\n184244\n184246\n184247\n184249\n184252\n184254\n184255\n184273\n184278\n184283\n184284\n184289\n184297\n184299\n184307\n184311\n184318\n184319\n184322\n184329\n184332\n184339\n184343\n184347\n184348\n184357\n184358\n184361\n184362\n184365\n184366\n184367\n184368\n184373\n184374\n184380\n184394\n184397\n184401\n184405\n184406\n184407\n184411\n184414\n184415\n184419\n184428\n184433\n184438\n184442\n184445\n184450\n184453\n184463\n184466\n184467\n184469\n184470\n184480\n184486\n184488\n184506\n184515\n184520\n184522\n184523\n184539\n184543\n184550\n184559\n184560\n184561\n184563\n184565\n184566\n184570\n184578\n184581\n184582\n184586\n184588\n184589\n184591\n184597\n184605\n184606\n184610\n184618\n184620\n184629\n184631\n184638\n184642\n184646\n184647\n184648\n184670\n184673\n184681\n184686\n184688\n184690\n184698\n184699\n184700\n184714\n184715\n184722\n184727\n184729\n184731\n184734\n184740\n184742\n184755\n184757\n184764\n184778\n184780\n184783\n184785\n184799\n184808\n184819\n184832\n184838\n184847\n184850\n184855\n184869\n184871\n184872\n184877\n184878\n184881\n184897\n184913\n184919\n184923\n184929\n184932\n184941\n184943\n184952\n184965\n184970\n184973\n184979\n184983\n184985\n184986\n184989\n184991\n184993\n184999\n185001\n185009\n185014\n185025\n185035\n185042\n185044\n185051\n185063\n185070\n185078\n185079\n185089\n185090\n185091\n185096\n185099\n185100\n185116\n185117\n185132\n185133\n185134\n185137\n185145\n185146\n185151\n185154\n185158\n185162\n185164\n185170\n185179\n185180\n185183\n185186\n185189\n185194\n185196\n185201\n185203\n185210\n185213\n185218\n185220\n185222\n185227\n185234\n185237\n185248\n185252\n185256\n185264\n185265\n185267\n185269\n185279\n185280\n185284\n185285\n185310\n185312\n185321\n185324\n185327\n185330\n185355\n185356\n185363\n185370\n185371\n185380\n185383\n185390\n185392\n185400\n185404\n185408\n185409\n185416\n185436\n185439\n185440\n185441\n185443\n185452\n185454\n185455\n185463\n185467\n185468\n185475\n185477\n185479\n185483\n185484\n185486\n185487\n185489\n185494\n185498\n185502\n185514\n185521\n185524\n185526\n185532\n185533\n185534\n185555\n185556\n185557\n185571\n185576\n185577\n185602\n185613\n185615\n185616\n185617\n185619\n185625\n185627\n185639\n185640\n185642\n185649\n185659\n185660\n185662\n185664\n185671\n185675\n185687\n185689\n185690\n185693\n185694\n185705\n185707\n185710\n185711\n185716\n185724\n185729\n185732\n185736\n185738\n185751\n185766\n185768\n185781\n185784\n185790\n185791\n185803\n185815\n185816\n185817\n185825\n185826\n185828\n185830\n185849\n185851\n185862\n185865\n185867\n185869\n185881\n185886\n185888\n185889\n185891\n185893\n185897\n185899\n185908\n185909\n185911\n185917\n185932\n185937\n185940\n185941\n185943\n185947\n185948\n185952\n185953\n185956\n185958\n185970\n185974\n185981\n185990\n186001\n186003\n186007\n186008\n186009\n186014\n186027\n186031\n186036\n186040\n186057\n186058\n186059\n186060\n186063\n186065\n186076\n186080\n186094\n186096\n186107\n186116\n186118\n186119\n186123\n186128\n186135\n186141\n186144\n186152\n186153\n186154\n186159\n186163\n186167\n186177\n186178\n186186\n186189\n186202\n186209\n186214\n186216\n186218\n186221\n186226\n186235\n186236\n186242\n186246\n186249\n186260\n186261\n186263\n186274\n186275\n186277\n186278\n186279\n186283\n186289\n186293\n186297\n186300\n186302\n186317\n186319\n186320\n186326\n186337\n186353\n186360\n186367\n186369\n186374\n186375\n186380\n186385\n186402\n186408\n186411\n186413\n186417\n186423\n186425\n186428\n186440\n186444\n186462\n186464\n186473\n186475\n186480\n186483\n186484\n186485\n186487\n186489\n186490\n186491\n186507\n186512\n186515\n186521\n186536\n186537\n186541\n186542\n186543\n186544\n186552\n186554\n186555\n186558\n186561\n186565\n186570\n186584\n186587\n186594\n186596\n186597\n186605\n186613\n186622\n186625\n186628\n186631\n186642\n186650\n186651\n186652\n186655\n186658\n186665\n186674\n186676\n186680\n186686\n186698\n186700\n186701\n186716\n186719\n186723\n186725\n186731\n186742\n186751\n186754\n186757\n186764\n186769\n186774\n186785\n186789\n186791\n186801\n186803\n186806\n186809\n186811\n186812\n186815\n186823\n186828\n186833\n186840\n186846\n186847\n186848\n186854\n186856\n186858\n186859\n186866\n186872\n186874\n186879\n186882\n186886\n186889\n186895\n186913\n186926\n186929\n186933\n186937\n186943\n186960\n186967\n186968\n186971\n186987\n186990\n186996\n187005\n187008\n187013\n187021\n187035\n187038\n187047\n187051\n187056\n187061\n187063\n187067\n187069\n187075\n187077\n187082\n187086\n187090\n187091\n187098\n187100\n187105\n187110\n187119\n187125\n187128\n187131\n187132\n187136\n187140\n187176\n187179\n187187\n187203\n187207\n187212\n187224\n187227\n187241\n187242\n187246\n187250\n187251\n187253\n187254\n187262\n187271\n187274\n187275\n187277\n187278\n187279\n187287\n187293\n187295\n187311\n187314\n187322\n187324\n187336\n187340\n187341\n187349\n187355\n187363\n187365\n187367\n187369\n187371\n187393\n187394\n187396\n187397\n187398\n187407\n187409\n187411\n187412\n187415\n187416\n187436\n187439\n187448\n187454\n187467\n187473\n187480\n187483\n187484\n187485\n187494\n187497\n187503\n187508\n187519\n187536\n187537\n187538\n187542\n187557\n187561\n187563\n187575\n187579\n187582\n187592\n187600\n187603\n187608\n187609\n187619\n187622\n187633\n187634\n187641\n187645\n187648\n187649\n187652\n187665\n187672\n187685\n187688\n187689\n187700\n187706\n187717\n187723\n187724\n187725\n187726\n187743\n187745\n187748\n187760\n187764\n187765\n187777\n187778\n187781\n187789\n187802\n187803\n187808\n187813\n187818\n187820\n187839\n187842\n187853\n187854\n187857\n187858\n187867\n187869\n187871\n187888\n187891\n187895\n187897\n187901\n187905\n187911\n187917\n187919\n187922\n187930\n187932\n187935\n187939\n187940\n187941\n187944\n187951\n187954\n187968\n187977\n187978\n187979\n187983\n187991\n188003\n188004\n188008\n188009\n188014\n188016\n188018\n188019\n188027\n188028\n188030\n188036\n188042\n188048\n188050\n188051\n188056\n188058\n188061\n188063\n188073\n188077\n188100\n188105\n188117\n188121\n188123\n188129\n188131\n188140\n188142\n188153\n188158\n188162\n188164\n188168\n188169\n188172\n188174\n188175\n188178\n188180\n188196\n188199\n188204\n188209\n188223\n188227\n188250\n188266\n188286\n188287\n188292\n188295\n188301\n188303\n188305\n188307\n188310\n188312\n188313\n188314\n188315\n188317\n188322\n188324\n188326\n188327\n188328\n188332\n188340\n188341\n188351\n188357\n188360\n188362\n188364\n188372\n188376\n188378\n188387\n188407\n188409\n188410\n188419\n188420\n188428\n188436\n188438\n188439\n188447\n188450\n188472\n188476\n188485\n188506\n188509\n188512\n188517\n188518\n188527\n188528\n188529\n188530\n188531\n188536\n188539\n188540\n188542\n188553\n188564\n188570\n188576\n188588\n188590\n188594\n188597\n188605\n188613\n188625\n188626\n188631\n188635\n188659\n188663\n188665\n188668\n188675\n188679\n188680\n188681\n188689\n188690\n188694\n188696\n188698\n188700\n188723\n188728\n188735\n188738\n188745\n188746\n188752\n188754\n188763\n188767\n188768\n188771\n188773\n188777\n188779\n188782\n188787\n188796\n188797\n188810\n188818\n188819\n188824\n188825\n188836\n188838\n188839\n188843\n188852\n188864\n188870\n188873\n188875\n188887\n188888\n188890\n188895\n188902\n188907\n188909\n188917\n188932\n188935\n188944\n188945\n188949\n188957\n188962\n188963\n188964\n188965\n188971\n188972\n188974\n188978\n188979\n188983\n188984\n188986\n188987\n188992\n189004\n189006\n189007\n189008\n189009\n189010\n189013\n189021\n189032\n189037\n189038\n189039\n189042\n189052\n189053\n189063\n189069\n189071\n189075\n189080\n189083\n189085\n189087\n189094\n189095\n189100\n189102\n189110\n189111\n189121\n189132\n189133\n189141\n189149\n189150\n189152\n189156\n189161\n189162\n189172\n189179\n189181\n189182\n189201\n189204\n189227\n189244\n189245\n189252\n189266\n189269\n189277\n189279\n189280\n189283\n189288\n189292\n189295\n189297\n189303\n189314\n189315\n189318\n189323\n189327\n189329\n189332\n189333\n189340\n189342\n189360\n189364\n189366\n189367\n189368\n189375\n189376\n189378\n189381\n189384\n189392\n189401\n189404\n189407\n189410\n189411\n189412\n189414\n189415\n189417\n189425\n189431\n189437\n189439\n189441\n189446\n189454\n189456\n189457\n189462\n189469\n189470\n189471\n189472\n189474\n189476\n189490\n189494\n189499\n189500\n189517\n189518\n189528\n189529\n189533\n189538\n189540\n189545\n189547\n189552\n189553\n189558\n189560\n189571\n189575\n189583\n189584\n189585\n189587\n189596\n189603\n189604\n189605\n189610\n189616\n189618\n189622\n189624\n189627\n189636\n189642\n189659\n189663\n189670\n189673\n189676\n189677\n189678\n189680\n189681\n189682\n189684\n189687\n189704\n189715\n189721\n189722\n189732\n189735\n189742\n189745\n189753\n189754\n189765\n189768\n189774\n189785\n189792\n189795\n189796\n189805\n189807\n189808\n189811\n189813\n189817\n189820\n189823\n189827\n189834\n189835\n189839\n189841\n189843\n189849\n189850\n189853\n189858\n189864\n189865\n189870\n189872\n189874\n189879\n189885\n189891\n189896\n189897\n189899\n189904\n189905\n189917\n189921\n189924\n189928\n189931\n189937\n189941\n189945\n189947\n189953\n189955\n189959\n189970\n189977\n189990\n189994\n189996\n189998\n190004\n190013\n190014\n190023\n190030\n190031\n190036\n190045\n190051\n190060\n190061\n190062\n190073\n190075\n190080\n190087\n190093\n190099\n190103\n190106\n190112\n190114\n190120\n190128\n190131\n190135\n190137\n190139\n190144\n190145\n190146\n190149\n190155\n190159\n190160\n190163\n190164\n190183\n190184\n190200\n190208\n190215\n190219\n190223\n190234\n190243\n190249\n190260\n190273\n190281\n190291\n190293\n190296\n190300\n190305\n190309\n190310\n190311\n190313\n190315\n190316\n190318\n190322\n190323\n190324\n190329\n190331\n190342\n190345\n190346\n190347\n190352\n190368\n190370\n190371\n190378\n190383\n190384\n190390\n190391\n190392\n190398\n190423\n190424\n190433\n190439\n190446\n190450\n190457\n190460\n190473\n190477\n190481\n190486\n190487\n190502\n190514\n190516\n190522\n190530\n190531\n190540\n190545\n190548\n190550\n190551\n190556\n190567\n190571\n190594\n190599\n190600\n190603\n190605\n190606\n190609\n190617\n190618\n190619\n190622\n190625\n190634\n190635\n190640\n190641\n190642\n190651\n190656\n190673\n190678\n190682\n190684\n190690\n190698\n190707\n190711\n190715\n190721\n190724\n190740\n190743\n190749\n190759\n190773\n190778\n190779\n190781\n190795\n190796\n190799\n190802\n190803\n190805\n190811\n190813\n190820\n190821\n190829\n190833\n190834\n190840\n190841\n190842\n190852\n190864\n190870\n190871\n190875\n190883\n190889\n190892\n190896\n190897\n190902\n190907\n190915\n190920\n190925\n190926\n190932\n190937\n190938\n190959\n190964\n190968\n190969\n190979\n190983\n190986\n190996\n190999\n191000\n191004\n191007\n191009\n191012\n191015\n191018\n191026\n191027\n191029\n191036\n191037\n191040\n191045\n191050\n191058\n191062\n191068\n191076\n191080\n191081\n191084\n191085\n191086\n191091\n191093\n191101\n191118\n191122\n191128\n191130\n191136\n191145\n191151\n191154\n191156\n191162\n191163\n191167\n191168\n191171\n191177\n191178\n191183\n191187\n191188\n191191\n191202\n191204\n191217\n191223\n191228\n191230\n191233\n191242\n191247\n191248\n191260\n191261\n191263\n191267\n191268\n191269\n191272\n191281\n191293\n191294\n191295\n191301\n191303\n191315\n191321\n191324\n191326\n191328\n191336\n191344\n191345\n191347\n191352\n191354\n191358\n191359\n191360\n191363\n191367\n191369\n191373\n191394\n191404\n191405\n191407\n191408\n191413\n191414\n191437\n191439\n191451\n191460\n191461\n191462\n191464\n191472\n191476\n191482\n191484\n191488\n191490\n191494\n191495\n191497\n191499\n191502\n191509\n191527\n191528\n191535\n191537\n191538\n191555\n191556\n191565\n191569\n191572\n191574\n191576\n191584\n191591\n191593\n191604\n191609\n191615\n191619\n191621\n191623\n191631\n191634\n191636\n191647\n191649\n191650\n191658\n191660\n191663\n191664\n191667\n191680\n191683\n191687\n191693\n191698\n191702\n191704\n191711\n191723\n191727\n191728\n191735\n191741\n191745\n191760\n191762\n191770\n191775\n191778\n191793\n191795\n191798\n191815\n191825\n191826\n191827\n191831\n191833\n191837\n191851\n191859\n191860\n191864\n191865\n191867\n191869\n191885\n191889\n191890\n191891\n191912\n191928\n191944\n191954\n191967\n191971\n191978\n191981\n191983\n191994\n191999\n192004\n192005\n192007\n192008\n192010\n192017\n192020\n192022\n192025\n192030\n192034\n192035\n192038\n192042\n192051\n192056\n192059\n192061\n192065\n192066\n192067\n192069\n192073\n192079\n192081\n192083\n192086\n192088\n192089\n192091\n192098\n192100\n192103\n192118\n192119\n192122\n192129\n192134\n192135\n192136\n192140\n192144\n192162\n192163\n192165\n192166\n192169\n192171\n192172\n192184\n192201\n192211\n192212\n192215\n192220\n192226\n192239\n192259\n192260\n192261\n192266\n192267\n192268\n192269\n192272\n192276\n192287\n192294\n192298\n192305\n192309\n192315\n192318\n192323\n192346\n192347\n192360\n192365\n192371\n192376\n192380\n192382\n192391\n192393\n192396\n192398\n192400\n192412\n192417\n192430\n192431\n192433\n192458\n192466\n192479\n192483\n192486\n192492\n192495\n192496\n192497\n192505\n192507\n192508\n192513\n192519\n192524\n192527\n192534\n192537\n192539\n192553\n192557\n192566\n192567\n192577\n192579\n192580\n192581\n192595\n192599\n192601\n192617\n192619\n192624\n192627\n192642\n192648\n192655\n192656\n192660\n192661\n192662\n192663\n192668\n192669\n192677\n192680\n192690\n192692\n192696\n192720\n192724\n192726\n192731\n192733\n192738\n192746\n192753\n192759\n192760\n192762\n192764\n192765\n192768\n192769\n192775\n192784\n192785\n192786\n192787\n192788\n192792\n192796\n192805\n192808\n192812\n192832\n192836\n192849\n192850\n192852\n192860\n192864\n192866\n192869\n192875\n192880\n192881\n192885\n192888\n192895\n192896\n192904\n192907\n192908\n192915\n192916\n192922\n192923\n192925\n192927\n192933\n192935\n192938\n192954\n192965\n192970\n192972\n192983\n192984\n192986\n192989\n192994\n193012\n193039\n193042\n193044\n193045\n193056\n193061\n193063\n193069\n193075\n193080\n193085\n193087\n193089\n193096\n193099\n193104\n193105\n193110\n193117\n193126\n193129\n193133\n193134\n193143\n193152\n193155\n193163\n193164\n193165\n193168\n193172\n193176\n193178\n193180\n193184\n193186\n193190\n193191\n193194\n193201\n193210\n193212\n193215\n193220\n193229\n193230\n193231\n193232\n193245\n193260\n193262\n193269\n193276\n193277\n193285\n193299\n193301\n193303\n193312\n193313\n193316\n193319\n193322\n193324\n193331\n193334\n193341\n193343\n193351\n193355\n193360\n193362\n193386\n193391\n193394\n193396\n193401\n193406\n193409\n193411\n193413\n193416\n193425\n193426\n193427\n193433\n193439\n193442\n193443\n193468\n193469\n193476\n193483\n193489\n193491\n193500\n193502\n193504\n193507\n193521\n193529\n193535\n193539\n193541\n193551\n193553\n193571\n193580\n193584\n193586\n193592\n193594\n193602\n193603\n193604\n193616\n193620\n193623\n193627\n193631\n193633\n193640\n193642\n193658\n193665\n193667\n193668\n193670\n193675\n193676\n193683\n193687\n193689\n193694\n193698\n193703\n193707\n193715\n193719\n193728\n193738\n193739\n193742\n193748\n193754\n193757\n193763\n193766\n193767\n193772\n193778\n193791\n193800\n193808\n193813\n193818\n193819\n193820\n193838\n193842\n193844\n193853\n193854\n193874\n193875\n193876\n193880\n193896\n193897\n193903\n193906\n193907\n193910\n193913\n193917\n193919\n193925\n193938\n193939\n193947\n193948\n193949\n193950\n193951\n193961\n193963\n193976\n193981\n193988\n193989\n193996\n194000\n194003\n194007\n194009\n194010\n194031\n194035\n194047\n194066\n194074\n194079\n194083\n194084\n194086\n194091\n194095\n194096\n194097\n194099\n194106\n194107\n194110\n194113\n194114\n194120\n194121\n194124\n194128\n194133\n194135\n194138\n194152\n194154\n194156\n194157\n194159\n194161\n194169\n194171\n194174\n194176\n194188\n194191\n194196\n194212\n194220\n194222\n194226\n194227\n194234\n194240\n194247\n194251\n194252\n194254\n194259\n194262\n194269\n194273\n194288\n194298\n194309\n194313\n194314\n194316\n194323\n194325\n194326\n194330\n194347\n194348\n194351\n194353\n194356\n194359\n194361\n194362\n194365\n194367\n194373\n194384\n194386\n194387\n194393\n194395\n194417\n194422\n194427\n194428\n194430\n194431\n194436\n194446\n194462\n194465\n194466\n194470\n194477\n194482\n194483\n194484\n194486\n194487\n194489\n194497\n194502\n194503\n194506\n194507\n194509\n194521\n194522\n194524\n194525\n194527\n194540\n194551\n194553\n194559\n194560\n194561\n194562\n194564\n194565\n194579\n194581\n194584\n194588\n194591\n194599\n194606\n194616\n194619\n194620\n194633\n194641\n194642\n194644\n194646\n194648\n194653\n194660\n194662\n194664\n194680\n194681\n194690\n194692\n194693\n194699\n194706\n194716\n194724\n194727\n194730\n194734\n194741\n194743\n194746\n194749\n194752\n194753\n194755\n194760\n194763\n194764\n194775\n194779\n194783\n194785\n194801\n194803\n194807\n194808\n194809\n194810\n194815\n194820\n194821\n194837\n194853\n194864\n194872\n194880\n194898\n194899\n194907\n194909\n194915\n194919\n194926\n194928\n194936\n194940\n194942\n194944\n194946\n194948\n194962\n194965\n194967\n194971\n194976\n194982\n194987\n195000\n195002\n195015\n195020\n195021\n195024\n195028\n195048\n195061\n195090\n195099\n195101\n195103\n195105\n195107\n195116\n195123\n195127\n195128\n195130\n195133\n195136\n195137\n195142\n195143\n195155\n195169\n195174\n195182\n195184\n195186\n195189\n195190\n195191\n195192\n195197\n195205\n195210\n195212\n195213\n195219\n195225\n195226\n195232\n195238\n195243\n195255\n195257\n195261\n195265\n195283\n195286\n195289\n195292\n195294\n195301\n195304\n195325\n195330\n195339\n195342\n195347\n195348\n195349\n195352\n195353\n195355\n195359\n195371\n195376\n195379\n195383\n195384\n195385\n195387\n195390\n195391\n195408\n195409\n195416\n195417\n195418\n195442\n195445\n195457\n195463\n195464\n195471\n195482\n195493\n195495\n195496\n195499\n195504\n195508\n195512\n195523\n195532\n195537\n195542\n195546\n195548\n195552\n195558\n195563\n195564\n195568\n195576\n195583\n195587\n195588\n195592\n195593\n195598\n195599\n195600\n195611\n195624\n195626\n195633\n195636\n195639\n195649\n195658\n195660\n195665\n195668\n195673\n195675\n195679\n195683\n195689\n195696\n195702\n195706\n195718\n195722\n195727\n195744\n195757\n195759\n195760\n195762\n195765\n195767\n195774\n195776\n195778\n195783\n195787\n195789\n195792\n195794\n195795\n195817\n195819\n195820\n195825\n195829\n195837\n195842\n195844\n195845\n195859\n195864\n195865\n195876\n195893\n195896\n195897\n195904\n195910\n195915\n195916\n195928\n195929\n195936\n195946\n195947\n195956\n195958\n195960\n195962\n195977\n195986\n195992\n195999\n196004\n196005\n196010\n196014\n196015\n196018\n196024\n196029\n196035\n196037\n196042\n196044\n196049\n196056\n196057\n196064\n196066\n196067\n196071\n196077\n196081\n196082\n196086\n196097\n196098\n196101\n196104\n196111\n196118\n196122\n196127\n196131\n196133\n196134\n196139\n196147\n196154\n196158\n196159\n196161\n196168\n196171\n196173\n196178\n196181\n196183\n196185\n196186\n196192\n196195\n196198\n196207\n196211\n196213\n196218\n196224\n196230\n196232\n196240\n196243\n196245\n196255\n196258\n196260\n196272\n196275\n196290\n196310\n196313\n196322\n196324\n196328\n196329\n196331\n196334\n196335\n196338\n196344\n196346\n196348\n196351\n196352\n196356\n196359\n196365\n196367\n196368\n196369\n196372\n196381\n196393\n196396\n196398\n196402\n196404\n196412\n196413\n196414\n196415\n196418\n196423\n196426\n196427\n196433\n196435\n196437\n196447\n196448\n196453\n196457\n196462\n196464\n196471\n196497\n196509\n196519\n196520\n196524\n196530\n196537\n196538\n196539\n196542\n196546\n196549\n196553\n196556\n196562\n196567\n196575\n196581\n196582\n196583\n196585\n196588\n196590\n196591\n196593\n196607\n196619\n196621\n196628\n196629\n196632\n196638\n196639\n196652\n196656\n196658\n196663\n196679\n196682\n196684\n196689\n196696\n196697\n196699\n196700\n196701\n196716\n196718\n196722\n196724\n196727\n196732\n196737\n196752\n196754\n196757\n196760\n196761\n196764\n196767\n196768\n196779\n196788\n196789\n196795\n196798\n196831\n196832\n196838\n196844\n196850\n196860\n196867\n196869\n196881\n196889\n196891\n196893\n196897\n196904\n196905\n196906\n196915\n196916\n196925\n196937\n196942\n196943\n196950\n196951\n196960\n196963\n196967\n196971\n196982\n196985\n197000\n197004\n197007\n197011\n197018\n197021\n197025\n197026\n197029\n197033\n197035\n197042\n197048\n197049\n197060\n197064\n197073\n197077\n197079\n197083\n197090\n197092\n197096\n197098\n197105\n197108\n197115\n197122\n197128\n197134\n197144\n197145\n197167\n197169\n197170\n197173\n197183\n197193\n197198\n197200\n197201\n197202\n197204\n197211\n197217\n197219\n197221\n197229\n197232\n197234\n197237\n197242\n197244\n197248\n197249\n197253\n197264\n197271\n197274\n197278\n197281\n197296\n197297\n197298\n197299\n197304\n197305\n197311\n197314\n197317\n197324\n197325\n197328\n197331\n197339\n197352\n197365\n197366\n197367\n197372\n197386\n197389\n197391\n197396\n197403\n197404\n197409\n197410\n197412\n197415\n197431\n197435\n197439\n197440\n197448\n197456\n197460\n197461\n197463\n197468\n197470\n197471\n197477\n197478\n197480\n197502\n197510\n197516\n197517\n197518\n197521\n197523\n197527\n197528\n197535\n197542\n197545\n197550\n197568\n197575\n197578\n197582\n197591\n197592\n197619\n197628\n197630\n197635\n197640\n197643\n197654\n197661\n197696\n197698\n197701\n197712\n197717\n197718\n197722\n197724\n197732\n197734\n197737\n197738\n197743\n197748\n197754\n197756\n197757\n197759\n197761\n197765\n197770\n197773\n197778\n197781\n197786\n197791\n197799\n197800\n197803\n197812\n197816\n197817\n197823\n197829\n197839\n197850\n197858\n197861\n197876\n197878\n197883\n197894\n197900\n197903\n197908\n197909\n197911\n197912\n197913\n197915\n197916\n197923\n197926\n197928\n197930\n197932\n197943\n197945\n197946\n197949\n197950\n197963\n197979\n197982\n197983\n197984\n197988\n198004\n198006\n198022\n198031\n198042\n198045\n198047\n198054\n198061\n198067\n198068\n198070\n198077\n198078\n198080\n198089\n198093\n198095\n198113\n198119\n198121\n198123\n198128\n198132\n198134\n198136\n198143\n198148\n198151\n198155\n198157\n198164\n198170\n198171\n198177\n198180\n198182\n198183\n198195\n198210\n198219\n198225\n198227\n198233\n198238\n198241\n198250\n198251\n198255\n198260\n198261\n198266\n198297\n198298\n198300\n198306\n198309\n198315\n198317\n198327\n198328\n198335\n198337\n198339\n198341\n198355\n198358\n198361\n198363\n198372\n198375\n198376\n198379\n198382\n198386\n198397\n198403\n198406\n198408\n198413\n198419\n198422\n198425\n198426\n198436\n198437\n198446\n198455\n198457\n198463\n198477\n198482\n198492\n198497\n198507\n198509\n198517\n198518\n198521\n198525\n198528\n198530\n198533\n198534\n198535\n198545\n198550\n198552\n198560\n198561\n198565\n198567\n198576\n198580\n198587\n198588\n198589\n198592\n198604\n198605\n198615\n198616\n198618\n198625\n198630\n198635\n198636\n198643\n198644\n198646\n198654\n198661\n198673\n198678\n198687\n198689\n198695\n198699\n198734\n198745\n198746\n198748\n198749\n198758\n198760\n198763\n198768\n198770\n198782\n198801\n198804\n198805\n198809\n198810\n198812\n198815\n198818\n198821\n198822\n198825\n198826\n198828\n198832\n198834\n198837\n198843\n198861\n198862\n198865\n198866\n198868\n198875\n198879\n198887\n198893\n198899\n198900\n198903\n198905\n198908\n198909\n198914\n198916\n198920\n198925\n198930\n198938\n198945\n198948\n198951\n198952\n198963\n198972\n198980\n198981\n198985\n198987\n198991\n198998\n199003\n199007\n199010\n199012\n199017\n199021\n199027\n199028\n199043\n199047\n199051\n199052\n199055\n199060\n199061\n199072\n199090\n199091\n199096\n199110\n199114\n199118\n199120\n199127\n199141\n199143\n199148\n199149\n199156\n199157\n199162\n199166\n199167\n199169\n199197\n199201\n199205\n199210\n199216\n199217\n199220\n199226\n199230\n199231\n199242\n199246\n199251\n199261\n199262\n199264\n199265\n199266\n199274\n199283\n199284\n199285\n199291\n199292\n199294\n199297\n199303\n199309\n199312\n199314\n199318\n199321\n199326\n199327\n199338\n199339\n199340\n199343\n199344\n199348\n199353\n199355\n199357\n199358\n199360\n199365\n199368\n199369\n199373\n199376\n199381\n199382\n199383\n199384\n199387\n199390\n199395\n199403\n199415\n199417\n199430\n199432\n199433\n199453\n199454\n199461\n199465\n199468\n199478\n199481\n199483\n199486\n199487\n199488\n199490\n199500\n199503\n199504\n199505\n199506\n199508\n199513\n199515\n199525\n199528\n199529\n199533\n199536\n199538\n199542\n199551\n199552\n199561\n199565\n199568\n199576\n199582\n199584\n199586\n199598\n199601\n199602\n199615\n199622\n199632\n199639\n199642\n199644\n199649\n199651\n199656\n199664\n199666\n199669\n199670\n199674\n199679\n199688\n199689\n199700\n199716\n199717\n199724\n199734\n199735\n199740\n199743\n199744\n199746\n199747\n199759\n199762\n199763\n199765\n199770\n199776\n199777\n199781\n199782\n199783\n199798\n199799\n199803\n199804\n199807\n199812\n199814\n199820\n199822\n199825\n199829\n199845\n199851\n199854\n199861\n199863\n199865\n199871\n199875\n199883\n199885\n199887\n199888\n199894\n199895\n199900\n199903\n199911\n199912\n199913\n199914\n199916\n199918\n199919\n199921\n199935\n199937\n199938\n199944\n199946\n199954\n199960\n199974\n199977\n199979\n199982\n199986\n199989\n199992\n199994\n199996\n199998\n200002\n200007\n200010\n200014\n200017\n200019\n200022\n200027\n200029\n200030\n200032\n200033\n200037\n200038\n200043\n200044\n200046\n200047\n200049\n200054\n200057\n200058\n200061\n200066\n200070\n200074\n200075\n200079\n200082\n200086\n200095\n200107\n200108\n200110\n200118\n200124\n200125\n200131\n200132\n200134\n200145\n200152\n200155\n200160\n200165\n200166\n200169\n200170\n200172\n200175\n200183\n200186\n200192\n200202\n200204\n200220\n200223\n200227\n200239\n200240\n200261\n200262\n200263\n200268\n200271\n200277\n200278\n200280\n200286\n200291\n200301\n200303\n200308\n200311\n200319\n200320\n200326\n200328\n200337\n200342\n200344\n200346\n200358\n200361\n200365\n200366\n200371\n200372\n200373\n200380\n200383\n200387\n200390\n200391\n200392\n200394\n200401\n200404\n200406\n200412\n200418\n200419\n200427\n200429\n200433\n200437\n200445\n200453\n200457\n200458\n200466\n200470\n200474\n200477\n200492\n200496\n200498\n200501\n200502\n200505\n200514\n200517\n200518\n200524\n200534\n200536\n200538\n200539\n200549\n200552\n200554\n200560\n200561\n200564\n200567\n200581\n200582\n200591\n200597\n200608\n200612\n200616\n200617\n200631\n200640\n200643\n200649\n200652\n200654\n200661\n200664\n200665\n200668\n200673\n200677\n200679\n200680\n200690\n200694\n200696\n200713\n200714\n200718\n200721\n200725\n200726\n200732\n200753\n200755\n200757\n200758\n200759\n200765\n200767\n200768\n200780\n200781\n200785\n200787\n200790\n200794\n200795\n200796\n200799\n200802\n200805\n200816\n200825\n200835\n200839\n200843\n200849\n200855\n200876\n200878\n200881\n200882\n200883\n200885\n200890\n200893\n200906\n200910\n200911\n200912\n200914\n200916\n200918\n200919\n200920\n200921\n200925\n200929\n200931\n200933\n200935\n200941\n200943\n200955\n200967\n200991\n200992\n200993\n200995\n200996\n200997\n201004\n201006\n201009\n201010\n201017\n201020\n201023\n201024\n201031\n201037\n201043\n201047\n201050\n201053\n201060\n201061\n201065\n201068\n201072\n201077\n201078\n201079\n201089\n201091\n201092\n201093\n201094\n201096\n201097\n201100\n201111\n201131\n201144\n201146\n201156\n201165\n201167\n201171\n201173\n201177\n201187\n201192\n201196\n201200\n201203\n201204\n201207\n201214\n201220\n201223\n201226\n201230\n201233\n201237\n201243\n201261\n201268\n201269\n201285\n201301\n201311\n201317\n201323\n201326\n201327\n201328\n201335\n201340\n201357\n201364\n201367\n201368\n201370\n201382\n201383\n201393\n201394\n201398\n201406\n201408\n201417\n201426\n201434\n201453\n201454\n201455\n201460\n201462\n201466\n201470\n201475\n201479\n201481\n201483\n201485\n201486\n201489\n201490\n201491\n201493\n201496\n201502\n201508\n201512\n201516\n201526\n201536\n201543\n201558\n201562\n201574\n201576\n201578\n201581\n201590\n201591\n201597\n201602\n201614\n201615\n201616\n201618\n201619\n201621\n201627\n201629\n201631\n201641\n201646\n201651\n201682\n201686\n201699\n201703\n201706\n201710\n201714\n201728\n201736\n201741\n201763\n201767\n201768\n201774\n201775\n201777\n201785\n201787\n201793\n201794\n201795\n201797\n201808\n201809\n201819\n201826\n201827\n201831\n201836\n201841\n201842\n201848\n201855\n201859\n201862\n201863\n201870\n201874\n201875\n201881\n201882\n201885\n201889\n201890\n201892\n201896\n201905\n201909\n201933\n201934\n201935\n201937\n201939\n201947\n201953\n201954\n201962\n201963\n201967\n201972\n201979\n201980\n201981\n201985\n201989\n201991\n202000\n202002\n202021\n202033\n202039\n202040\n202045\n202046\n202051\n202059\n202062\n202068\n202070\n202071\n202075\n202076\n202080\n202087\n202092\n202095\n202099\n202105\n202108\n202110\n202111\n202118\n202130\n202134\n202138\n202144\n202158\n202161\n202165\n202166\n202172\n202176\n202178\n202183\n202186\n202189\n202195\n202197\n202201\n202203\n202207\n202211\n202214\n202219\n202225\n202230\n202231\n202241\n202242\n202244\n202250\n202260\n202261\n202267\n202269\n202282\n202285\n202286\n202297\n202307\n202317\n202322\n202325\n202326\n202331\n202340\n202343\n202346\n202347\n202349\n202359\n202369\n202370\n202372\n202374\n202375\n202377\n202384\n202398\n202401\n202413\n202414\n202419\n202428\n202452\n202453\n202456\n202464\n202465\n202471\n202472\n202474\n202479\n202480\n202481\n202482\n202483\n202486\n202487\n202492\n202496\n202497\n202501\n202502\n202510\n202516\n202518\n202521\n202522\n202524\n202526\n202534\n202535\n202536\n202543\n202544\n202550\n202552\n202559\n202561\n202581\n202585\n202594\n202597\n202600\n202604\n202613\n202615\n202617\n202628\n202635\n202638\n202654\n202655\n202662\n202663\n202665\n202670\n202673\n202675\n202676\n202679\n202680\n202687\n202691\n202698\n202705\n202707\n202720\n202722\n202723\n202724\n202730\n202731\n202737\n202744\n202745\n202754\n202757\n202758\n202761\n202775\n202779\n202782\n202788\n202789\n202796\n202798\n202808\n202810\n202814\n202816\n202829\n202832\n202853\n202864\n202865\n202866\n202878\n202884\n202905\n202907\n202918\n202928\n202933\n202934\n202940\n202944\n202945\n202946\n202950\n202953\n202976\n202977\n202978\n202991\n202995\n202996\n203000\n203003\n203021\n203031\n203037\n203044\n203050\n203055\n203058\n203060\n203062\n203064\n203067\n203078\n203080\n203085\n203094\n203100\n203101\n203119\n203127\n203128\n203133\n203134\n203143\n203152\n203154\n203165\n203173\n203177\n203180\n203181\n203184\n203190\n203191\n203195\n203206\n203213\n203215\n203216\n203225\n203226\n203228\n203241\n203256\n203257\n203265\n203266\n203282\n203287\n203291\n203296\n203297\n203300\n203301\n203304\n203309\n203318\n203321\n203327\n203332\n203334\n203341\n203343\n203355\n203358\n203362\n203364\n203370\n203376\n203377\n203384\n203386\n203387\n203393\n203398\n203399\n203400\n203402\n203407\n203409\n203418\n203423\n203428\n203433\n203435\n203440\n203441\n203442\n203443\n203450\n203453\n203462\n203464\n203466\n203468\n203473\n203480\n203483\n203492\n203494\n203506\n203511\n203518\n203520\n203528\n203530\n203531\n203540\n203541\n203549\n203557\n203561\n203579\n203580\n203588\n203593\n203604\n203605\n203616\n203620\n203623\n203626\n203627\n203630\n203642\n203645\n203648\n203650\n203654\n203664\n203665\n203674\n203678\n203687\n203697\n203698\n203702\n203704\n203713\n203728\n203737\n203743\n203748\n203761\n203767\n203782\n203788\n203789\n203795\n203796\n203799\n203805\n203817\n203823\n203824\n203840\n203850\n203851\n203859\n203862\n203872\n203877\n203879\n203881\n203884\n203891\n203893\n203904\n203914\n203937\n203942\n203945\n203951\n203952\n203955\n203966\n203979\n203980\n203986\n203996\n204008\n204025\n204029\n204040\n204041\n204042\n204047\n204053\n204058\n204083\n204084\n204086\n204087\n204089\n204092\n204093\n204103\n204108\n204112\n204113\n204116\n204117\n204118\n204122\n204126\n204129\n204139\n204153\n204155\n204157\n204158\n204159\n204162\n204164\n204169\n204176\n204177\n204179\n204186\n204187\n204188\n204194\n204195\n204202\n204203\n204204\n204210\n204218\n204219\n204225\n204231\n204233\n204235\n204237\n204238\n204239\n204241\n204244\n204245\n204247\n204253\n204254\n204261\n204264\n204267\n204269\n204290\n204298\n204302\n204307\n204310\n204312\n204317\n204323\n204324\n204328\n204329\n204331\n204335\n204336\n204337\n204339\n204341\n204344\n204345\n204348\n204351\n204352\n204354\n204355\n204376\n204386\n204387\n204399\n204401\n204402\n204407\n204408\n204409\n204411\n204422\n204426\n204427\n204438\n204442\n204446\n204451\n204455\n204477\n204479\n204482\n204484\n204492\n204502\n204504\n204505\n204506\n204508\n204517\n204526\n204532\n204533\n204536\n204537\n204541\n204551\n204552\n204553\n204554\n204556\n204559\n204560\n204585\n204591\n204606\n204607\n204608\n204610\n204614\n204626\n204627\n204635\n204637\n204644\n204649\n204658\n204664\n204666\n204669\n204672\n204677\n204682\n204691\n204692\n204700\n204701\n204703\n204709\n204713\n204714\n204717\n204723\n204726\n204727\n204731\n204735\n204736\n204737\n204745\n204746\n204755\n204764\n204766\n204770\n204785\n204794\n204795\n204798\n204799\n204801\n204802\n204806\n204808\n204810\n204816\n204826\n204837\n204838\n204842\n204844\n204847\n204848\n204851\n204865\n204872\n204875\n204876\n204882\n204888\n204890\n204894\n204903\n204904\n204905\n204908\n204909\n204913\n204914\n204921\n204932\n204936\n204940\n204942\n204950\n204954\n204956\n204959\n204967\n204968\n204971\n204974\n204981\n204984\n204989\n204994\n205002\n205009\n205025\n205028\n205035\n205037\n205039\n205048\n205057\n205058\n205062\n205064\n205072\n205073\n205079\n205086\n205093\n205097\n205098\n205102\n205108\n205110\n205116\n205120\n205132\n205134\n205148\n205149\n205157\n205163\n205166\n205171\n205177\n205182\n205184\n205188\n205194\n205206\n205208\n205213\n205227\n205233\n205240\n205243\n205245\n205255\n205258\n205268\n205269\n205277\n205281\n205282\n205285\n205287\n205292\n205296\n205300\n205303\n205304\n205312\n205317\n205318\n205329\n205331\n205338\n205340\n205344\n205350\n205353\n205354\n205355\n205370\n205374\n205381\n205383\n205397\n205399\n205402\n205404\n205416\n205429\n205434\n205438\n205443\n205444\n205448\n205453\n205456\n205458\n205461\n205465\n205466\n205468\n205474\n205475\n205483\n205486\n205491\n205492\n205510\n205511\n205518\n205522\n205523\n205528\n205529\n205530\n205534\n205536\n205537\n205539\n205540\n205545\n205552\n205553\n205557\n205563\n205577\n205578\n205585\n205586\n205589\n205591\n205592\n205593\n205594\n205595\n205601\n205603\n205614\n205617\n205619\n205620\n205621\n205622\n205624\n205635\n205640\n205647\n205653\n205659\n205663\n205683\n205685\n205687\n205692\n205695\n205720\n205723\n205727\n205728\n205730\n205733\n205743\n205746\n205750\n205753\n205755\n205756\n205759\n205765\n205768\n205772\n205779\n205783\n205788\n205804\n205816\n205819\n205824\n205826\n205830\n205837\n205838\n205839\n205852\n205853\n205870\n205875\n205876\n205880\n205883\n205893\n205896\n205905\n205912\n205913\n205918\n205922\n205923\n205926\n205931\n205938\n205939\n205942\n205950\n205954\n205956\n205957\n205960\n205964\n205965\n205973\n205975\n205978\n205981\n205993\n205995\n205996\n206000\n206010\n206011\n206019\n206020\n206038\n206044\n206057\n206066\n206079\n206080\n206083\n206089\n206091\n206112\n206116\n206124\n206127\n206136\n206137\n206139\n206141\n206146\n206153\n206157\n206165\n206176\n206179\n206181\n206182\n206183\n206189\n206191\n206196\n206200\n206210\n206213\n206218\n206223\n206227\n206230\n206238\n206243\n206246\n206250\n206253\n206256\n206259\n206261\n206265\n206267\n206278\n206279\n206280\n206283\n206286\n206287\n206297\n206299\n206301\n206305\n206308\n206310\n206311\n206312\n206313\n206329\n206341\n206346\n206360\n206362\n206363\n206369\n206376\n206379\n206383\n206387\n206392\n206393\n206404\n206405\n206411\n206415\n206417\n206418\n206426\n206427\n206429\n206431\n206442\n206444\n206447\n206450\n206452\n206466\n206486\n206487\n206488\n206490\n206495\n206497\n206500\n206511\n206512\n206524\n206527\n206546\n206549\n206553\n206559\n206567\n206575\n206585\n206587\n206592\n206593\n206598\n206600\n206605\n206611\n206612\n206617\n206623\n206637\n206639\n206648\n206649\n206650\n206659\n206682\n206690\n206692\n206705\n206710\n206716\n206718\n206724\n206727\n206729\n206731\n206738\n206741\n206742\n206747\n206751\n206760\n206762\n206765\n206770\n206773\n206779\n206781\n206786\n206787\n206788\n206793\n206797\n206806\n206812\n206814\n206819\n206822\n206827\n206831\n206834\n206851\n206860\n206869\n206878\n206881\n206885\n206891\n206901\n206903\n206904\n206907\n206914\n206915\n206921\n206922\n206923\n206935\n206940\n206942\n206948\n206955\n206960\n206971\n206973\n206974\n206977\n206978\n206985\n206987\n206989\n207002\n207006\n207007\n207022\n207025\n207029\n207030\n207034\n207051\n207055\n207056\n207057\n207062\n207069\n207070\n207079\n207081\n207083\n207089\n207093\n207094\n207095\n207096\n207097\n207101\n207103\n207104\n207109\n207111\n207113\n207114\n207119\n207121\n207124\n207129\n207137\n207143\n207145\n207152\n207161\n207170\n207171\n207173\n207174\n207181\n207187\n207191\n207192\n207202\n207205\n207210\n207216\n207217\n207224\n207225\n207227\n207231\n207232\n207247\n207248\n207249\n207252\n207256\n207257\n207258\n207261\n207263\n207268\n207272\n207279\n207281\n207282\n207285\n207287\n207291\n207294\n207325\n207328\n207330\n207334\n207339\n207347\n207349\n207352\n207355\n207360\n207365\n207366\n207369\n207372\n207373\n207376\n207378\n207381\n207382\n207384\n207388\n207398\n207405\n207409\n207412\n207413\n207418\n207420\n207424\n207428\n207429\n207445\n207454\n207455\n207467\n207468\n207476\n207477\n207478\n207479\n207481\n207482\n207483\n207484\n207489\n207498\n207511\n207518\n207520\n207529\n207541\n207555\n207560\n207561\n207562\n207570\n207575\n207576\n207595\n207608\n207622\n207626\n207635\n207638\n207639\n207640\n207642\n207651\n207661\n207681\n207688\n207690\n207695\n207696\n207705\n207707\n207708\n207709\n207721\n207723\n207724\n207725\n207728\n207731\n207737\n207739\n207754\n207755\n207756\n207765\n207775\n207776\n207780\n207781\n207782\n207785\n207786\n207790\n207792\n207794\n207804\n207809\n207811\n207812\n207814\n207817\n207823\n207831\n207834\n207844\n207855\n207858\n207862\n207875\n207876\n207884\n207888\n207892\n207893\n207894\n207905\n207906\n207913\n207920\n207927\n207934\n207941\n207953\n207958\n207961\n207964\n207974\n207982\n207993\n207997\n207998\n208006\n208011\n208026\n208034\n208035\n208037\n208041\n208048\n208049\n208051\n208057\n208062\n208069\n208072\n208077\n208078\n208079\n208083\n208084\n208092\n208094\n208105\n208107\n208112\n208115\n208121\n208126\n208127\n208131\n208156\n208168\n208170\n208171\n208191\n208193\n208194\n208195\n208198\n208207\n208209\n208214\n208219\n208223\n208230\n208232\n208233\n208244\n208248\n208254\n208258\n208261\n208262\n208267\n208274\n208290\n208293\n208299\n208301\n208302\n208303\n208307\n208313\n208315\n208323\n208324\n208328\n208329\n208330\n208344\n208348\n208349\n208353\n208359\n208362\n208364\n208377\n208385\n208387\n208398\n208405\n208408\n208416\n208424\n208431\n208432\n208440\n208445\n208446\n208447\n208463\n208465\n208467\n208473\n208489\n208491\n208495\n208497\n208510\n208520\n208525\n208546\n208547\n208549\n208550\n208557\n208560\n208563\n208564\n208575\n208576\n208582\n208593\n208599\n208609\n208617\n208624\n208628\n208635\n208651\n208659\n208668\n208673\n208683\n208684\n208698\n208700\n208704\n208705\n208708\n208717\n208720\n208722\n208724\n208726\n208727\n208729\n208732\n208737\n208740\n208746\n208753\n208762\n208794\n208797\n208805\n208806\n208814\n208817\n208823\n208824\n208825\n208827\n208832\n208839\n208858\n208862\n208864\n208865\n208867\n208868\n208871\n208875\n208881\n208884\n208885\n208889\n208891\n208897\n208898\n208905\n208906\n208908\n208934\n208935\n208937\n208940\n208946\n208954\n208956\n208966\n208969\n208971\n208973\n208980\n208984\n208986\n208990\n208995\n208996\n208999\n209004\n209005\n209009\n209010\n209015\n209016\n209017\n209029\n209031\n209046\n209053\n209055\n209056\n209062\n209064\n209068\n209078\n209086\n209108\n209112\n209126\n209136\n209142\n209146\n209147\n209155\n209162\n209163\n209169\n209174\n209175\n209177\n209181\n209185\n209195\n209198\n209205\n209206\n209212\n209216\n209226\n209228\n209229\n209235\n209241\n209244\n209248\n209249\n209250\n209251\n209260\n209261\n209263\n209270\n209275\n209279\n209289\n209291\n209296\n209300\n209304\n209309\n209313\n209316\n209318\n209324\n209325\n209329\n209334\n209345\n209365\n209370\n209372\n209373\n209379\n209383\n209384\n209401\n209405\n209406\n209409\n209410\n209413\n209416\n209434\n209437\n209438\n209441\n209449\n209450\n209451\n209453\n209454\n209459\n209461\n209471\n209478\n209491\n209498\n209501\n209504\n209507\n209522\n209523\n209527\n209531\n209534\n209535\n209536\n209537\n209539\n209542\n209550\n209558\n209571\n209573\n209574\n209576\n209579\n209581\n209584\n209591\n209593\n209594\n209598\n209600\n209604\n209607\n209626\n209632\n209635\n209650\n209655\n209656\n209658\n209660\n209665\n209668\n209669\n209677\n209680\n209683\n209685\n209688\n209689\n209692\n209698\n209704\n209725\n209728\n209734\n209741\n209742\n209743\n209744\n209757\n209764\n209768\n209769\n209779\n209783\n209788\n209804\n209807\n209811\n209812\n209819\n209829\n209833\n209849\n209850\n209861\n209870\n209875\n209901\n209906\n209911\n209916\n209929\n209934\n209937\n209939\n209941\n209966\n209973\n209976\n209978\n209981\n209982\n209984\n209985\n209996\n210002\n210003\n210010\n210016\n210017\n210019\n210022\n210026\n210028\n210036\n210045\n210052\n210053\n210055\n210057\n210061\n210064\n210069\n210074\n210086\n210090\n210094\n210095\n210097\n210105\n210120\n210123\n210129\n210130\n210133\n210140\n210153\n210154\n210167\n210178\n210188\n210196\n210198\n210202\n210212\n210216\n210221\n210224\n210234\n210236\n210237\n210238\n210244\n210249\n210254\n210276\n210278\n210283\n210301\n210303\n210304\n210308\n210314\n210318\n210322\n210326\n210327\n210331\n210334\n210339\n210340\n210342\n210344\n210347\n210349\n210350\n210353\n210374\n210379\n210391\n210393\n210411\n210413\n210424\n210429\n210430\n210440\n210448\n210452\n210453\n210462\n210467\n210474\n210486\n210502\n210503\n210504\n210505\n210519\n210531\n210539\n210541\n210554\n210567\n210576\n210590\n210594\n210609\n210613\n210642\n210645\n210653\n210664\n210666\n210669\n210670\n210672\n210675\n210681\n210686\n210689\n210698\n210699\n210729\n210734\n210735\n210736\n210738\n210739\n210740\n210746\n210749\n210754\n210756\n210759\n210764\n210783\n210786\n210791\n210792\n210796\n210804\n210806\n210808\n210811\n210818\n210823\n210824\n210833\n210835\n210837\n210839\n210841\n210852\n210857\n210859\n210860\n210862\n210863\n210866\n210878\n210882\n210885\n210894\n210896\n210899\n210902\n210917\n210919\n210921\n210925\n210926\n210929\n210930\n210931\n210933\n210934\n210944\n210946\n210949\n210951\n210952\n210954\n210962\n210964\n210966\n210968\n210969\n210972\n210976\n210983\n210986\n210987\n210988\n210996\n211003\n211004\n211025\n211033\n211037\n211044\n211048\n211055\n211066\n211077\n211081\n211083\n211088\n211095\n211100\n211112\n211120\n211123\n211126\n211127\n211128\n211134\n211136\n211138\n211141\n211143\n211144\n211150\n211155\n211157\n211159\n211163\n211164\n211176\n211178\n211181\n211187\n211191\n211192\n211197\n211199\n211201\n211202\n211212\n211226\n211229\n211238\n211240\n211246\n211251\n211254\n211261\n211272\n211274\n211276\n211283\n211285\n211299\n211305\n211310\n211313\n211320\n211331\n211332\n211337\n211340\n211341\n211343\n211346\n211347\n211348\n211352\n211358\n211360\n211364\n211368\n211380\n211381\n211393\n211394\n211395\n211404\n211410\n211411\n211416\n211421\n211429\n211435\n211445\n211468\n211472\n211488\n211491\n211497\n211498\n211500\n211501\n211506\n211522\n211528\n211529\n211530\n211541\n211546\n211547\n211548\n211553\n211565\n211570\n211572\n211575\n211576\n211577\n211578\n211582\n211583\n211589\n211597\n211603\n211608\n211611\n211612\n211616\n211618\n211621\n211622\n211623\n211627\n211628\n211629\n211635\n211639\n211640\n211641\n211654\n211658\n211662\n211663\n211669\n211670\n211674\n211675\n211676\n211678\n211679\n211680\n211682\n211685\n211692\n211695\n211696\n211698\n211700\n211704\n211706\n211708\n211716\n211726\n211729\n211731\n211733\n211738\n211741\n211742\n211745\n211746\n211749\n211750\n211755\n211766\n211768\n211770\n211805\n211807\n211810\n211818\n211821\n211827\n211828\n211830\n211835\n211838\n211849\n211853\n211859\n211864\n211875\n211889\n211892\n211896\n211897\n211898\n211900\n211901\n211902\n211903\n211905\n211913\n211919\n211921\n211922\n211924\n211929\n211933\n211937\n211938\n211946\n211952\n211955\n211956\n211957\n211963\n211964\n211966\n211971\n211975\n211976\n211983\n211986\n211988\n211993\n212003\n212004\n212006\n212019\n212020\n212023\n212024\n212025\n212035\n212042\n212044\n212047\n212052\n212057\n212064\n212069\n212073\n212075\n212077\n212082\n212085\n212093\n212095\n212100\n212103\n212105\n212109\n212112\n212121\n212132\n212137\n212145\n212146\n212151\n212152\n212153\n212170\n212171\n212177\n212183\n212185\n212187\n212199\n212200\n212202\n212205\n212211\n212218\n212219\n212224\n212225\n212227\n212228\n212229\n212230\n212231\n212235\n212248\n212252\n212260\n212262\n212282\n212285\n212288\n212292\n212294\n212298\n212301\n212307\n212315\n212323\n212324\n212327\n212332\n212338\n212340\n212344\n212345\n212359\n212366\n212373\n212381\n212385\n212391\n212395\n212400\n212404\n212407\n212419\n212420\n212422\n212429\n212432\n212441\n212446\n212451\n212452\n212455\n212458\n212469\n212471\n212475\n212513\n212516\n212517\n212520\n212525\n212527\n212533\n212534\n212535\n212536\n212538\n212554\n212562\n212568\n212574\n212582\n212589\n212590\n212597\n212618\n212622\n212633\n212636\n212641\n212643\n212644\n212650\n212652\n212653\n212658\n212660\n212661\n212666\n212668\n212675\n212682\n212684\n212691\n212693\n212695\n212699\n212703\n212705\n212706\n212718\n212719\n212724\n212729\n212732\n212735\n212736\n212737\n212741\n212742\n212750\n212752\n212760\n212769\n212772\n212775\n212779\n212780\n212784\n212787\n212788\n212797\n212800\n212802\n212803\n212810\n212813\n212816\n212818\n212819\n212820\n212826\n212831\n212832\n212842\n212858\n212863\n212883\n212886\n212904\n212906\n212911\n212912\n212918\n212925\n212926\n212932\n212933\n212934\n212938\n212945\n212947\n212949\n212954\n212956\n212970\n212975\n212976\n212980\n212985\n212988\n212990\n212995\n212996\n213006\n213018\n213023\n213024\n213029\n213031\n213046\n213047\n213056\n213060\n213061\n213065\n213070\n213077\n213079\n213084\n213088\n213090\n213099\n213102\n213108\n213111\n213121\n213122\n213133\n213136\n213148\n213152\n213153\n213156\n213157\n213161\n213164\n213165\n213167\n213169\n213171\n213172\n213177\n213180\n213196\n213199\n213203\n213207\n213208\n213219\n213220\n213221\n213226\n213230\n213231\n213234\n213235\n213248\n213252\n213256\n213261\n213271\n213283\n213288\n213290\n213291\n213294\n213297\n213299\n213308\n213309\n213311\n213312\n213316\n213321\n213327\n213333\n213337\n213340\n213342\n213345\n213346\n213350\n213363\n213370\n213381\n213384\n213391\n213392\n213397\n213400\n213401\n213402\n213423\n213428\n213435\n213444\n213447\n213449\n213451\n213467\n213470\n213479\n213480\n213482\n213484\n213489\n213496\n213502\n213504\n213514\n213516\n213518\n213525\n213531\n213535\n213538\n213551\n213552\n213555\n213556\n213561\n213563\n213566\n213567\n213574\n213586\n213592\n213595\n213599\n213601\n213610\n213611\n213620\n213623\n213625\n213626\n213629\n213633\n213637\n213638\n213649\n213650\n213657\n213660\n213663\n213664\n213668\n213669\n213677\n213687\n213693\n213694\n213703\n213704\n213705\n213706\n213709\n213711\n213721\n213722\n213723\n213730\n213738\n213746\n213753\n213769\n213770\n213772\n213782\n213795\n213799\n213804\n213810\n213811\n213816\n213827\n213829\n213842\n213843\n213852\n213853\n213874\n213879\n213881\n213883\n213889\n213892\n213901\n213903\n213913\n213915\n213920\n213922\n213924\n213926\n213943\n213948\n213951\n213965\n213966\n213974\n213977\n213983\n213984\n213989\n213993\n214002\n214004\n214009\n214011\n214014\n214024\n214027\n214028\n214034\n214039\n214052\n214055\n214061\n214063\n214065\n214069\n214084\n214090\n214093\n214094\n214099\n214100\n214102\n214107\n214109\n214126\n214131\n214143\n214148\n214154\n214156\n214159\n214163\n214168\n214171\n214180\n214181\n214188\n214193\n214198\n214199\n214200\n214201\n214205\n214206\n214208\n214211\n214232\n214233\n214237\n214245\n214247\n214252\n214268\n214269\n214272\n214275\n214277\n214278\n214282\n214287\n214292\n214294\n214302\n214312\n214316\n214319\n214321\n214325\n214335\n214356\n214362\n214369\n214376\n214381\n214389\n214397\n214406\n214419\n214421\n214427\n214430\n214432\n214436\n214450\n214460\n214469\n214478\n214479\n214484\n214500\n214507\n214509\n214511\n214519\n214521\n214523\n214525\n214528\n214530\n214532\n214534\n214540\n214544\n214545\n214555\n214556\n214564\n214566\n214567\n214571\n214573\n214577\n214587\n214600\n214601\n214612\n214614\n214623\n214636\n214640\n214650\n214655\n214668\n214675\n214676\n214682\n214686\n214694\n214696\n214698\n214708\n214709\n214715\n214716\n214727\n214728\n214738\n214740\n214744\n214759\n214767\n214774\n214779\n214785\n214788\n214790\n214791\n214793\n214805\n214813\n214831\n214835\n214838\n214849\n214851\n214852\n214853\n214854\n214865\n214868\n214871\n214880\n214896\n214903\n214909\n214922\n214925\n214948\n214958\n214965\n214967\n214976\n214981\n214985\n214989\n214990\n214993\n215006\n215008\n215012\n215016\n215018\n215021\n215025\n215026\n215027\n215029\n215042\n215049\n215051\n215058\n215061\n215062\n215065\n215067\n215069\n215073\n215076\n215085\n215091\n215094\n215096\n215098\n215101\n215102\n215112\n215117\n215124\n215131\n215139\n215145\n215151\n215154\n215155\n215157\n215159\n215171\n215184\n215194\n215224\n215234\n215237\n215239\n215240\n215244\n215246\n215252\n215261\n215266\n215276\n215281\n215283\n215285\n215288\n215292\n215296\n215299\n215306\n215308\n215310\n215312\n215316\n215326\n215330\n215332\n215336\n215344\n215349\n215353\n215357\n215365\n215368\n215369\n215371\n215373\n215375\n215382\n215386\n215393\n215399\n215400\n215403\n215406\n215409\n215430\n215435\n215440\n215446\n215458\n215461\n215466\n215469\n215475\n215480\n215485\n215488\n215489\n215492\n215502\n215510\n215512\n215513\n215514\n215518\n215525\n215528\n215530\n215531\n215545\n215549\n215552\n215563\n215564\n215565\n215566\n215569\n215570\n215571\n215586\n215588\n215589\n215591\n215598\n215601\n215610\n215614\n215615\n215625\n215628\n215630\n215632\n215635\n215642\n215647\n215648\n215649\n215664\n215667\n215671\n215675\n215683\n215688\n215691\n215694\n215697\n215703\n215704\n215708\n215712\n215714\n215734\n215745\n215748\n215755\n215774\n215779\n215795\n215796\n215806\n215809\n215810\n215811\n215813\n215818\n215821\n215825\n215827\n215829\n215833\n215838\n215839\n215852\n215857\n215860\n215862\n215873\n215876\n215877\n215884\n215889\n215891\n215904\n215908\n215913\n215921\n215924\n215926\n215930\n215935\n215938\n215940\n215950\n215953\n215957\n215960\n215965\n215968\n215969\n215972\n215975\n215976\n215979\n215980\n215982\n215987\n215988\n215990\n215998\n216006\n216016\n216020\n216022\n216024\n216029\n216030\n216035\n216038\n216042\n216045\n216056\n216064\n216069\n216071\n216077\n216088\n216091\n216092\n216100\n216102\n216106\n216111\n216129\n216139\n216141\n216148\n216151\n216152\n216159\n216163\n216174\n216177\n216186\n216187\n216190\n216191\n216193\n216194\n216214\n216226\n216228\n216231\n216232\n216234\n216236\n216246\n216249\n216256\n216269\n216275\n216281\n216282\n216284\n216297\n216300\n216305\n216312\n216328\n216329\n216330\n216334\n216335\n216341\n216350\n216368\n216369\n216372\n216373\n216388\n216391\n216392\n216393\n216399\n216401\n216405\n216409\n216416\n216418\n216420\n216427\n216436\n216453\n216459\n216461\n216467\n216482\n216483\n216484\n216486\n216492\n216501\n216505\n216507\n216510\n216520\n216529\n216530\n216532\n216544\n216553\n216566\n216567\n216570\n216571\n216595\n216596\n216599\n216603\n216607\n216617\n216618\n216623\n216632\n216645\n216647\n216653\n216655\n216657\n216663\n216665\n216678\n216680\n216686\n216694\n216696\n216705\n216706\n216710\n216714\n216728\n216729\n216732\n216736\n216746\n216757\n216778\n216780\n216785\n216786\n216790\n216794\n216795\n216813\n216832\n216839\n216843\n216848\n216853\n216857\n216859\n216860\n216865\n216866\n216877\n216901\n216902\n216910\n216915\n216919\n216929\n216934\n216943\n216944\n216950\n216955\n216961\n216965\n216967\n216969\n216987\n216989\n216990\n216994\n217002\n217007\n217008\n217025\n217041\n217042\n217048\n217058\n217063\n217064\n217071\n217075\n217084\n217094\n217096\n217100\n217101\n217103\n217113\n217116\n217121\n217131\n217135\n217145\n217159\n217167\n217169\n217171\n217181\n217193\n217195\n217199\n217231\n217232\n217233\n217234\n217235\n217240\n217251\n217258\n217266\n217267\n217268\n217271\n217274\n217279\n217288\n217291\n217306\n217312\n217326\n217331\n217332\n217349\n217353\n217359\n217373\n217374\n217378\n217380\n217381\n217386\n217408\n217410\n217414\n217423\n217424\n217430\n217435\n217437\n217438\n217440\n217448\n217453\n217460\n217462\n217464\n217465\n217470\n217471\n217487\n217498\n217499\n217512\n217513\n217517\n217521\n217531\n217536\n217540\n217542\n217544\n217549\n217551\n217563\n217571\n217573\n217575\n217580\n217584\n217588\n217589\n217594\n217598\n217599\n217607\n217613\n217635\n217645\n217649\n217653\n217660\n217661\n217671\n217674\n217677\n217680\n217681\n217688\n217693\n217694\n217697\n217703\n217710\n217711\n217715\n217717\n217723\n217728\n217729\n217740\n217742\n217744\n217750\n217761\n217762\n217770\n217771\n217781\n217783\n217805\n217807\n217808\n217812\n217814\n217815\n217819\n217851\n217853\n217857\n217859\n217865\n217870\n217886\n217887\n217892\n217899\n217909\n217915\n217919\n217921\n217924\n217926\n217932\n217933\n217944\n217945\n217947\n217950\n217957\n217958\n217959\n217961\n217965\n217967\n217972\n217988\n217992\n217998\n218009\n218016\n218018\n218022\n218024\n218029\n218030\n218032\n218033\n218039\n218043\n218044\n218051\n218052\n218060\n218071\n218073\n218077\n218079\n218083\n218085\n218088\n218092\n218094\n218103\n218107\n218110\n218115\n218117\n218118\n218124\n218125\n218135\n218141\n218150\n218160\n218163\n218164\n218178\n218180\n218183\n218191\n218196\n218203\n218204\n218207\n218209\n218212\n218218\n218220\n218225\n218232\n218234\n218236\n218237\n218239\n218241\n218242\n218248\n218258\n218260\n218262\n218268\n218282\n218294\n218300\n218320\n218323\n218324\n218326\n218336\n218337\n218342\n218346\n218347\n218351\n218361\n218371\n218372\n218387\n218389\n218390\n218396\n218400\n218412\n218425\n218430\n218445\n218451\n218458\n218461\n218466\n218467\n218471\n218476\n218478\n218481\n218490\n218499\n218500\n218501\n218518\n218524\n218528\n218545\n218546\n218547\n218552\n218553\n218555\n218556\n218561\n218565\n218566\n218571\n218582\n218585\n218589\n218591\n218617\n218618\n218619\n218628\n218634\n218644\n218649\n218651\n218652\n218653\n218656\n218657\n218669\n218672\n218673\n218677\n218689\n218691\n218693\n218701\n218703\n218705\n218706\n218712\n218713\n218714\n218719\n218732\n218742\n218743\n218744\n218747\n218748\n218759\n218762\n218766\n218776\n218781\n218784\n218798\n218806\n218815\n218817\n218822\n218823\n218824\n218825\n218832\n218834\n218838\n218839\n218841\n218843\n218848\n218856\n218862\n218863\n218866\n218867\n218868\n218874\n218876\n218878\n218880\n218891\n218892\n218912\n218917\n218919\n218921\n218922\n218936\n218937\n218938\n218940\n218946\n218949\n218951\n218953\n218956\n218957\n218958\n218962\n218969\n218972\n218974\n218982\n218984\n218989\n218991\n218993\n219000\n219002\n219010\n219013\n219016\n219024\n219032\n219036\n219038\n219043\n219053\n219055\n219064\n219075\n219080\n219081\n219084\n219119\n219125\n219132\n219141\n219144\n219152\n219154\n219159\n219162\n219166\n219168\n219169\n219170\n219171\n219176\n219178\n219180\n219181\n219183\n219198\n219205\n219214\n219218\n219225\n219230\n219231\n219237\n219239\n219240\n219241\n219243\n219250\n219253\n219256\n219263\n219264\n219269\n219275\n219277\n219279\n219281\n219283\n219292\n219295\n219296\n219303\n219305\n219306\n219312\n219313\n219332\n219333\n219335\n219336\n219338\n219339\n219348\n219354\n219362\n219366\n219367\n219372\n219375\n219376\n219397\n219398\n219406\n219408\n219410\n219411\n219426\n219435\n219438\n219447\n219452\n219462\n219464\n219471\n219476\n219483\n219486\n219493\n219495\n219503\n219505\n219510\n219512\n219513\n219522\n219524\n219527\n219529\n219536\n219537\n219539\n219540\n219546\n219548\n219549\n219550\n219551\n219570\n219571\n219573\n219575\n219578\n219579\n219580\n219585\n219602\n219610\n219620\n219631\n219635\n219638\n219639\n219640\n219643\n219644\n219650\n219654\n219655\n219658\n219670\n219675\n219680\n219686\n219693\n219695\n219701\n219702\n219705\n219711\n219714\n219715\n219716\n219730\n219734\n219757\n219759\n219763\n219765\n219770\n219789\n219803\n219806\n219812\n219816\n219817\n219824\n219841\n219845\n219846\n219847\n219853\n219855\n219883\n219887\n219890\n219892\n219896\n219917\n219920\n219931\n219933\n219947\n219955\n219956\n219973\n219977\n219985\n219987\n219989\n219990\n219997\n219998\n220001\n220024\n220025\n220032\n220037\n220038\n220043\n220046\n220056\n220061\n220066\n220068\n220071\n220073\n220075\n220089\n220092\n220102\n220108\n220109\n220111\n220115\n220123\n220128\n220130\n220131\n220134\n220140\n220151\n220162\n220165\n220168\n220172\n220173\n220174\n220175\n220189\n220191\n220193\n220194\n220198\n220204\n220217\n220224\n220225\n220229\n220231\n220232\n220236\n220250\n220257\n220260\n220266\n220279\n220288\n220289\n220300\n220302\n220313\n220320\n220321\n220323\n220332\n220333\n220334\n220346\n220368\n220369\n220378\n220379\n220380\n220382\n220386\n220390\n220392\n220394\n220400\n220402\n220405\n220409\n220418\n220425\n220429\n220430\n220432\n220434\n220438\n220439\n220444\n220468\n220470\n220473\n220476\n220478\n220486\n220487\n220491\n220494\n220500\n220504\n220505\n220506\n220510\n220522\n220535\n220536\n220548\n220565\n220569\n220572\n220574\n220576\n220581\n220585\n220587\n220589\n220590\n220598\n220604\n220610\n220612\n220614\n220616\n220619\n220622\n220623\n220625\n220631\n220632\n220636\n220638\n220650\n220652\n220653\n220656\n220663\n220670\n220671\n220681\n220683\n220701\n220705\n220708\n220709\n220711\n220721\n220728\n220729\n220737\n220748\n220756\n220757\n220759\n220768\n220775\n220787\n220796\n220810\n220831\n220836\n220838\n220840\n220845\n220847\n220862\n220863\n220864\n220868\n220872\n220880\n220883\n220887\n220888\n220891\n220892\n220895\n220899\n220902\n220903\n220912\n220920\n220921\n220946\n220947\n220948\n220955\n220956\n220959\n220963\n220968\n220976\n220982\n220984\n220993\n220995\n221003\n221006\n221007\n221013\n221016\n221018\n221024\n221030\n221040\n221047\n221048\n221049\n221061\n221065\n221068\n221073\n221089\n221098\n221099\n221107\n221113\n221119\n221130\n221131\n221133\n221134\n221135\n221138\n221139\n221145\n221160\n221170\n221174\n221179\n221189\n221192\n221199\n221203\n221209\n221217\n221224\n221230\n221239\n221256\n221257\n221262\n221266\n221274\n221281\n221293\n221298\n221311\n221312\n221314\n221315\n221319\n221323\n221324\n221329\n221332\n221334\n221338\n221339\n221341\n221355\n221361\n221376\n221377\n221379\n221388\n221390\n221396\n221409\n221413\n221430\n221432\n221433\n221435\n221437\n221438\n221441\n221442\n221444\n221445\n221454\n221460\n221464\n221468\n221471\n221473\n221493\n221500\n221510\n221514\n221522\n221524\n221528\n221535\n221538\n221539\n221542\n221545\n221548\n221552\n221553\n221568\n221569\n221570\n221576\n221582\n221585\n221586\n221591\n221598\n221603\n221609\n221611\n221619\n221621\n221622\n221629\n221638\n221643\n221645\n221646\n221647\n221648\n221652\n221669\n221681\n221686\n221687\n221693\n221706\n221707\n221711\n221712\n221719\n221721\n221722\n221727\n221729\n221731\n221734\n221736\n221737\n221741\n221744\n221745\n221748\n221749\n221756\n221764\n221765\n221766\n221777\n221782\n221783\n221792\n221794\n221796\n221801\n221805\n221807\n221809\n221810\n221814\n221824\n221830\n221845\n221846\n221847\n221852\n221863\n221870\n221876\n221877\n221879\n221890\n221891\n221892\n221896\n221899\n221900\n221901\n221906\n221910\n221913\n221914\n221932\n221933\n221937\n221952\n221956\n221957\n221963\n221968\n221984\n221996\n221999\n222002\n222007\n222017\n222018\n222019\n222024\n222025\n222046\n222051\n222054\n222061\n222067\n222068\n222070\n222072\n222079\n222081\n222095\n222105\n222108\n222109\n222114\n222123\n222127\n222132\n222144\n222149\n222162\n222165\n222167\n222176\n222182\n222191\n222200\n222202\n222206\n222210\n222211\n222217\n222226\n222234\n222235\n222238\n222242\n222245\n222247\n222263\n222269\n222273\n222283\n222284\n222290\n222293\n222296\n222298\n222299\n222300\n222302\n222306\n222311\n222316\n222318\n222329\n222330\n222358\n222362\n222363\n222378\n222386\n222390\n222396\n222417\n222433\n222446\n222454\n222459\n222461\n222466\n222471\n222473\n222474\n222476\n222478\n222479\n222480\n222491\n222495\n222497\n222498\n222504\n222508\n222509\n222511\n222514\n222516\n222519\n222523\n222534\n222536\n222543\n222549\n222552\n222557\n222561\n222585\n222591\n222593\n222607\n222618\n222628\n222640\n222646\n222649\n222660\n222662\n222667\n222668\n222672\n222674\n222675\n222676\n222678\n222679\n222682\n222685\n222693\n222694\n222703\n222711\n222714\n222722\n222725\n222731\n222735\n222753\n222758\n222760\n222766\n222772\n222778\n222781\n222796\n222799\n222803\n222807\n222813\n222836\n222843\n222850\n222854\n222862\n222873\n222886\n222899\n222903\n222907\n222908\n222909\n222910\n222912\n222915\n222918\n222928\n222934\n222938\n222944\n222960\n222971\n222973\n222974\n222976\n222978\n222980\n222984\n222985\n222998\n223003\n223005\n223007\n223018\n223020\n223026\n223030\n223034\n223040\n223045\n223051\n223060\n223061\n223063\n223067\n223069\n223070\n223072\n223081\n223097\n223098\n223100\n223110\n223113\n223123\n223127\n223128\n223140\n223149\n223150\n223161\n223162\n223169\n223174\n223179\n223186\n223187\n223188\n223198\n223201\n223202\n223203\n223204\n223211\n223216\n223225\n223229\n223230\n223232\n223233\n223236\n223238\n223239\n223241\n223247\n223255\n223260\n223263\n223269\n223271\n223273\n223284\n223285\n223302\n223309\n223312\n223322\n223323\n223329\n223335\n223338\n223346\n223348\n223353\n223354\n223360\n223368\n223369\n223380\n223381\n223385\n223386\n223387\n223389\n223395\n223397\n223401\n223407\n223408\n223411\n223412\n223413\n223414\n223419\n223423\n223428\n223429\n223436\n223437\n223438\n223440\n223441\n223449\n223450\n223457\n223461\n223471\n223473\n223476\n223477\n223479\n223483\n223485\n223492\n223494\n223497\n223500\n223504\n223506\n223513\n223522\n223525\n223527\n223530\n223535\n223539\n223547\n223548\n223549\n223551\n223554\n223555\n223563\n223567\n223569\n223572\n223575\n223578\n223585\n223594\n223599\n223601\n223607\n223614\n223616\n223617\n223624\n223626\n223632\n223652\n223660\n223667\n223669\n223681\n223690\n223695\n223696\n223698\n223713\n223715\n223719\n223722\n223723\n223724\n223726\n223727\n223735\n223737\n223740\n223741\n223743\n223751\n223754\n223773\n223776\n223778\n223781\n223791\n223801\n223809\n223815\n223819\n223821\n223822\n223824\n223826\n223834\n223849\n223855\n223863\n223868\n223882\n223885\n223917\n223920\n223923\n223926\n223933\n223934\n223945\n223952\n223953\n223956\n223957\n223960\n223963\n223964\n223970\n223976\n223979\n223980\n223984\n223985\n223987\n223992\n223998\n224004\n224006\n224013\n224021\n224022\n224023\n224028\n224039\n224053\n224057\n224072\n224081\n224083\n224084\n224097\n224098\n224099\n224101\n224109\n224126\n224127\n224128\n224132\n224134\n224143\n224148\n224149\n224161\n224169\n224188\n224194\n224210\n224216\n224224\n224228\n224229\n224230\n224232\n224233\n224238\n224239\n224240\n224242\n224244\n224249\n224251\n224258\n224262\n224266\n224275\n224283\n224307\n224309\n224315\n224320\n224321\n224326\n224335\n224344\n224353\n224354\n224355\n224359\n224367\n224372\n224376\n224377\n224378\n224382\n224386\n224388\n224391\n224396\n224398\n224401\n224409\n224417\n224422\n224423\n224431\n224432\n224433\n224434\n224436\n224438\n224445\n224451\n224457\n224461\n224464\n224470\n224472\n224476\n224478\n224483\n224484\n224485\n224488\n224494\n224501\n224510\n224522\n224524\n224530\n224532\n224545\n224549\n224551\n224558\n224561\n224564\n224569\n224587\n224598\n224599\n224605\n224607\n224608\n224612\n224618\n224620\n224635\n224645\n224650\n224655\n224656\n224657\n224658\n224663\n224680\n224682\n224683\n224686\n224698\n224700\n224701\n224706\n224710\n224719\n224727\n224729\n224740\n224746\n224748\n224751\n224753\n224761\n224770\n224772\n224773\n224784\n224785\n224786\n224794\n224796\n224799\n224809\n224810\n224813\n224827\n224828\n224831\n224835\n224849\n224855\n224857\n224860\n224866\n224868\n224872\n224875\n224879\n224882\n224886\n224888\n224890\n224895\n224897\n224898\n224899\n224900\n224905\n224908\n224909\n224911\n224923\n224938\n224941\n224943\n224949\n224969\n224970\n224971\n224976\n224977\n224981\n224982\n224984\n224996\n225012\n225015\n225020\n225021\n225026\n225030\n225032\n225038\n225039\n225050\n225051\n225054\n225065\n225075\n225090\n225091\n225093\n225100\n225101\n225103\n225106\n225109\n225118\n225122\n225127\n225129\n225130\n225139\n225141\n225148\n225152\n225155\n225166\n225171\n225182\n225183\n225184\n225188\n225195\n225196\n225200\n225211\n225220\n225221\n225231\n225253\n225261\n225263\n225271\n225273\n225275\n225276\n225279\n225288\n225290\n225300\n225302\n225305\n225309\n225314\n225315\n225316\n225330\n225332\n225333\n225334\n225336\n225337\n225340\n225346\n225348\n225351\n225354\n225356\n225357\n225362\n225363\n225367\n225368\n225371\n225390\n225391\n225397\n225403\n225407\n225420\n225424\n225425\n225427\n225429\n225434\n225440\n225446\n225448\n225450\n225453\n225468\n225474\n225475\n225480\n225483\n225485\n225487\n225489\n225492\n225493\n225518\n225521\n225527\n225531\n225533\n225537\n225538\n225540\n225541\n225544\n225548\n225559\n225560\n225579\n225580\n225587\n225590\n225593\n225597\n225603\n225619\n225622\n225628\n225629\n225636\n225647\n225648\n225651\n225657\n225659\n225678\n225679\n225685\n225696\n225711\n225718\n225731\n225732\n225741\n225742\n225747\n225751\n225754\n225755\n225770\n225772\n225779\n225782\n225784\n225785\n225786\n225797\n225807\n225816\n225831\n225833\n225834\n225835\n225851\n225864\n225872\n225877\n225878\n225880\n225882\n225884\n225886\n225888\n225891\n225892\n225893\n225895\n225905\n225906\n225911\n225915\n225919\n225920\n225926\n225928\n225940\n225947\n225951\n225961\n225963\n225965\n225969\n225971\n225974\n225975\n225984\n225996\n226003\n226004\n226009\n226012\n226020\n226023\n226033\n226035\n226038\n226045\n226054\n226057\n226060\n226071\n226076\n226078\n226079\n226083\n226090\n226091\n226100\n226105\n226119\n226121\n226122\n226129\n226131\n226134\n226136\n226144\n226145\n226148\n226152\n226154\n226156\n226159\n226160\n226163\n226170\n226173\n226179\n226188\n226204\n226208\n226210\n226211\n226219\n226226\n226232\n226235\n226241\n226248\n226250\n226258\n226259\n226260\n226261\n226264\n226272\n226274\n226278\n226301\n226303\n226308\n226309\n226312\n226320\n226326\n226336\n226338\n226345\n226354\n226355\n226356\n226362\n226372\n226373\n226375\n226384\n226402\n226411\n226414\n226417\n226418\n226421\n226422\n226425\n226426\n226435\n226445\n226447\n226449\n226456\n226460\n226463\n226468\n226472\n226494\n226497\n226499\n226503\n226504\n226505\n226509\n226514\n226517\n226518\n226526\n226531\n226535\n226536\n226539\n226553\n226555\n226556\n226557\n226558\n226566\n226571\n226574\n226579\n226583\n226584\n226590\n226597\n226608\n226621\n226624\n226644\n226645\n226646\n226648\n226650\n226651\n226657\n226658\n226662\n226676\n226681\n226687\n226696\n226699\n226700\n226704\n226709\n226713\n226716\n226726\n226727\n226731\n226741\n226747\n226752\n226756\n226765\n226772\n226776\n226777\n226783\n226788\n226794\n226795\n226798\n226802\n226813\n226814\n226822\n226823\n226830\n226835\n226847\n226855\n226858\n226861\n226867\n226872\n226876\n226883\n226887\n226889\n226891\n226895\n226906\n226908\n226913\n226926\n226932\n226937\n226942\n226949\n226957\n226960\n226963\n226969\n226971\n226978\n226982\n226985\n226989\n226997\n226998\n227004\n227007\n227023\n227025\n227037\n227052\n227091\n227107\n227117\n227119\n227133\n227134\n227140\n227143\n227148\n227151\n227152\n227176\n227184\n227185\n227197\n227216\n227219\n227228\n227239\n227245\n227247\n227251\n227261\n227262\n227264\n227266\n227270\n227271\n227272\n227273\n227290\n227291\n227292\n227295\n227299\n227301\n227310\n227312\n227315\n227316\n227319\n227323\n227326\n227328\n227338\n227342\n227347\n227354\n227357\n227358\n227370\n227375\n227377\n227381\n227386\n227403\n227407\n227409\n227416\n227418\n227430\n227439\n227442\n227445\n227447\n227450\n227452\n227457\n227467\n227470\n227472\n227473\n227477\n227478\n227490\n227495\n227496\n227498\n227503\n227509\n227513\n227515\n227524\n227536\n227544\n227546\n227548\n227550\n227554\n227557\n227565\n227566\n227568\n227569\n227571\n227586\n227593\n227596\n227597\n227604\n227605\n227608\n227621\n227628\n227631\n227635\n227641\n227646\n227655\n227661\n227668\n227669\n227670\n227694\n227699\n227707\n227719\n227723\n227738\n227741\n227742\n227745\n227746\n227753\n227755\n227758\n227760\n227763\n227765\n227769\n227776\n227778\n227787\n227789\n227794\n227795\n227797\n227804\n227817\n227824\n227833\n227852\n227863\n227874\n227878\n227881\n227889\n227897\n227899\n227906\n227912\n227913\n227919\n227923\n227924\n227927\n227933\n227938\n227940\n227957\n227960\n227965\n227968\n227969\n227982\n227985\n227986\n227996\n227999\n228009\n228016\n228018\n228020\n228021\n228026\n228027\n228028\n228029\n228030\n228035\n228037\n228043\n228044\n228049\n228057\n228060\n228064\n228072\n228075\n228078\n228084\n228094\n228096\n228114\n228117\n228118\n228126\n228132\n228133\n228138\n228146\n228147\n228151\n228161\n228168\n228169\n228171\n228177\n228183\n228185\n228190\n228191\n228192\n228194\n228200\n228201\n228202\n228206\n228207\n228211\n228219\n228223\n228225\n228228\n228235\n228243\n228244\n228247\n228253\n228255\n228265\n228268\n228270\n228280\n228285\n228287\n228293\n228300\n228304\n228309\n228320\n228338\n228356\n228361\n228367\n228370\n228390\n228400\n228403\n228407\n228408\n228412\n228415\n228417\n228418\n228423\n228433\n228439\n228440\n228443\n228447\n228451\n228455\n228458\n228471\n228472\n228474\n228486\n228488\n228494\n228505\n228535\n228536\n228539\n228545\n228556\n228560\n228573\n228581\n228584\n228589\n228593\n228596\n228597\n228605\n228606\n228610\n228611\n228615\n228619\n228625\n228628\n228631\n228633\n228634\n228637\n228640\n228643\n228644\n228645\n228665\n228667\n228675\n228680\n228684\n228689\n228693\n228696\n228703\n228705\n228708\n228714\n228720\n228740\n228741\n228746\n228750\n228757\n228764\n228768\n228769\n228773\n228774\n228778\n228782\n228784\n228796\n228803\n228806\n228809\n228812\n228818\n228826\n228829\n228830\n228836\n228841\n228846\n228852\n228862\n228865\n228869\n228871\n228872\n228873\n228879\n228887\n228889\n228890\n228896\n228901\n228909\n228910\n228912\n228916\n228918\n228925\n228932\n228934\n228937\n228938\n228941\n228949\n228952\n228954\n228956\n228965\n228966\n228972\n228973\n228976\n228977\n228980\n228984\n228986\n228993\n228994\n228997\n229003\n229010\n229014\n229020\n229024\n229034\n229038\n229045\n229048\n229055\n229071\n229082\n229084\n229094\n229095\n229100\n229102\n229103\n229107\n229112\n229115\n229121\n229138\n229143\n229144\n229148\n229149\n229150\n229155\n229160\n229163\n229166\n229168\n229169\n229170\n229171\n229175\n229180\n229181\n229187\n229189\n229192\n229201\n229204\n229206\n229208\n229209\n229224\n229226\n229239\n229241\n229244\n229259\n229261\n229269\n229274\n229279\n229280\n229281\n229284\n229296\n229300\n229301\n229308\n229314\n229317\n229319\n229326\n229329\n229335\n229340\n229345\n229352\n229355\n229359\n229372\n229374\n229384\n229386\n229399\n229423\n229424\n229430\n229441\n229448\n229458\n229465\n229473\n229481\n229510\n229514\n229516\n229517\n229521\n229537\n229539\n229547\n229559\n229562\n229575\n229576\n229581\n229589\n229591\n229592\n229593\n229594\n229597\n229599\n229601\n229602\n229603\n229606\n229610\n229613\n229617\n229620\n229629\n229631\n229632\n229634\n229637\n229639\n229657\n229662\n229665\n229667\n229668\n229679\n229680\n229689\n229693\n229696\n229699\n229705\n229714\n229715\n229725\n229734\n229740\n229741\n229742\n229743\n229744\n229748\n229755\n229756\n229757\n229758\n229764\n229767\n229780\n229783\n229794\n229799\n229801\n229810\n229814\n229818\n229820\n229823\n229826\n229831\n229832\n229836\n229837\n229839\n229850\n229862\n229871\n229875\n229883\n229893\n229896\n229897\n229902\n229910\n229913\n229914\n229915\n229920\n229930\n229938\n229939\n229947\n229949\n229952\n229958\n229962\n229966\n229969\n229977\n229983\n229984\n229987\n229991\n229997\n229998\n230000\n230003\n230007\n230008\n230011\n230013\n230017\n230021\n230025\n230029\n230038\n230039\n230046\n230050\n230079\n230085\n230087\n230097\n230101\n230103\n230104\n230108\n230109\n230111\n230121\n230131\n230132\n230133\n230134\n230135\n230139\n230142\n230148\n230151\n230154\n230157\n230160\n230163\n230164\n230176\n230183\n230195\n230199\n230205\n230206\n230209\n230212\n230225\n230233\n230235\n230242\n230245\n230264\n230267\n230270\n230275\n230280\n230283\n230287\n230288\n230295\n230309\n230314\n230320\n230324\n230329\n230331\n230336\n230339\n230343\n230348\n230350\n230351\n230356\n230365\n230368\n230371\n230372\n230378\n230391\n230398\n230413\n230415\n230418\n230421\n230430\n230435\n230439\n230444\n230452\n230465\n230468\n230475\n230480\n230487\n230494\n230495\n230496\n230510\n230511\n230520\n230527\n230528\n230529\n230530\n230534\n230537\n230538\n230542\n230547\n230549\n230558\n230562\n230565\n230571\n230576\n230577\n230582\n230583\n230587\n230588\n230589\n230591\n230592\n230593\n230595\n230610\n230611\n230616\n230619\n230624\n230632\n230638\n230640\n230643\n230652\n230654\n230660\n230668\n230670\n230673\n230689\n230691\n230697\n230712\n230714\n230716\n230717\n230719\n230721\n230722\n230724\n230746\n230759\n230764\n230770\n230773\n230778\n230780\n230781\n230783\n230785\n230786\n230796\n230803\n230813\n230818\n230832\n230840\n230848\n230851\n230856\n230858\n230869\n230875\n230884\n230894\n230906\n230908\n230910\n230913\n230917\n230918\n230919\n230921\n230924\n230928\n230937\n230938\n230942\n230945\n230947\n230948\n230949\n230950\n230955\n230963\n230964\n230965\n230971\n230977\n230978\n230985\n230990\n230992\n230998\n231002\n231015\n231016\n231018\n231023\n231026\n231030\n231044\n231047\n231050\n231051\n231055\n231057\n231064\n231078\n231079\n231090\n231093\n231094\n231108\n231112\n231113\n231114\n231120\n231122\n231127\n231130\n231132\n231134\n231138\n231146\n231149\n231150\n231166\n231168\n231175\n231186\n231189\n231192\n231213\n231216\n231219\n231220\n231223\n231236\n231244\n231246\n231249\n231253\n231255\n231259\n231267\n231275\n231285\n231292\n231297\n231299\n231300\n231306\n231311\n231316\n231321\n231322\n231327\n231330\n231335\n231341\n231350\n231353\n231354\n231356\n231359\n231368\n231377\n231388\n231390\n231393\n231394\n231395\n231400\n231403\n231405\n231413\n231415\n231419\n231423\n231427\n231435\n231438\n231443\n231451\n231452\n231453\n231455\n231462\n231467\n231472\n231488\n231494\n231498\n231499\n231501\n231503\n231507\n231509\n231512\n231518\n231523\n231531\n231533\n231536\n231546\n231548\n231556\n231562\n231567\n231569\n231570\n231577\n231578\n231581\n231584\n231585\n231589\n231616\n231617\n231622\n231624\n231631\n231632\n231637\n231638\n231647\n231649\n231651\n231659\n231660\n231671\n231674\n231681\n231683\n231685\n231688\n231690\n231702\n231706\n231711\n231714\n231716\n231717\n231721\n231726\n231729\n231731\n231737\n231745\n231746\n231763\n231770\n231772\n231778\n231783\n231785\n231793\n231794\n231796\n231799\n231803\n231821\n231824\n231826\n231836\n231839\n231840\n231855\n231859\n231872\n231879\n231883\n231900\n231906\n231907\n231914\n231917\n231918\n231923\n231938\n231941\n231946\n231956\n231964\n231966\n231968\n231973\n231976\n231980\n231988\n231990\n231991\n231997\n232000\n232019\n232020\n232022\n232024\n232030\n232037\n232040\n232041\n232046\n232047\n232048\n232050\n232053\n232055\n232057\n232058\n232063\n232064\n232068\n232070\n232072\n232075\n232081\n232082\n232085\n232088\n232097\n232098\n232105\n232115\n232118\n232119\n232120\n232126\n232130\n232131\n232139\n232150\n232152\n232153\n232164\n232166\n232170\n232177\n232184\n232186\n232193\n232202\n232204\n232206\n232210\n232216\n232219\n232224\n232226\n232230\n232233\n232251\n232255\n232260\n232282\n232284\n232285\n232292\n232295\n232296\n232300\n232305\n232308\n232313\n232319\n232330\n232338\n232344\n232347\n232349\n232352\n232355\n232360\n232361\n232363\n232366\n232368\n232374\n232376\n232379\n232385\n232388\n232393\n232397\n232398\n232426\n232428\n232430\n232437\n232451\n232452\n232453\n232456\n232468\n232471\n232472\n232475\n232476\n232478\n232480\n232488\n232491\n232492\n232493\n232499\n232508\n232510\n232515\n232520\n232525\n232534\n232535\n232551\n232566\n232567\n232572\n232582\n232587\n232589\n232590\n232604\n232610\n232614\n232618\n232635\n232636\n232637\n232640\n232657\n232660\n232666\n232667\n232673\n232675\n232677\n232681\n232683\n232686\n232693\n232696\n232698\n232700\n232703\n232709\n232710\n232718\n232720\n232731\n232732\n232738\n232739\n232742\n232743\n232749\n232750\n232752\n232765\n232766\n232768\n232774\n232776\n232777\n232778\n232779\n232782\n232788\n232791\n232792\n232794\n232804\n232807\n232820\n232840\n232844\n232855\n232857\n232866\n232868\n232873\n232874\n232885\n232888\n232893\n232897\n232917\n232923\n232926\n232941\n232955\n232958\n232966\n232969\n232973\n232977\n232980\n232993\n232994\n233003\n233005\n233006\n233016\n233018\n233027\n233031\n233037\n233045\n233050\n233053\n233056\n233061\n233082\n233090\n233094\n233097\n233114\n233118\n233141\n233143\n233145\n233148\n233153\n233156\n233157\n233160\n233162\n233163\n233170\n233173\n233183\n233187\n233194\n233196\n233200\n233203\n233204\n233209\n233211\n233213\n233221\n233228\n233232\n233233\n233235\n233236\n233243\n233244\n233247\n233256\n233258\n233259\n233260\n233266\n233284\n233286\n233288\n233301\n233303\n233305\n233313\n233319\n233328\n233329\n233330\n233337\n233339\n233340\n233341\n233345\n233347\n233348\n233354\n233356\n233358\n233359\n233360\n233363\n233366\n233367\n233372\n233378\n233383\n233384\n233391\n233393\n233405\n233406\n233413\n233419\n233420\n233421\n233429\n233436\n233452\n233456\n233458\n233459\n233469\n233481\n233483\n233486\n233501\n233506\n233515\n233516\n233517\n233523\n233524\n233536\n233542\n233571\n233598\n233603\n233605\n233607\n233609\n233616\n233618\n233621\n233626\n233630\n233632\n233635\n233638\n233642\n233648\n233649\n233652\n233657\n233660\n233666\n233668\n233677\n233679\n233680\n233681\n233685\n233707\n233709\n233712\n233719\n233721\n233724\n233730\n233738\n233746\n233747\n233766\n233768\n233770\n233778\n233785\n233791\n233807\n233808\n233813\n233822\n233824\n233831\n233834\n233837\n233841\n233847\n233848\n233860\n233861\n233867\n233868\n233870\n233871\n233879\n233883\n233884\n233886\n233891\n233895\n233896\n233897\n233900\n233913\n233919\n233921\n233930\n233931\n233934\n233944\n233953\n233961\n233963\n233964\n233967\n233968\n233982\n233991\n233993\n233997\n234003\n234005\n234008\n234012\n234017\n234021\n234025\n234027\n234029\n234035\n234039\n234041\n234053\n234062\n234090\n234091\n234096\n234097\n234098\n234101\n234106\n234109\n234110\n234113\n234118\n234125\n234129\n234145\n234149\n234153\n234154\n234155\n234158\n234165\n234176\n234183\n234187\n234188\n234194\n234197\n234204\n234207\n234208\n234210\n234223\n234226\n234230\n234234\n234241\n234246\n234247\n234248\n234252\n234256\n234262\n234264\n234265\n234289\n234308\n234314\n234317\n234318\n234321\n234323\n234330\n234336\n234338\n234344\n234348\n234353\n234365\n234375\n234382\n234390\n234397\n234400\n234414\n234417\n234423\n234427\n234428\n234437\n234438\n234439\n234442\n234443\n234444\n234445\n234448\n234453\n234460\n234462\n234465\n234466\n234469\n234471\n234476\n234483\n234485\n234487\n234489\n234492\n234495\n234500\n234518\n234522\n234523\n234530\n234548\n234551\n234552\n234553\n234554\n234564\n234576\n234586\n234588\n234589\n234592\n234595\n234596\n234599\n234601\n234620\n234621\n234626\n234639\n234646\n234649\n234650\n234653\n234654\n234658\n234659\n234661\n234664\n234673\n234676\n234682\n234689\n234696\n234713\n234726\n234728\n234730\n234736\n234737\n234738\n234745\n234750\n234751\n234757\n234770\n234773\n234775\n234780\n234784\n234787\n234800\n234802\n234803\n234810\n234813\n234814\n234817\n234818\n234819\n234820\n234825\n234827\n234833\n234835\n234837\n234842\n234848\n234850\n234857\n234862\n234865\n234873\n234875\n234879\n234881\n234887\n234914\n234916\n234927\n234934\n234952\n234964\n234967\n234968\n234975\n234976\n234985\n234988\n234993\n235001\n235012\n235013\n235015\n235018\n235029\n235030\n235036\n235042\n235045\n235047\n235051\n235077\n235080\n235083\n235085\n235087\n235089\n235090\n235094\n235098\n235103\n235106\n235107\n235110\n235113\n235118\n235128\n235132\n235134\n235135\n235140\n235143\n235145\n235148\n235149\n235151\n235154\n235158\n235178\n235187\n235189\n235197\n235199\n235200\n235201\n235210\n235211\n235216\n235218\n235226\n235231\n235235\n235249\n235251\n235265\n235268\n235277\n235279\n235282\n235284\n235287\n235291\n235301\n235307\n235310\n235317\n235322\n235325\n235328\n235332\n235344\n235348\n235355\n235357\n235358\n235363\n235372\n235373\n235379\n235382\n235387\n235391\n235396\n235397\n235400\n235422\n235431\n235435\n235437\n235456\n235464\n235471\n235478\n235479\n235486\n235489\n235503\n235510\n235517\n235523\n235528\n235538\n235542\n235547\n235548\n235553\n235562\n235568\n235573\n235574\n235577\n235579\n235583\n235587\n235598\n235606\n235622\n235635\n235636\n235637\n235638\n235643\n235647\n235649\n235655\n235658\n235662\n235665\n235667\n235668\n235673\n235675\n235681\n235687\n235689\n235690\n235700\n235723\n235724\n235737\n235738\n235742\n235749\n235756\n235775\n235778\n235783\n235785\n235787\n235791\n235796\n235798\n235799\n235801\n235818\n235822\n235824\n235828\n235830\n235832\n235833\n235837\n235847\n235848\n235854\n235858\n235869\n235873\n235893\n235894\n235899\n235902\n235908\n235909\n235920\n235921\n235928\n235940\n235941\n235956\n235960\n235962\n235970\n235974\n235975\n235979\n235984\n235988\n235993\n235996\n236004\n236029\n236045\n236048\n236068\n236075\n236076\n236080\n236087\n236089\n236099\n236100\n236103\n236104\n236105\n236106\n236111\n236116\n236120\n236134\n236152\n236159\n236163\n236173\n236176\n236182\n236185\n236190\n236201\n236210\n236211\n236214\n236218\n236219\n236225\n236226\n236227\n236229\n236230\n236237\n236239\n236243\n236246\n236250\n236259\n236260\n236263\n236267\n236271\n236274\n236280\n236282\n236292\n236299\n236308\n236316\n236320\n236325\n236328\n236333\n236339\n236341\n236344\n236347\n236351\n236355\n236356\n236364\n236371\n236374\n236375\n236382\n236386\n236388\n236389\n236394\n236399\n236402\n236409\n236419\n236430\n236435\n236437\n236438\n236440\n236445\n236449\n236454\n236457\n236463\n236465\n236473\n236486\n236497\n236505\n236506\n236515\n236516\n236525\n236530\n236531\n236533\n236534\n236535\n236544\n236549\n236553\n236562\n236563\n236569\n236575\n236580\n236581\n236582\n236583\n236586\n236587\n236591\n236592\n236593\n236597\n236616\n236618\n236619\n236625\n236631\n236643\n236653\n236654\n236657\n236658\n236660\n236661\n236665\n236666\n236668\n236675\n236680\n236686\n236690\n236695\n236698\n236704\n236705\n236708\n236728\n236730\n236741\n236744\n236746\n236755\n236756\n236757\n236763\n236764\n236775\n236776\n236780\n236783\n236784\n236787\n236791\n236792\n236794\n236801\n236803\n236812\n236818\n236821\n236827\n236830\n236832\n236846\n236848\n236859\n236860\n236869\n236870\n236873\n236879\n236888\n236889\n236893\n236897\n236898\n236908\n236925\n236926\n236932\n236934\n236937\n236944\n236949\n236952\n236954\n236959\n236971\n236972\n236974\n236975\n236984\n236988\n236992\n236995\n237000\n237015\n237018\n237025\n237029\n237038\n237042\n237062\n237075\n237078\n237084\n237088\n237089\n237104\n237105\n237108\n237111\n237117\n237123\n237132\n237137\n237140\n237151\n237159\n237164\n237173\n237182\n237187\n237190\n237194\n237195\n237197\n237200\n237201\n237203\n237211\n237212\n237217\n237228\n237229\n237235\n237238\n237243\n237259\n237260\n237261\n237278\n237280\n237288\n237294\n237295\n237297\n237300\n237301\n237306\n237320\n237324\n237328\n237342\n237345\n237350\n237355\n237362\n237363\n237379\n237386\n237389\n237390\n237391\n237393\n237395\n237400\n237404\n237412\n237418\n237425\n237430\n237437\n237440\n237441\n237447\n237465\n237479\n237481\n237482\n237489\n237492\n237494\n237501\n237504\n237505\n237513\n237516\n237527\n237530\n237543\n237544\n237551\n237553\n237559\n237563\n237564\n237582\n237583\n237592\n237596\n237607\n237615\n237620\n237626\n237628\n237634\n237640\n237646\n237652\n237665\n237666\n237682\n237683\n237684\n237701\n237702\n237703\n237710\n237718\n237720\n237721\n237722\n237723\n237726\n237732\n237733\n237736\n237741\n237745\n237746\n237748\n237755\n237756\n237764\n237769\n237770\n237773\n237776\n237780\n237781\n237782\n237783\n237785\n237788\n237792\n237798\n237805\n237807\n237811\n237816\n237819\n237822\n237826\n237828\n237831\n237850\n237851\n237854\n237858\n237863\n237865\n237867\n237888\n237895\n237905\n237909\n237912\n237936\n237948\n237954\n237957\n237960\n237964\n237966\n237970\n237972\n237977\n237989\n237995\n237999\n238007\n238010\n238011\n238032\n238033\n238037\n238044\n238047\n238051\n238052\n238054\n238060\n238063\n238065\n238067\n238068\n238070\n238074\n238085\n238086\n238092\n238097\n238106\n238112\n238113\n238115\n238116\n238123\n238128\n238131\n238133\n238134\n238139\n238143\n238149\n238151\n238158\n238160\n238165\n238167\n238173\n238184\n238186\n238192\n238193\n238202\n238204\n238214\n238215\n238218\n238221\n238222\n238223\n238224\n238234\n238248\n238249\n238251\n238263\n238268\n238281\n238287\n238289\n238291\n238294\n238301\n238307\n238308\n238309\n238312\n238321\n238330\n238337\n238363\n238371\n238372\n238377\n238388\n238389\n238390\n238393\n238394\n238395\n238396\n238410\n238418\n238419\n238426\n238436\n238440\n238441\n238445\n238453\n238458\n238459\n238463\n238464\n238472\n238474\n238481\n238483\n238484\n238485\n238487\n238489\n238491\n238495\n238497\n238501\n238517\n238525\n238527\n238532\n238534\n238539\n238540\n238545\n238552\n238555\n238559\n238560\n238562\n238568\n238569\n238570\n238573\n238580\n238582\n238583\n238585\n238592\n238594\n238598\n238602\n238604\n238608\n238613\n238620\n238624\n238639\n238643\n238644\n238646\n238653\n238664\n238666\n238668\n238678\n238679\n238680\n238683\n238689\n238694\n238710\n238712\n238717\n238721\n238723\n238728\n238732\n238735\n238737\n238738\n238748\n238757\n238758\n238761\n238764\n238766\n238771\n238774\n238777\n238779\n238781\n238784\n238795\n238800\n238802\n238809\n238812\n238816\n238828\n238840\n238849\n238867\n238872\n238873\n238876\n238896\n238901\n238904\n238906\n238914\n238925\n238934\n238940\n238945\n238948\n238957\n238964\n238970\n238972\n238978\n238988\n238993\n238996\n239014\n239020\n239031\n239037\n239048\n239055\n239056\n239057\n239083\n239090\n239100\n239101\n239102\n239103\n239104\n239107\n239120\n239121\n239125\n239127\n239128\n239130\n239141\n239143\n239146\n239159\n239162\n239169\n239186\n239187\n239192\n239207\n239222\n239227\n239228\n239235\n239237\n239239\n239244\n239252\n239263\n239265\n239266\n239272\n239274\n239277\n239279\n239284\n239287\n239289\n239292\n239294\n239296\n239301\n239303\n239305\n239319\n239327\n239330\n239347\n239349\n239357\n239373\n239375\n239391\n239394\n239397\n239398\n239401\n239411\n239415\n239416\n239418\n239420\n239430\n239447\n239450\n239451\n239454\n239463\n239465\n239479\n239480\n239483\n239488\n239492\n239494\n239506\n239508\n239515\n239516\n239531\n239535\n239536\n239538\n239545\n239549\n239558\n239561\n239563\n239582\n239585\n239594\n239595\n239602\n239603\n239605\n239611\n239612\n239622\n239632\n239643\n239645\n239668\n239678\n239683\n239684\n239686\n239695\n239696\n239704\n239705\n239706\n239707\n239714\n239715\n239717\n239723\n239726\n239728\n239729\n239735\n239736\n239738\n239743\n239744\n239745\n239771\n239772\n239780\n239781\n239783\n239791\n239793\n239794\n239803\n239804\n239820\n239822\n239825\n239828\n239833\n239857\n239858\n239864\n239869\n239874\n239875\n239877\n239884\n239890\n239891\n239892\n239894\n239897\n239901\n239905\n239908\n239910\n239928\n239933\n239940\n239942\n239944\n239945\n239951\n239959\n239967\n239974\n239977\n239978\n239983\n239991\n239993\n239995\n239999\n240004\n240022\n240032\n240037\n240062\n240063\n240074\n240082\n240085\n240086\n240089\n240092\n240098\n240100\n240102\n240106\n240109\n240113\n240119\n240125\n240135\n240142\n240143\n240147\n240149\n240158\n240161\n240166\n240172\n240178\n240180\n240182\n240192\n240204\n240226\n240227\n240247\n240249\n240252\n240265\n240274\n240276\n240277\n240281\n240282\n240289\n240297\n240307\n240308\n240310\n240315\n240319\n240323\n240327\n240337\n240349\n240352\n240354\n240356\n240359\n240366\n240371\n240375\n240376\n240377\n240381\n240384\n240396\n240403\n240404\n240408\n240411\n240415\n240416\n240417\n240428\n240440\n240444\n240450\n240452\n240454\n240455\n240456\n240458\n240466\n240469\n240472\n240477\n240489\n240493\n240495\n240498\n240504\n240506\n240509\n240513\n240520\n240530\n240532\n240536\n240539\n240540\n240550\n240556\n240557\n240565\n240566\n240572\n240582\n240584\n240585\n240589\n240614\n240617\n240620\n240621\n240622\n240629\n240631\n240633\n240650\n240656\n240659\n240660\n240672\n240673\n240674\n240675\n240677\n240681\n240688\n240702\n240714\n240724\n240732\n240746\n240759\n240761\n240766\n240770\n240777\n240778\n240779\n240780\n240781\n240790\n240791\n240793\n240798\n240801\n240806\n240807\n240812\n240823\n240827\n240828\n240839\n240846\n240849\n240851\n240852\n240854\n240857\n240858\n240861\n240875\n240879\n240883\n240884\n240885\n240887\n240889\n240892\n240894\n240910\n240915\n240918\n240920\n240923\n240927\n240939\n240950\n240952\n240956\n240961\n240962\n240970\n240971\n240980\n240981\n240986\n241004\n241008\n241011\n241016\n241017\n241020\n241023\n241024\n241026\n241028\n241029\n241033\n241041\n241047\n241048\n241050\n241052\n241059\n241067\n241072\n241076\n241080\n241090\n241092\n241097\n241108\n241112\n241113\n241131\n241136\n241139\n241144\n241153\n241162\n241165\n241168\n241174\n241191\n241193\n241194\n241200\n241201\n241203\n241210\n241213\n241219\n241221\n241231\n241233\n241238\n241239\n241241\n241248\n241261\n241262\n241273\n241275\n241276\n241277\n241284\n241306\n241309\n241316\n241319\n241323\n241336\n241338\n241339\n241340\n241348\n241353\n241356\n241361\n241365\n241369\n241373\n241374\n241385\n241387\n241391\n241392\n241404\n241411\n241414\n241416\n241417\n241418\n241423\n241424\n241427\n241443\n241444\n241452\n241454\n241459\n241460\n241467\n241468\n241471\n241477\n241484\n241485\n241491\n241493\n241502\n241506\n241509\n241510\n241511\n241514\n241519\n241525\n241531\n241534\n241535\n241538\n241546\n241553\n241556\n241558\n241561\n241568\n241571\n241575\n241582\n241593\n241596\n241601\n241604\n241607\n241609\n241612\n241623\n241624\n241630\n241635\n241636\n241638\n241644\n241645\n241646\n241648\n241653\n241662\n241663\n241666\n241677\n241684\n241689\n241691\n241694\n241698\n241709\n241710\n241712\n241718\n241719\n241722\n241731\n241740\n241742\n241746\n241747\n241748\n241754\n241755\n241756\n241761\n241767\n241768\n241771\n241774\n241782\n241789\n241810\n241811\n241813\n241815\n241822\n241825\n241829\n241839\n241844\n241848\n241857\n241860\n241862\n241866\n241867\n241876\n241884\n241887\n241897\n241900\n241908\n241913\n241914\n241916\n241926\n241942\n241944\n241946\n241951\n241954\n241963\n241971\n241978\n241984\n241986\n241988\n241996\n241999\n242002\n242026\n242028\n242036\n242044\n242047\n242064\n242066\n242071\n242075\n242088\n242092\n242096\n242098\n242115\n242116\n242117\n242123\n242131\n242135\n242138\n242141\n242142\n242164\n242171\n242176\n242186\n242187\n242197\n242199\n242201\n242202\n242207\n242209\n242223\n242230\n242240\n242241\n242243\n242244\n242249\n242255\n242257\n242261\n242262\n242279\n242286\n242290\n242293\n242300\n242302\n242306\n242315\n242318\n242320\n242321\n242327\n242336\n242342\n242348\n242353\n242356\n242358\n242360\n242362\n242367\n242373\n242376\n242385\n242387\n242390\n242399\n242406\n242408\n242411\n242421\n242423\n242429\n242431\n242433\n242434\n242436\n242457\n242463\n242464\n242468\n242478\n242479\n242482\n242483\n242487\n242490\n242500\n242510\n242515\n242516\n242519\n242540\n242544\n242556\n242557\n242559\n242562\n242563\n242569\n242576\n242585\n242590\n242606\n242609\n242623\n242633\n242636\n242637\n242655\n242660\n242663\n242666\n242668\n242681\n242682\n242683\n242688\n242692\n242696\n242709\n242721\n242724\n242729\n242731\n242742\n242743\n242747\n242748\n242749\n242754\n242755\n242756\n242767\n242770\n242771\n242776\n242777\n242788\n242791\n242793\n242794\n242796\n242798\n242802\n242805\n242810\n242825\n242832\n242834\n242841\n242843\n242852\n242856\n242857\n242858\n242861\n242871\n242872\n242873\n242874\n242881\n242902\n242907\n242909\n242913\n242920\n242926\n242932\n242937\n242940\n242945\n242959\n242961\n242967\n242982\n242996\n243000\n243004\n243011\n243013\n243017\n243039\n243042\n243044\n243047\n243053\n243056\n243060\n243062\n243068\n243072\n243074\n243079\n243088\n243092\n243095\n243101\n243102\n243110\n243126\n243138\n243139\n243143\n243152\n243154\n243158\n243183\n243186\n243198\n243200\n243202\n243203\n243211\n243212\n243214\n243236\n243239\n243242\n243245\n243246\n243247\n243256\n243257\n243260\n243262\n243264\n243266\n243282\n243289\n243292\n243293\n243294\n243300\n243307\n243311\n243314\n243315\n243323\n243328\n243331\n243335\n243357\n243368\n243369\n243381\n243385\n243388\n243392\n243401\n243406\n243414\n243420\n243426\n243434\n243443\n243451\n243458\n243459\n243465\n243469\n243470\n243476\n243488\n243491\n243495\n243498\n243502\n243507\n243509\n243523\n243525\n243526\n243528\n243534\n243536\n243551\n243553\n243554\n243557\n243559\n243560\n243569\n243571\n243583\n243590\n243616\n243645\n243646\n243650\n243654\n243656\n243660\n243661\n243663\n243671\n243691\n243697\n243699\n243700\n243723\n243725\n243734\n243740\n243745\n243747\n243757\n243758\n243761\n243762\n243765\n243772\n243773\n243775\n243776\n243795\n243799\n243802\n243815\n243839\n243850\n243853\n243858\n243859\n243871\n243893\n243897\n243906\n243917\n243921\n243931\n243933\n243943\n243945\n243948\n243949\n243962\n243967\n243976\n243977\n243978\n243985\n244003\n244006\n244007\n244010\n244016\n244022\n244025\n244027\n244032\n244034\n244037\n244044\n244051\n244053\n244064\n244072\n244075\n244076\n244078\n244082\n244084\n244092\n244093\n244098\n244105\n244106\n244109\n244110\n244112\n244124\n244140\n244149\n244150\n244152\n244156\n244158\n244159\n244161\n244163\n244176\n244186\n244200\n244222\n244227\n244231\n244234\n244254\n244267\n244281\n244284\n244286\n244287\n244290\n244294\n244302\n244307\n244310\n244312\n244324\n244326\n244328\n244331\n244335\n244338\n244341\n244343\n244346\n244351\n244352\n244353\n244362\n244364\n244367\n244371\n244378\n244382\n244386\n244390\n244391\n244393\n244396\n244404\n244407\n244420\n244422\n244435\n244437\n244449\n244457\n244458\n244460\n244461\n244464\n244469\n244470\n244473\n244475\n244482\n244485\n244489\n244494\n244500\n244502\n244506\n244508\n244513\n244514\n244518\n244519\n244530\n244538\n244541\n244544\n244555\n244559\n244562\n244563\n244570\n244573\n244575\n244576\n244577\n244582\n244586\n244587\n244595\n244602\n244603\n244605\n244606\n244612\n244614\n244619\n244628\n244630\n244637\n244641\n244646\n244647\n244648\n244651\n244665\n244672\n244674\n244677\n244679\n244680\n244687\n244704\n244720\n244727\n244729\n244744\n244750\n244754\n244755\n244758\n244763\n244769\n244777\n244779\n244781\n244783\n244786\n244790\n244794\n244810\n244816\n244817\n244822\n244825\n244827\n244829\n244835\n244841\n244842\n244851\n244857\n244866\n244868\n244870\n244873\n244877\n244880\n244883\n244896\n244902\n244907\n244908\n244910\n244914\n244916\n244918\n244919\n244921\n244924\n244930\n244932\n244936\n244937\n244939\n244947\n244958\n244962\n244968\n244969\n244973\n244976\n244979\n244980\n244984\n244985\n244986\n244995\n244997\n244999\n245002\n245005\n245012\n245016\n245017\n245022\n245027\n245028\n245031\n245032\n245035\n245041\n245044\n245045\n245046\n245065\n245080\n245082\n245100\n245106\n245113\n245114\n245115\n245119\n245124\n245133\n245147\n245151\n245152\n245158\n245160\n245168\n245177\n245179\n245188\n245196\n245200\n245201\n245202\n245224\n245225\n245232\n245233\n245239\n245240\n245242\n245247\n245248\n245250\n245261\n245262\n245277\n245278\n245280\n245281\n245282\n245292\n245296\n245297\n245301\n245305\n245321\n245323\n245347\n245353\n245355\n245363\n245371\n245379\n245382\n245387\n245398\n245399\n245400\n245422\n245429\n245436\n245438\n245447\n245448\n245454\n245466\n245467\n245472\n245497\n245507\n245508\n245511\n245515\n245526\n245529\n245535\n245536\n245538\n245539\n245542\n245546\n245547\n245556\n245558\n245562\n245578\n245581\n245590\n245603\n245604\n245608\n245610\n245615\n245616\n245632\n245633\n245638\n245650\n245655\n245660\n245666\n245669\n245670\n245677\n245679\n245687\n245694\n245697\n245702\n245704\n245711\n245712\n245720\n245725\n245726\n245727\n245729\n245736\n245739\n245742\n245746\n245750\n245752\n245758\n245764\n245771\n245772\n245773\n245782\n245787\n245790\n245795\n245798\n245811\n245819\n245829\n245841\n245848\n245850\n245851\n245855\n245861\n245868\n245869\n245877\n245887\n245889\n245890\n245891\n245892\n245912\n245918\n245932\n245933\n245939\n245942\n245943\n245949\n245954\n245955\n245972\n245982\n245985\n245999\n246001\n246008\n246016\n246017\n246026\n246031\n246037\n246038\n246049\n246052\n246055\n246067\n246074\n246078\n246079\n246081\n246083\n246088\n246089\n246095\n246098\n246100\n246110\n246121\n246123\n246131\n246134\n246139\n246142\n246143\n246149\n246164\n246167\n246170\n246181\n246185\n246187\n246203\n246211\n246212\n246215\n246225\n246229\n246231\n246232\n246236\n246239\n246243\n246246\n246250\n246253\n246255\n246259\n246260\n246269\n246271\n246277\n246288\n246295\n246299\n246310\n246319\n246320\n246323\n246326\n246335\n246336\n246339\n246358\n246361\n246366\n246368\n246371\n246376\n246392\n246395\n246401\n246403\n246404\n246406\n246407\n246416\n246429\n246431\n246432\n246434\n246448\n246458\n246462\n246474\n246481\n246484\n246489\n246491\n246500\n246505\n246507\n246510\n246516\n246518\n246529\n246532\n246539\n246542\n246546\n246550\n246562\n246568\n246571\n246573\n246575\n246581\n246592\n246597\n246598\n246599\n246600\n246601\n246606\n246611\n246612\n246617\n246623\n246652\n246656\n246658\n246664\n246665\n246673\n246691\n246694\n246696\n246702\n246705\n246711\n246714\n246715\n246730\n246739\n246746\n246752\n246761\n246768\n246769\n246770\n246779\n246784\n246789\n246790\n246793\n246794\n246800\n246802\n246804\n246808\n246821\n246831\n246833\n246836\n246861\n246862\n246865\n246869\n246870\n246873\n246875\n246880\n246896\n246900\n246903\n246912\n246924\n246925\n246926\n246927\n246938\n246954\n246955\n246962\n246963\n246969\n246970\n246974\n246978\n246986\n246989\n246999\n247006\n247008\n247009\n247010\n247016\n247018\n247023\n247024\n247025\n247036\n247041\n247043\n247045\n247052\n247054\n247058\n247061\n247091\n247101\n247104\n247109\n247114\n247116\n247117\n247118\n247121\n247124\n247128\n247129\n247134\n247135\n247146\n247147\n247154\n247175\n247178\n247192\n247203\n247209\n247221\n247230\n247231\n247236\n247238\n247245\n247246\n247251\n247252\n247254\n247262\n247272\n247278\n247279\n247280\n247281\n247287\n247290\n247292\n247304\n247306\n247308\n247315\n247316\n247321\n247323\n247324\n247325\n247329\n247332\n247334\n247339\n247343\n247349\n247350\n247353\n247356\n247359\n247360\n247379\n247384\n247390\n247394\n247408\n247414\n247422\n247426\n247431\n247434\n247446\n247449\n247456\n247463\n247466\n247468\n247472\n247479\n247481\n247487\n247496\n247499\n247507\n247509\n247513\n247515\n247516\n247523\n247524\n247533\n247534\n247551\n247559\n247561\n247569\n247571\n247574\n247578\n247579\n247589\n247594\n247595\n247600\n247603\n247620\n247625\n247629\n247633\n247638\n247647\n247648\n247651\n247653\n247659\n247666\n247677\n247681\n247693\n247695\n247700\n247702\n247705\n247717\n247718\n247728\n247730\n247739\n247740\n247744\n247747\n247750\n247755\n247763\n247764\n247766\n247776\n247779\n247782\n247785\n247787\n247788\n247789\n247790\n247799\n247800\n247805\n247807\n247808\n247810\n247811\n247813\n247816\n247826\n247827\n247830\n247833\n247835\n247843\n247846\n247853\n247854\n247857\n247860\n247865\n247872\n247873\n247874\n247879\n247881\n247883\n247884\n247889\n247893\n247897\n247898\n247901\n247903\n247908\n247915\n247923\n247926\n247931\n247932\n247939\n247946\n247948\n247949\n247956\n247968\n247971\n247981\n247983\n247993\n247998\n248000\n248002\n248004\n248015\n248018\n248029\n248033\n248038\n248045\n248047\n248048\n248056\n248059\n248065\n248081\n248082\n248088\n248090\n248096\n248098\n248101\n248103\n248107\n248111\n248124\n248125\n248126\n248132\n248135\n248145\n248149\n248150\n248156\n248162\n248165\n248166\n248167\n248173\n248182\n248185\n248189\n248192\n248194\n248197\n248198\n248205\n248210\n248211\n248224\n248227\n248235\n248237\n248261\n248266\n248268\n248270\n248271\n248278\n248279\n248284\n248296\n248297\n248298\n248301\n248307\n248310\n248311\n248315\n248320\n248321\n248323\n248324\n248336\n248350\n248352\n248353\n248364\n248367\n248371\n248374\n248376\n248378\n248380\n248382\n248384\n248390\n248392\n248403\n248405\n248411\n248412\n248425\n248430\n248432\n248437\n248445\n248448\n248452\n248473\n248474\n248477\n248482\n248486\n248494\n248495\n248499\n248504\n248506\n248508\n248510\n248512\n248516\n248523\n248525\n248528\n248531\n248533\n248536\n248538\n248539\n248541\n248543\n248547\n248561\n248562\n248567\n248577\n248597\n248598\n248602\n248607\n248610\n248611\n248616\n248617\n248621\n248627\n248629\n248632\n248634\n248636\n248641\n248643\n248644\n248647\n248653\n248660\n248661\n248663\n248673\n248676\n248678\n248679\n248681\n248683\n248684\n248689\n248690\n248693\n248694\n248698\n248699\n248703\n248704\n248708\n248711\n248714\n248715\n248722\n248725\n248728\n248730\n248741\n248746\n248748\n248768\n248774\n248777\n248778\n248793\n248794\n248796\n248798\n248801\n248807\n248808\n248810\n248812\n248818\n248819\n248838\n248841\n248842\n248843\n248844\n248851\n248857\n248860\n248861\n248868\n248871\n248873\n248874\n248876\n248877\n248883\n248901\n248902\n248903\n248913\n248916\n248917\n248918\n248931\n248934\n248935\n248948\n248949\n248954\n248955\n248956\n248966\n248968\n248970\n248982\n248987\n248999\n249002\n249003\n249026\n249033\n249037\n249047\n249050\n249055\n249060\n249064\n249065\n249068\n249081\n249082\n249085\n249087\n249092\n249093\n249098\n249102\n249105\n249113\n249117\n249120\n249132\n249133\n249134\n249135\n249141\n249145\n249154\n249158\n249160\n249161\n249164\n249173\n249174\n249176\n249181\n249187\n249193\n249216\n249220\n249226\n249234\n249237\n249242\n249249\n249259\n249266\n249271\n249274\n249276\n249277\n249286\n249296\n249301\n249304\n249305\n249321\n249325\n249334\n249341\n249342\n249345\n249347\n249351\n249352\n249374\n249375\n249378\n249384\n249385\n249386\n249387\n249389\n249398\n249403\n249409\n249413\n249414\n249416\n249417\n249426\n249430\n249434\n249437\n249438\n249440\n249446\n249448\n249450\n249456\n249473\n249482\n249487\n249499\n249501\n249505\n249517\n249523\n249530\n249533\n249535\n249540\n249548\n249550\n249553\n249554\n249558\n249560\n249565\n249569\n249571\n249578\n249584\n249590\n249594\n249597\n249606\n249612\n249613\n249623\n249631\n249635\n249645\n249652\n249658\n249659\n249660\n249664\n249666\n249670\n249674\n249679\n249686\n249687\n249692\n249693\n249697\n249704\n249726\n249728\n249730\n249732\n249740\n249746\n249751\n249754\n249756\n249760\n249762\n249764\n249773\n249778\n249782\n249786\n249788\n249792\n249794\n249814\n249817\n249830\n249832\n249849\n249851\n249853\n249855\n249861\n249868\n249883\n249897\n249899\n249905\n249914\n249915\n249919\n249920\n249930\n249934\n249936\n249939\n249945\n249952\n249954\n249956\n249959\n249968\n249976\n249978\n249981\n249983\n249994\n249998\n250014\n250017\n250023\n250024\n250025\n250027\n250035\n250037\n250041\n250042\n250047\n250050\n250052\n250053\n250054\n250060\n250061\n250069\n250071\n250073\n250081\n250083\n250090\n250097\n250100\n250112\n250118\n250123\n250139\n250140\n250150\n250156\n250160\n250161\n250175\n250178\n250180\n250182\n250192\n250197\n250198\n250214\n250215\n250233\n250235\n250242\n250243\n250244\n250246\n250250\n250257\n250261\n250274\n250278\n250281\n250301\n250302\n250307\n250308\n250310\n250317\n250319\n250321\n250326\n250350\n250360\n250364\n250367\n250371\n250374\n250375\n250377\n250380\n250383\n250389\n250390\n250391\n250400\n250409\n250411\n250416\n250418\n250428\n250430\n250432\n250434\n250439\n250440\n250442\n250445\n250464\n250469\n250478\n250491\n250492\n250496\n250499\n250503\n250507\n250508\n250510\n250523\n250524\n250526\n250528\n250530\n250548\n250558\n250562\n250565\n250576\n250577\n250580\n250594\n250597\n250607\n250608\n250618\n250621\n250631\n250633\n250635\n250636\n250640\n250643\n250646\n250647\n250652\n250661\n250663\n250691\n250692\n250694\n250709\n250711\n250715\n250717\n250726\n250737\n250741\n250743\n250748\n250749\n250751\n250754\n250765\n250767\n250771\n250774\n250776\n250780\n250787\n250788\n250789\n250792\n250813\n250820\n250825\n250826\n250827\n250830\n250832\n250838\n250840\n250843\n250845\n250850\n250852\n250854\n250858\n250862\n250864\n250865\n250873\n250881\n250886\n250888\n250895\n250898\n250899\n250918\n250923\n250926\n250927\n250933\n250936\n250945\n250952\n250961\n250975\n250976\n250978\n250989\n251000\n251007\n251013\n251019\n251026\n251027\n251031\n251037\n251049\n251052\n251064\n251067\n251068\n251071\n"
  },
  {
    "path": "data/void_ids.csv",
    "content": "124990\n124991\n124992\n124993\n124994\n124995\n124996\n124997\n124998\n124999\n125000\n125001\n125002\n125003\n125004\n125005\n125006\n125007\n125008\n125009\n125010\n125011\n125012\n125013\n125014\n125015\n125016\n125017\n125018\n125019\n125020\n125021\n125022\n125023\n125024\n125025\n125026\n125027\n125028\n125029\n125030\n125031\n125032\n125033\n125034\n125035\n125036\n125037\n125038\n125039\n125040\n125041\n125042\n125043\n125044\n125045\n125046\n125047\n125048\n125049\n125050\n125051\n125052\n125054\n125055\n125058\n125059\n125060\n125061\n125062\n125063\n125064\n125066\n125067\n125069\n125070\n125071\n125072\n125073\n125074\n125075\n125076\n125079\n125083\n125084\n125087\n125089\n125090\n125094\n125095\n125103\n125104\n125112\n125125\n125129\n125140\n179723\n"
  },
  {
    "path": "src/benchmark/pretrain_data2vec/readme.md",
    "content": "Refer to https://github.com/facebookresearch/fairseq/tree/main/examples/data2vec."
  },
  {
    "path": "src/benchmark/pretrain_ssl/datasets/SSL4EO/ssl4eo_dataset.py",
    "content": "import numpy as np\nimport rasterio\nimport torch\nimport os\nimport cv2\nimport csv\nimport pickle\nimport torch\nimport numpy as np\nfrom torch.utils.data import Dataset, DataLoader\nimport lmdb\nfrom tqdm import tqdm\n\n\n\nALL_BANDS_S2_L2A = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B9', 'B11', 'B12']\nALL_BANDS_S2_L1C = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B9', 'B10', 'B11', 'B12']\nRGB_BANDS = ['B4', 'B3', 'B2']\nALL_BANDS_S1_GRD = ['VV','VH']\n\n\n### band statistics: mean & std\n# calculated from 50k data\nS1_MEAN = [-12.54847273, -20.19237134]\nS1_STD = [5.25697717, 5.91150917]\n\nS2A_MEAN = [752.40087073, 884.29673756, 1144.16202635, 1297.47289228, 1624.90992062, 2194.6423161, 2422.21248945, 2517.76053101, 2581.64687018, 2645.51888987, 2368.51236873, 1805.06846033]\n\nS2A_STD = [1108.02887453, 1155.15170768, 1183.6292542, 1368.11351514, 1370.265037, 1355.55390699, 1416.51487101, 1474.78900051, 1439.3086061, 1582.28010962, 1455.52084939, 1343.48379601]\n\nS2C_MEAN = [1605.57504906, 1390.78157673, 1314.8729939, 1363.52445545, 1549.44374991, 2091.74883118, 2371.7172463, 2299.90463006, 2560.29504086, 830.06605044, 22.10351321, 2177.07172323, 1524.06546312]\n\nS2C_STD = [786.78685367, 850.34818441, 875.06484736, 1138.84957046, 1122.17775652, 1161.59187054, 1274.39184232, 1248.42891965, 1345.52684884, 577.31607053, 51.15431158, 1336.09932639, 1136.53823676]\n\n# normalize: standardize + percentile\ndef normalize(img, mean, std):\n    min_value = mean - 2 * std\n    max_value = mean + 2 * std\n    img = (img - min_value) / (max_value - min_value) * 255.0\n    img = np.clip(img, 0, 255).astype(np.uint8)\n    return img\n\n\n### dataset class\nclass SSL4EO(torch.utils.data.Dataset):\n\n    def __init__(self,root, normalize=False, mode=['s1','s2a','s2c'], dtype='uint8'):\n        self.root = root\n        self.normalize = normalize\n        self.mode = mode\n        self.dtype = dtype\n        \n        self.ids = os.listdir(os.path.join(self.root,self.mode[0]))\n        self.length = len(self.ids)\n\n    def __getitem__(self,index):\n        \n        if 's1' in self.mode:\n            img_s1_4s = self.get_array(self.ids[index], 's1') # [4,2,264,264] float32 or uint8                \n        else:\n            img_s1_4s = None\n            \n        if 's2a' in self.mode:\n            img_s2a_4s = self.get_array(self.ids[index], 's2a') # [4,12,264,264] int16 or uint8\n        else:\n            img_s2a_4s = None\n            \n        if 's2c' in self.mode:\n            img_s2c_4s = self.get_array(self.ids[index], 's2c') # [4,13,264,264] int16 or uint8\n        else:\n            img_s2c_4s = None\n\n        return img_s1_4s, img_s2a_4s, img_s2c_4s\n        \n    def __len__(self):    \n        return self.length\n\n    def get_array(self, patch_id, mode):\n        data_root_patch = os.path.join(self.root, mode, patch_id)\n        patch_seasons = os.listdir(data_root_patch)\n        seasons = []\n\n        if mode=='s1':\n            bands = ALL_BANDS_S1_GRD\n            MEAN = S1_MEAN\n            STD = S1_STD\n        elif mode=='s2a':\n            bands = ALL_BANDS_S2_L2A\n            MEAN = S2A_MEAN\n            STD = S2A_STD            \n        elif mode=='s2c':\n            bands = ALL_BANDS_S2_L1C\n            MEAN = S2C_MEAN\n            STD = S2C_STD\n            \n        for patch_id_season in patch_seasons:\n            chs = []\n            for i,band in enumerate(bands):\n                patch_path = os.path.join(data_root_patch,patch_id_season,f'{band}.tif')\n                with rasterio.open(patch_path) as dataset:\n                    ch = dataset.read(1)\n                    ch = cv2.resize(ch, dsize=(264, 264), interpolation=cv2.INTER_LINEAR_EXACT) # [264,264]\n                    #coord = dataset.xy(0,0) # up left\n                    if self.normalize or (self.dtype=='uint8' and mode=='s1'):\n                        ch = normalize(ch, MEAN[i], STD[i])\n                        \n                chs.append(ch)\n            img = np.stack(chs, axis=0) # [C,264,264]\n            seasons.append(img)\n        img_4s = np.stack(seasons, axis=0) # [4,C,264,264]\n\n        if self.normalize:\n            return img_4s\n        elif self.dtype=='uint8':\n            if mode=='s1':\n                return img_4s\n            else:\n                return (img_4s / 10000.0 * 255.0).astype('uint8')\n        else:\n            if mode=='s1':                    \n                return img_4s.astype('float32')\n            else:\n                return img_4s.astype('int16')\n\n\n            \nclass Subset(Dataset):\n\n    def __init__(self, dataset, indices):\n        self.dataset = dataset\n        self.indices = indices\n\n    def __getitem__(self, idx):\n        return self.dataset[self.indices[idx]]\n\n    def __len__(self):\n        return len(self.indices)\n\n    def __getattr__(self, name):\n        return getattr(self.dataset, name)\n\n\ndef random_subset(dataset, frac, seed=None):\n    rng = np.random.default_rng(seed)\n    indices = rng.choice(range(len(dataset)), int(frac * len(dataset)))\n    return Subset(dataset, indices)\n\n\nclass _RepeatSampler(object):\n    \"\"\"\n    Sampler that repeats forever.\n    Args:\n        sampler (Sampler)\n    \"\"\"\n\n    def __init__(self, sampler):\n        self.sampler = sampler\n\n    def __iter__(self):\n        while True:\n            yield from iter(self.sampler)\n\n\nclass InfiniteDataLoader(DataLoader):\n    \"\"\"\n    Dataloader that reuses workers.\n    Uses same syntax as vanilla DataLoader.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        object.__setattr__(self, 'batch_sampler', _RepeatSampler(self.batch_sampler))\n        self.iterator = super().__iter__()\n\n    def __len__(self):\n        return len(self.batch_sampler.sampler)\n\n    def __iter__(self):\n        for i in range(len(self)):\n            yield next(self.iterator)\n\n\ndef make_lmdb(dataset, lmdb_file, num_workers=6,mode=['s1','s2a','s2c']):\n    loader = InfiniteDataLoader(dataset, num_workers=num_workers, collate_fn=lambda x: x[0])\n    #env = lmdb.open(lmdb_file, map_size=1099511627776,writemap=True) # continuously write to disk\n    env = lmdb.open(lmdb_file, map_size=1099511627776)\n    txn = env.begin(write=True)\n    for index, (s1, s2a, s2c) in tqdm(enumerate(loader), total=len(dataset), desc='Creating LMDB'):\n        if 's1' in mode:\n            sample_s1 = np.array(s1)\n        if 's2a' in mode:\n            sample_s2a = np.array(s2a)\n        if 's2c' in mode:\n            sample_s2c = np.array(s2c)\n            \n        if mode==['s1','s2a','s2c']:\n            obj = (sample_s1.tobytes(), sample_s1.shape, sample_s2a.tobytes(), sample_s2a.shape, sample_s2c.tobytes(), sample_s2c.shape)\n        elif mode==['s1']:\n            obj = (sample_s1.tobytes(), sample_s1.shape)\n        elif mode==['s2a']:\n            obj = (sample_s2a.tobytes(), sample_s2a.shape)\n        elif mode==['s2c']:\n            obj = (sample_s2c.tobytes(), sample_s2c.shape)\n            \n        txn.put(str(index).encode(), pickle.dumps(obj))            \n\n        if index % 1000 == 0:\n            txn.commit()\n            txn = env.begin(write=True)\n    txn.commit()\n\n    env.sync()\n    env.close()\n            \n            \n            \n    \nif __name__ == '__main__':\n\n    import argparse\n    import shutil\n    from tqdm import tqdm\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--root', type=str)\n    parser.add_argument('--save_path',type=str)\n    parser.add_argument('--make_lmdb_file',action='store_true',default=False)\n    parser.add_argument('--frac',type=float,default=1.0)\n    parser.add_argument('--num_workers', type=int, default=6)\n    parser.add_argument('--normalize',action='store_true',default=False)\n    parser.add_argument('--mode', nargs='*', type=str, default=['s1','s2a','s2c'])\n    parser.add_argument('--dtype',type=str, default='uint8')\n    args = parser.parse_args()\n\n    ### make lmdb dataset\n    if args.make_lmdb_file:\n        if os.path.isdir(args.save_path):\n            shutil.rmtree(args.save_path)        \n        train_dataset = SSL4EO(root=args.root, normalize=args.normalize, mode=args.mode, dtype=args.dtype)\n        train_subset = random_subset(train_dataset,frac=args.frac,seed=42)\n\n        make_lmdb(train_subset,args.save_path,num_workers=args.num_workers,mode=args.mode)\n\n    ### check dataset class\n    else:   \n        train_dataset = SSL4EO(root=args.root, transform = None)\n        train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=1, num_workers=0)\n        i=0\n        for idx, (s1,s2a,s2c) in tqdm(enumerate(train_loader),total=len(train_dataset)):\n            if idx>0:\n                break\n            print(s1.shape, s1.dtype, s2a.shape,s2a.dtype, s2c.shape, s2c.dtype)\n\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/datasets/SSL4EO/ssl4eo_dataset_lmdb.py",
    "content": "import pickle\nimport torch\nimport numpy as np\nfrom torch.utils.data import Dataset, DataLoader\nimport lmdb\nfrom tqdm import tqdm\nimport pdb\n\n### band statistics: mean & std\n# calculated from 50k subset\nS1_MEAN = [-12.54847273, -20.19237134]\nS1_STD = [5.25697717, 5.91150917]\n\nS2A_MEAN = [752.40087073, 884.29673756, 1144.16202635, 1297.47289228, 1624.90992062, 2194.6423161, 2422.21248945, 2517.76053101, 2581.64687018, 2645.51888987, 2368.51236873, 1805.06846033]\n\nS2A_STD = [1108.02887453, 1155.15170768, 1183.6292542, 1368.11351514, 1370.265037, 1355.55390699, 1416.51487101, 1474.78900051, 1439.3086061, 1582.28010962, 1455.52084939, 1343.48379601]\n\nS2C_MEAN = [1605.57504906, 1390.78157673, 1314.8729939, 1363.52445545, 1549.44374991, 2091.74883118, 2371.7172463, 2299.90463006, 2560.29504086, 830.06605044, 22.10351321, 2177.07172323, 1524.06546312]\n\nS2C_STD = [786.78685367, 850.34818441, 875.06484736, 1138.84957046, 1122.17775652, 1161.59187054, 1274.39184232, 1248.42891965, 1345.52684884, 577.31607053, 51.15431158, 1336.09932639, 1136.53823676]\n\n\ndef normalize(img, mean, std):\n    min_value = mean - 2 * std\n    max_value = mean + 2 * std\n    img = (img - min_value) / (max_value - min_value) * 255.0\n    img = np.clip(img, 0, 255).astype(np.uint8)\n    return img\n    \n    \n\nclass Subset(Dataset):\n\n    def __init__(self, dataset, indices):\n        self.dataset = dataset\n        self.indices = indices\n\n    def __getitem__(self, idx):\n        return self.dataset[self.indices[idx]]\n\n    def __len__(self):\n        return len(self.indices)\n\n    def __getattr__(self, name):\n        return getattr(self.dataset, name)\n\n\ndef random_subset(dataset, frac, seed=None):\n    rng = np.random.default_rng(seed)\n    indices = rng.choice(range(len(dataset)), int(frac * len(dataset)))\n    return Subset(dataset, indices)\n\n\nclass _RepeatSampler(object):\n    \"\"\"\n    Sampler that repeats forever.\n    Args:\n        sampler (Sampler)\n    \"\"\"\n\n    def __init__(self, sampler):\n        self.sampler = sampler\n\n    def __iter__(self):\n        while True:\n            yield from iter(self.sampler)\n\n\nclass InfiniteDataLoader(DataLoader):\n    \"\"\"\n    Dataloader that reuses workers.\n    Uses same syntax as vanilla DataLoader.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        object.__setattr__(self, 'batch_sampler', _RepeatSampler(self.batch_sampler))\n        self.iterator = super().__iter__()\n\n    def __len__(self):\n        return len(self.batch_sampler.sampler)\n\n    def __iter__(self):\n        for i in range(len(self)):\n            yield next(self.iterator)\n\n\ndef make_lmdb(dataset, lmdb_file, num_workers=6,mode=['s1','s2a','s2c']):\n    loader = InfiniteDataLoader(dataset, num_workers=num_workers, collate_fn=lambda x: x[0])\n    #env = lmdb.open(lmdb_file, map_size=1099511627776,writemap=True) # continuously write to disk\n    env = lmdb.open(lmdb_file, map_size=1099511627776)\n    txn = env.begin(write=True)\n    for index, (s1, s2a, s2c) in tqdm(enumerate(loader), total=len(dataset), desc='Creating LMDB'):\n        if 's1' in mode:\n            sample_s1 = np.array(s1)\n        if 's2a' in mode:\n            sample_s2a = np.array(s2a)\n        if 's2c' in mode:\n            sample_s2c = np.array(s2c)\n            \n        if mode==['s1','s2a','s2c']:\n            obj = (sample_s1.tobytes(), sample_s1.shape, sample_s2a.tobytes(), sample_s2a.shape, sample_s2c.tobytes(), sample_s2c.shape)\n        elif mode==['s1']:\n            obj = (sample_s1.tobytes(), sample_s1.shape)\n        elif mode==['s2a']:\n            obj = (sample_s2a.tobytes(), sample_s2a.shape)\n        elif mode==['s2c']:\n            obj = (sample_s2c.tobytes(), sample_s2c.shape)\n            \n        txn.put(str(index).encode(), pickle.dumps(obj))            \n\n        if index % 1000 == 0:\n            txn.commit()\n            txn = env.begin(write=True)\n    txn.commit()\n\n    env.sync()\n    env.close()\n\n\nclass LMDBDataset(Dataset):\n\n    def __init__(self, lmdb_file, is_slurm_job=False, s1_transform=None, s2a_transform=None, s2c_transform=None, subset=None, normalize=False, mode=['s1','s2a','s2c'], dtype='raw'):\n        self.lmdb_file = lmdb_file\n        self.s1_transform = s1_transform\n        self.s2a_transform = s2a_transform\n        self.s2c_transform = s2c_transform\n        self.is_slurm_job = is_slurm_job\n        self.subset = subset\n        self.normalize = normalize\n        self.mode = mode\n        self.dtype = dtype\n\n        if not self.is_slurm_job:\n            self.env = lmdb.open(self.lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n            with self.env.begin(write=False) as txn:\n                self.length = txn.stat()['entries']            \n        else:\n            # Workaround to have length from the start since we don't have LMDB at initialization time\n            self.env = None\n            if self.subset is not None:\n                self.length = 50000\n            else:\n                self.length = 250000\n\n    def _init_db(self):\n        \n        self.env = lmdb.open(self.lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n        with self.env.begin(write=False) as txn:\n            self.length = txn.stat()['entries']\n\n    def __getitem__(self, index):\n        if self.is_slurm_job:\n            # Delay loading LMDB data until after initialization\n            if self.env is None:\n                self._init_db()\n\n        with self.env.begin(write=False) as txn:\n            data = txn.get(str(index).encode())\n        \n        ## s1\n        if self.mode==['s1']:\n            s1_bytes, s1_shape = pickle.loads(data)\n            if self.dtype=='uint8':\n                sample_s1 = np.frombuffer(s1_bytes, dtype=np.uint8).reshape(s1_shape)\n            else:\n                sample_s1 = np.frombuffer(s1_bytes, dtype=np.float32).reshape(s1_shape)\n            if self.s1_transform is not None:\n                sample_s1 = self.s1_transform(sample_s1)\n            return sample_s1\n\n        ## s2a\n        if self.mode==['s2a']:\n            s2a_bytes, s2a_shape = pickle.loads(data)\n            if self.dtype=='uint8':\n                sample_s2a = np.frombuffer(s2a_bytes, dtype=np.uint8).reshape(s2a_shape)\n            else:\n                sample_s2a = np.frombuffer(s2a_bytes, dtype=np.int16).reshape(s2a_shape)\n                sample_s2a = (sample_s2a / 10000.0).astype(np.float32)\n            if self.s2a_transform is not None:\n                sample_s2a = self.s2a_transform(sample_s2a)\n            return sample_s2a\n        \n        ## s2c\n        if self.mode==['s2c']:\n            s2c_bytes, s2c_shape = pickle.loads(data)\n            if self.dtype=='uint8':\n                sample_s2c = np.frombuffer(s2c_bytes, dtype=np.uint8).reshape(s2c_shape)\n            else:\n                sample_s2c = np.frombuffer(s2c_bytes, dtype=np.int16).reshape(s2c_shape)\n                sample_s2c = (sample_s2c / 10000.0).astype(np.float32)\n            if self.s2c_transform is not None:\n                sample_s2c = self.s2c_transform(sample_s2c)\n            return sample_s2c\n    \n        ## s1, s2a, s2c [TBD, for 50k subset experiments]\n        if self.mode==['s1','s2a','s2c']:    \n            s1_bytes, s1_shape, s2a_bytes, s2a_shape, s2c_bytes, s2c_shape = pickle.loads(data)\n            '''\n            if self.dtype=='uint8':\n                sample_s1 = np.frombuffer(s1_bytes, dtype=np.uint8).reshape(s1_shape)\n                sample_s2a = np.frombuffer(s2a_bytes, dtype=np.uint8).reshape(s2a_shape)\n                sample_s2c = np.frombuffer(s2c_bytes, dtype=np.uint8).reshape(s2c_shape)\n            else:\n            '''\n            sample_s1 = np.frombuffer(s1_bytes, dtype=np.float32).reshape(s1_shape)\n            sample_s2a = np.frombuffer(s2a_bytes, dtype=np.int16).reshape(s2a_shape)\n            sample_s2c = np.frombuffer(s2c_bytes, dtype=np.int16).reshape(s2c_shape)\n\n            #sample_s1 = sample_s1.astype(np.float32)\n            #sample_s2a = (sample_s2a / 10000.0).astype(np.float32)\n            #sample_s2c = (sample_s2c / 10000.0).astype(np.float32)\n            \n            #if self.dtype=='uint8':\n            #    sample_s2c = (sample_s2c * 255).astype(np.uint8)\n            \n            if self.s1_transform is not None:\n                sample_s1 = self.s1_transform(sample_s1)\n            if self.s2a_transform is not None:\n                sample_s2a = self.s2a_transform(sample_s2a)\n            if self.s2c_transform is not None:\n                sample_s2c = self.s2c_transform(sample_s2c)                \n\n            return sample_s1, sample_s2a, sample_s2c\n            #return sample_s2c\n    \n    \n    def __len__(self):\n        return self.length\n\n    \n    \n\n    \n    \nif __name__ == '__main__':\n\n    \n    from cvtorchvision import cvtransforms\n    import numpy as np\n    import torch\n    import random\n    from PIL import ImageFilter\n    import random\n    import cv2\n\n    class TwoCropsTransform:\n        \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n        def __init__(self, base_transform, season='fixed'):\n            self.base_transform = base_transform\n            self.season = season\n\n        def __call__(self, x):\n\n            if self.season=='augment':\n                season1 = np.random.choice([0,1,2,3])\n                season2 = np.random.choice([0,1,2,3])\n            elif self.season=='fixed':\n                np.random.seed(42)\n                season1 = np.random.choice([0,1,2,3])\n                season2 = season1\n            elif self.season=='random':\n                season1 = np.random.choice([0,1,2,3])\n                season2 = season1\n                \n            x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n            x2 = np.transpose(x[season2,:,:,:],(1,2,0))\n\n            q = self.base_transform(x1)\n            k = self.base_transform(x2)\n\n            return [q, k]\n\n\n    class GaussianBlur(object):\n        \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n        def __init__(self, sigma=[.1, 2.]):\n            self.sigma = sigma\n\n        def __call__(self, x):\n            sigma = random.uniform(self.sigma[0], self.sigma[1])\n            #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n            #return x\n            return cv2.GaussianBlur(x,(0,0),sigma)\n\n\n    class RandomBrightness(object):\n        \"\"\" Random Brightness \"\"\"\n\n        def __init__(self, brightness=0.4):\n            self.brightness = brightness\n\n        def __call__(self, sample):\n            s = np.random.uniform(max(0, 1 - self.brightness), 1 + self.brightness)\n            img = sample * s\n\n            return img\n\n    class RandomContrast(object):\n        \"\"\" Random Contrast \"\"\"\n\n        def __init__(self, contrast=0.4):\n            self.contrast = contrast\n\n        def __call__(self, sample):\n            s = np.random.uniform(max(0, 1 - self.contrast), 1 + self.contrast)\n            mean = np.mean(sample, axis=(0, 1))\n\n            return ((sample - mean) * s + mean)\n\n    class ToGray(object):\n        def __init__(self, out_channels):\n            self.out_channels = out_channels\n        def __call__(self,sample):\n            gray_img = np.mean(sample, axis=-1)\n            gray_img = np.tile(gray_img, (self.out_channels, 1, 1))\n            gray_img = np.transpose(gray_img, [1, 2, 0])\n            return gray_img\n\n\n    class RandomChannelDrop(object):\n        \"\"\" Random Channel Drop \"\"\"\n\n        def __init__(self, min_n_drop=1, max_n_drop=8):\n            self.min_n_drop = min_n_drop\n            self.max_n_drop = max_n_drop\n\n        def __call__(self, sample):\n            n_channels = random.randint(self.min_n_drop, self.max_n_drop)\n            channels = np.random.choice(range(sample.shape[0]), size=n_channels, replace=False)\n\n            for c in channels:\n                sample[c, :, :] = 0        \n            return sample\n\n    \n    train_transforms_s1 = cvtransforms.Compose([\n        cvtransforms.RandomResizedCrop(112, scale=(0.2, 1.)),\n        cvtransforms.RandomApply([\n            RandomBrightness(0.4),\n            RandomContrast(0.4)\n        ], p=0.8),\n        cvtransforms.RandomApply([ToGray(2)], p=0.2),\n        cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.5),\n        cvtransforms.RandomHorizontalFlip(),\n        #cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),        \n        cvtransforms.ToTensor()])\n    train_transforms_s2a = cvtransforms.Compose([\n        cvtransforms.RandomResizedCrop(112, scale=(0.2, 1.)),\n        cvtransforms.RandomApply([\n            RandomBrightness(0.4),\n            RandomContrast(0.4)\n        ], p=0.8),\n        cvtransforms.RandomApply([ToGray(12)], p=0.2),\n        cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.5),\n        cvtransforms.RandomHorizontalFlip(),\n        cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),        \n        cvtransforms.ToTensor()])\n    train_transforms_s2c = cvtransforms.Compose([\n        cvtransforms.RandomResizedCrop(112, scale=(0.2, 1.)),\n        cvtransforms.RandomApply([\n            RandomBrightness(0.4),\n            RandomContrast(0.4)\n        ], p=0.8),\n        cvtransforms.RandomApply([ToGray(13)], p=0.2),\n        cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.5),\n        cvtransforms.RandomHorizontalFlip(),\n        cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),        \n        cvtransforms.ToTensor()\n    ])\n    \n    \n    train_dataset = LMDBDataset(\n        #lmdb_file='/p/scratch/hai_dm4eo/wang_yi/data/ssl4eo_50k.lmdb',\n        lmdb_file='/p/scratch/hai_ssl4eo/data/ssl4eo_s12/ssl4eo_250k_s2c_uint8.lmdb',\n        #s1_transform=TwoCropsTransform(train_transforms_s1),\n        #s2a_transform=TwoCropsTransform(train_transforms_s2a),\n        s2c_transform=TwoCropsTransform(train_transforms_s2c,season='augment'),\n        is_slurm_job=False,\n        #subset=True,\n        normalize = False,\n        mode = ['s2c'],\n        dtype='uint8'\n    )\n\n    train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=4, num_workers=0)\n    print(len(train_dataset))\n    for i, (s2c) in enumerate(train_loader):\n        if i>1:\n            break\n        #print(s1[0].shape,s1[0].dtype, s2a[1].shape, s2a[1].dtype, s2c[0].shape,s2c[1].dtype)\n        print(s2c[0].shape,s2c[0].dtype,s2c[0].mean(), s2c[1].shape,s2c[1].dtype,s2c[1].mean())\n\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/README.md",
    "content": "# data2vec\n\ndata2vec is a framework for self-supervised representation learning for images, speech, and text as described in data2vec: A General Framework for Self-supervised Learning in Speech, Vision and Language (Baevski et al., 2022). The algorithm uses the same learning mechanism for different modalities. You can read more about this work here [arxiv](https://arxiv.org/abs/2202.03555) and [fairseq repo](https://github.com/pytorch/fairseq/tree/main/examples/data2vec)\n\nFor details about how to setup your BEIT environment, please refer the original README [here](README_Original.md). Below you can find the necessary commands to reproduce the vision results reported in [data2vec: A General Framework for Self-supervised Learning in Speech, Vision and Language\n](https://arxiv.org/abs/2202.03555)\n\n## Model Checkpoints\n\nPretrained Model | Version | Link\n|---|---|---|\ndata2vec ViT-B | 800 epochs pretrained | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/base_800/checkpoint-799.pth)\ndata2vec ViT-L | 800 epochs pretrained | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/large_800/checkpoint-799.pth)\ndata2vec ViT-L | 1600 epochs pretrained | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/large_1600/checkpoint-799.pth)\ndata2vec ViT-B | Finetuned | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/finetuned_base/checkpoint-99/mp_rank_00_model_states.pt)\ndata2vec ViT-L | Finetuned | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/finetuned_large/checkpoint-49/mp_rank_00_model_states.pt)\n\n## VIT-B Pretraining and Finetuning\n\nCommand to pretrain the ViT-B model for 800 epochs\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_cyclical.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --num_mask_patches 120 \\\n        --model beit_base_patch16_224 \\\n        --seed 0 \\\n        --target_layers [6,7,8,9,10,11] \\\n        --ema_decay 0.9998 --ema_start_at 0 --ema_decay_init 0.999 \\\n        --batch_size 128 --lr 2e-3 --warmup_epochs 10 --epochs 800 \\\n        --clip_grad 3.0 --drop_path 0.25 --layer_scale_init_value 1e-4 \\\n        --layer_results 'end' \\\n        --var_w0 0.0 --var_w1 0.0 \\\n        --max_mask_patches_per_block 196 --min_mask_patches_per_block 16 \\\n        --l1_beta=2.0 \\\n        --weight_decay 0.05 \\\n        --imagenet_default_mean_and_std --dist_url $dist_url --loss_scale -1 --mask_dropout_prob -1.0 \\\n        --post_target_layer_norm --world_size 16 --attn_drop_rate 0.05 \n\n\n```\n\nCommand to finetune the ViT-B model\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n        --model beit_base_patch16_224 \\\n        --finetune $CHECKPOINT \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --batch_size 128 --lr 4e-3 --update_freq 1 \\\n        --warmup_epochs 10 --epochs 100 --layer_decay 0.65 --drop_path 0.2 --drop 0.0 \\\n        --weight_decay 0.0 --mixup 0.8 --cutmix 1.0 --enable_deepspeed --nb_classes 1000 \\\n        --target_layer -1 --world_size 8 --dist_url $dist_url \n\n```\n\n## VIT-L Pretraining and Finetuning\n\nCommand to pretrain the ViT-L model for 800 epochs\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=64 run_cyclical.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --num_mask_patches 120 \\\n        --model beit_large_patch16_224 \\\n        --seed 0 \\\n        --target_layers [18,19,20,21,22,23] \\\n        --ema_decay 0.9998 --ema_start_at 0 \\\n        --batch_size 64 --lr 1e-3 --warmup_epochs 80 --epochs 800 \\\n        --clip_grad 3.0 --drop_path 0.2 --layer_scale_init_value 1e-5 \\\n        --layer_results 'end' \\\n        --l1_beta=2 \\\n\t--var_w0 0.0 --var_w1 0.0 --var_margin0 0.5 \\\n\t--max_mask_patches_per_block 196 --min_mask_patches_per_block 16 \\\n        --imagenet_default_mean_and_std --dist_url $dist_url --world_size 64 \\\n         --post_target_layer_norm  --attn_drop_rate 0.15\n\n\n```\n\nYou further pretrain the ViT-L model for another 800 epochs with constant ema decay\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=64 run_cyclical.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --num_mask_patches 120 \\\n        --model beit_large_patch16_224 \\\n        --seed 0 \\\n        --target_layers [18,19,20,21,22,23] \\\n        --ema_decay 0.9999 --ema_start_at 0 --ema_decay_init 0.999 \\\n        --batch_size 64 --lr 1e-3 --warmup_epochs 40 --epochs 800 \\\n        --clip_grad 3.0 --drop_path 0.2 --layer_scale_init_value 1e-5 \\\n        --layer_results 'end' \\\n        --l1_beta=2 \\\n\t--var_w0 0.0 --var_w1 0.0 --var_margin0 0.5 \\\n\t--max_mask_patches_per_block 196 --min_mask_patches_per_block 16 \\\n        --imagenet_default_mean_and_std --dist_url $dist_url --world_size 64 \\\n         --post_target_layer_norm  --attn_drop_rate 0.15 \\\n         --seed_model {PATH_TO_800EPOCH_MODEL}\n\n```\n\nCommand to finetune the ViT-L model\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_cyclical.py \\\n        --model beit_large_patch16_224 \\\n        --finetune $CHECKPOINT \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --batch_size 64 --lr 5e-3 --update_freq 1 \\\n        --warmup_epochs $WARMUP --epochs 50 --layer_decay 0.65 --drop_path 0.25 --drop 0.0 \\\n        --weight_decay 0.05 --mixup 0.8 --cutmix 1.0 --enable_deepspeed --nb_classes 1000 --seed 0\\\n        --target_layer -1 --world_size 16 --dist_url $dist_url --attn_drop_rate 0.0\n\n\n```\n\n\n## LICENSE\nData2Vec is licensed under CC-BY-NC, however portions of the project are available under separate license terms: Unilm is licensed under the MIT license.\n\n## CITATION\nIf you find this repository useful, please consider citing our work:\n\n```\n@misc{https://doi.org/10.48550/arxiv.2202.03555,\n  doi = {10.48550/ARXIV.2202.03555},\n  url = {https://arxiv.org/abs/2202.03555},\n  author = {Baevski, Alexei and Hsu, Wei-Ning and Xu, Qiantong and Babu, Arun and Gu, Jiatao and Auli, Michael},\n  keywords = {Machine Learning (cs.LG), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {data2vec: A General Framework for Self-supervised Learning in Speech, Vision and Language},\n  publisher = {arXiv},\n  year = {2022},\n  copyright = {arXiv.org perpetual, non-exclusive license}\n}\n```\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/README_Original.md",
    "content": "# [BEiT: BERT Pre-Training of Image Transformers](https://arxiv.org/abs/2106.08254)\n\nOfficial PyTorch implementation and pretrained models of BEiT.\n\n- August 2021: [**BEiT**](https://huggingface.co/transformers/master/model_doc/beit.html) is on [HuggingFace](https://github.com/huggingface/transformers)\n- July 2021: BEiT-large achieves **[state-of-the-art results on ADE20K](https://paperswithcode.com/sota/semantic-segmentation-on-ade20k) (a big jump to 57.0 mIoU) for semantic segmentation**.\n- July 2021: BEiT-large achieves **state-of-the-art ImageNet top-1 accuracy (88.6%) under the setting without extra data other than ImageNet-22k**.\n- July 2021: release code and pretrained checkpoints (BEiT-base and BEiT-large)\n- June 2021: release preprint in [arXiv](https://arxiv.org/abs/2106.08254)\n\n\n---\n\n\n## Pretrained models\n\nWe provide four BEiT weights pretrained on ImageNet-22k. The models were pretrained with 224x224 resolution.\n\n- `BEiT-base`: #layer=12; hidden=768; FFN factor=4x; #head=12; patch=16x16 (#parameters: 86M)\n- `BEiT-large`: #layer=24; hidden=1024; FFN factor=4x; #head=16; patch=16x16 (#parameters: 304M)\n\nDownload checkpoints that are **self-supervised pretrained and then intermediate fine-tuned** on ImageNet-22k (recommended):\n- BEiT-base: [beit_base_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth)\n- BEiT-large: [beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth)\n\nDownload checkpoints that are **self-supervised pretrained** on ImageNet-22k:\n- BEiT-base: [beit_base_patch16_224_pt22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k.pth)\n- BEiT-large: [beit_large_patch16_224_pt22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k.pth)\n\n\n## Setup\n\n```\nalias=`whoami | cut -d'.' -f2`; docker run -it --rm --runtime=nvidia --ipc=host --privileged -v /home/${alias}:/home/${alias} pytorch/pytorch:1.7.1-cuda11.0-cudnn8-devel bash\n```\n\nFirst, clone the repo and install required packages:\n```\ngit clone https://github.com/microsoft/unilm.git\ncd unilm/beit\npip install -r requirements.txt\n```\n\nThe required packages including: [Pytorch](https://pytorch.org/) version 1.7.1, [torchvision](https://pytorch.org/vision/stable/index.html) version 0.8.2 and [Timm](https://github.com/rwightman/pytorch-image-models) version 0.3.2, etc.\n\nFor mixed-precision training, please install [apex](https://github.com/NVIDIA/apex)\n```\ngit clone https://github.com/NVIDIA/apex\ncd apex\npip install -v --disable-pip-version-check --no-cache-dir --global-option=\"--cpp_ext\" --global-option=\"--cuda_ext\" ./\n```\n\n\n## Fine-tuning on ImageNet-1k (image classification)\n\nWe summarize the validation results as follows. We also provide the fine-tuned weights and fine-tuning logs. The detailed instructions to reproduce the results can be found at [`get_started_for_image_classification.md`](get_started_for_image_classification.md).\n\n| name | initialized checkpoint | resolution | acc@1 | acc@5 | #params | weight | log |\n|------------|:----------------------------------------|:----------:|:-----:|:-----:|:-------:|-------------------|-----|\n| BEiT-base | [beit_base_patch16_224_pt22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k.pth) | 224x224 | 83.7 | 96.6 | 87M | [link](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft1k.pth) | [link](https://paste.ubuntu.com/p/79z5PncrKZ/) |\n| BEiT-base | [beit_base_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth) | 224x224 | 85.2 | 97.6 | 87M | [link](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/KqFh55cwq4/) |\n| BEiT-base | [beit_base_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth) | 384x384 | 86.8 | 98.1 | 87M | [link](https://unilm.blob.core.windows.net/beit/beit_base_patch16_384_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/jnpD4NGZQn/) |\n| BEiT-large | [beit_large_patch16_224_pt22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k.pth) | 224x224 | 86.0 | 97.6 | 304M | [link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft1k.pth) | [link](https://paste.ubuntu.com/p/r4X4gHq6W5/) |\n| BEiT-large | [beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth) | 224x224 | 87.4 | 98.3 | 304M | [link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/DpHhW5Zgk5/) |\n| BEiT-large | [beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth) | 384x384 | 88.4 | 98.6 | 305M | [link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_384_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/xKTBDwPMd2/) |\n| BEiT-large | [beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth) | 512x512 | 88.60 | 98.66 | 306M | [link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_512_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/Wsb3NwkfCR/) |\n\n\n## Fine-tuning on ADE20K (segmantic segmentation)\n\nWe summarize the validation results as follows. We also provide the fine-tuned weights and fine-tuning logs. The detailed instructions to reproduce the results can be found at [`semantic_segmentation/README.md`](semantic_segmentation/README.md).\n\n|name|initialized checkpoint|method|crop size|Lr schd|mIoU|mIoU (ms+flip)|#params|weight|log|\n|:-----------|:---------------------|:-------:|:---------:|:-------:|:----:|:--------------:|:-------:|:-------|:---:|\n|BEiT-base|[beit_base_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth)|UPerNet|640x640|160k|53.6|54.2|194M|[link](https://unilm.blob.core.windows.net/beit/beit_base_patch16_640_pt22k_ft22ktoade20k.pth)|[link](https://paste.ubuntu.com/p/sdsWCDRzk2/)|\n|BEiT-large|[beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth)|UPerNet|640x640|160k|56.7|57.0|502M|[link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_640_pt22k_ft22ktoade20k.pth)|[link](https://paste.ubuntu.com/p/FKc2cvvJsC/)|\n\n\n## Example: Pre-training BEiT-base on ImageNet-22k\n\nThe BEiT-base model can be pretrained on ImageNet-22k using a DGX-2 box (16 V100-32GB):\n\n```bash\n# Set the path to save checkpoints\nOUTPUT_DIR=/path/to/save/your_model\n# Download and extract ImageNet-22k\nDATA_PATH=/path/to/imagenet22k\n# Download the tokenizer weight from OpenAI's DALL-E\nTOKENIZER_PATH=/path/to/save/dall_e_tokenizer_weight\nmkdir -p $TOKENIZER_PATH\nwget -o $TOKENIZER_PATH/encoder.pkl https://cdn.openai.com/dall-e/encoder.pkl\nwget -o $TOKENIZER_PATH/decoder.pkl https://cdn.openai.com/dall-e/decoder.pkl\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_beit_pretraining.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --num_mask_patches 75 \\\n        --model beit_base_patch16_224_8k_vocab --discrete_vae_weight_path ${TOKENIZER_PATH} \\\n        --batch_size 128 --lr 1.5e-3 --warmup_steps 10000 --epochs 150 \\\n        --clip_grad 3.0 --drop_path 0.1 --layer_scale_init_value 0.1\n```\n- `--num_mask_patches`: number of the input patches need be masked.\n- `--batch_size`: batch size per GPU.\n- Effective batch size = `number of GPUs` * `--batch_size`. So in the above example, the effective batch size is `128*16 = 2048`.\n- `--lr`: learning rate.\n- `--warmup_steps`: learning rate warmup steps.\n- `--epochs`: total pre-training epochs.\n- `--clip_grad`: clip gradient norm.\n- `--drop_path`: stochastic depth rate.\n- `--imagenet_default_mean_and_std`: enable this for ImageNet-1k pre-training, i.e., `(0.485, 0.456, 0.406)` for mean and `(0.229, 0.224, 0.225)` for std. We use `(0.5, 0.5, 0.5)` for mean and `(0.5, 0.5, 0.5)` for std by default on other pre-training data.\n- `--layer_scale_init_value`: 0.1 for base, 1e-5 for large, set 0 to disable layerscale.\n\n## Example: Pre-training BEiT-base on ImageNet-1k\n\nThe BEiT-base model can be pretrained on ImageNet-1k using a DGX-2 box (16 V100-32GB):\n```bash\n# Set the path to save checkpoints\nOUTPUT_DIR=/path/to/save/your_model\n# Download and extract ImageNet-1k\nDATA_PATH=/path/to/imagenet1k_train_set\n# Download the tokenizer weight from OpenAI's DALL-E\nTOKENIZER_PATH=/path/to/save/dall_e_tokenizer_weight\nmkdir -p $TOKENIZER_PATH\nwget -o $TOKENIZER_PATH/encoder.pkl https://cdn.openai.com/dall-e/encoder.pkl\nwget -o $TOKENIZER_PATH/decoder.pkl https://cdn.openai.com/dall-e/decoder.pkl\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_beit_pretraining.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --num_mask_patches 75 \\\n        --model beit_base_patch16_224_8k_vocab --discrete_vae_weight_path ${TOKENIZER_PATH} \\\n        --batch_size 128 --lr 1.5e-3 --warmup_epochs 10 --epochs 300 \\\n        --clip_grad 3.0 --drop_path 0.1 --layer_scale_init_value 0.1 \\\n        --imagenet_default_mean_and_std\n```\n\n## Example: Fine-tuning BEiT on ImageNet-22k\n\nThe BEiT-large model can be fine-tuned on ImageNet-22k using a DGX-2 box (16 V100-32GB):\n\n```bash\n# Set the path to save checkpoints\nOUTPUT_DIR=/path/to/save/your_model\n# Download and extract ImageNet-22k\nDATA_PATH=/path/to/imagenet22k\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_class_finetuning.py \\\n    --model beit_large_patch16_224 --data_path $DATA_PATH \\\n    --nb_classes 21841 --data_set image_folder --disable_eval_during_finetuning \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k.pth \\\n    --output_dir $OUTPUT_DIR --batch_size 64 --lr 2e-3 --update_freq 2 \\\n    --warmup_epochs 5 --epochs 90 --layer_decay 0.75 --drop_path 0.2 \\\n    --weight_decay 0.05 --enable_deepspeed --layer_scale_init_value 1e-5 --clip_grad 1.0\n```\n- `--batch_size`: batch size per GPU.\n- Effective batch size = `number of GPUs` * `--batch_size` * `--update_freq`. So in the above example, the effective batch size is `16*64*2 = 2048`.\n- `--lr`: learning rate.\n- `--warmup_epochs`: learning rate warmup epochs.\n- `--epochs`: total pre-training epochs.\n- `--clip_grad`: clip gradient norm.\n- `--drop_path`: stochastic depth rate.\n- `--layer_scale_init_value`: 0.1 for base, 1e-5 for large, set 0 to disable layerscale.\n\nThe BEiT-base can be fine-tuned on ImageNet-22k as follows:\n\n```bash\n# Set the path to save checkpoints\nOUTPUT_DIR=/path/to/save/your_model\n# Download and extract ImageNet-22k\nDATA_PATH=/path/to/imagenet22k\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_class_finetuning.py \\\n    --model beit_base_patch16_224 --data_path $DATA_PATH \\\n    --nb_classes 21841 --data_set image_folder --disable_eval_during_finetuning \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k.pth \\\n    --output_dir $OUTPUT_DIR --batch_size 256 --lr 3e-3 --update_freq 1 \\\n    --warmup_epochs 5 --epochs 90 --layer_decay 0.65 --drop_path 0.2 \\\n    --weight_decay 0.05 --enable_deepspeed --layer_scale_init_value 0.1 --clip_grad 3.0\n```\n\n## Citation\n\nIf you find this repository useful, please consider citing our work:\n```\n@article{beit,\n      title={{BEiT}: {BERT} Pre-Training of Image Transformers}, \n      author={Hangbo Bao and Li Dong and Furu Wei},\n      year={2021},\n      eprint={2106.08254},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n\n## Acknowledgement\n\nThis repository is built using the [timm](https://github.com/rwightman/pytorch-image-models) library, the [DeiT](https://github.com/facebookresearch/deit) repository and the [Dino](https://github.com/facebookresearch/dino) repository.\n\n\n## License\nThis project is licensed under the license found in the LICENSE file in the root directory of this source tree.\n\n[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct)\n\n### Contact Information\n\nFor help or issues using BEiT models, please submit a GitHub issue.\n\nFor other communications related to UniLM AI, please contact Li Dong (`lidong1@microsoft.com`), [Furu Wei](http://gitnlp.org/) (`fuwei@microsoft.com`).\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/dall_e/__init__.py",
    "content": "import io, requests\nimport torch\nimport torch.nn as nn\n\nfrom .encoder import Encoder\nfrom .decoder import Decoder\nfrom .utils   import map_pixels, unmap_pixels\n\ndef load_model(path: str, device: torch.device = None) -> nn.Module:\n    if path.startswith('http://') or path.startswith('https://'):\n        resp = requests.get(path)\n        resp.raise_for_status()\n            \n        with io.BytesIO(resp.content) as buf:\n            return torch.load(buf, map_location=device)\n    else:\n        with open(path, 'rb') as f:\n            return torch.load(f, map_location=device)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/dall_e/decoder.py",
    "content": "import attr\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom collections  import OrderedDict\nfrom functools    import partial\nfrom .utils import Conv2d\n\n@attr.s(eq=False, repr=False)\nclass DecoderBlock(nn.Module):\n\tn_in:     int = attr.ib(validator=lambda i, a, x: x >= 1)\n\tn_out:    int = attr.ib(validator=lambda i, a, x: x >= 1 and x % 4 ==0)\n\tn_layers: int = attr.ib(validator=lambda i, a, x: x >= 1)\n\n\tdevice:        torch.device = attr.ib(default=None)\n\trequires_grad: bool         = attr.ib(default=False)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\t\tself.n_hid = self.n_out // 4\n\t\tself.post_gain = 1 / (self.n_layers ** 2)\n\n\t\tmake_conv     = partial(Conv2d, device=self.device, requires_grad=self.requires_grad)\n\t\tself.id_path  = make_conv(self.n_in, self.n_out, 1) if self.n_in != self.n_out else nn.Identity()\n\t\tself.res_path = nn.Sequential(OrderedDict([\n\t\t\t\t('relu_1', nn.ReLU()),\n\t\t\t\t('conv_1', make_conv(self.n_in,  self.n_hid, 1)),\n\t\t\t\t('relu_2', nn.ReLU()),\n\t\t\t\t('conv_2', make_conv(self.n_hid, self.n_hid, 3)),\n\t\t\t\t('relu_3', nn.ReLU()),\n\t\t\t\t('conv_3', make_conv(self.n_hid, self.n_hid, 3)),\n\t\t\t\t('relu_4', nn.ReLU()),\n\t\t\t\t('conv_4', make_conv(self.n_hid, self.n_out, 3)),]))\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\treturn self.id_path(x) + self.post_gain * self.res_path(x)\n\n@attr.s(eq=False, repr=False)\nclass Decoder(nn.Module):\n\tgroup_count:     int = 4\n\tn_init:          int = attr.ib(default=128,  validator=lambda i, a, x: x >= 8)\n\tn_hid:           int = attr.ib(default=256,  validator=lambda i, a, x: x >= 64)\n\tn_blk_per_group: int = attr.ib(default=2,    validator=lambda i, a, x: x >= 1)\n\toutput_channels: int = attr.ib(default=3,    validator=lambda i, a, x: x >= 1)\n\tvocab_size:      int = attr.ib(default=8192, validator=lambda i, a, x: x >= 512)\n\n\tdevice:              torch.device = attr.ib(default=torch.device('cpu'))\n\trequires_grad:       bool         = attr.ib(default=False)\n\tuse_mixed_precision: bool         = attr.ib(default=True)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\n\t\tblk_range  = range(self.n_blk_per_group)\n\t\tn_layers   = self.group_count * self.n_blk_per_group\n\t\tmake_conv  = partial(Conv2d, device=self.device, requires_grad=self.requires_grad)\n\t\tmake_blk   = partial(DecoderBlock, n_layers=n_layers, device=self.device,\n\t\t\t\trequires_grad=self.requires_grad)\n\n\t\tself.blocks = nn.Sequential(OrderedDict([\n\t\t\t('input', make_conv(self.vocab_size, self.n_init, 1, use_float16=False)),\n\t\t\t('group_1', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(self.n_init if i == 0 else 8 * self.n_hid, 8 * self.n_hid)) for i in blk_range],\n\t\t\t\t('upsample', nn.Upsample(scale_factor=2, mode='nearest')),\n\t\t\t]))),\n\t\t\t('group_2', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(8 * self.n_hid if i == 0 else 4 * self.n_hid, 4 * self.n_hid)) for i in blk_range],\n\t\t\t\t('upsample', nn.Upsample(scale_factor=2, mode='nearest')),\n\t\t\t]))),\n\t\t\t('group_3', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(4 * self.n_hid if i == 0 else 2 * self.n_hid, 2 * self.n_hid)) for i in blk_range],\n\t\t\t\t('upsample', nn.Upsample(scale_factor=2, mode='nearest')),\n\t\t\t]))),\n\t\t\t('group_4', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(2 * self.n_hid if i == 0 else 1 * self.n_hid, 1 * self.n_hid)) for i in blk_range],\n\t\t\t]))),\n\t\t\t('output', nn.Sequential(OrderedDict([\n\t\t\t\t('relu', nn.ReLU()),\n\t\t\t\t('conv', make_conv(1 * self.n_hid, 2 * self.output_channels, 1)),\n\t\t\t]))),\n\t\t]))\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\tif len(x.shape) != 4:\n\t\t\traise ValueError(f'input shape {x.shape} is not 4d')\n\t\tif x.shape[1] != self.vocab_size:\n\t\t\traise ValueError(f'input has {x.shape[1]} channels but model built for {self.vocab_size}')\n\t\tif x.dtype != torch.float32:\n\t\t\traise ValueError('input must have dtype torch.float32')\n\n\t\treturn self.blocks(x)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/dall_e/encoder.py",
    "content": "import attr\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom collections  import OrderedDict\nfrom functools    import partial\nfrom .utils import Conv2d\n\n@attr.s(eq=False, repr=False)\nclass EncoderBlock(nn.Module):\n\tn_in:     int = attr.ib(validator=lambda i, a, x: x >= 1)\n\tn_out:    int = attr.ib(validator=lambda i, a, x: x >= 1 and x % 4 ==0)\n\tn_layers: int = attr.ib(validator=lambda i, a, x: x >= 1)\n\n\tdevice:        torch.device = attr.ib(default=None)\n\trequires_grad: bool         = attr.ib(default=False)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\t\tself.n_hid = self.n_out // 4\n\t\tself.post_gain = 1 / (self.n_layers ** 2)\n\n\t\tmake_conv     = partial(Conv2d, device=self.device, requires_grad=self.requires_grad)\n\t\tself.id_path  = make_conv(self.n_in, self.n_out, 1) if self.n_in != self.n_out else nn.Identity()\n\t\tself.res_path = nn.Sequential(OrderedDict([\n\t\t\t\t('relu_1', nn.ReLU()),\n\t\t\t\t('conv_1', make_conv(self.n_in,  self.n_hid, 3)),\n\t\t\t\t('relu_2', nn.ReLU()),\n\t\t\t\t('conv_2', make_conv(self.n_hid, self.n_hid, 3)),\n\t\t\t\t('relu_3', nn.ReLU()),\n\t\t\t\t('conv_3', make_conv(self.n_hid, self.n_hid, 3)),\n\t\t\t\t('relu_4', nn.ReLU()),\n\t\t\t\t('conv_4', make_conv(self.n_hid, self.n_out, 1)),]))\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\treturn self.id_path(x) + self.post_gain * self.res_path(x)\n\n@attr.s(eq=False, repr=False)\nclass Encoder(nn.Module):\n\tgroup_count:     int = 4\n\tn_hid:           int = attr.ib(default=256,  validator=lambda i, a, x: x >= 64)\n\tn_blk_per_group: int = attr.ib(default=2,    validator=lambda i, a, x: x >= 1)\n\tinput_channels:  int = attr.ib(default=3,    validator=lambda i, a, x: x >= 1)\n\tvocab_size:      int = attr.ib(default=8192, validator=lambda i, a, x: x >= 512)\n\n\tdevice:              torch.device = attr.ib(default=torch.device('cpu'))\n\trequires_grad:       bool         = attr.ib(default=False)\n\tuse_mixed_precision: bool         = attr.ib(default=True)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\n\t\tblk_range  = range(self.n_blk_per_group)\n\t\tn_layers   = self.group_count * self.n_blk_per_group\n\t\tmake_conv  = partial(Conv2d, device=self.device, requires_grad=self.requires_grad)\n\t\tmake_blk   = partial(EncoderBlock, n_layers=n_layers, device=self.device,\n\t\t\t\trequires_grad=self.requires_grad)\n\n\t\tself.blocks = nn.Sequential(OrderedDict([\n\t\t\t('input', make_conv(self.input_channels, 1 * self.n_hid, 7)),\n\t\t\t('group_1', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(1 * self.n_hid, 1 * self.n_hid)) for i in blk_range],\n\t\t\t\t('pool', nn.MaxPool2d(kernel_size=2)),\n\t\t\t]))),\n\t\t\t('group_2', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(1 * self.n_hid if i == 0 else 2 * self.n_hid, 2 * self.n_hid)) for i in blk_range],\n\t\t\t\t('pool', nn.MaxPool2d(kernel_size=2)),\n\t\t\t]))),\n\t\t\t('group_3', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(2 * self.n_hid if i == 0 else 4 * self.n_hid, 4 * self.n_hid)) for i in blk_range],\n\t\t\t\t('pool', nn.MaxPool2d(kernel_size=2)),\n\t\t\t]))),\n\t\t\t('group_4', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(4 * self.n_hid if i == 0 else 8 * self.n_hid, 8 * self.n_hid)) for i in blk_range],\n\t\t\t]))),\n\t\t\t('output', nn.Sequential(OrderedDict([\n\t\t\t\t('relu', nn.ReLU()),\n\t\t\t\t('conv', make_conv(8 * self.n_hid, self.vocab_size, 1, use_float16=False)),\n\t\t\t]))),\n\t\t]))\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\tif len(x.shape) != 4:\n\t\t\traise ValueError(f'input shape {x.shape} is not 4d')\n\t\tif x.shape[1] != self.input_channels:\n\t\t\traise ValueError(f'input has {x.shape[1]} channels but model built for {self.input_channels}')\n\t\tif x.dtype != torch.float32:\n\t\t\traise ValueError('input must have dtype torch.float32')\n\n\t\treturn self.blocks(x)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/dall_e/utils.py",
    "content": "import attr\nimport math\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nlogit_laplace_eps: float = 0.1\n\n@attr.s(eq=False)\nclass Conv2d(nn.Module):\n\tn_in:  int = attr.ib(validator=lambda i, a, x: x >= 1)\n\tn_out: int = attr.ib(validator=lambda i, a, x: x >= 1)\n\tkw:    int = attr.ib(validator=lambda i, a, x: x >= 1 and x % 2 == 1)\n\n\tuse_float16:   bool         = attr.ib(default=True)\n\tdevice:        torch.device = attr.ib(default=torch.device('cpu'))\n\trequires_grad: bool         = attr.ib(default=False)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\n\t\tw = torch.empty((self.n_out, self.n_in, self.kw, self.kw), dtype=torch.float32,\n\t\t\tdevice=self.device, requires_grad=self.requires_grad)\n\t\tw.normal_(std=1 / math.sqrt(self.n_in * self.kw ** 2))\n\n\t\tb = torch.zeros((self.n_out,), dtype=torch.float32, device=self.device,\n\t\t\trequires_grad=self.requires_grad)\n\t\tself.w, self.b = nn.Parameter(w), nn.Parameter(b)\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\tif self.use_float16 and 'cuda' in self.w.device.type:\n\t\t\tif x.dtype != torch.float16:\n\t\t\t\tx = x.half()\n\n\t\t\tw, b = self.w.half(), self.b.half()\n\t\telse:\n\t\t\tif x.dtype != torch.float32:\n\t\t\t\tx = x.float()\n\n\t\t\tw, b = self.w, self.b\n\n\t\treturn F.conv2d(x, w, b, padding=(self.kw - 1) // 2)\n\ndef map_pixels(x: torch.Tensor) -> torch.Tensor:\n\tif x.dtype != torch.float:\n\t\traise ValueError('expected input to have type float')\n\n\treturn (1 - 2 * logit_laplace_eps) * x + logit_laplace_eps\n\ndef unmap_pixels(x: torch.Tensor) -> torch.Tensor:\n\tif len(x.shape) != 4:\n\t\traise ValueError('expected input to be 4d')\n\tif x.dtype != torch.float:\n\t\traise ValueError('expected input to have type float')\n\n\treturn torch.clamp((x - logit_laplace_eps) / (1 - 2 * logit_laplace_eps), 0, 1)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/dataset_folder.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Modified on torchvision code bases\n# https://github.com/pytorch/vision\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nfrom torchvision.datasets.vision import VisionDataset\n\nfrom PIL import Image\n\nimport os\nimport os.path\nimport random\nfrom typing import Any, Callable, cast, Dict, List, Optional, Tuple\n\n\ndef has_file_allowed_extension(filename: str, extensions: Tuple[str, ...]) -> bool:\n    \"\"\"Checks if a file is an allowed extension.\n\n    Args:\n        filename (string): path to a file\n        extensions (tuple of strings): extensions to consider (lowercase)\n\n    Returns:\n        bool: True if the filename ends with one of given extensions\n    \"\"\"\n    return filename.lower().endswith(extensions)\n\n\ndef is_image_file(filename: str) -> bool:\n    \"\"\"Checks if a file is an allowed image extension.\n\n    Args:\n        filename (string): path to a file\n\n    Returns:\n        bool: True if the filename ends with a known image extension\n    \"\"\"\n    return has_file_allowed_extension(filename, IMG_EXTENSIONS)\n\n\ndef make_dataset(\n    directory: str,\n    class_to_idx: Dict[str, int],\n    extensions: Optional[Tuple[str, ...]] = None,\n    is_valid_file: Optional[Callable[[str], bool]] = None,\n) -> List[Tuple[str, int]]:\n    instances = []\n    directory = os.path.expanduser(directory)\n    both_none = extensions is None and is_valid_file is None\n    both_something = extensions is not None and is_valid_file is not None\n    if both_none or both_something:\n        raise ValueError(\"Both extensions and is_valid_file cannot be None or not None at the same time\")\n    if extensions is not None:\n        def is_valid_file(x: str) -> bool:\n            return has_file_allowed_extension(x, cast(Tuple[str, ...], extensions))\n    is_valid_file = cast(Callable[[str], bool], is_valid_file)\n    for target_class in sorted(class_to_idx.keys()):\n        class_index = class_to_idx[target_class]\n        target_dir = os.path.join(directory, target_class)\n        if not os.path.isdir(target_dir):\n            continue\n        for root, _, fnames in sorted(os.walk(target_dir, followlinks=True)):\n            for fname in sorted(fnames):\n                path = os.path.join(root, fname)\n                if is_valid_file(path):\n                    item = path, class_index\n                    instances.append(item)\n    return instances\n\n\nclass DatasetFolder(VisionDataset):\n    \"\"\"A generic data loader where the samples are arranged in this way: ::\n\n        root/class_x/xxx.ext\n        root/class_x/xxy.ext\n        root/class_x/xxz.ext\n\n        root/class_y/123.ext\n        root/class_y/nsdf3.ext\n        root/class_y/asd932_.ext\n\n    Args:\n        root (string): Root directory path.\n        loader (callable): A function to load a sample given its path.\n        extensions (tuple[string]): A list of allowed extensions.\n            both extensions and is_valid_file should not be passed.\n        transform (callable, optional): A function/transform that takes in\n            a sample and returns a transformed version.\n            E.g, ``transforms.RandomCrop`` for images.\n        target_transform (callable, optional): A function/transform that takes\n            in the target and transforms it.\n        is_valid_file (callable, optional): A function that takes path of a file\n            and check if the file is a valid file (used to check of corrupt files)\n            both extensions and is_valid_file should not be passed.\n\n     Attributes:\n        classes (list): List of the class names sorted alphabetically.\n        class_to_idx (dict): Dict with items (class_name, class_index).\n        samples (list): List of (sample path, class_index) tuples\n        targets (list): The class_index value for each image in the dataset\n    \"\"\"\n\n    def __init__(\n            self,\n            root: str,\n            loader: Callable[[str], Any],\n            extensions: Optional[Tuple[str, ...]] = None,\n            transform: Optional[Callable] = None,\n            target_transform: Optional[Callable] = None,\n            is_valid_file: Optional[Callable[[str], bool]] = None,\n    ) -> None:\n        super(DatasetFolder, self).__init__(root, transform=transform,\n                                            target_transform=target_transform)\n        print(\"finding classes\")\n        classes, class_to_idx = self._find_classes(self.root)\n        print(\"making dataset\")\n        samples = make_dataset(self.root, class_to_idx, extensions, is_valid_file)\n        if len(samples) == 0:\n            msg = \"Found 0 files in subfolders of: {}\\n\".format(self.root)\n            if extensions is not None:\n                msg += \"Supported extensions are: {}\".format(\",\".join(extensions))\n            raise RuntimeError(msg)\n\n        self.loader = loader\n        self.extensions = extensions\n\n        self.classes = classes\n        self.class_to_idx = class_to_idx\n        self.samples = samples\n        self.targets = [s[1] for s in samples]\n        print(\"done initializing dataset folder\")\n\n    def _find_classes(self, dir: str) -> Tuple[List[str], Dict[str, int]]:\n        \"\"\"\n        Finds the class folders in a dataset.\n\n        Args:\n            dir (string): Root directory path.\n\n        Returns:\n            tuple: (classes, class_to_idx) where classes are relative to (dir), and class_to_idx is a dictionary.\n\n        Ensures:\n            No class is a subdirectory of another.\n        \"\"\"\n        classes = [d.name for d in os.scandir(dir) if d.is_dir()]\n        classes.sort()\n        class_to_idx = {cls_name: i for i, cls_name in enumerate(classes)}\n        return classes, class_to_idx\n\n    def __getitem__(self, index: int) -> Tuple[Any, Any]:\n        \"\"\"\n        Args:\n            index (int): Index\n\n        Returns:\n            tuple: (sample, target) where target is class_index of the target class.\n        \"\"\"\n        while True:\n            try:\n                path, target = self.samples[index]\n                sample = self.loader(path)\n                break\n            except Exception as e:\n                print(e)\n                index = random.randint(0, len(self.samples) - 1)\n\n        if self.transform is not None:\n            sample = self.transform(sample)\n        if self.target_transform is not None:\n            target = self.target_transform(target)\n\n        return sample, target\n\n    def __len__(self) -> int:\n        return len(self.samples)\n\n\nIMG_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif', '.tiff', '.webp')\n\n\ndef pil_loader(path: str) -> Image.Image:\n    # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835)\n    with open(path, 'rb') as f:\n        img = Image.open(f)\n        return img.convert('RGB')\n\n\n# TODO: specify the return type\ndef accimage_loader(path: str) -> Any:\n    import accimage\n    try:\n        return accimage.Image(path)\n    except IOError:\n        # Potentially a decoding problem, fall back to PIL.Image\n        return pil_loader(path)\n\n\ndef default_loader(path: str) -> Any:\n    from torchvision import get_image_backend\n    from shutil import copyfile\n    import os\n\n    #sp = path.split('/')\n    #name = sp[-1]\n    #base = '/'.join(sp[:-1])\n\n    #image_cache_str = \"image_cache6\"\n\n    # if os.path.exists('/scratch/'+image_cache_str+'/') and not os.access('/scratch/'+image_cache_str+'/', os.R_OK):\n    #     image_cache_str = \"image_cache3\"\n\n    #if not os.path.isdir('scratch/'+image_cache_str+'/' + base):\n    #    os.makedirs('scratch/'+image_cache_str+'/'+ base)\n\n    #if not os.path.exists('scratch/'+image_cache_str+'/' + path):\n    #    copyfile(path, 'scratch/'+image_cache_str+'/' + path)\n    #path = 'scratch/'+image_cache_str+'/' + path\n    #print('name', name)\n    #print('base', base)\n    #print('path', path)\n\n    if get_image_backend() == 'accimage':\n        return accimage_loader(path)\n    else:\n        return pil_loader(path)\n\n\nclass ImageFolder(DatasetFolder):\n    \"\"\"A generic data loader where the images are arranged in this way: ::\n\n        root/dog/xxx.png\n        root/dog/xxy.png\n        root/dog/xxz.png\n\n        root/cat/123.png\n        root/cat/nsdf3.png\n        root/cat/asd932_.png\n\n    Args:\n        root (string): Root directory path.\n        transform (callable, optional): A function/transform that  takes in an PIL image\n            and returns a transformed version. E.g, ``transforms.RandomCrop``\n        target_transform (callable, optional): A function/transform that takes in the\n            target and transforms it.\n        loader (callable, optional): A function to load an image given its path.\n        is_valid_file (callable, optional): A function that takes path of an Image file\n            and check if the file is a valid file (used to check of corrupt files)\n\n     Attributes:\n        classes (list): List of the class names sorted alphabetically.\n        class_to_idx (dict): Dict with items (class_name, class_index).\n        imgs (list): List of (image path, class_index) tuples\n    \"\"\"\n\n    def __init__(\n            self,\n            root: str,\n            transform: Optional[Callable] = None,\n            target_transform: Optional[Callable] = None,\n            loader: Callable[[str], Any] = default_loader,\n            is_valid_file: Optional[Callable[[str], bool]] = None,\n            filter: Optional[str] = None\n    ):\n        super(ImageFolder, self).__init__(root, loader, IMG_EXTENSIONS if is_valid_file is None else None,\n                                          transform=transform,\n                                          target_transform=target_transform,\n                                          is_valid_file=is_valid_file)\n        self.imgs = self.samples\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/datasets.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport os\nimport torch\nimport numpy as np\n\nfrom torchvision import datasets, transforms\n\n\nfrom timm.data import create_transform\n\nfrom .dall_e.utils import map_pixels\nfrom .masking_generator import MaskingGenerator\nfrom .dataset_folder import ImageFolder\nfrom PIL import Image\nfrom models.moco_v3 import loader as moco_loader\nfrom datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\nfrom sklearn.model_selection import train_test_split\n\n\nfrom cvtorchvision import cvtransforms\n\n\n\nclass SeasonTransform:\n\n    def __init__(self, base_transform, season='fixed'):\n        self.base_transform = base_transform\n        self.season = season\n\n    def __call__(self, x):\n\n        if self.season=='augment':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = np.random.choice([0,1,2,3])\n            \n            x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n            x2 = np.transpose(x[season2,:,:,:],(1,2,0))            \n            image = self.base_transform(x1)\n            #target = self.base_transform2(x2)\n            return image, target\n            \n        elif self.season=='fixed':\n            np.random.seed(42)\n            season1 = np.random.choice([0,1,2,3])\n\n        elif self.season=='random':\n            season1 = np.random.choice([0,1,2,3])\n\n        x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n        image = self.base_transform(x1)\n        return image\n\nclass DataAugmentations(object):\n    def __init__(self, args):\n        if args.aug_level == 0:\n            print(\"Please\")\n            base_transform = transforms.Compose([\n                cvtransforms.CenterCrop(size=args.in_size), \n            ])\n            \n        elif args.aug_level == 1:\n            base_transform = transforms.Compose([\n                cvtransforms.CenterCrop(size=args.in_size), \n                cvtransforms.RandomHorizontalFlip()\n            ])\n        elif args.aug_level == 2:\n            base_transform = transforms.Compose([\n                cvtransforms.RandomResizedCrop(args.in_size, scale=(args.crop_min, 1.)), \n                cvtransforms.RandomHorizontalFlip()\n            ])\n        elif args.aug_level == 3:\n            base_transform = transforms.Compose([\n                cvtransforms.RandomResizedCrop(args.in_size, scale=(args.crop_min, 1.)),\n                cvtransforms.RandomApply([\n                    RandomBrightness(0.4),\n                    RandomContrast(0.4)\n                ], p=0.8),\n                cvtransforms.RandomApply([ToGray(13)], p=0.2),\n                cvtransforms.RandomApply([moco_loader.GaussianBlur([.1, 2.])], p=1.0),\n                cvtransforms.RandomHorizontalFlip(),\n                cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),  \n            ])  \n        else:\n            base_transform = transforms.Compose([cvtransforms.ToTensor()])\n            \n        self.common_transform = SeasonTransform(base_transform, season=args.season)\n        \n        self.patch_transform = transforms.Compose([\n                cvtransforms.ToTensor()\n                #transforms.Normalize(\n                #    mean=torch.tensor(0),\n                #    std=torch.tensor(1))\n            ])\n        \n        if getattr(args, 'discrete_vae_type', None) is None:\n            self.visual_token_transform = lambda z: z\n        elif args.discrete_vae_type == \"dall-e\":\n            self.visual_token_transform = transforms.Compose([\n                transforms.ToTensor(),\n                map_pixels,\n            ])\n        elif args.discrete_vae_type == \"customized\":\n            self.visual_token_transform = transforms.Compose([\n                transforms.ToTensor(),\n                transforms.Normalize(\n                    mean=IMAGENET_INCEPTION_MEAN,\n                    std=IMAGENET_INCEPTION_STD,\n                ),\n            ])\n        else:\n            raise NotImplementedError()\n        \n        self.masked_position_generator = MaskingGenerator(\n            args.window_size, num_masking_patches=args.num_mask_patches,\n            max_num_patches=args.max_mask_patches_per_block,\n            min_num_patches=args.min_mask_patches_per_block,\n        )\n    \n    def __call__(self, image):\n        z = self.common_transform(image)\n        if isinstance(z, tuple):\n            for_patches, for_visual_tokens = z\n            return \\\n                self.patch_transform(for_patches), self.visual_token_transform(for_visual_tokens), \\\n                self.masked_position_generator()\n        else:\n            return self.patch_transform(z), self.masked_position_generator()\n\n\n    def __repr__(self):\n        repr = \"(DataAugmentationForBEiT,\\n\"\n        repr += \"  common_transform = %s,\\n\" % str(self.common_transform)\n        repr += \"  patch_transform = %s,\\n\" % str(self.patch_transform)\n        repr += \"  visual_tokens_transform = %s,\\n\" % str(self.visual_token_transform)\n        repr += \"  Masked position generator = %s,\\n\" % str(self.masked_position_generator)\n        repr += \")\"\n        return repr\n\n    \n\ndef build_beit_pretraining_dataset(args):\n    transform = DataAugmentations(args)\n    train_dataset = LMDBDataset(\n        lmdb_file=args.data_path,\n        s2c_transform=transform,#TwoCropsTransform(base_transform1=cvtransforms.Compose(augmentation1), base_transform2 = cvtransforms.Compose(augmentation2),season=args.season),\n        is_slurm_job=False,#args.is_slurm_job,\n        normalize=False,\n        dtype=args.dtype,\n        mode=args.mode\n    )\n    return train_dataset\n    \n\n        \n\ndef build_transform(is_train, args):\n    resize_im = args.input_size > 32\n    imagenet_default_mean_and_std = args.imagenet_default_mean_and_std\n    mean = IMAGENET_INCEPTION_MEAN if not imagenet_default_mean_and_std else IMAGENET_DEFAULT_MEAN\n    std = IMAGENET_INCEPTION_STD if not imagenet_default_mean_and_std else IMAGENET_DEFAULT_STD\n\n    if is_train:\n        # this should always dispatch to transforms_imagenet_train\n        transform = create_transform(\n            input_size=args.input_size,\n            is_training=True,\n            color_jitter=args.color_jitter,\n            auto_augment=args.aa,\n            interpolation=args.train_interpolation,\n            re_prob=args.reprob,\n            re_mode=args.remode,\n            re_count=args.recount,\n            mean=mean,\n            std=std,\n        )\n        if not resize_im:\n            # replace RandomResizedCropAndInterpolation with\n            # RandomCrop\n            transform.transforms[0] = transforms.RandomCrop(\n                args.input_size, padding=4)\n        return transform\n\n    t = []\n    if resize_im:\n        if args.crop_pct is None:\n            if args.input_size < 384:\n                args.crop_pct = 224 / 256\n            else:\n                args.crop_pct = 1.0\n        size = int(args.input_size / args.crop_pct)\n        t.append(\n            transforms.Resize(size, interpolation=3),  # to maintain same ratio w.r.t. 224 images\n        )\n        t.append(transforms.CenterCrop(args.input_size))\n\n    t.append(transforms.ToTensor())\n    t.append(transforms.Normalize(mean, std))\n    return transforms.Compose(t)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/engine_for_cyclical.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport sys\nfrom typing import Iterable\n\nimport torch\nimport torch.nn.functional as F\n\nfrom . import utils\n\n\ndef train_one_epoch(model: torch.nn.Module, model_ema: torch.nn.Module, ema_start_at, decay_init, decay, target_layers,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,     \n                    l1_beta: float = 0.12,\n                    log_writer=None, lr_scheduler=None, start_steps=None,\n                    lr_schedule_values=None, wd_schedule_values=None, l2_loss=False, layer_results='end',\n                    var_w0=0, var_w1=0, var_margin0=0.5, var_margin1=0.5, start_lr_decay_at_step=-1,loss_scale=-1, mask_dropout_prob=-1.0,\n                    target_layer_norm_last=True, target_batch_norm=False, target_instance_norm=False,post_target_instance_norm=False,post_target_layer_norm=False):\n    print(' <<<<<<<< layer_results >>>>>>>>', layer_results)\n    print(' <<<<<<<< var_w0, var_w1 >>>>>>>>', var_w0, var_w1)\n    model.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('min_lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('loss_var0', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    # metric_logger.add_meter('loss_var1', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 10\n\n    cur_decay = decay\n    for step, batch in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n    #for batch in data_loader:\n        # assign learning rate & weight decay for each step\n        it = start_steps + step  # global training iteration\n        if lr_schedule_values is not None or wd_schedule_values is not None:\n            for i, param_group in enumerate(optimizer.param_groups):\n                if lr_schedule_values is not None:\n                    param_group[\"lr\"] = lr_schedule_values[it] * param_group[\"lr_scale\"]\n                if wd_schedule_values is not None and param_group[\"weight_decay\"] > 0:\n                    param_group[\"weight_decay\"] = wd_schedule_values[it]\n\n        if it < ema_start_at:\n            cur_decay = decay_init + it * (decay - decay_init) / ema_start_at \n        \n        samples, bool_masked_pos = batch\n        samples = samples.to(device, non_blocking=True)\n        bool_masked_pos = bool_masked_pos.to(device, non_blocking=True)\n\n        if mask_dropout_prob > 0:\n            new_mask_tensor = torch.ones_like(bool_masked_pos, dtype=samples.dtype)\n            new_mask_tensor.fill_(1-mask_dropout_prob)\n            bool_new_mask_tensor = torch.bernoulli(new_mask_tensor)\n            bool_masked_pos = torch.logical_and(bool_new_mask_tensor, bool_masked_pos)\n        \n        with torch.no_grad():\n            targets = model_ema.module(samples, bool_masked_pos=None, return_all_tokens=True, layer_results=layer_results)\n            fsz = targets[0].size(-1)\n            #shape of targets[0] == b x t x dim\n            layer_vals = [targets[i] for i in target_layers]\n            \n            if target_instance_norm or target_batch_norm:\n                layer_vals = [val.permute(0,2,1) for val in layer_vals] # btc => bct\n\n            if target_batch_norm:\n                layer_vals = [F.batch_norm(val.float(), running_mean=None, running_var=None, training=True) for val in layer_vals] # bct => bct\n\n            if target_instance_norm:\n                layer_vals = [F.instance_norm(val.float()) for val in layer_vals] # bct => bct\n            \n            if target_instance_norm or target_batch_norm:\n                layer_vals = [val.permute(0,2,1) for val in layer_vals] # bct => btc\n\n            if target_layer_norm_last:\n                layer_vals = (F.layer_norm(val.float(), (fsz,)) for val in layer_vals)\n\n            targets = sum(layer_vals) / len(target_layers)\n\n            if post_target_instance_norm:\n                targets = targets.permute(0,2,1)\n                targets = F.instance_norm(targets.float())\n                targets = targets.permute(0,2,1)\n\n            if post_target_layer_norm:\n                targets = F.layer_norm(targets.float(), (fsz,))\n\n            fsz = targets.size(-1)\n            target_mask = bool_masked_pos.flatten().bool()\n            targets = targets.reshape(-1, fsz)[target_mask]\n\n        with torch.cuda.amp.autocast():\n            outputs = model(samples, bool_masked_pos=bool_masked_pos, return_all_tokens=False)\n\n        outputs = outputs.float()\n\n        eps=1e-6\n        z0 = outputs.reshape(-1, outputs.size(-1))\n        z0 = torch.sqrt(z0.var(dim=0) + eps)\n\n        if var_w0 > 0:\n            std_loss0 = torch.sum(F.relu(var_margin0 - z0)) / z0.size(0)\n        else:\n            std_loss0 = 0\n\n        # z1 = torch.sqrt(outputs.var(dim=1) + eps)\n        # std_loss1 = torch.sum(F.relu(var_margin1 - z1)) / outputs.size(0)\n\n        # print(outputs.shape)\n        outputs = outputs.reshape(-1, fsz)\n        assert outputs.shape == targets.shape\n        if l2_loss:\n            loss_cyc = F.mse_loss(outputs, targets)\n        else:\n            loss_cyc = F.smooth_l1_loss(outputs, targets, beta=l1_beta)\n\n        # loss = loss_cyc + std_loss0 * var_w0 + std_loss1 * var_w1\n        loss = loss_cyc + std_loss0 * var_w0 \n        if loss_scale!=-1:\n            loss = loss * loss_scale\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value), force=True)\n            sys.exit(1)\n\n        optimizer.zero_grad()\n        # this attribute is added by timm on one optimizer (adahessian)\n        is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order\n        grad_norm = loss_scaler(loss, optimizer, clip_grad=max_norm,\n                                parameters=model.parameters(), create_graph=is_second_order)\n        loss_scale_value = loss_scaler.state_dict()[\"scale\"]\n\n        # if it == ema_start_at and ema_start_at > 0:\n        #     print(f\"setting EMA to model params at update {it}\")\n        #     model_ema.set(model)\n        # elif it >= ema_start_at:\n        #     model_ema.update(model)\n        if cur_decay!=1 and (start_lr_decay_at_step==-1 or it<=start_lr_decay_at_step):\n            model_ema._update(model, update_fn=lambda e, m: cur_decay * e + (1. - cur_decay) * m)\n        else:\n            cur_decay=0\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        metric_logger.update(loss_scale=loss_scale_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n        metric_logger.update(min_lr=min_lr)\n        metric_logger.update(loss_var0=std_loss0)\n        # metric_logger.update(loss_var1=std_loss1)\n        weight_decay_value = None\n        for group in optimizer.param_groups:\n            if group[\"weight_decay\"] > 0:\n                weight_decay_value = group[\"weight_decay\"]\n        metric_logger.update(weight_decay=weight_decay_value)\n        metric_logger.update(grad_norm=grad_norm)\n        metric_logger.update(cur_decay=cur_decay)\n\n        if log_writer is not None:\n            log_writer.update(loss=loss_value, head=\"loss\")\n            # log_writer.update(std_loss0=std_loss0.item(), head=\"std_loss0\")\n            # log_writer.update(std_loss1=std_loss1.item(), head=\"std_loss1\")\n            log_writer.update(loss_scale=loss_scale_value, head=\"opt\")\n            log_writer.update(lr=max_lr, head=\"opt\")\n            log_writer.update(min_lr=min_lr, head=\"opt\")\n            log_writer.update(weight_decay=weight_decay_value, head=\"opt\")\n            log_writer.update(grad_norm=grad_norm, head=\"opt\")\n            log_writer.update(cur_decay=cur_decay, head=\"cur_decay\")\n\n            log_writer.set_step()\n\n        if lr_scheduler is not None:\n            lr_scheduler.step_update(start_steps + step)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/engine_for_cyclical_joint.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport sys\nfrom typing import Iterable\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nimport utils\n\n\ndef train_one_epoch(model: torch.nn.Module, model_ema: torch.nn.Module, ema_start_at, target_layers,\n                    d_vae: torch.nn.Module, vae_loss_weight: float,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0, l1_beta: float = 0.12,\n                    log_writer=None, lr_scheduler=None, start_steps=None,\n                    lr_schedule_values=None, wd_schedule_values=None, l2_loss=False):\n    model.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('min_lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('loss_cyc', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('loss_beit', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 10\n\n    for step, (batch, _) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n        # assign learning rate & weight decay for each step\n        it = start_steps + step  # global training iteration\n        if lr_schedule_values is not None or wd_schedule_values is not None:\n            for i, param_group in enumerate(optimizer.param_groups):\n                if lr_schedule_values is not None:\n                    param_group[\"lr\"] = lr_schedule_values[it] * param_group[\"lr_scale\"]\n                if wd_schedule_values is not None and param_group[\"weight_decay\"] > 0:\n                    param_group[\"weight_decay\"] = wd_schedule_values[it]\n\n        samples, images, bool_masked_pos = batch\n\n        images = images.to(device, non_blocking=True)\n        samples = samples.to(device, non_blocking=True)\n        bool_masked_pos = bool_masked_pos.to(device, non_blocking=True)\n\n        with torch.no_grad():\n            targets = model_ema.module(samples, bool_masked_pos=None, return_all_tokens=True, layer_results=True)\n            fsz = targets[0].size(-1)\n\n            targets = sum(F.layer_norm(targets[i], (fsz,)) for i in target_layers) / len(target_layers)\n\n            fsz = targets.size(-1)\n            target_mask = bool_masked_pos.flatten().bool()\n            targets = targets.reshape(-1, fsz)[target_mask]\n\n            # beit part\n            input_ids = d_vae.get_codebook_indices(images).flatten(1)\n            bool_masked_pos = bool_masked_pos.flatten(1).to(torch.bool)\n            labels = input_ids[bool_masked_pos]\n\n        with torch.cuda.amp.autocast():\n            outputs, beit_outputs = model(samples, bool_masked_pos=bool_masked_pos, return_all_tokens=False)\n            outputs = outputs.reshape(-1, fsz)\n            assert outputs.shape == targets.shape\n            if l2_loss:\n                cyc_loss = F.mse_loss(outputs, targets)\n            else:\n                cyc_loss = F.smooth_l1_loss(outputs, targets, beta=l1_beta)\n\n            # beit part\n            beit_loss = nn.CrossEntropyLoss()(input=beit_outputs, target=labels)\n\n        # loss = cyc_loss / (vae_loss_weight + 1) + beit_loss * vae_loss_weight / (vae_loss_weight + 1)\n        beit_w = max(1 - (epoch / vae_loss_weight), 0)\n        loss = cyc_loss * (1 - beit_w) + beit_loss * beit_w\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        optimizer.zero_grad()\n        # this attribute is added by timm on one optimizer (adahessian)\n        is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order\n        grad_norm = loss_scaler(loss, optimizer, clip_grad=max_norm,\n                                parameters=model.parameters(), create_graph=is_second_order)\n        loss_scale_value = loss_scaler.state_dict()[\"scale\"]\n\n        if it == ema_start_at and ema_start_at > 0:\n            print(f\"setting EMA to model params at update {it}\")\n            model_ema.set(model)\n        elif it >= ema_start_at:\n            model_ema.update(model)\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        metric_logger.update(loss_scale=loss_scale_value)\n        metric_logger.update(loss_cyc=cyc_loss.item())\n        metric_logger.update(loss_beit=beit_loss.item())\n        # metric_logger.update(loss_cyc=cyc_loss.item(), head=\"loss_cyc\")\n        # metric_logger.update(loss_beit=beit_loss.item(), head=\"loss_beit\")\n\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n        metric_logger.update(min_lr=min_lr)\n        weight_decay_value = None\n        for group in optimizer.param_groups:\n            if group[\"weight_decay\"] > 0:\n                weight_decay_value = group[\"weight_decay\"]\n        metric_logger.update(weight_decay=weight_decay_value)\n        metric_logger.update(grad_norm=grad_norm)\n\n        if log_writer is not None:\n            log_writer.update(loss=loss_value, head=\"loss\")\n            log_writer.update(loss=cyc_loss.item(), head=\"loss_cyc\")\n            log_writer.update(loss=beit_loss.item(), head=\"loss_beit\")\n            log_writer.update(loss_scale=loss_scale_value, head=\"opt\")\n            log_writer.update(lr=max_lr, head=\"opt\")\n            log_writer.update(min_lr=min_lr, head=\"opt\")\n            log_writer.update(weight_decay=weight_decay_value, head=\"opt\")\n            log_writer.update(grad_norm=grad_norm, head=\"opt\")\n\n            log_writer.set_step()\n\n        if lr_scheduler is not None:\n            lr_scheduler.step_update(start_steps + step)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/engine_for_finetuning.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy, ModelEma\nfrom sklearn.metrics import average_precision_score\n\n\nfrom . import utils\n\n\ndef train_class_batch(model, samples, target, criterion, bool_masked_pos=None):\n    outputs = model(samples, bool_masked_pos=bool_masked_pos)\n    loss = criterion(outputs, target)\n    return loss, outputs\n\n\ndef get_loss_scale_for_deepspeed(model):\n    optimizer = model.optimizer\n    return optimizer.loss_scale if hasattr(optimizer, \"loss_scale\") else optimizer.cur_scale\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    model_ema: Optional[ModelEma] = None, mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    start_steps=None, lr_schedule_values=None, wd_schedule_values=None,\n                    num_training_steps_per_epoch=None, update_freq=None, masked_position_generator=None, metric='acc', padd=False, onehot=False):\n    model.train(True)\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('min_lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 10\n\n    if loss_scaler is None:\n        model.zero_grad()\n        model.micro_steps = 0\n    else:\n        optimizer.zero_grad()\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n        if onehot:\n            targets = torch.argmax(targets, axis=1).long()\n        if padd:\n            b_zeros = torch.zeros((samples.shape[0],1,samples.shape[2],samples.shape[3]),dtype=torch.float32)\n            samples = torch.cat((samples[:,:10,:,:],b_zeros,samples[:,10:,:,:]),dim=1)\n        \n        step = data_iter_step // update_freq\n        if step >= num_training_steps_per_epoch:\n            continue\n        it = start_steps + step  # global training iteration\n        # Update LR & WD for the first acc\n        if lr_schedule_values is not None or wd_schedule_values is not None and data_iter_step % update_freq == 0:\n            for i, param_group in enumerate(optimizer.param_groups):\n                if lr_schedule_values is not None:\n                    param_group[\"lr\"] = lr_schedule_values[it] * param_group[\"lr_scale\"]\n                if wd_schedule_values is not None and param_group[\"weight_decay\"] > 0:\n                    param_group[\"weight_decay\"] = wd_schedule_values[it]\n\n        bool_masked_pos = None\n        if masked_position_generator is not None:\n            bool_masked_pos = torch.tensor([masked_position_generator() for _ in range(samples.size(0))], device=device)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n\n        if loss_scaler is None:\n            samples = samples.half()\n            loss, output = train_class_batch(\n                model, samples, targets, criterion, bool_masked_pos)\n        else:\n            with torch.cuda.amp.autocast():\n                loss, output = train_class_batch(\n                    model, samples, targets, criterion, bool_masked_pos)\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value), force=True)\n            sys.exit(1)\n\n        if loss_scaler is None:\n            loss /= update_freq\n            model.backward(loss)\n            model.step()\n\n            if (data_iter_step + 1) % update_freq == 0:\n                # model.zero_grad()\n                # Deepspeed will call step() & model.zero_grad() automatic\n                if model_ema is not None:\n                    model_ema.update(model)\n            grad_norm = None\n            loss_scale_value = get_loss_scale_for_deepspeed(model)\n        else:\n            # this attribute is added by timm on one optimizer (adahessian)\n            is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order\n            loss /= update_freq\n            grad_norm = loss_scaler(loss, optimizer, clip_grad=max_norm,\n                                    parameters=model.parameters(), create_graph=is_second_order,\n                                    update_grad=(data_iter_step + 1) % update_freq == 0)\n            if (data_iter_step + 1) % update_freq == 0:\n                optimizer.zero_grad()\n                if model_ema is not None:\n                    model_ema.update(model)\n            loss_scale_value = loss_scaler.state_dict()[\"scale\"]\n\n        torch.cuda.synchronize()\n\n        #if mixup_fn is None:\n        if metric == 'acc':\n            class_acc = (output.max(-1)[-1] == targets).float().mean()\n        elif metric == 'map':\n            class_acc = average_precision_score(targets.cpu().detach().numpy(), output.cpu().detach().numpy(), average='micro') \n        #else:\n        #    class_acc = None\n            \n            \n        metric_logger.update(loss=loss_value)\n        metric_logger.update(class_acc=class_acc)\n        metric_logger.update(loss_scale=loss_scale_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n        metric_logger.update(min_lr=min_lr)\n        weight_decay_value = None\n        for group in optimizer.param_groups:\n            if group[\"weight_decay\"] > 0:\n                weight_decay_value = group[\"weight_decay\"]\n        metric_logger.update(weight_decay=weight_decay_value)\n        metric_logger.update(grad_norm=grad_norm)\n\n        if log_writer is not None:\n            log_writer.update(loss=loss_value, head=\"loss\")\n            log_writer.update(class_acc=class_acc, head=\"loss\")\n            log_writer.update(loss_scale=loss_scale_value, head=\"opt\")\n            log_writer.update(lr=max_lr, head=\"opt\")\n            log_writer.update(min_lr=min_lr, head=\"opt\")\n            log_writer.update(weight_decay=weight_decay_value, head=\"opt\")\n            log_writer.update(grad_norm=grad_norm, head=\"opt\")\n\n            log_writer.set_step()\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device, metric='acc', padd=False, onehot=False):\n    if metric == 'acc':\n        criterion = torch.nn.CrossEntropyLoss()\n    elif metric == 'map':\n        criterion = torch.nn.MultiLabelSoftMarginLoss()\n\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n         \n        images = batch[0]\n        if padd:\n            b_zeros = torch.zeros((images.shape[0],1,images.shape[2],images.shape[3]),dtype=torch.float32)\n            images = torch.cat((images[:,:10,:,:],b_zeros,images[:,10:,:,:]),dim=1)\n        \n        target = batch[-1]\n        \n        if onehot:\n            target = torch.argmax(target, axis=1).long()\n            \n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, target)\n        \n        if metric == 'acc':\n            acc1, acc5 = accuracy(output, target, topk=(1, 5))\n        elif metric == 'map':\n            acc1 = average_precision_score(target.cpu().detach().numpy(), output.cpu().detach().numpy(), average='micro') \n            acc5 = acc1\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/engine_for_pretraining.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\nimport math\nimport sys\nfrom typing import Iterable\n\nimport torch\nimport torch.nn as nn\n\nimport utils\n\n\ndef train_one_epoch(model: torch.nn.Module, d_vae: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    log_writer=None, lr_scheduler=None, start_steps=None,\n                    lr_schedule_values=None, wd_schedule_values=None):\n    model.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('min_lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 10\n\n    for step, (batch, _) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n        # assign learning rate & weight decay for each step\n        it = start_steps + step  # global training iteration\n        if lr_schedule_values is not None or wd_schedule_values is not None:\n            for i, param_group in enumerate(optimizer.param_groups):\n                if lr_schedule_values is not None:\n                    param_group[\"lr\"] = lr_schedule_values[it] * param_group[\"lr_scale\"]\n                if wd_schedule_values is not None and param_group[\"weight_decay\"] > 0:\n                    param_group[\"weight_decay\"] = wd_schedule_values[it]\n\n        samples, images, bool_masked_pos = batch\n\n        images = images.to(device, non_blocking=True)\n        samples = samples.to(device, non_blocking=True)\n        bool_masked_pos = bool_masked_pos.to(device, non_blocking=True)\n\n        with torch.no_grad():\n            input_ids = d_vae.get_codebook_indices(images).flatten(1)\n            bool_masked_pos = bool_masked_pos.flatten(1).to(torch.bool)\n            labels = input_ids[bool_masked_pos]\n\n        with torch.cuda.amp.autocast():\n            outputs = model(samples, bool_masked_pos=bool_masked_pos, return_all_tokens=False)\n            loss = nn.CrossEntropyLoss()(input=outputs, target=labels)\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        optimizer.zero_grad()\n        # this attribute is added by timm on one optimizer (adahessian)\n        is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order\n        grad_norm = loss_scaler(loss, optimizer, clip_grad=max_norm,\n                                parameters=model.parameters(), create_graph=is_second_order)\n        loss_scale_value = loss_scaler.state_dict()[\"scale\"]\n\n        torch.cuda.synchronize()\n\n        mlm_acc = (outputs.max(-1)[1] == labels).float().mean().item()\n\n        metric_logger.update(mlm_acc=mlm_acc)\n        if log_writer is not None:\n            log_writer.update(mlm_acc=mlm_acc, head=\"loss\")\n\n        metric_logger.update(loss=loss_value)\n        metric_logger.update(loss_scale=loss_scale_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n        metric_logger.update(min_lr=min_lr)\n        weight_decay_value = None\n        for group in optimizer.param_groups:\n            if group[\"weight_decay\"] > 0:\n                weight_decay_value = group[\"weight_decay\"]\n        metric_logger.update(weight_decay=weight_decay_value)\n        metric_logger.update(grad_norm=grad_norm)\n\n        if log_writer is not None:\n            log_writer.update(loss=loss_value, head=\"loss\")\n            log_writer.update(loss_scale=loss_scale_value, head=\"opt\")\n            log_writer.update(lr=max_lr, head=\"opt\")\n            log_writer.update(min_lr=min_lr, head=\"opt\")\n            log_writer.update(weight_decay=weight_decay_value, head=\"opt\")\n            log_writer.update(grad_norm=grad_norm, head=\"opt\")\n\n            log_writer.set_step()\n\n        if lr_scheduler is not None:\n            lr_scheduler.step_update(start_steps + step)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/get_started_for_image_classification.md",
    "content": "# Fine-tuning BEiT on ImageNet-1k (image classification)\n\n## Setup\n\n1. [Setup environment](README.md#setup).\n2. Download and extract ImageNet-1k from http://image-net.org/.\n\nThe directory structure is the standard layout of torchvision's [`datasets.ImageFolder`](https://pytorch.org/docs/stable/torchvision/datasets.html#imagefolder). The training and validation data are expected to be in the `train/` folder and `val` folder, respectively:\n\n```\n/path/to/imagenet/\n  train/\n    class1/\n      img1.jpeg\n    class2/\n      img2.jpeg\n  val/\n    class1/\n      img3.jpeg\n    class/2\n      img4.jpeg\n```\n\n\n## Fine-tuning\n\nWe recommend you to use the checkpoints that are **self-supervised pretrained and then intermediate fine-tuned** on ImageNet-22k for better performance. We use following commands to fine-tune BEiT-large with 8 V100-16GB cards:\n```bash\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n    --model beit_large_patch16_224 --data_path /path/to/imagenet \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth \\\n    --output_dir /path/to/save_result --batch_size 32 --lr 2e-5 --update_freq 2 \\\n    --warmup_epochs 5 --epochs 30 --layer_decay 0.9 --drop_path 0.4 \\\n    --weight_decay 1e-8 --enable_deepspeed\n```\n- `--batch_size`: batch size per GPU.\n- `--update_freq`: gradient accumulation steps.\n- Effective batch size = `number of GPUs` * `--batch_size` * `--update_freq`. So in the above example, the effective batch size is `8*32*2 = 512`. The three arguments need to be adjusted together in order to keep the total batch size unchanged.\n- Gradient accumulation: if your GPU memory is limited (i.e., OOM issues), you can reduce `--batch size` and increase `--update_freq` to use the same effective batch size.\n- `--enable_deepspeed`: enable [deepspeed](https://github.com/microsoft/DeepSpeed) during fine-tuning, which uses Apex O2 mixed-precision training. If without this argument, the code will use torch.amp for fine-tuning.\n- In order to fine-tune BEiT in higher resolution (such as 384), we can set `--input_size 384` and reset `--model beit_large_patch16_384`. Gradient accumulation can be used for OOM issues.\n\nFor BEiT-base, we set `--layer_decay 0.85 --drop_path 0.1` and keep other arguments unchanged as follows:\n```bash\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n    --model beit_base_patch16_224 --data_path /path/to/imagenet \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth \\\n    --output_dir /path/to/save_result --batch_size 64 --lr 2e-5 --update_freq 1 \\\n    --warmup_epochs 5 --epochs 30 --layer_decay 0.85 --drop_path 0.1 \\\n    --weight_decay 1e-8 --enable_deepspeed\n```\n\nFor the BEiT models that are fully self-supervised pretrained on ImageNet-22k (without intermediate fine-tuning on ImageNet-22k), we recommend you to enable mixup and cutmix during fine-tuning. We use the following commands for BEiT-large and BEiT-base:\n\n```bash\n# BEiT-large\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n    --model beit_large_patch16_224 --data_path /path/to/imagenet \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k.pth \\\n    --output_dir /path/to/save_result --batch_size 64 --lr 1e-3 --update_freq 2 \\\n    --warmup_epochs 5 --epochs 50 --layer_decay 0.75 --drop_path 0.2 \\\n    --weight_decay 0.05 --mixup 0.8 --cutmix 1.0 --enable_deepspeed\n# BEiT-base\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n    --model beit_base_patch16_224 --data_path /path/to/imagenet \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k.pth \\\n    --output_dir /path/to/save_result --batch_size 128 --lr 4e-3 --update_freq 1 \\\n    --warmup_epochs 20 --epochs 100 --layer_decay 0.65 --drop_path 0.1 \\\n    --weight_decay 0.05 --mixup 0.8 --cutmix 1.0 --enable_deepspeed\n```\n\n\n## Evaluate our fine-tuned checkpoints\n\n- Evaluate our fine-tuned BEiT-large model in 224 resolution on ImageNet val with a single GPU:\n```bash\npython run_class_finetuning.py \\\n    --eval --model beit_large_patch16_224 --data_path /path/to/imagenet \\\n    --resume https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22kto1k.pth \n```\nExpected results:\n```\n* Acc@1 87.396 Acc@5 98.282 loss 0.515\n```\n\n- Evaluate our fine-tuned BEiT-base model in 384 resolution on ImageNet val with a single GPU:\n```bash\npython run_class_finetuning.py \\\n    --eval --model beit_base_patch16_384 --input_size 384 --data_path /path/to/imagenet \\\n    --resume https://unilm.blob.core.windows.net/beit/beit_base_patch16_384_pt22k_ft22kto1k.pth \n```\nExpected results:\n```\n* Acc@1 86.820 Acc@5 98.124 loss 0.565\n```\n\n- Evaluate our fine-tuned BEiT-large model in 384 resolution on ImageNet val with a single GPU:\n```bash\npython run_class_finetuning.py \\\n    --eval --model beit_large_patch16_384 --input_size 384 --data_path /path/to/imagenet \\\n    --resume https://unilm.blob.core.windows.net/beit/beit_large_patch16_384_pt22k_ft22kto1k.pth \n```\nExpected results:\n```\n* Acc@1 88.408 Acc@5 98.602 loss 0.479\n```\n\n- Evaluate our fine-tuned BEiT-large model in 512 resolution on ImageNet val with a single GPU:\n```bash\npython run_class_finetuning.py \\\n    --eval --model beit_large_patch16_512 --input_size 512 --data_path /path/to/imagenet \\\n    --resume https://unilm.blob.core.windows.net/beit/beit_large_patch16_512_pt22k_ft22kto1k.pth \n```\nExpected results:\n```\n* Acc@1 88.600 Acc@5 98.658 loss 0.474\n```\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/masking_generator.py",
    "content": "\"\"\"\nOriginally inspired by impl at https://github.com/zhunzhong07/Random-Erasing, Apache 2.0\nCopyright Zhun Zhong & Liang Zheng\n\nHacked together by / Copyright 2020 Ross Wightman\n\nModified by Hangbo Bao, for generating the masked position for visual image transformer\n\"\"\"\n# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# Originally inspired by impl at https://github.com/zhunzhong07/Random-Erasing, Apache 2.0\n# Copyright Zhun Zhong & Liang Zheng\n#\n# Hacked together by / Copyright 2020 Ross Wightman\n#\n# Modified by Hangbo Bao, for generating the masked position for visual image transformer\n# --------------------------------------------------------'\nimport random\nimport math\nimport numpy as np\n\n\nclass MaskingGenerator:\n    def __init__(\n            self, input_size, num_masking_patches, min_num_patches=4, max_num_patches=None,\n            min_aspect=0.3, max_aspect=None):\n        if not isinstance(input_size, tuple):\n            input_size = (input_size, ) * 2\n        self.height, self.width = input_size\n\n        self.num_patches = self.height * self.width\n        self.num_masking_patches = num_masking_patches\n\n        self.min_num_patches = min_num_patches\n        self.max_num_patches = num_masking_patches if max_num_patches is None else max_num_patches\n\n        max_aspect = max_aspect or 1 / min_aspect\n        self.log_aspect_ratio = (math.log(min_aspect), math.log(max_aspect))\n\n    def __repr__(self):\n        repr_str = \"Generator(%d, %d -> [%d ~ %d], max = %d, %.3f ~ %.3f)\" % (\n            self.height, self.width, self.min_num_patches, self.max_num_patches,\n            self.num_masking_patches, self.log_aspect_ratio[0], self.log_aspect_ratio[1])\n        return repr_str\n\n    def get_shape(self):\n        return self.height, self.width\n\n    def _mask(self, mask, max_mask_patches):\n        delta = 0\n        for attempt in range(10):\n            target_area = random.uniform(self.min_num_patches, max_mask_patches)\n            aspect_ratio = math.exp(random.uniform(*self.log_aspect_ratio))\n            h = int(round(math.sqrt(target_area * aspect_ratio)))\n            w = int(round(math.sqrt(target_area / aspect_ratio)))\n            if w < self.width and h < self.height:\n                top = random.randint(0, self.height - h)\n                left = random.randint(0, self.width - w)\n\n                num_masked = mask[top: top + h, left: left + w].sum()\n                # Overlap\n                if 0 < h * w - num_masked <= max_mask_patches:\n                    for i in range(top, top + h):\n                        for j in range(left, left + w):\n                            if mask[i, j] == 0:\n                                mask[i, j] = 1\n                                delta += 1\n\n                if delta > 0:\n                    break\n        return delta\n\n    def __call__(self):\n        mask = np.zeros(shape=self.get_shape(), dtype=np.int)\n        mask_count = 0\n        while mask_count < self.num_masking_patches:\n            max_mask_patches = self.num_masking_patches - mask_count\n            max_mask_patches = min(max_mask_patches, self.max_num_patches)\n\n            delta = self._mask(mask, max_mask_patches)\n            if delta == 0:\n                break\n            else:\n                mask_count += delta\n\n        return mask\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/modeling_cyclical.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport torch\nimport torch.nn as nn\nfrom functools import partial\n\nfrom .modeling_finetune import Block, _cfg, PatchEmbed, RelativePositionBias\nfrom timm.models.registry import register_model\nfrom timm.models.layers import trunc_normal_ as __call_trunc_normal_\n\n\ndef trunc_normal_(tensor, mean=0.0, std=1.0):\n    __call_trunc_normal_(tensor, mean=mean, std=std, a=-std, b=std)\n\n\n__all__ = [\n    \"beit_base_patch16_224\",\n    # 'beit_large_patch16_224_8k_vocab',\n]\n\n\nclass VisionTransformerForCyclicalTraining(nn.Module):\n    def __init__(\n        self,\n        img_size=224,\n        patch_size=16,\n        in_chans=3,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4.0,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.0,\n        attn_drop_rate=0.0,\n        drop_path_rate=0.0,\n        norm_layer=None,\n        init_values=None,\n        attn_head_dim=None,\n        use_abs_pos_emb=True,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=False,\n        init_std=0.02,\n    ):\n        super().__init__()\n        self.num_features = (\n            self.embed_dim\n        ) = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size,\n            patch_size=patch_size,\n            in_chans=in_chans,\n            embed_dim=embed_dim,\n        )\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(\n                window_size=self.patch_embed.patch_shape, num_heads=num_heads\n            )\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, depth)\n        ]  # stochastic depth decay rule\n        self.blocks = nn.ModuleList(\n            [\n                Block(\n                    dim=embed_dim,\n                    num_heads=num_heads,\n                    mlp_ratio=mlp_ratio,\n                    qkv_bias=qkv_bias,\n                    qk_scale=qk_scale,\n                    drop=drop_rate,\n                    attn_drop=attn_drop_rate,\n                    drop_path=dpr[i],\n                    norm_layer=norm_layer,\n                    init_values=init_values,\n                    window_size=self.patch_embed.patch_shape\n                    if use_rel_pos_bias\n                    else None,\n                    attn_head_dim=attn_head_dim,\n                )\n                for i in range(depth)\n            ]\n        )\n        self.norm = norm_layer(embed_dim)\n\n        self.init_std = init_std\n        # self.lm_head = nn.Sequential(\n        #     nn.Linear(embed_dim, embed_dim * 2),\n        #     nn.GELU(),\n        #     nn.Linear(embed_dim * 2, embed_dim),\n        # )\n        # self.lm_head = nn.Sequential(\n        #     nn.Linear(embed_dim, embed_dim),\n        # )\n        self.lm_head = nn.Linear(embed_dim, embed_dim)\n        \n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=self.init_std)\n        trunc_normal_(self.cls_token, std=self.init_std)\n        trunc_normal_(self.mask_token, std=self.init_std)\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=self.init_std)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n        elif isinstance(m, nn.Conv2d):\n            trunc_normal_(m.weight, std=self.init_std)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {\"pos_embed\", \"cls_token\"}\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    def forward_features(self, x, bool_masked_pos, layer_results):\n        x = self.patch_embed(x, bool_masked_pos=bool_masked_pos)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(\n            batch_size, -1, -1\n        )  # stole cls_tokens impl from Phil Wang, thanks\n        mask_token = self.mask_token.expand(batch_size, seq_len, -1)\n\n        if bool_masked_pos is not None:\n            # replace the masked visual tokens by mask_token\n            w = bool_masked_pos.view(bool_masked_pos.size(0), -1, 1).type_as(mask_token)\n            x = x * (1 - w) + mask_token * w # B x T x C\n            \n            # print(bool_masked_pos.shape)\n            # print(bool_masked_pos.sum((1,2)))\n            # print('x', x.shape)\n            # bool_masked = bool_masked_pos.reshape(bool_masked_pos.size(0), -1).bool()\n            # print('bool_masked', bool_masked.shape)\n            # print('asd1', x[bool_masked].shape)\n            # exit(0)\n\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n\n        z = []\n        for i, blk in enumerate(self.blocks):\n            x, fc_feature = blk(x, rel_pos_bias=rel_pos_bias)\n            if layer_results == 'end':\n                z.append(x)\n            elif layer_results == 'fc':\n                z.append(fc_feature)\n\n        return z if layer_results else self.norm(x)\n\n    def forward(self, x, bool_masked_pos, return_all_tokens=False, layer_results=None):\n        x = self.forward_features(\n            x, bool_masked_pos=bool_masked_pos, layer_results=layer_results\n        )\n        if layer_results:\n            return [z[:, 1:] for z in x]\n        elif return_all_tokens:\n            x = x[:, 1:]\n            return self.lm_head(x)\n        else:\n            # return the masked tokens\n            x = x[:, 1:]\n            bsz = x.size(0)\n            fsz = x.size(-1)\n            bool_masked_pos = bool_masked_pos.flatten().bool()\n            x = x.reshape(-1, fsz)[bool_masked_pos]\n            return self.lm_head(x)\n\n\n@register_model\ndef beit_base_patch16_224(pretrained=False, **kwargs):\n    #_ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalTraining(\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n@register_model\ndef beit_small_patch16_224(pretrained=False, **kwargs):\n    #_ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalTraining(\n        patch_size=16,\n        in_chans=13,\n        embed_dim=384,\n        depth=12,\n        num_heads=6,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n@register_model\ndef beit_large_patch16_224(pretrained=False, **kwargs):\n    # _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalTraining(\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n@register_model\ndef beit_huge_patch16_224(pretrained=False, **kwargs):\n    # _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalTraining(\n        patch_size=16,\n        embed_dim=1280,\n        depth=32,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n# @register_model\n# def beit_large_patch16_224_8k_vocab(pretrained=False, **kwargs):\n#     _ = kwargs.pop(\"num_classes\")\n#     model = VisionTransformerForMaskedImageModeling(\n#         patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n#         norm_layer=partial(nn.LayerNorm, eps=1e-6), vocab_size=8192, **kwargs)\n#     model.default_cfg = _cfg()\n#     if pretrained:\n#         checkpoint = torch.load(\n#             kwargs[\"init_ckpt\"], map_location=\"cpu\"\n#         )\n#         model.load_state_dict(checkpoint[\"model\"])\n#     return model\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/modeling_cyclical_joint.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport torch\nimport torch.nn as nn\nfrom functools import partial\n\nfrom modeling_finetune import Block, _cfg, PatchEmbed, RelativePositionBias\nfrom timm.models.registry import register_model\nfrom timm.models.layers import trunc_normal_ as __call_trunc_normal_\n\n\ndef trunc_normal_(tensor, mean=0.0, std=1.0):\n    __call_trunc_normal_(tensor, mean=mean, std=std, a=-std, b=std)\n\n\n__all__ = [\n    \"beit_base_joint_patch16_224\",\n    # 'beit_large_patch16_224_8k_vocab',\n]\n\n\nclass VisionTransformerForCyclicalJointTraining(nn.Module):\n    def __init__(\n        self,\n        img_size=224,\n        patch_size=16,\n        in_chans=3,\n        vocab_size=8192,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4.0,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.0,\n        attn_drop_rate=0.0,\n        drop_path_rate=0.0,\n        norm_layer=None,\n        init_values=None,\n        attn_head_dim=None,\n        use_abs_pos_emb=True,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=False,\n        init_std=0.02,\n    ):\n        super().__init__()\n        self.num_features = (\n            self.embed_dim\n        ) = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size,\n            patch_size=patch_size,\n            in_chans=in_chans,\n            embed_dim=embed_dim,\n        )\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(\n                window_size=self.patch_embed.patch_shape, num_heads=num_heads\n            )\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, depth)\n        ]  # stochastic depth decay rule\n        self.blocks = nn.ModuleList(\n            [\n                Block(\n                    dim=embed_dim,\n                    num_heads=num_heads,\n                    mlp_ratio=mlp_ratio,\n                    qkv_bias=qkv_bias,\n                    qk_scale=qk_scale,\n                    drop=drop_rate,\n                    attn_drop=attn_drop_rate,\n                    drop_path=dpr[i],\n                    norm_layer=norm_layer,\n                    init_values=init_values,\n                    window_size=self.patch_embed.patch_shape\n                    if use_rel_pos_bias\n                    else None,\n                    attn_head_dim=attn_head_dim,\n                )\n                for i in range(depth)\n            ]\n        )\n        self.norm = norm_layer(embed_dim)\n\n        self.init_std = init_std\n        self.lm_head = nn.Sequential(\n            nn.Linear(embed_dim, embed_dim * 2),\n            nn.GELU(),\n            nn.Linear(embed_dim * 2, embed_dim),\n        )\n        self.beit_head = nn.Linear(embed_dim, vocab_size)\n\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=self.init_std)\n        trunc_normal_(self.cls_token, std=self.init_std)\n        trunc_normal_(self.mask_token, std=self.init_std)\n        trunc_normal_(self.beit_head.weight, std=self.init_std)\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=self.init_std)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n        elif isinstance(m, nn.Conv2d):\n            trunc_normal_(m.weight, std=self.init_std)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {\"pos_embed\", \"cls_token\"}\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    def forward_features(self, x, bool_masked_pos, layer_results):\n        x = self.patch_embed(x, bool_masked_pos=bool_masked_pos)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(\n            batch_size, -1, -1\n        )  # stole cls_tokens impl from Phil Wang, thanks\n        mask_token = self.mask_token.expand(batch_size, seq_len, -1)\n\n        if bool_masked_pos is not None:\n            # replace the masked visual tokens by mask_token\n            w = bool_masked_pos.view(bool_masked_pos.size(0), -1, 1).type_as(mask_token)\n            x = x * (1 - w) + mask_token * w\n\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n\n        z = []\n        for i, blk in enumerate(self.blocks):\n            x, _ = blk(x, rel_pos_bias=rel_pos_bias)\n            if layer_results:\n                z.append(x)\n\n        return z if layer_results else self.norm(x)\n\n    def forward(self, x, bool_masked_pos, return_all_tokens=False, layer_results=False):\n        x = self.forward_features(\n            x, bool_masked_pos=bool_masked_pos, layer_results=layer_results\n        )\n        if layer_results:\n            return [z[:, 1:] for z in x]\n        elif return_all_tokens:\n            x = x[:, 1:]\n            return self.lm_head(x), self.beit_head(x)\n        else:\n            # return the masked tokens\n            x = x[:, 1:]\n            bsz = x.size(0)\n            fsz = x.size(-1)\n            bool_masked_pos = bool_masked_pos.flatten().bool()\n            x = x.reshape(-1, fsz)[bool_masked_pos]\n            return self.lm_head(x), self.beit_head(x)\n\n\n@register_model\ndef beit_base_joint_patch16_224(pretrained=False, **kwargs):\n    _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalJointTraining(\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        vocab_size=8192,\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n# @register_model\n# def beit_large_patch16_224_8k_vocab(pretrained=False, **kwargs):\n#     _ = kwargs.pop(\"num_classes\")\n#     model = VisionTransformerForMaskedImageModeling(\n#         patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n#         norm_layer=partial(nn.LayerNorm, eps=1e-6), vocab_size=8192, **kwargs)\n#     model.default_cfg = _cfg()\n#     if pretrained:\n#         checkpoint = torch.load(\n#             kwargs[\"init_ckpt\"], map_location=\"cpu\"\n#         )\n#         model.load_state_dict(checkpoint[\"model\"])\n#     return model\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/modeling_discrete_vae.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on OpenAI DALL-E and lucidrains' DALLE-pytorch code bases\n# https://github.com/openai/DALL-E\n# https://github.com/lucidrains/DALLE-pytorch\n# --------------------------------------------------------'\nfrom math import sqrt\nimport os\nimport torch\nfrom torch import nn, einsum\nimport torch.nn.functional as F\nfrom einops import rearrange\n\n\ndef top_k(logits, thres = 0.5):\n    num_logits = logits.shape[-1]\n    k = max(int((1 - thres) * num_logits), 1)\n    val, ind = torch.topk(logits, k)\n    probs = torch.full_like(logits, float('-inf'))\n    probs.scatter_(1, ind, val)\n    return probs\n\n\ndef exists(val):\n    return val is not None\n\n\ndef default(val, d):\n    return val if exists(val) else d\n\n\ndef eval_decorator(fn):\n    def inner(model, *args, **kwargs):\n        was_training = model.training\n        model.eval()\n        out = fn(model, *args, **kwargs)\n        model.train(was_training)\n        return out\n    return inner\n\n\nclass BasicVAE(nn.Module):\n\n    def get_codebook_indices(self, images):\n        raise NotImplementedError()\n\n    def decode(self, img_seq):\n        raise NotImplementedError()\n\n    def get_codebook_probs(self, img_seq):\n        raise NotImplementedError()\n\n    def get_image_tokens_size(self):\n        pass\n\n    def get_image_size(self):\n        pass\n\n\nclass ResBlock(nn.Module):\n    def __init__(self, chan_in, hidden_size, chan_out):\n        super().__init__()\n        self.net = nn.Sequential(\n            nn.Conv2d(chan_in, hidden_size, 3, padding=1),\n            nn.ReLU(),\n            nn.Conv2d(hidden_size, hidden_size, 3, padding=1),\n            nn.ReLU(),\n            nn.Conv2d(hidden_size, chan_out, 1)\n        )\n\n    def forward(self, x):\n        return self.net(x) + x\n\n\nclass DiscreteVAE(BasicVAE):\n    def __init__(\n        self,\n        image_size = 256,\n        num_tokens = 512,\n        codebook_dim = 512,\n        num_layers = 3,\n        hidden_dim = 64,\n        channels = 3,\n        smooth_l1_loss = False,\n        temperature = 0.9,\n        straight_through = False,\n        kl_div_loss_weight = 0.\n    ):\n        super().__init__()\n        # assert log2(image_size).is_integer(), 'image size must be a power of 2'\n        assert num_layers >= 1, 'number of layers must be greater than or equal to 1'\n\n        self.image_size = image_size\n        self.num_tokens = num_tokens\n        self.num_layers = num_layers\n        self.temperature = temperature\n        self.straight_through = straight_through\n        self.codebook = nn.Embedding(num_tokens, codebook_dim)\n\n        enc_layers = []\n        dec_layers = []\n\n        enc_in = channels\n        dec_in = codebook_dim\n\n        for layer_id in range(num_layers):\n            enc_layers.append(nn.Sequential(nn.Conv2d(enc_in, hidden_dim, 4, stride=2, padding=1), nn.ReLU()))\n            enc_layers.append(ResBlock(chan_in=hidden_dim, hidden_size=hidden_dim, chan_out=hidden_dim))\n            enc_in = hidden_dim\n            dec_layers.append(nn.Sequential(nn.ConvTranspose2d(dec_in, hidden_dim, 4, stride=2, padding=1), nn.ReLU()))\n            dec_layers.append(ResBlock(chan_in=hidden_dim, hidden_size=hidden_dim, chan_out=hidden_dim))\n            dec_in = hidden_dim\n\n        enc_layers.append(nn.Conv2d(hidden_dim, num_tokens, 1))\n        dec_layers.append(nn.Conv2d(hidden_dim, channels, 1))\n\n        self.encoder = nn.Sequential(*enc_layers)\n        self.decoder = nn.Sequential(*dec_layers)\n\n        self.loss_fn = F.smooth_l1_loss if smooth_l1_loss else F.mse_loss\n        self.kl_div_loss_weight = kl_div_loss_weight\n\n    def get_image_size(self):\n        return self.image_size\n\n    def get_image_tokens_size(self):\n        return self.image_size // 8\n\n    @torch.no_grad()\n    @eval_decorator\n    def get_codebook_indices(self, images):\n        logits = self.forward(images, return_logits = True)\n        codebook_indices = logits.argmax(dim = 1)\n        return codebook_indices\n\n    @torch.no_grad()\n    @eval_decorator\n    def get_codebook_probs(self, images):\n        logits = self.forward(images, return_logits = True)\n        return nn.Softmax(dim=1)(logits)\n\n    def decode(\n        self,\n        img_seq\n    ):\n        image_embeds = self.codebook(img_seq)\n        b, n, d = image_embeds.shape\n        h = w = int(sqrt(n))\n\n        image_embeds = rearrange(image_embeds, 'b (h w) d -> b d h w', h = h, w = w)\n        images = self.decoder(image_embeds)\n        return images\n\n    def forward(\n        self,\n        img,\n        return_loss = False,\n        return_recons = False,\n        return_logits = False,\n        temp = None\n    ):\n        device, num_tokens, image_size, kl_div_loss_weight = img.device, self.num_tokens, self.image_size, self.kl_div_loss_weight\n        assert img.shape[-1] == image_size and img.shape[-2] == image_size, f'input must have the correct image size {image_size}'\n\n        logits = self.encoder(img)\n\n        if return_logits:\n            return logits # return logits for getting hard image indices for DALL-E training\n\n        temp = default(temp, self.temperature)\n        soft_one_hot = F.gumbel_softmax(logits, tau = temp, dim = 1, hard = self.straight_through)\n        sampled = einsum('b n h w, n d -> b d h w', soft_one_hot, self.codebook.weight)\n        out = self.decoder(sampled)\n\n        if not return_loss:\n            return out\n\n        # reconstruction loss\n\n        recon_loss = self.loss_fn(img, out)\n\n        # kl divergence\n\n        logits = rearrange(logits, 'b n h w -> b (h w) n')\n        qy = F.softmax(logits, dim = -1)\n\n        log_qy = torch.log(qy + 1e-10)\n        log_uniform = torch.log(torch.tensor([1. / num_tokens], device = device))\n        kl_div = F.kl_div(log_uniform, log_qy, None, None, 'batchmean', log_target = True)\n\n        loss = recon_loss + (kl_div * kl_div_loss_weight)\n\n        if not return_recons:\n            return loss\n\n        return loss, out\n\n\nfrom .dall_e import load_model\n\n\nclass Dalle_VAE(BasicVAE):\n    def __init__(self, image_size):\n        super().__init__()\n        self.encoder = None\n        self.decoder = None\n        self.image_size = image_size\n\n    def load_model(self, model_dir, device):\n        self.encoder = load_model(os.path.join(model_dir, \"encoder.pkl\"), device)\n        self.decoder = load_model(os.path.join(model_dir, \"decoder.pkl\"), device)\n\n    def decode(self, img_seq):\n        bsz = img_seq.size()[0]\n        img_seq = img_seq.view(bsz, self.image_size // 8, self.image_size // 8)\n        z = F.one_hot(img_seq, num_classes=self.encoder.vocab_size).permute(0, 3, 1, 2).float()\n        return self.decoder(z).float()\n\n    def get_codebook_indices(self, images):\n        z_logits = self.encoder(images)\n        return torch.argmax(z_logits, axis=1)\n\n    def get_codebook_probs(self, images):\n        z_logits = self.encoder(images)\n        return nn.Softmax(dim=1)(z_logits)\n\n    def forward(self, img_seq_prob, no_process=False):\n        if no_process:\n            return self.decoder(img_seq_prob.float()).float()\n        else:\n            bsz, seq_len, num_class = img_seq_prob.size()\n            z = img_seq_prob.view(bsz, self.image_size // 8, self.image_size // 8, self.encoder.vocab_size)\n            return self.decoder(z.permute(0, 3, 1, 2).float()).float()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/modeling_finetune.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom timm.models.layers import drop_path, to_2tuple, trunc_normal_\nfrom timm.models.registry import register_model\n\n\ndef _cfg(url='', **kwargs):\n    return {\n        'url': url,\n        'num_classes': 1000, 'input_size': (3, 224, 224), 'pool_size': None,\n        'crop_pct': .9, 'interpolation': 'bicubic',\n        'mean': (0.5, 0.5, 0.5), 'std': (0.5, 0.5, 0.5),\n        **kwargs\n    }\n\n\nclass DropPath(nn.Module):\n    \"\"\"Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).\n    \"\"\"\n    def __init__(self, drop_prob=None):\n        super(DropPath, self).__init__()\n        self.drop_prob = drop_prob\n\n    def forward(self, x):\n        return drop_path(x, self.drop_prob, self.training)\n    \n    def extra_repr(self) -> str:\n        return 'p={}'.format(self.drop_prob)\n\n\nclass Mlp(nn.Module):\n    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        # x = self.drop(x)\n        # commit this for the orignal BERT implement \n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\nclass Attention(nn.Module):\n    def __init__(\n            self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0.,\n            proj_drop=0., window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        if attn_head_dim is not None:\n            head_dim = attn_head_dim\n        all_head_dim = head_dim * self.num_heads\n        self.scale = qk_scale or head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, all_head_dim * 3, bias=False)\n        if qkv_bias:\n            self.q_bias = nn.Parameter(torch.zeros(all_head_dim))\n            self.v_bias = nn.Parameter(torch.zeros(all_head_dim))\n        else:\n            self.q_bias = None\n            self.v_bias = None\n\n        if window_size:\n            self.window_size = window_size\n            self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n            self.relative_position_bias_table = nn.Parameter(\n                torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n            # cls to token & token 2 cls & cls to cls\n\n            # get pair-wise relative position index for each token inside the window\n            coords_h = torch.arange(window_size[0])\n            coords_w = torch.arange(window_size[1])\n            coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n            coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n            relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n            relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n            relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n            relative_coords[:, :, 1] += window_size[1] - 1\n            relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n            relative_position_index = \\\n                torch.zeros(size=(window_size[0] * window_size[1] + 1, ) * 2, dtype=relative_coords.dtype)\n            relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n            relative_position_index[0, 0:] = self.num_relative_distance - 3\n            relative_position_index[0:, 0] = self.num_relative_distance - 2\n            relative_position_index[0, 0] = self.num_relative_distance - 1\n\n            self.register_buffer(\"relative_position_index\", relative_position_index)\n        else:\n            self.window_size = None\n            self.relative_position_bias_table = None\n            self.relative_position_index = None\n\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(all_head_dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n    def forward(self, x, rel_pos_bias=None):\n        B, N, C = x.shape\n        qkv_bias = None\n        if self.q_bias is not None:\n            qkv_bias = torch.cat((self.q_bias, torch.zeros_like(self.v_bias, requires_grad=False), self.v_bias))\n        # qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)\n        qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias)\n        qkv = qkv.reshape(B, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[2]   # make torchscript happy (cannot use tensor as tuple)\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        if self.relative_position_bias_table is not None:\n            relative_position_bias = \\\n                self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                    self.window_size[0] * self.window_size[1] + 1,\n                    self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n            relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n            attn = attn + relative_position_bias.unsqueeze(0)\n\n        if rel_pos_bias is not None:\n            attn = attn + rel_pos_bias\n        \n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, -1)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n\nclass Block(nn.Module):\n\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,\n                 drop_path=0., init_values=None, act_layer=nn.GELU, norm_layer=nn.LayerNorm,\n                 window_size=None, attn_head_dim=None):\n        super().__init__()\n\n        self.norm1 = norm_layer(dim)\n        self.attn = Attention(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale,\n            attn_drop=attn_drop, proj_drop=drop, window_size=window_size, attn_head_dim=attn_head_dim)\n        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n        if init_values > 0:\n            self.gamma_1 = nn.Parameter(init_values * torch.ones((dim)),requires_grad=True)\n            self.gamma_2 = nn.Parameter(init_values * torch.ones((dim)),requires_grad=True)\n        else:\n            self.gamma_1, self.gamma_2 = None, None\n\n    def forward(self, x, rel_pos_bias=None):\n        if self.gamma_1 is None:\n            x = x + self.drop_path(self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            fc_feature = self.drop_path(self.mlp(self.norm2(x)))\n            x = x + fc_feature\n        else:\n            x = x + self.drop_path(self.gamma_1 * self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            fc_feature = self.drop_path(self.gamma_2 * self.mlp(self.norm2(x)))\n            x = x + fc_feature\n        return x, fc_feature\n\n\nclass PatchEmbed(nn.Module):\n    \"\"\" Image to Patch Embedding\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):\n        super().__init__()\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        num_patches = (img_size[1] // patch_size[1]) * (img_size[0] // patch_size[0])\n        self.patch_shape = (img_size[0] // patch_size[0], img_size[1] // patch_size[1])\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.num_patches = num_patches\n\n        self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n\n    def forward(self, x, **kwargs):\n        B, C, H, W = x.shape\n        # FIXME look at relaxing size constraints\n        assert H == self.img_size[0] and W == self.img_size[1], \\\n            f\"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]}).\"\n        x = self.proj(x).flatten(2).transpose(1, 2)\n        return x\n\n\nclass RelativePositionBias(nn.Module):\n\n    def __init__(self, window_size, num_heads):\n        super().__init__()\n        self.window_size = window_size\n        self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n        self.relative_position_bias_table = nn.Parameter(\n            torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n        # cls to token & token 2 cls & cls to cls\n\n        # get pair-wise relative position index for each token inside the window\n        coords_h = torch.arange(window_size[0])\n        coords_w = torch.arange(window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n        relative_coords[:, :, 1] += window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n        relative_position_index = \\\n            torch.zeros(size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype)\n        relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        relative_position_index[0, 0:] = self.num_relative_distance - 3\n        relative_position_index[0:, 0] = self.num_relative_distance - 2\n        relative_position_index[0, 0] = self.num_relative_distance - 1\n\n        self.register_buffer(\"relative_position_index\", relative_position_index)\n\n        # trunc_normal_(self.relative_position_bias_table, std=.02)\n\n    def forward(self):\n        relative_position_bias = \\\n            self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1] + 1,\n                self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n        return relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n\n\nclass VisionTransformer(nn.Module):\n    \"\"\" Vision Transformer with support for patch or hybrid CNN input stage\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, num_classes=1000, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., norm_layer=nn.LayerNorm, init_values=None,\n                 use_abs_pos_emb=True, use_rel_pos_bias=False, use_shared_rel_pos_bias=False,\n                 use_mean_pooling=True, init_scale=0.001, linear_classifier=False, has_masking=False,\n                 learn_layer_weights=False, layernorm_before_combine=False):\n        super().__init__()\n        self.num_classes = num_classes\n        self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n\n        if has_masking:\n            self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(window_size=self.patch_embed.patch_shape, num_heads=num_heads)\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.use_rel_pos_bias = use_rel_pos_bias\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,\n                init_values=init_values, window_size=self.patch_embed.patch_shape if use_rel_pos_bias else None)\n            for i in range(depth)])\n        self.use_mean_pooling = use_mean_pooling\n        self.norm = nn.Identity() if use_mean_pooling else norm_layer(embed_dim)\n        self.fc_norm = norm_layer(embed_dim, elementwise_affine=not linear_classifier) if use_mean_pooling else None\n        self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=.02)\n        trunc_normal_(self.cls_token, std=.02)\n        if has_masking:\n            trunc_normal_(self.mask_token, std=.02)\n        trunc_normal_(self.head.weight, std=.02)\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n        self.learn_layer_weights = learn_layer_weights\n        self.layernorm_before_combine = layernorm_before_combine\n        if learn_layer_weights:\n            self.layer_log_weights = nn.Parameter(torch.zeros(depth,))\n\n        self.head.weight.data.mul_(init_scale)\n        self.head.bias.data.mul_(init_scale)\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n            if m.weight is not None:\n                nn.init.constant_(m.weight, 1.0)\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def get_classifier(self):\n        return self.head\n\n    def reset_classifier(self, num_classes, global_pool=''):\n        self.num_classes = num_classes\n        self.head = nn.Linear(self.embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n    def forward_features(self, x, bool_masked_pos=None):\n        x = self.patch_embed(x)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n\n        if bool_masked_pos is not None and self.training:\n            mask_token = self.mask_token.expand(batch_size, seq_len, -1)\n            # replace the masked visual tokens by mask_token\n            w = bool_masked_pos.view(bool_masked_pos.size(0), -1, 1).type_as(mask_token)\n            x = x * (1 - w) + mask_token * w\n\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n        layer_xs = []\n        for blk in self.blocks:\n            x, _ = blk(x, rel_pos_bias=rel_pos_bias)  # B x T x C\n            layer_xs.append(x)\n\n        if self.learn_layer_weights:\n            layer_xs = [\n                layer_x.mean(1) if self.use_mean_pooling else layer_x[:, 0]\n                for layer_x in layer_xs\n            ]\n            layer_xs = [\n                F.layer_norm(layer_x.float(), layer_x.shape[-1:])\n                if self.layernorm_before_combine else layer_x\n                for layer_x in layer_xs\n            ]\n            weights = self.layer_log_weights.softmax(-1)\n            return F.linear(torch.stack(layer_xs, -1), weights)\n        else:\n            x = self.norm(x)\n            if self.fc_norm is not None:\n                t = x[:, 1:, :]\n                return self.fc_norm(t.mean(1))\n            else:\n                return x[:, 0]\n\n    def forward(self, x, bool_masked_pos=None):\n        x = self.forward_features(x, bool_masked_pos)\n        x = self.head(x)\n        return x\n\n\n@register_model\ndef beit_small_patch16_224(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        patch_size=16, in_chans=13, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_base_patch16_224(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_base_patch16_384(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        img_size=384, patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_large_patch16_224(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_large_patch16_384(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        img_size=384, patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_large_patch16_512(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        img_size=512, patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/modeling_pretrain.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport torch\nimport torch.nn as nn\nfrom functools import partial\n\nfrom modeling_finetune import Block, _cfg, PatchEmbed, RelativePositionBias\nfrom timm.models.registry import register_model\nfrom timm.models.layers import trunc_normal_ as __call_trunc_normal_\n\n\ndef trunc_normal_(tensor, mean=0., std=1.):\n    __call_trunc_normal_(tensor, mean=mean, std=std, a=-std, b=std)\n\n\n__all__ = [\n    'beit_base_patch16_224_8k_vocab', \n    'beit_large_patch16_224_8k_vocab', \n]\n\n\nclass VisionTransformerForMaskedImageModeling(nn.Module):\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, vocab_size=8192, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=True, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., norm_layer=None, init_values=None, attn_head_dim=None,\n                 use_abs_pos_emb=True, use_rel_pos_bias=False, use_shared_rel_pos_bias=False, init_std=0.02):\n        super().__init__()\n        self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(window_size=self.patch_embed.patch_shape, num_heads=num_heads)\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,\n                init_values=init_values, window_size=self.patch_embed.patch_shape if use_rel_pos_bias else None,\n                attn_head_dim=attn_head_dim,\n            )\n            for i in range(depth)])\n        self.norm = norm_layer(embed_dim)\n\n        self.init_std = init_std\n        self.lm_head = nn.Linear(embed_dim, vocab_size)\n\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=self.init_std)\n        trunc_normal_(self.cls_token, std=self.init_std)\n        trunc_normal_(self.mask_token, std=self.init_std)\n        trunc_normal_(self.lm_head.weight, std=self.init_std)\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=self.init_std)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n        elif isinstance(m, nn.Conv2d):\n            trunc_normal_(m.weight, std=self.init_std)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    def forward_features(self, x, bool_masked_pos):\n        x = self.patch_embed(x, bool_masked_pos=bool_masked_pos)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n        mask_token = self.mask_token.expand(batch_size, seq_len, -1)\n\n        # replace the masked visual tokens by mask_token\n        w = bool_masked_pos.unsqueeze(-1).type_as(mask_token)\n        x = x * (1 - w) + mask_token * w\n\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n        for blk in self.blocks:\n            x, _ = blk(x, rel_pos_bias=rel_pos_bias)\n\n        return self.norm(x)\n\n    def forward(self, x, bool_masked_pos, return_all_tokens=False):\n        x = self.forward_features(x, bool_masked_pos=bool_masked_pos)\n        x = x[:, 1:]\n        if return_all_tokens:\n            return self.lm_head(x)\n        else:\n            # return the masked tokens\n            return self.lm_head(x[bool_masked_pos])\n\n\n@register_model\ndef beit_base_patch16_224_8k_vocab(pretrained=False, **kwargs):\n    _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForMaskedImageModeling(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), vocab_size=8192, **kwargs)\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(\n            kwargs[\"init_ckpt\"], map_location=\"cpu\"\n        )\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n@register_model\ndef beit_large_patch16_224_8k_vocab(pretrained=False, **kwargs):\n    _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForMaskedImageModeling(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), vocab_size=8192, **kwargs)\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(\n            kwargs[\"init_ckpt\"], map_location=\"cpu\"\n        )\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/models.py",
    "content": "\"\"\" BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\nModel from official source: https://github.com/microsoft/unilm/tree/master/beit\nAt this point only the 1k fine-tuned classification weights and model configs have been added,\nsee original source above for pre-training models and procedure.\nModifications by / Copyright 2021 Ross Wightman, original copyrights below\n\"\"\"\n# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\nimport math\nfrom functools import partial\nfrom typing import Optional\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom timm.models.helpers import build_model_with_cfg\nfrom timm.models.layers import PatchEmbed, Mlp, DropPath, trunc_normal_\nfrom timm.models.registry import register_model\nfrom timm.models.vision_transformer import checkpoint_filter_fn\n\n\ndef _cfg(url='', **kwargs):\n    return {\n        'url': url,\n        'num_classes': 1000, 'input_size': (3, 224, 224), 'pool_size': None,\n        'crop_pct': .9, 'interpolation': 'bicubic', 'fixed_input_size': True,\n        'mean': (0.5, 0.5, 0.5), 'std': (0.5, 0.5, 0.5),\n        'first_conv': 'patch_embed.proj', 'classifier': 'head',\n        **kwargs\n    }\n\n\ndefault_cfgs = {\n    'beit_base_patch16_224': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22kto1k.pth'),\n    'beit_base_patch16_384': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_base_patch16_384_pt22k_ft22kto1k.pth',\n        input_size=(3, 384, 384), crop_pct=1.0,\n    ),\n    'beit_base_patch16_224_in22k': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth',\n        num_classes=21841,\n    ),\n    'beit_large_patch16_224': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22kto1k.pth'),\n    'beit_large_patch16_384': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_large_patch16_384_pt22k_ft22kto1k.pth',\n        input_size=(3, 384, 384), crop_pct=1.0,\n    ),\n    'beit_large_patch16_512': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_large_patch16_512_pt22k_ft22kto1k.pth',\n        input_size=(3, 512, 512), crop_pct=1.0,\n    ),\n    'beit_large_patch16_224_in22k': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth',\n        num_classes=21841,\n    ),\n}\n\n\nclass Attention(nn.Module):\n    def __init__(\n            self, dim, num_heads=8, qkv_bias=False, attn_drop=0.,\n            proj_drop=0., window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        if attn_head_dim is not None:\n            head_dim = attn_head_dim\n        all_head_dim = head_dim * self.num_heads\n        self.scale = head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, all_head_dim * 3, bias=False)\n        if qkv_bias:\n            self.q_bias = nn.Parameter(torch.zeros(all_head_dim))\n            self.register_buffer('k_bias', torch.zeros(all_head_dim), persistent=False)\n            self.v_bias = nn.Parameter(torch.zeros(all_head_dim))\n        else:\n            self.q_bias = None\n            self.k_bias = None\n            self.v_bias = None\n\n        if window_size:\n            self.window_size = window_size\n            self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n            self.relative_position_bias_table = nn.Parameter(\n                torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n            # cls to token & token 2 cls & cls to cls\n\n            # get pair-wise relative position index for each token inside the window\n            coords_h = torch.arange(window_size[0])\n            coords_w = torch.arange(window_size[1])\n            coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n            coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n            relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n            relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n            relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n            relative_coords[:, :, 1] += window_size[1] - 1\n            relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n            relative_position_index = \\\n                torch.zeros(size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype)\n            relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n            relative_position_index[0, 0:] = self.num_relative_distance - 3\n            relative_position_index[0:, 0] = self.num_relative_distance - 2\n            relative_position_index[0, 0] = self.num_relative_distance - 1\n\n            self.register_buffer(\"relative_position_index\", relative_position_index)\n        else:\n            self.window_size = None\n            self.relative_position_bias_table = None\n            self.relative_position_index = None\n\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(all_head_dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n    def forward(self, x, rel_pos_bias: Optional[torch.Tensor] = None):\n        B, N, C = x.shape\n        qkv_bias = torch.cat((self.q_bias, self.k_bias, self.v_bias)) if self.q_bias is not None else None\n        qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias)\n        qkv = qkv.reshape(B, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv.unbind(0)  # make torchscript happy (cannot use tensor as tuple)\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        if self.relative_position_bias_table is not None:\n            relative_position_bias = \\\n                self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                    self.window_size[0] * self.window_size[1] + 1,\n                    self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n            relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n            attn = attn + relative_position_bias.unsqueeze(0)\n\n        if rel_pos_bias is not None:\n            attn = attn + rel_pos_bias\n\n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, -1)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n\nclass Block(nn.Module):\n\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, drop=0., attn_drop=0.,\n                 drop_path=0., init_values=None, act_layer=nn.GELU, norm_layer=nn.LayerNorm,\n                 window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.norm1 = norm_layer(dim)\n        self.attn = Attention(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, attn_drop=attn_drop, proj_drop=drop,\n            window_size=window_size, attn_head_dim=attn_head_dim)\n        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n        if init_values:\n            self.gamma_1 = nn.Parameter(init_values * torch.ones((dim)), requires_grad=True)\n            self.gamma_2 = nn.Parameter(init_values * torch.ones((dim)), requires_grad=True)\n        else:\n            self.gamma_1, self.gamma_2 = None, None\n\n    def forward(self, x, rel_pos_bias: Optional[torch.Tensor] = None):\n        if self.gamma_1 is None:\n            x = x + self.drop_path(self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            x = x + self.drop_path(self.mlp(self.norm2(x)))\n        else:\n            x = x + self.drop_path(self.gamma_1 * self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            x = x + self.drop_path(self.gamma_2 * self.mlp(self.norm2(x)))\n        return x\n\n\nclass RelativePositionBias(nn.Module):\n\n    def __init__(self, window_size, num_heads):\n        super().__init__()\n        self.window_size = window_size\n        self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n        self.relative_position_bias_table = nn.Parameter(\n            torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n        # cls to token & token 2 cls & cls to cls\n\n        # get pair-wise relative position index for each token inside the window\n        coords_h = torch.arange(window_size[0])\n        coords_w = torch.arange(window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n        relative_coords[:, :, 1] += window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n        relative_position_index = \\\n            torch.zeros(size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype)\n        relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        relative_position_index[0, 0:] = self.num_relative_distance - 3\n        relative_position_index[0:, 0] = self.num_relative_distance - 2\n        relative_position_index[0, 0] = self.num_relative_distance - 1\n\n        self.register_buffer(\"relative_position_index\", relative_position_index)\n\n        # trunc_normal_(self.relative_position_bias_table, std=.02)\n\n    def forward(self):\n        relative_position_bias = \\\n            self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1] + 1,\n                self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n        return relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n\n\nclass Beit(nn.Module):\n    \"\"\" Vision Transformer with support for patch or hybrid CNN input stage\n    \"\"\"\n\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, num_classes=1000, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=True, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., norm_layer=partial(nn.LayerNorm, eps=1e-6), init_values=None,\n                 use_abs_pos_emb=True, use_rel_pos_bias=False, use_shared_rel_pos_bias=False,\n                 use_mean_pooling=True, init_scale=0.001):\n        super().__init__()\n        self.num_classes = num_classes\n        self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        # self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(window_size=self.patch_embed.grid_size, num_heads=num_heads)\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.use_rel_pos_bias = use_rel_pos_bias\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,\n                init_values=init_values, window_size=self.patch_embed.grid_size if use_rel_pos_bias else None)\n            for i in range(depth)])\n        self.norm = nn.Identity() if use_mean_pooling else norm_layer(embed_dim)\n        self.fc_norm = norm_layer(embed_dim) if use_mean_pooling else None\n        self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n        self.apply(self._init_weights)\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=.02)\n        trunc_normal_(self.cls_token, std=.02)\n        # trunc_normal_(self.mask_token, std=.02)\n        self.fix_init_weight()\n        if isinstance(self.head, nn.Linear):\n            trunc_normal_(self.head.weight, std=.02)\n            self.head.weight.data.mul_(init_scale)\n            self.head.bias.data.mul_(init_scale)\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def get_classifier(self):\n        return self.head\n\n    def reset_classifier(self, num_classes, global_pool=''):\n        self.num_classes = num_classes\n        self.head = nn.Linear(self.embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n    def forward_features(self, x):\n        x = self.patch_embed(x)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n        for blk in self.blocks:\n            x = blk(x, rel_pos_bias=rel_pos_bias)\n\n        x = self.norm(x)\n        if self.fc_norm is not None:\n            t = x[:, 1:, :]\n            return self.fc_norm(t.mean(1))\n        else:\n            return x[:, 0]\n\n    def forward(self, x):\n        x = self.forward_features(x)\n        x = self.head(x)\n        return x\n\n\ndef _create_beit(variant, pretrained=False, default_cfg=None, **kwargs):\n    default_cfg = default_cfg or default_cfgs[variant]\n    if kwargs.get('features_only', None):\n        raise RuntimeError('features_only not implemented for Beit models.')\n\n    model = build_model_with_cfg(\n        Beit, variant, pretrained,\n        default_cfg=default_cfg,\n        # FIXME an updated filter fn needed to interpolate rel pos emb if fine tuning to diff model sizes\n        pretrained_filter_fn=checkpoint_filter_fn,\n        **kwargs)\n    return model\n\n\n@register_model\ndef beit_base_patch16_224(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,\n        #use_abs_pos_emb=False, \n        use_rel_pos_bias=True, \n        #init_values=0.1, \n        **kwargs)\n    model = _create_beit('beit_base_patch16_224', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_base_patch16_384(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        img_size=384, patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=0.1, **kwargs)\n    model = _create_beit('beit_base_patch16_384', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_base_patch16_224_in22k(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=0.1, **kwargs)\n    model = _create_beit('beit_base_patch16_224_in22k', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_large_patch16_224(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=1e-5,  **kwargs)\n    model = _create_beit('beit_large_patch16_224', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_large_patch16_384(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        img_size=384, patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=1e-5, **kwargs)\n    model = _create_beit('beit_large_patch16_384', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_large_patch16_512(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        img_size=512, patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=1e-5, **kwargs)\n    model = _create_beit('beit_large_patch16_512', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_large_patch16_224_in22k(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=1e-5,  **kwargs)\n    model = _create_beit('beit_large_patch16_224_in22k', pretrained=pretrained, **model_kwargs)\n    return model"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/optim_factory.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# --------------------------------------------------------'\nimport torch\nfrom torch import optim as optim\n\nfrom timm.optim.adafactor import Adafactor\nfrom timm.optim.adahessian import Adahessian\nfrom timm.optim.adamp import AdamP\nfrom timm.optim.lookahead import Lookahead\nfrom timm.optim.nadam import Nadam\n# from timm.optim.novograd import NovoGrad\nfrom timm.optim.nvnovograd import NvNovoGrad\nfrom timm.optim.radam import RAdam\nfrom timm.optim.rmsprop_tf import RMSpropTF\nfrom timm.optim.sgdp import SGDP\n\nimport json\n\ntry:\n    from apex.optimizers import FusedNovoGrad, FusedAdam, FusedLAMB, FusedSGD\n    has_apex = True\nexcept ImportError:\n    has_apex = False\n\n\ndef get_num_layer_for_vit(var_name, num_max_layer):\n    if var_name in (\"cls_token\", \"mask_token\", \"pos_embed\"):\n        return 0\n    elif var_name.startswith(\"patch_embed\"):\n        return 0\n    elif var_name.startswith(\"rel_pos_bias\"):\n        return num_max_layer - 1\n    elif var_name.startswith(\"blocks\"):\n        layer_id = int(var_name.split('.')[1])\n        return layer_id + 1\n    else:\n        return num_max_layer - 1\n\n\nclass LayerDecayValueAssigner(object):\n    def __init__(self, values):\n        self.values = values\n\n    def get_scale(self, layer_id):\n        return self.values[layer_id]\n\n    def get_layer_id(self, var_name):\n        return get_num_layer_for_vit(var_name, len(self.values))\n\n\ndef get_parameter_groups(model, weight_decay=1e-5, skip_list=(), get_num_layer=None, get_layer_scale=None):\n    parameter_group_names = {}\n    parameter_group_vars = {}\n\n    for name, param in model.named_parameters():\n        if not param.requires_grad:\n            continue  # frozen weights\n        if len(param.shape) == 1 or name.endswith(\".bias\") or name in skip_list:\n            group_name = \"no_decay\"\n            this_weight_decay = 0.\n        else:\n            group_name = \"decay\"\n            this_weight_decay = weight_decay\n        if get_num_layer is not None:\n            layer_id = get_num_layer(name)\n            group_name = \"layer_%d_%s\" % (layer_id, group_name)\n        else:\n            layer_id = None\n\n        if group_name not in parameter_group_names:\n            if get_layer_scale is not None:\n                scale = get_layer_scale(layer_id)\n            else:\n                scale = 1.\n\n            parameter_group_names[group_name] = {\n                \"weight_decay\": this_weight_decay,\n                \"params\": [],\n                \"lr_scale\": scale\n            }\n            parameter_group_vars[group_name] = {\n                \"weight_decay\": this_weight_decay,\n                \"params\": [],\n                \"lr_scale\": scale\n            }\n\n        parameter_group_vars[group_name][\"params\"].append(param)\n        parameter_group_names[group_name][\"params\"].append(name)\n    print(\"Param groups = %s\" % json.dumps(parameter_group_names, indent=2))\n    return list(parameter_group_vars.values())\n\n\ndef create_optimizer(args, model, get_num_layer=None, get_layer_scale=None, filter_bias_and_bn=True, skip_list=None):\n    opt_lower = args.opt.lower()\n    weight_decay = args.weight_decay\n    if weight_decay and filter_bias_and_bn:\n        skip = {}\n        if skip_list is not None:\n            skip = skip_list\n        elif hasattr(model, 'no_weight_decay'):\n            skip = model.no_weight_decay()\n        parameters = get_parameter_groups(model, weight_decay, skip, get_num_layer, get_layer_scale)\n        weight_decay = 0.\n    else:\n        parameters = model.parameters()\n\n    if 'fused' in opt_lower:\n        assert has_apex and torch.cuda.is_available(), 'APEX and CUDA required for fused optimizers'\n\n    opt_args = dict(lr=args.lr, weight_decay=weight_decay)\n    if hasattr(args, 'opt_eps') and args.opt_eps is not None:\n        opt_args['eps'] = args.opt_eps\n    if hasattr(args, 'opt_betas') and args.opt_betas is not None:\n        opt_args['betas'] = args.opt_betas\n\n    opt_split = opt_lower.split('_')\n    opt_lower = opt_split[-1]\n    if opt_lower == 'sgd' or opt_lower == 'nesterov':\n        opt_args.pop('eps', None)\n        optimizer = optim.SGD(parameters, momentum=args.momentum, nesterov=True, **opt_args)\n    elif opt_lower == 'momentum':\n        opt_args.pop('eps', None)\n        optimizer = optim.SGD(parameters, momentum=args.momentum, nesterov=False, **opt_args)\n    elif opt_lower == 'adam':\n        optimizer = optim.Adam(parameters, **opt_args)\n    elif opt_lower == 'adamw':\n        optimizer = optim.AdamW(parameters, **opt_args)\n    elif opt_lower == 'nadam':\n        optimizer = Nadam(parameters, **opt_args)\n    elif opt_lower == 'radam':\n        optimizer = RAdam(parameters, **opt_args)\n    elif opt_lower == 'adamp':\n        optimizer = AdamP(parameters, wd_ratio=0.01, nesterov=True, **opt_args)\n    elif opt_lower == 'sgdp':\n        optimizer = SGDP(parameters, momentum=args.momentum, nesterov=True, **opt_args)\n    elif opt_lower == 'adadelta':\n        optimizer = optim.Adadelta(parameters, **opt_args)\n    elif opt_lower == 'adafactor':\n        if not args.lr:\n            opt_args['lr'] = None\n        optimizer = Adafactor(parameters, **opt_args)\n    elif opt_lower == 'adahessian':\n        optimizer = Adahessian(parameters, **opt_args)\n    elif opt_lower == 'rmsprop':\n        optimizer = optim.RMSprop(parameters, alpha=0.9, momentum=args.momentum, **opt_args)\n    elif opt_lower == 'rmsproptf':\n        optimizer = RMSpropTF(parameters, alpha=0.9, momentum=args.momentum, **opt_args)\n    elif opt_lower == 'novograd':\n        optimizer = NovoGrad(parameters, **opt_args)\n    elif opt_lower == 'nvnovograd':\n        optimizer = NvNovoGrad(parameters, **opt_args)\n    elif opt_lower == 'fusedsgd':\n        opt_args.pop('eps', None)\n        optimizer = FusedSGD(parameters, momentum=args.momentum, nesterov=True, **opt_args)\n    elif opt_lower == 'fusedmomentum':\n        opt_args.pop('eps', None)\n        optimizer = FusedSGD(parameters, momentum=args.momentum, nesterov=False, **opt_args)\n    elif opt_lower == 'fusedadam':\n        optimizer = FusedAdam(parameters, adam_w_mode=False, **opt_args)\n    elif opt_lower == 'fusedadamw':\n        optimizer = FusedAdam(parameters, adam_w_mode=True, **opt_args)\n    elif opt_lower == 'fusedlamb':\n        optimizer = FusedLAMB(parameters, **opt_args)\n    elif opt_lower == 'fusednovograd':\n        opt_args.setdefault('betas', (0.95, 0.98))\n        optimizer = FusedNovoGrad(parameters, **opt_args)\n    else:\n        assert False and \"Invalid optimizer\"\n        raise ValueError\n\n    if len(opt_split) > 1:\n        if opt_split[0] == 'lookahead':\n            optimizer = Lookahead(optimizer)\n\n    return optimizer\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/requirements.txt",
    "content": "torch==1.7.1\ntorchvision==0.8.2\ntimm==0.3.2\nPillow\nblobfile\nmypy\nnumpy\npytest\nrequests\neinops\ntensorboardX\ndeepspeed==0.4.0\nscipy\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/run_beit_pretraining.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.models import create_model\nfrom optim_factory import create_optimizer\n\nfrom datasets import build_beit_pretraining_dataset\nfrom engine_for_pretraining import train_one_epoch\nfrom utils import NativeScalerWithGradNormCount as NativeScaler\nimport utils\nimport modeling_pretrain\n\n\ndef get_args():\n    parser = argparse.ArgumentParser('BEiT pre-training script', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int)\n    parser.add_argument('--epochs', default=300, type=int)\n    parser.add_argument('--save_ckpt_freq', default=10, type=int)\n    parser.add_argument(\"--discrete_vae_weight_path\", type=str)\n    parser.add_argument(\"--discrete_vae_type\", type=str, default=\"dall-e\")\n    # Model parameters\n    parser.add_argument('--model', default='deit_base_patch16_224', type=str, metavar='MODEL',\n                        help='Name of model to train')\n    parser.add_argument('--rel_pos_bias', action='store_true')\n    parser.add_argument('--disable_rel_pos_bias', action='store_false', dest='rel_pos_bias')\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument('--abs_pos_emb', action='store_true')\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument('--layer_scale_init_value', default=0.1, type=float, \n                        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\")\n\n    parser.add_argument('--num_mask_patches', default=75, type=int,\n                        help='number of the visual tokens/patches need be masked')\n    parser.add_argument('--max_mask_patches_per_block', type=int, default=None)\n    parser.add_argument('--min_mask_patches_per_block', type=int, default=16)\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size for backbone')\n    parser.add_argument('--second_input_size', default=112, type=int,\n                        help='images input size for discrete vae')\n\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    # Optimizer parameters\n    parser.add_argument('--opt', default='adamw', type=str, metavar='OPTIMIZER',\n                        help='Optimizer (default: \"adamw\"')\n    parser.add_argument('--opt_eps', default=1e-8, type=float, metavar='EPSILON',\n                        help='Optimizer Epsilon (default: 1e-8)')\n    parser.add_argument('--opt_betas', default=None, type=float, nargs='+', metavar='BETA',\n                        help='Optimizer Betas (default: None, use opt default)')\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',\n                        help='SGD momentum (default: 0.9)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n    parser.add_argument('--weight_decay_end', type=float, default=None, help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD. \n        (Set the same value with args.weight_decay to keep weight decay no change)\"\"\")\n\n    parser.add_argument('--lr', type=float, default=5e-4, metavar='LR',\n                        help='learning rate (default: 5e-4)')\n    parser.add_argument('--warmup_lr', type=float, default=1e-6, metavar='LR',\n                        help='warmup learning rate (default: 1e-6)')\n    parser.add_argument('--min_lr', type=float, default=1e-5, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0 (1e-5)')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n    parser.add_argument('--warmup_steps', type=int, default=-1, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=0.4, metavar='PCT',\n                        help='Color jitter factor (default: 0.4)')\n    parser.add_argument('--train_interpolation', type=str, default='bicubic',\n                        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")')\n    parser.add_argument('--second_interpolation', type=str, default='lanczos',\n                        help='Interpolation for discrete vae (random, bilinear, bicubic default: \"lanczos\")')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--imagenet_default_mean_and_std', default=False, action='store_true')\n\n    parser.add_argument('--output_dir', default='',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default=None,\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='', help='resume from checkpoint')\n    parser.add_argument('--auto_resume', action='store_true')\n    parser.add_argument('--no_auto_resume', action='store_false', dest='auto_resume')\n    parser.set_defaults(auto_resume=False)\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem',\n                        help='')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--aug_level', default=-100, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://', help='url used to set up distributed training')\n\n    return parser.parse_args()\n\n\ndef get_model(args):\n    print(f\"Creating model: {args.model}\")\n    model = create_model(\n        args.model,\n        pretrained=False,\n        drop_path_rate=args.drop_path,\n        drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n    )\n\n    return model\n\n\ndef main(args):\n    utils.init_distributed_mode(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    model = get_model(args)\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (args.input_size // patch_size[0], args.input_size // patch_size[1])\n    args.patch_size = patch_size\n\n    # get dataset\n    dataset_train = build_beit_pretraining_dataset(args)\n\n    # prepare discrete vae\n    d_vae = utils.create_d_vae(\n        weight_path=args.discrete_vae_weight_path, d_vae_type=args.discrete_vae_type,\n        device=device, image_size=args.second_input_size)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_rank = global_rank\n        num_training_steps_per_epoch = len(dataset_train) // args.batch_size // num_tasks\n\n        print(\"pre-sampler\", num_tasks, global_rank, sampler_rank)\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=sampler_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    model.to(device)\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params:', n_parameters)\n\n    total_batch_size = args.batch_size * utils.get_world_size()\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Number of training steps = %d\" % num_training_steps_per_epoch)\n    print(\"Number of training examples per epoch = %d\" % (total_batch_size * num_training_steps_per_epoch))\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n        model_without_ddp = model.module\n\n    optimizer = create_optimizer(\n        args, model_without_ddp)\n    loss_scaler = NativeScaler()\n\n    print(\"Use step level LR & WD scheduler!\")\n    lr_schedule_values = utils.cosine_scheduler(\n        args.lr, args.min_lr, args.epochs, num_training_steps_per_epoch,\n        warmup_epochs=args.warmup_epochs, warmup_steps=args.warmup_steps,\n    )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay, args.weight_decay_end, args.epochs, num_training_steps_per_epoch)\n    print(\"Max WD = %.7f, Min WD = %.7f\" % (max(wd_schedule_values), min(wd_schedule_values)))\n\n    utils.auto_load_model(\n        args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch)\n        train_stats = train_one_epoch(\n            model, d_vae, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            args.clip_grad, log_writer=log_writer,\n            start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values,\n            wd_schedule_values=wd_schedule_values,\n        )\n        if args.output_dir:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                    loss_scaler=loss_scaler, epoch=epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                     'epoch': epoch, 'n_parameters': n_parameters}\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    opts = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/run_class_finetuning.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.nn as nn\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.data.mixup import Mixup\nfrom timm.models import create_model\nfrom timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy\nfrom timm.utils import ModelEma\nfrom optim_factory import create_optimizer, get_parameter_groups, LayerDecayValueAssigner\n\nfrom datasets import build_dataset\nfrom engine_for_finetuning import train_one_epoch, evaluate\nfrom utils import NativeScalerWithGradNormCount as NativeScaler\nimport utils\nfrom scipy import interpolate\nimport modeling_finetune\n\n\ndef get_args():\n    parser = argparse.ArgumentParser('BEiT fine-tuning and evaluation script for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int)\n    parser.add_argument('--epochs', default=30, type=int)\n    parser.add_argument('--update_freq', default=1, type=int)\n    parser.add_argument('--save_ckpt_freq', default=5, type=int)\n\n    # Model parameters\n    parser.add_argument('--model', default='deit_base_patch16_224', type=str, metavar='MODEL',\n                        help='Name of model to train')\n    parser.add_argument('--rel_pos_bias', action='store_true')\n    parser.add_argument('--disable_rel_pos_bias', action='store_false', dest='rel_pos_bias')\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument('--abs_pos_emb', action='store_true')\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument('--layer_scale_init_value', default=0.1, type=float, \n                        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\")\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--drop', type=float, default=0.0, metavar='PCT',\n                        help='Dropout rate (default: 0.)')\n    parser.add_argument('--attn_drop_rate', type=float, default=0.0, metavar='PCT',\n                        help='Attention dropout rate (default: 0.)')\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    parser.add_argument('--disable_eval_during_finetuning', action='store_true', default=False)\n\n    parser.add_argument('--model_ema', action='store_true', default=False)\n    parser.add_argument('--model_ema_decay', type=float, default=0.9999, help='')\n    parser.add_argument('--model_ema_force_cpu', action='store_true', default=False, help='')\n\n    # Optimizer parameters\n    parser.add_argument('--opt', default='adamw', type=str, metavar='OPTIMIZER',\n                        help='Optimizer (default: \"adamw\"')\n    parser.add_argument('--opt_eps', default=1e-8, type=float, metavar='EPSILON',\n                        help='Optimizer Epsilon (default: 1e-8)')\n    parser.add_argument('--opt_betas', default=None, type=float, nargs='+', metavar='BETA',\n                        help='Optimizer Betas (default: None, use opt default)')\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',\n                        help='SGD momentum (default: 0.9)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n    parser.add_argument('--weight_decay_end', type=float, default=None, help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD and using a larger decay by\n        the end of training improves performance for ViTs.\"\"\")\n\n    parser.add_argument('--lr', type=float, default=5e-4, metavar='LR',\n                        help='learning rate (default: 5e-4)')\n    parser.add_argument('--layer_decay', type=float, default=0.9)\n\n    parser.add_argument('--warmup_lr', type=float, default=1e-6, metavar='LR',\n                        help='warmup learning rate (default: 1e-6)')\n    parser.add_argument('--min_lr', type=float, default=1e-6, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0 (1e-5)')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n    parser.add_argument('--warmup_steps', type=int, default=-1, metavar='N',\n                        help='num of steps to warmup LR, will overload warmup_epochs if set > 0')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=0.4, metavar='PCT',\n                        help='Color jitter factor (default: 0.4)')\n    parser.add_argument('--aa', type=str, default='rand-m9-mstd0.5-inc1', metavar='NAME',\n                        help='Use AutoAugment policy. \"v0\" or \"original\". \" + \"(default: rand-m9-mstd0.5-inc1)'),\n    parser.add_argument('--smoothing', type=float, default=0.1,\n                        help='Label smoothing (default: 0.1)')\n    parser.add_argument('--train_interpolation', type=str, default='bicubic',\n                        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")')\n\n    # Evaluation parameters\n    parser.add_argument('--crop_pct', type=float, default=None)\n\n    # * Random Erase params\n    parser.add_argument('--reprob', type=float, default=0.25, metavar='PCT',\n                        help='Random erase prob (default: 0.25)')\n    parser.add_argument('--remode', type=str, default='pixel',\n                        help='Random erase mode (default: \"pixel\")')\n    parser.add_argument('--recount', type=int, default=1,\n                        help='Random erase count (default: 1)')\n    parser.add_argument('--resplit', action='store_true', default=False,\n                        help='Do not random erase first (clean) augmentation split')\n\n    # * Mixup params\n    parser.add_argument('--mixup', type=float, default=0,\n                        help='mixup alpha, mixup enabled if > 0.')\n    parser.add_argument('--cutmix', type=float, default=0,\n                        help='cutmix alpha, cutmix enabled if > 0.')\n    parser.add_argument('--cutmix_minmax', type=float, nargs='+', default=None,\n                        help='cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None)')\n    parser.add_argument('--mixup_prob', type=float, default=1.0,\n                        help='Probability of performing mixup or cutmix when either/both is enabled')\n    parser.add_argument('--mixup_switch_prob', type=float, default=0.5,\n                        help='Probability of switching to cutmix when both mixup and cutmix enabled')\n    parser.add_argument('--mixup_mode', type=str, default='batch',\n                        help='How to apply mixup/cutmix params. Per \"batch\", \"pair\", or \"elem\"')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--model_key', default='model|module', type=str)\n    parser.add_argument('--model_prefix', default='', type=str)\n    parser.add_argument('--init_scale', default=0.001, type=float)\n    parser.add_argument('--use_mean_pooling', action='store_true')\n    parser.set_defaults(use_mean_pooling=True)\n    parser.add_argument('--use_cls', action='store_false', dest='use_mean_pooling')\n    parser.add_argument('--disable_weight_decay_on_rel_pos_bias', action='store_true', default=False)\n    parser.add_argument('--target_layer', default=-1, type=int, help=\"target output layer (0-based)\")\n    parser.add_argument('--remove_final_norm', action='store_true', dest='remove_final_norm')\n    parser.add_argument('--reinit_final_norm', action='store_true', dest='reinit_final_norm')\n    parser.add_argument('--learn_layer_weights', action='store_true', dest='learn_layer_weights')  # supersede `target_layer`\n    parser.add_argument('--layernorm_before_combine', action='store_true', dest='layernorm_before_combine')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--eval_data_path', default=None, type=str,\n                        help='dataset path for evaluation')\n    parser.add_argument('--nb_classes', default=0, type=int,\n                        help='number of the classification types')\n    parser.add_argument('--linear_classifier', action='store_true',\n                        help='linear classifier')\n    parser.add_argument('--imagenet_default_mean_and_std', default=False, action='store_true')\n\n    parser.add_argument('--data_set', default='IMNET', choices=['CIFAR', 'IMNET', 'image_folder'],\n                        type=str, help='ImageNet dataset path')\n    parser.add_argument('--data_set_filter_file', type=str, default=None, help=\"path to filter to filter dataset\")\n    parser.add_argument('--output_dir', default='',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default=None,\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n    parser.add_argument('--auto_resume', action='store_true')\n    parser.add_argument('--no_auto_resume', action='store_false', dest='auto_resume')\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument('--save_ckpt', action='store_true')\n    parser.add_argument('--no_save_ckpt', action='store_false', dest='save_ckpt')\n    parser.set_defaults(save_ckpt=True)\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    parser.add_argument('--enable_deepspeed', action='store_true', default=False)\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=0,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n\n    known_args, _ = parser.parse_known_args()\n\n    if known_args.enable_deepspeed:\n        try:\n            print(\"why\")\n            import deepspeed\n            print(\"Imported deepspeed\")\n            from deepspeed import DeepSpeedConfig\n            print(\"Imported config\")\n            parser = deepspeed.add_config_arguments(parser)\n            print(\"Created parser\")\n            ds_init = deepspeed.initialize\n            print(\"Inited deepspeed\")\n        except:\n            print(\"Please 'pip install deepspeed==0.4.0'\")\n            exit(0)\n    else:\n        ds_init = None\n\n    return parser.parse_args(), ds_init\n\n\ndef main(args, ds_init):\n    utils.init_distributed_mode(args)\n\n    if ds_init is not None:\n        utils.create_ds_config(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    dataset_train, args.nb_classes = build_dataset(is_train=True, args=args)\n    if args.disable_eval_during_finetuning:\n        dataset_val = None\n    else:\n        dataset_val, _ = build_dataset(is_train=False, args=args)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=False)\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    if dataset_val is not None:\n        data_loader_val = torch.utils.data.DataLoader(\n            dataset_val, sampler=sampler_val,\n            batch_size=int(1.5 * args.batch_size),\n            num_workers=args.num_workers,\n            pin_memory=args.pin_mem,\n            drop_last=False\n        )\n    else:\n        data_loader_val = None\n\n    mixup_fn = None\n    mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None\n    if mixup_active:\n        print(\"Mixup is activated!\")\n        mixup_fn = Mixup(\n            mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax,\n            prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode,\n            label_smoothing=args.smoothing, num_classes=args.nb_classes)\n\n    model = create_model(\n        args.model,\n        pretrained=False,\n        num_classes=args.nb_classes,\n        drop_rate=args.drop,\n        drop_path_rate=args.drop_path,\n        attn_drop_rate=args.attn_drop_rate,\n        drop_block_rate=None,\n        use_mean_pooling=args.use_mean_pooling,\n        init_scale=args.init_scale,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        linear_classifier=args.linear_classifier,\n        has_masking=args.num_mask_patches > 0,\n        learn_layer_weights=args.learn_layer_weights,\n        layernorm_before_combine=args.layernorm_before_combine,\n    )\n\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (args.input_size // patch_size[0], args.input_size // patch_size[1])\n    args.patch_size = patch_size\n\n    masked_position_generator = None\n    if args.num_mask_patches > 0:\n        from masking_generator import MaskingGenerator\n        masked_position_generator = MaskingGenerator(\n            args.window_size, num_masking_patches=args.num_mask_patches,\n            max_num_patches=args.max_mask_patches_per_block,\n            min_num_patches=args.min_mask_patches_per_block,\n        )\n\n    if args.finetune:\n        if args.finetune.startswith('https'):\n            checkpoint = torch.hub.load_state_dict_from_url(\n                args.finetune, map_location='cpu', check_hash=True)\n        else:\n            checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load ckpt from %s\" % args.finetune)\n        checkpoint_model = None\n        for model_key in args.model_key.split('|'):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n        if args.reinit_final_norm:\n            for k in ['norm.weight', 'norm.bias', 'fc_norm.weight', 'fc_norm.bias']:\n                if k in checkpoint_model:\n                    print(f\"Removing key {k} from pretrained checkpoint\")\n                    del checkpoint_model[k]\n\n        if model.use_rel_pos_bias and \"rel_pos_bias.relative_position_bias_table\" in checkpoint_model:\n            print(\"Expand the shared relative position embedding to each transformer block. \")\n            num_layers = model.get_num_layers()\n            rel_pos_bias = checkpoint_model[\"rel_pos_bias.relative_position_bias_table\"]\n            for i in range(num_layers):\n                checkpoint_model[\"blocks.%d.attn.relative_position_bias_table\" % i] = rel_pos_bias.clone()\n\n            checkpoint_model.pop(\"rel_pos_bias.relative_position_bias_table\")\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (dst_patch_shape[1] * 2 - 1)\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\"Position interpolate for %s from %dx%d to %dx%d\" % (\n                        key, src_size, src_size, dst_size, dst_size))\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind='cubic')\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy)).contiguous().view(-1, 1).to(rel_pos_bias.device))\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if 'pos_embed' in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model['pos_embed']\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model['pos_embed'] = new_pos_embed\n\n        if not args.learn_layer_weights and args.target_layer != -1:\n            print(f\"model target layer is {args.target_layer}\")\n            model.blocks = model.blocks[:args.target_layer+1]\n\n        if args.remove_final_norm:\n            print(f\"removing final norm by replacing it with Identity\")\n            model.norm = None if model.norm is None else nn.Identity()\n            model.fc_norm = None if model.fc_norm is None else nn.Identity()\n\n        if args.linear_classifier:\n            frozen_params = (\n                set(n for n, _ in model.named_parameters())\n                & set(checkpoint_model.keys())\n            )\n            for n, p in model.named_parameters():\n                if n in frozen_params:\n                    p.requires_grad_(False)\n            param_names = [n for n, p in model.named_parameters() if p.requires_grad]\n            print(f\"Trainable weights: {param_names}\")\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n        # model.load_state_dict(checkpoint_model, strict=False)\n\n    model.to(device)\n\n    model_ema = None\n    if args.model_ema:\n        # Important to create EMA model after cuda(), DP wrapper, and AMP but before SyncBN and DDP wrapper\n        model_ema = ModelEma(\n            model,\n            decay=args.model_ema_decay,\n            device='cpu' if args.model_ema_force_cpu else '',\n            resume='')\n        print(\"Using EMA with decay = %.8f\" % args.model_ema_decay)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params:', n_parameters)\n\n    total_batch_size = args.batch_size * args.update_freq * utils.get_world_size()\n    num_training_steps_per_epoch = len(dataset_train) // total_batch_size\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Update frequent = %d\" % args.update_freq)\n    print(\"Number of training examples = %d\" % len(dataset_train))\n    print(\"Number of training training per epoch = %d\" % num_training_steps_per_epoch)\n\n    num_layers = model_without_ddp.get_num_layers()\n    if args.layer_decay < 1.0:\n        assigner = LayerDecayValueAssigner(list(args.layer_decay ** (num_layers + 1 - i) for i in range(num_layers + 2)))\n    else:\n        assigner = None\n\n    if assigner is not None:\n        print(\"Assigned values = %s\" % str(assigner.values))\n\n    skip_weight_decay_list = model.no_weight_decay()\n    if args.disable_weight_decay_on_rel_pos_bias:\n        for i in range(num_layers):\n            skip_weight_decay_list.add(\"blocks.%d.attn.relative_position_bias_table\" % i)\n\n    if args.enable_deepspeed:\n        loss_scaler = None\n        optimizer_params = get_parameter_groups(\n            model, args.weight_decay, skip_weight_decay_list,\n            assigner.get_layer_id if assigner is not None else None,\n            assigner.get_scale if assigner is not None else None)\n        model, optimizer, _, _ = ds_init(\n            args=args, model=model, model_parameters=optimizer_params, dist_init_required=not args.distributed,\n        )\n\n        print(\"model.gradient_accumulation_steps() = %d\" % model.gradient_accumulation_steps())\n        assert model.gradient_accumulation_steps() == args.update_freq\n    else:\n        if args.distributed:\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n            model_without_ddp = model.module\n\n        optimizer = create_optimizer(\n            args, model_without_ddp, skip_list=skip_weight_decay_list,\n            get_num_layer=assigner.get_layer_id if assigner is not None else None, \n            get_layer_scale=assigner.get_scale if assigner is not None else None)\n        loss_scaler = NativeScaler()\n\n    print(\"Use step level LR scheduler!\")\n    lr_schedule_values = utils.cosine_scheduler(\n        args.lr, args.min_lr, args.epochs, num_training_steps_per_epoch,\n        warmup_epochs=args.warmup_epochs, warmup_steps=args.warmup_steps,\n    )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay, args.weight_decay_end, args.epochs, num_training_steps_per_epoch)\n    print(\"Max WD = %.7f, Min WD = %.7f\" % (max(wd_schedule_values), min(wd_schedule_values)))\n\n    if mixup_fn is not None:\n        # smoothing is handled with mixup label transform\n        criterion = SoftTargetCrossEntropy()\n    elif args.smoothing > 0.:\n        criterion = LabelSmoothingCrossEntropy(smoothing=args.smoothing)\n    else:\n        criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    utils.auto_load_model(\n        args=args, model=model, model_without_ddp=model_without_ddp,\n        optimizer=optimizer, loss_scaler=loss_scaler, model_ema=model_ema)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch * args.update_freq)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train, optimizer,\n            device, epoch, loss_scaler, args.clip_grad, model_ema, mixup_fn,\n            log_writer=log_writer, start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values, wd_schedule_values=wd_schedule_values,\n            num_training_steps_per_epoch=num_training_steps_per_epoch, update_freq=args.update_freq,\n            masked_position_generator=masked_position_generator,\n        )\n        if args.output_dir and args.save_ckpt:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                    loss_scaler=loss_scaler, epoch=epoch, model_ema=model_ema)\n        if data_loader_val is not None:\n            test_stats = evaluate(data_loader_val, model, device)\n            print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            if max_accuracy < test_stats[\"acc1\"]:\n                max_accuracy = test_stats[\"acc1\"]\n                if args.output_dir and args.save_ckpt:\n                    utils.save_model(\n                        args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                        loss_scaler=loss_scaler, epoch=\"best\", model_ema=model_ema)\n\n            print(f'Max accuracy: {max_accuracy:.2f}%')\n            if log_writer is not None:\n                log_writer.update(test_acc1=test_stats['acc1'], head=\"perf\", step=epoch)\n                log_writer.update(test_acc5=test_stats['acc5'], head=\"perf\", step=epoch)\n                log_writer.update(test_loss=test_stats['loss'], head=\"perf\", step=epoch)\n\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n        else:\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         # **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    opts, ds_init = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts, ds_init)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/run_cyclical.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\nimport timm\nfrom pathlib import Path\n\nfrom timm.models import create_model\nfrom timm.utils import ModelEmaV2\nfrom optim_factory import create_optimizer\n\nfrom datasets import build_beit_pretraining_dataset\nfrom engine_for_cyclical import train_one_epoch\nfrom utils import NativeScalerWithGradNormCount as NativeScaler\nfrom . import utils\nfrom scipy import interpolate\nimport modeling_cyclical\n#from models import beit_base_patch16_224\n\n\ndef get_args():\n    print(timm.__version__)\n    print(torch.__version__)\n    parser = argparse.ArgumentParser(\"BEiT pre-training script\", add_help=False)\n    parser.add_argument(\"--batch_size\", default=64, type=int)\n    parser.add_argument(\"--epochs\", default=300, type=int)\n    parser.add_argument(\"--save_ckpt_freq\", default=10, type=int)\n    # Model parameters\n    parser.add_argument(\n        \"--model\",\n        default=\"deit_base_patch16_224\",\n        type=str,\n        metavar=\"MODEL\",\n        help=\"Name of model to train\",\n    )\n    parser.add_argument(\"--rel_pos_bias\", action=\"store_true\")\n    parser.add_argument(\n        \"--disable_rel_pos_bias\", action=\"store_false\", dest=\"rel_pos_bias\"\n    )\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument(\"--abs_pos_emb\", action=\"store_true\")\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument(\n        \"--layer_scale_init_value\",\n        default=0.1,\n        type=float,\n        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\",\n    )\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=75,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n\n    parser.add_argument(\n        \"--input_size\", default=224, type=int, help=\"images input size for backbone\"\n    )\n\n    parser.add_argument(\n        \"--drop_path\",\n        type=float,\n        default=0.1,\n        metavar=\"PCT\",\n        help=\"Drop path rate (default: 0.1)\",\n    )\n\n    # Optimizer parameters\n    parser.add_argument(\n        \"--opt\",\n        default=\"adamw\",\n        type=str,\n        metavar=\"OPTIMIZER\",\n        help='Optimizer (default: \"adamw\"',\n    )\n    parser.add_argument(\n        \"--opt_eps\",\n        default=1e-8,\n        type=float,\n        metavar=\"EPSILON\",\n        help=\"Optimizer Epsilon (default: 1e-8)\",\n    )\n    parser.add_argument(\n        \"--opt_betas\",\n        default=None,\n        type=float,\n        nargs=\"+\",\n        metavar=\"BETA\",\n        help=\"Optimizer Betas (default: None, use opt default)\",\n    )\n    parser.add_argument(\n        \"--clip_grad\",\n        type=float,\n        default=None,\n        metavar=\"NORM\",\n        help=\"Clip gradient norm (default: None, no clipping)\",\n    )\n    parser.add_argument(\n        \"--momentum\",\n        type=float,\n        default=0.9,\n        metavar=\"M\",\n        help=\"SGD momentum (default: 0.9)\",\n    )\n    parser.add_argument(\n        \"--weight_decay\", type=float, default=0.05, help=\"weight decay (default: 0.05)\"\n    )\n    parser.add_argument(\n        \"--weight_decay_end\",\n        type=float,\n        default=None,\n        help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD. \n        (Set the same value with args.weight_decay to keep weight decay no change)\"\"\",\n    )\n\n    parser.add_argument(\n        \"--lr\",\n        type=float,\n        default=5e-4,\n        metavar=\"LR\",\n        help=\"learning rate (default: 5e-4)\",\n    )\n    parser.add_argument(\n        \"--warmup_lr\",\n        type=float,\n        default=1e-6,\n        metavar=\"LR\",\n        help=\"warmup learning rate (default: 1e-6)\",\n    )\n    parser.add_argument(\n        \"--min_lr\",\n        type=float,\n        default=1e-5,\n        metavar=\"LR\",\n        help=\"lower lr bound for cyclic schedulers that hit 0 (1e-5)\",\n    )\n\n    parser.add_argument(\n        \"--tri_phase_schedule\",\n        type=str,\n        default=None,\n        help=\"string containing a tuple with phase ratios for warmup and decay. e.g. '(0.05,0.15) means 5% warmup, 80% hold, 15% decay\",\n    )\n\n    parser.add_argument(\n        \"--warmup_epochs\",\n        type=int,\n        default=5,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n    parser.add_argument(\n        \"--warmup_steps\",\n        type=int,\n        default=-1,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n\n    # Augmentation parameters\n    parser.add_argument(\n        \"--color_jitter\",\n        type=float,\n        default=0.4,\n        metavar=\"PCT\",\n        help=\"Color jitter factor (default: 0.4)\",\n    )\n    parser.add_argument(\n        \"--train_interpolation\",\n        type=str,\n        default=\"bicubic\",\n        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")',\n    )\n    parser.add_argument(\"--aug_level\", default=-1, type=int)\n\n\n    parser.add_argument(\n        \"--target_layers\", type=str, default=\"[]\", help=\"target layers (python list)\"\n    )\n\n    # Dataset parameters\n    parser.add_argument(\n        \"--data_path\",\n        default=\"/datasets01/imagenet_full_size/061417/\",\n        type=str,\n        help=\"dataset path\",\n    )\n    parser.add_argument(\n        \"--imagenet_default_mean_and_std\", default=False, action=\"store_true\"\n    )\n\n    parser.add_argument(\n        \"--output_dir\", default=\"\", help=\"path where to save, empty for no saving\"\n    )\n    parser.add_argument(\"--log_dir\", default=None, help=\"path where to tensorboard log\")\n    parser.add_argument(\n        \"--device\", default=\"cuda\", help=\"device to use for training / testing\"\n    )\n    parser.add_argument(\"--seed\", default=0, type=int)\n    parser.add_argument(\"--resume\", default=\"\", help=\"resume from checkpoint\")\n    parser.add_argument(\"--auto_resume\", action=\"store_true\")\n    parser.add_argument(\"--no_auto_resume\", action=\"store_false\", dest=\"auto_resume\")\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument(\"--ema_decay_init\", default=0.999, type=float)\n    parser.add_argument(\"--ema_decay\", default=0.9998, type=float)\n    parser.add_argument(\"--ema_start_at\", default=25000, type=int)\n\n    parser.add_argument(\n        \"--start_epoch\", default=0, type=int, metavar=\"N\", help=\"start epoch\"\n    )\n    parser.add_argument(\"--num_workers\", default=10, type=int)\n    parser.add_argument(\n        \"--pin_mem\",\n        action=\"store_true\",\n        help=\"Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.\",\n    )\n    parser.add_argument(\"--no_pin_mem\", action=\"store_false\", dest=\"pin_mem\", help=\"\")\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument(\n        \"--world_size\", default=1, type=int, help=\"number of distributed processes\"\n    )\n    parser.add_argument(\"--local_rank\", default=-1, type=int)\n    parser.add_argument(\"--dist_on_itp\", action=\"store_true\")\n    parser.add_argument(\n        \"--dist_url\", default=\"env://\", help=\"url used to set up distributed training\"\n    )\n\n    parser.add_argument(\"--seed_model\", default=None, type=str, help=\"seed model\")\n    parser.add_argument(\"--model_key\", default=\"model|module\", type=str)\n    parser.add_argument(\"--model_prefix\", default=\"\", type=str)\n\n    parser.add_argument(\"--l2_loss\", default=False, action=\"store_true\")\n    parser.add_argument(\"--l1_beta\", default=0.12, type=float)\n\n    parser.add_argument(\"--layer_results\", default=\"end\", type=str)\n\n    parser.add_argument(\"--var_w0\", default=0., type=float)\n    parser.add_argument(\"--var_w1\", default=0., type=float)\n    parser.add_argument(\"--var_margin0\", default=0.5, type=float)\n    parser.add_argument(\"--var_margin1\", default=0.5, type=float)\n    parser.add_argument(\"--skip_ema_during_lr_decay_for_tri\", action=\"store_true\")\n    parser.add_argument(\"--loss_scale\", default=-1, type=float)\n    parser.add_argument(\"--ema_annealing_till_end\", default=False, action=\"store_true\")\n    parser.add_argument(\"--attn_drop_rate\", default=0.0, type=float)\n    parser.add_argument(\"--mask_dropout_prob\", default=-1.0, type=float, help=\"prob of flipping already masked position to unmasked\")\n\n    #target_layer_norm_last=True, target_batch_norm=False, target_instance_norm=False\n    parser.add_argument(\"--no_target_layer_norm_last\", default=False, action=\"store_true\")\n    parser.add_argument(\"--target_batch_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--target_instance_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--post_target_instance_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--post_target_layer_norm\", default=False, action=\"store_true\")\n\n    return parser.parse_args()\n\n\ndef get_model(args):\n    print(f\"Creating model: {args.model}\")\n    if args.model == 'beit_base_patch16_224' and False:\n        model = beit_base_patch16_224(drop_path_rate=args.drop_path,\n        #drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        attn_drop_rate=args.attn_drop_rate)\n    \n    model = create_model(\n        args.model,\n        pretrained=False,\n        drop_path_rate=args.drop_path,\n        drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        attn_drop_rate=args.attn_drop_rate,\n    )\n\n    return model\n\n\ndef main(args):\n    utils.init_distributed_mode(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    model = get_model(args)\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (\n        args.input_size // patch_size[0],\n        args.input_size // patch_size[1],\n    )\n    args.patch_size = patch_size\n\n    if args.seed_model:\n        checkpoint = torch.load(args.seed_model, map_location=\"cpu\")\n        print(\"Load ckpt from %s\" % args.seed_model)\n\n        checkpoint_model = None\n        for model_key in args.model_key.split(\"|\"):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in [\"head.weight\", \"head.bias\"]:\n            if (\n                k in checkpoint_model\n                and checkpoint_model[k].shape != state_dict[k].shape\n            ):\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (\n                    dst_patch_shape[1] * 2 - 1\n                )\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\n                        \"Position interpolate for %s from %dx%d to %dx%d\"\n                        % (key, src_size, src_size, dst_size, dst_size)\n                    )\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind=\"cubic\")\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy))\n                            .contiguous()\n                            .view(-1, 1)\n                            .to(rel_pos_bias.device)\n                        )\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if \"pos_embed\" in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model[\"pos_embed\"]\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\n                    \"Position interpolate from %dx%d to %dx%d\"\n                    % (orig_size, orig_size, new_size, new_size)\n                )\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(\n                    -1, orig_size, orig_size, embedding_size\n                ).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens,\n                    size=(new_size, new_size),\n                    mode=\"bicubic\",\n                    align_corners=False,\n                )\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model[\"pos_embed\"] = new_pos_embed\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n\n    # get dataset\n    dataset_train = build_beit_pretraining_dataset(args)\n    print(dataset_train)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_rank = global_rank\n        num_training_steps_per_epoch = (\n            len(dataset_train) // args.batch_size // num_tasks\n        )\n\n        print(\"pre-sampler\", num_tasks, global_rank, sampler_rank)\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=sampler_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train,\n        sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    model.to(device)\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print(\"number of params:\", n_parameters)\n\n    model_ema = ModelEmaV2(model, decay=args.ema_decay)\n    print(\"Using EMA with decay = %.8f\" % args.ema_decay)\n\n    total_batch_size = args.batch_size * utils.get_world_size()\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Number of training steps = %d\" % num_training_steps_per_epoch)\n    print(\n        \"Number of training examples per epoch = %d\"\n        % (total_batch_size * num_training_steps_per_epoch)\n    )\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(\n            model, device_ids=[args.gpu], find_unused_parameters=True\n        )\n        model_without_ddp = model.module\n\n    optimizer = create_optimizer(args, model_without_ddp)\n    loss_scaler = NativeScaler()\n\n    start_lr_decay_at_step = -1\n    if args.tri_phase_schedule is not None:\n        from ast import literal_eval\n        warmup_phase, decay_phase = literal_eval(args.tri_phase_schedule)\n        print(\"Use tri phase lr schedule!\", warmup_phase, decay_phase)\n        lr_schedule_values = utils.tri_phase_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_perc=warmup_phase,\n            decay_perc=decay_phase,\n        )\n        if args.skip_ema_during_lr_decay_for_tri:\n            start_lr_decay_at_step= (1-decay_phase)*args.epochs*num_training_steps_per_epoch\n            print(\"ema will be skipped after \"+str(start_lr_decay_at_step)+\" updates\")\n    else:\n        print(\"Use step level LR & WD scheduler!\")\n        lr_schedule_values = utils.cosine_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_epochs=args.warmup_epochs,\n            warmup_steps=args.warmup_steps,\n        )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay,\n        args.weight_decay_end,\n        args.epochs,\n        num_training_steps_per_epoch,\n    )\n    print(\n        \"Max WD = %.7f, Min WD = %.7f\"\n        % (max(wd_schedule_values), min(wd_schedule_values))\n    )\n\n    utils.auto_load_model(\n        args=args,\n        model=model,\n        model_without_ddp=model_without_ddp,\n        optimizer=optimizer,\n        loss_scaler=loss_scaler,\n        model_ema=model_ema,\n    )\n\n    from ast import literal_eval\n\n    target_layers = literal_eval(args.target_layers)\n    assert len(target_layers) > 0\n    print(f\"target layers: {target_layers}\")\n\n    print(f\"Start training for {args.epochs} epochs\")\n\n    if args.ema_annealing_till_end:\n        args.ema_start_at = args.epochs * num_training_steps_per_epoch\n        print(f\"EMA annealing till the end activated\")\n\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch)\n        train_stats = train_one_epoch(\n            model,\n            model_ema,\n            args.ema_start_at,\n            args.ema_decay_init,\n            args.ema_decay,\n            target_layers,\n            data_loader_train,\n            optimizer,\n            device,\n            epoch,\n            loss_scaler,\n            args.clip_grad,\n            l1_beta=args.l1_beta,\n            log_writer=log_writer,\n            start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values,\n            wd_schedule_values=wd_schedule_values,\n            l2_loss=args.l2_loss,\n            layer_results=args.layer_results,\n            var_w0=args.var_w0, var_w1=args.var_w1, \n            var_margin0=args.var_margin0, var_margin1=args.var_margin1,\n            start_lr_decay_at_step=start_lr_decay_at_step,\n            loss_scale=args.loss_scale,\n            mask_dropout_prob=args.mask_dropout_prob,\n            target_layer_norm_last=not args.no_target_layer_norm_last, target_batch_norm=args.target_batch_norm, target_instance_norm=args.target_instance_norm,\n            post_target_instance_norm=args.post_target_instance_norm,\n            post_target_layer_norm=args.post_target_layer_norm\n        )\n\n        if args.output_dir:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args,\n                    model=model,\n                    model_without_ddp=model_without_ddp,\n                    optimizer=optimizer,\n                    loss_scaler=loss_scaler,\n                    epoch=epoch,\n                    model_ema=model_ema,\n                )\n\n        log_stats = {\n            **{f\"train_{k}\": v for k, v in train_stats.items()},\n            \"epoch\": epoch,\n            \"n_parameters\": n_parameters,\n        }\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(\n                os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\"\n            ) as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print(\"Training time {}\".format(total_time_str))\n\n\nif __name__ == \"__main__\":\n    opts = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/run_cyclical_joint.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.models import create_model\nfrom timm.utils import ModelEmaV2\nfrom optim_factory import create_optimizer\n\nfrom datasets import build_beit_pretraining_dataset\nfrom engine_for_cyclical_joint import train_one_epoch\nfrom utils import NativeScalerWithGradNormCount as NativeScaler\nimport utils\nfrom scipy import interpolate\nimport modeling_cyclical_joint\n\n\ndef get_args():\n    parser = argparse.ArgumentParser(\"BEiT pre-training script\", add_help=False)\n    parser.add_argument(\"--batch_size\", default=64, type=int)\n    parser.add_argument(\"--epochs\", default=300, type=int)\n    parser.add_argument(\"--save_ckpt_freq\", default=10, type=int)\n    # Model parameters\n    parser.add_argument(\n        \"--model\",\n        default=\"deit_base_patch16_224\",\n        type=str,\n        metavar=\"MODEL\",\n        help=\"Name of model to train\",\n    )\n    parser.add_argument(\"--rel_pos_bias\", action=\"store_true\")\n    parser.add_argument(\n        \"--disable_rel_pos_bias\", action=\"store_false\", dest=\"rel_pos_bias\"\n    )\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument(\"--abs_pos_emb\", action=\"store_true\")\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument(\n        \"--layer_scale_init_value\",\n        default=0.1,\n        type=float,\n        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\",\n    )\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=75,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n\n    parser.add_argument(\n        \"--input_size\", default=224, type=int, help=\"images input size for backbone\"\n    )\n\n    # added for vae\n    parser.add_argument('--second_input_size', default=112, type=int,\n                        help='images input size for discrete vae')\n    parser.add_argument('--second_interpolation', type=str, default='lanczos',\n                        help='Interpolation for discrete vae (random, bilinear, bicubic default: \"lanczos\")')\n    parser.add_argument(\"--discrete_vae_weight_path\", type=str)\n    parser.add_argument(\"--discrete_vae_type\", type=str, default=\"dall-e\")\n    parser.add_argument(\"--vae_loss_weight\", default=1., type=float)\n\n    parser.add_argument(\n        \"--drop_path\",\n        type=float,\n        default=0.1,\n        metavar=\"PCT\",\n        help=\"Drop path rate (default: 0.1)\",\n    )\n\n    # Optimizer parameters\n    parser.add_argument(\n        \"--opt\",\n        default=\"adamw\",\n        type=str,\n        metavar=\"OPTIMIZER\",\n        help='Optimizer (default: \"adamw\"',\n    )\n    parser.add_argument(\n        \"--opt_eps\",\n        default=1e-8,\n        type=float,\n        metavar=\"EPSILON\",\n        help=\"Optimizer Epsilon (default: 1e-8)\",\n    )\n    parser.add_argument(\n        \"--opt_betas\",\n        default=None,\n        type=float,\n        nargs=\"+\",\n        metavar=\"BETA\",\n        help=\"Optimizer Betas (default: None, use opt default)\",\n    )\n    parser.add_argument(\n        \"--clip_grad\",\n        type=float,\n        default=None,\n        metavar=\"NORM\",\n        help=\"Clip gradient norm (default: None, no clipping)\",\n    )\n    parser.add_argument(\n        \"--momentum\",\n        type=float,\n        default=0.9,\n        metavar=\"M\",\n        help=\"SGD momentum (default: 0.9)\",\n    )\n    parser.add_argument(\n        \"--weight_decay\", type=float, default=0.05, help=\"weight decay (default: 0.05)\"\n    )\n    parser.add_argument(\n        \"--weight_decay_end\",\n        type=float,\n        default=None,\n        help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD. \n        (Set the same value with args.weight_decay to keep weight decay no change)\"\"\",\n    )\n\n    parser.add_argument(\n        \"--lr\",\n        type=float,\n        default=5e-4,\n        metavar=\"LR\",\n        help=\"learning rate (default: 5e-4)\",\n    )\n    parser.add_argument(\n        \"--warmup_lr\",\n        type=float,\n        default=1e-6,\n        metavar=\"LR\",\n        help=\"warmup learning rate (default: 1e-6)\",\n    )\n    parser.add_argument(\n        \"--min_lr\",\n        type=float,\n        default=1e-5,\n        metavar=\"LR\",\n        help=\"lower lr bound for cyclic schedulers that hit 0 (1e-5)\",\n    )\n\n    parser.add_argument(\n        \"--tri_phase_schedule\",\n        type=str,\n        default=None,\n        help=\"string containing a tuple with phase ratios for warmup and decay. e.g. '(0.05,0.15) means 5% warmup, 80% hold, 15% decay\",\n    )\n\n    parser.add_argument(\n        \"--warmup_epochs\",\n        type=int,\n        default=5,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n    parser.add_argument(\n        \"--warmup_steps\",\n        type=int,\n        default=-1,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n\n    # Augmentation parameters\n    parser.add_argument(\n        \"--color_jitter\",\n        type=float,\n        default=0.4,\n        metavar=\"PCT\",\n        help=\"Color jitter factor (default: 0.4)\",\n    )\n    parser.add_argument(\n        \"--train_interpolation\",\n        type=str,\n        default=\"bicubic\",\n        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")',\n    )\n\n    parser.add_argument(\n        \"--target_layers\", type=str, default=\"[]\", help=\"target layers (python list)\"\n    )\n\n    # Dataset parameters\n    parser.add_argument(\n        \"--data_path\",\n        default=\"/datasets01/imagenet_full_size/061417/\",\n        type=str,\n        help=\"dataset path\",\n    )\n    parser.add_argument(\n        \"--imagenet_default_mean_and_std\", default=False, action=\"store_true\"\n    )\n\n    parser.add_argument(\n        \"--output_dir\", default=\"\", help=\"path where to save, empty for no saving\"\n    )\n    parser.add_argument(\"--log_dir\", default=None, help=\"path where to tensorboard log\")\n    parser.add_argument(\n        \"--device\", default=\"cuda\", help=\"device to use for training / testing\"\n    )\n    parser.add_argument(\"--seed\", default=0, type=int)\n    parser.add_argument(\"--resume\", default=\"\", help=\"resume from checkpoint\")\n    parser.add_argument(\"--auto_resume\", action=\"store_true\")\n    parser.add_argument(\"--no_auto_resume\", action=\"store_false\", dest=\"auto_resume\")\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument(\"--ema_decay\", default=0.9998, type=float)\n    parser.add_argument(\"--ema_start_at\", default=25000, type=int)\n\n    parser.add_argument(\n        \"--start_epoch\", default=0, type=int, metavar=\"N\", help=\"start epoch\"\n    )\n    parser.add_argument(\"--num_workers\", default=10, type=int)\n    parser.add_argument(\n        \"--pin_mem\",\n        action=\"store_true\",\n        help=\"Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.\",\n    )\n    parser.add_argument(\"--no_pin_mem\", action=\"store_false\", dest=\"pin_mem\", help=\"\")\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument(\n        \"--world_size\", default=1, type=int, help=\"number of distributed processes\"\n    )\n    parser.add_argument(\"--local_rank\", default=-1, type=int)\n    parser.add_argument(\"--dist_on_itp\", action=\"store_true\")\n    parser.add_argument(\n        \"--dist_url\", default=\"env://\", help=\"url used to set up distributed training\"\n    )\n\n    parser.add_argument(\"--seed_model\", default=None, type=str, help=\"seed model\")\n    parser.add_argument(\"--model_key\", default=\"model|module\", type=str)\n    parser.add_argument(\"--model_prefix\", default=\"\", type=str)\n\n    parser.add_argument(\"--l2_loss\", default=False, action=\"store_true\")\n    parser.add_argument(\"--l1_beta\", default=0.12, type=float)\n\n    return parser.parse_args()\n\n\ndef get_model(args):\n    print(f\"Creating model: {args.model}\")\n    model = create_model(\n        args.model,\n        pretrained=False,\n        drop_path_rate=args.drop_path,\n        drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n    )\n\n    return model\n\n\ndef main(args):\n    utils.init_distributed_mode(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    model = get_model(args)\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (\n        args.input_size // patch_size[0],\n        args.input_size // patch_size[1],\n    )\n    args.patch_size = patch_size\n\n    if args.seed_model:\n        checkpoint = torch.load(args.seed_model, map_location=\"cpu\")\n        print(\"Load ckpt from %s\" % args.seed_model)\n\n        checkpoint_model = None\n        for model_key in args.model_key.split(\"|\"):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in [\"head.weight\", \"head.bias\"]:\n            if (\n                k in checkpoint_model\n                and checkpoint_model[k].shape != state_dict[k].shape\n            ):\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (\n                    dst_patch_shape[1] * 2 - 1\n                )\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\n                        \"Position interpolate for %s from %dx%d to %dx%d\"\n                        % (key, src_size, src_size, dst_size, dst_size)\n                    )\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind=\"cubic\")\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy))\n                            .contiguous()\n                            .view(-1, 1)\n                            .to(rel_pos_bias.device)\n                        )\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if \"pos_embed\" in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model[\"pos_embed\"]\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\n                    \"Position interpolate from %dx%d to %dx%d\"\n                    % (orig_size, orig_size, new_size, new_size)\n                )\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(\n                    -1, orig_size, orig_size, embedding_size\n                ).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens,\n                    size=(new_size, new_size),\n                    mode=\"bicubic\",\n                    align_corners=False,\n                )\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model[\"pos_embed\"] = new_pos_embed\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n\n    # get dataset\n    dataset_train = build_beit_pretraining_dataset(args)\n\n    # prepare discrete vae\n    d_vae = utils.create_d_vae(\n        weight_path=args.discrete_vae_weight_path, d_vae_type=args.discrete_vae_type,\n        device=device, image_size=args.second_input_size)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_rank = global_rank\n        num_training_steps_per_epoch = (\n            len(dataset_train) // args.batch_size // num_tasks\n        )\n\n        print(\"pre-sampler\", num_tasks, global_rank, sampler_rank)\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=sampler_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train,\n        sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    model.to(device)\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print(\"number of params:\", n_parameters)\n\n    model_ema = ModelEmaV2(model, decay=args.ema_decay)\n    print(\"Using EMA with decay = %.8f\" % args.ema_decay)\n\n    total_batch_size = args.batch_size * utils.get_world_size()\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Number of training steps = %d\" % num_training_steps_per_epoch)\n    print(\n        \"Number of training examples per epoch = %d\"\n        % (total_batch_size * num_training_steps_per_epoch)\n    )\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(\n            model, device_ids=[args.gpu], find_unused_parameters=True\n        )\n        model_without_ddp = model.module\n\n    optimizer = create_optimizer(args, model_without_ddp)\n    loss_scaler = NativeScaler()\n\n    if args.tri_phase_schedule is not None:\n        from ast import literal_eval\n        warmup_phase, decay_phase = literal_eval(args.tri_phase_schedule)\n        print(\"Use tri phase lr schedule!\", warmup_phase, decay_phase)\n        lr_schedule_values = utils.tri_phase_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_perc=warmup_phase,\n            decay_perc=decay_phase,\n        )\n    else:\n        print(\"Use step level LR & WD scheduler!\")\n        lr_schedule_values = utils.cosine_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_epochs=args.warmup_epochs,\n            warmup_steps=args.warmup_steps,\n        )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay,\n        args.weight_decay_end,\n        args.epochs,\n        num_training_steps_per_epoch,\n    )\n    print(\n        \"Max WD = %.7f, Min WD = %.7f\"\n        % (max(wd_schedule_values), min(wd_schedule_values))\n    )\n\n    utils.auto_load_model(\n        args=args,\n        model=model,\n        model_without_ddp=model_without_ddp,\n        optimizer=optimizer,\n        loss_scaler=loss_scaler,\n        model_ema=model_ema,\n    )\n\n    from ast import literal_eval\n\n    target_layers = literal_eval(args.target_layers)\n    assert len(target_layers) > 0\n    print(f\"target layers: {target_layers}\")\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch)\n        train_stats = train_one_epoch(\n            model,\n            model_ema,\n            args.ema_start_at,\n            target_layers,\n            d_vae,\n            args.vae_loss_weight,\n            data_loader_train,\n            optimizer,\n            device,\n            epoch,\n            loss_scaler,\n            args.clip_grad,\n            l1_beta=args.l1_beta,\n            log_writer=log_writer,\n            start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values,\n            wd_schedule_values=wd_schedule_values,\n            l2_loss=args.l2_loss\n        )\n        if args.output_dir:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args,\n                    model=model,\n                    model_without_ddp=model_without_ddp,\n                    optimizer=optimizer,\n                    loss_scaler=loss_scaler,\n                    epoch=epoch,\n                    model_ema=model_ema,\n                )\n\n        log_stats = {\n            **{f\"train_{k}\": v for k, v in train_stats.items()},\n            \"epoch\": epoch,\n            \"n_parameters\": n_parameters,\n        }\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(\n                os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\"\n            ) as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print(\"Training time {}\".format(total_time_str))\n\n\nif __name__ == \"__main__\":\n    opts = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/README.md",
    "content": "# ADE20k Semantic segmentation with BEiT\n\n## Getting started \n\n1. Install the [mmsegmentation](https://github.com/open-mmlab/mmsegmentation) library and some required packages.\n\n```bash\npip install mmcv-full==1.3.0 mmsegmentation==0.11.0\npip install scipy timm==0.3.2\n```\n\n2. Install [apex](https://github.com/NVIDIA/apex) for mixed-precision training\n\n```bash\ngit clone https://github.com/NVIDIA/apex\ncd apex\npip install -v --disable-pip-version-check --no-cache-dir --global-option=\"--cpp_ext\" --global-option=\"--cuda_ext\" ./\n```\n\n3. Follow the guide in [mmseg](https://github.com/open-mmlab/mmsegmentation/blob/master/docs/dataset_prepare.md) to prepare the ADE20k dataset.\n\n\n## Fine-tuning\n\nCommand format:\n```\ntools/dist_train.sh <CONFIG_PATH> <NUM_GPUS>  --work-dir <SAVE_PATH> --seed 0  --deterministic --options model.pretrained=<IMAGENET_CHECKPOINT_PATH/URL>\n```\n\nFor example, using a BEiT-base backbone with UperNet:\n```bash\nbash tools/dist_train.sh \\\n    configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k.py 8 \\\n    --work-dir /path/to/save --seed 0  --deterministic \\\n    --options model.pretrained=https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth\n```\n\nMore config files can be found at [`configs/beit/upernet`](configs/beit/upernet).\n\n\n## Evaluation\n\nCommand format:\n```\ntools/dist_test.sh  <CONFIG_PATH> <CHECKPOINT_PATH> <NUM_GPUS> --eval mIoU\n```\n\nFor example, evaluate a BEiT-base backbone with UperNet:\n```bash\nbash tools/dist_test.sh configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k.py \\ \n    https://unilm.blob.core.windows.net/beit/beit_base_patch16_640_pt22k_ft22ktoade20k.pth  4 --eval mIoU\n```\n\nExpected results:\n```\n+--------+-------+-------+-------+\n| Scope  | mIoU  | mAcc  | aAcc  |\n+--------+-------+-------+-------+\n| global | 53.61 | 64.82 | 84.62 |\n+--------+-------+-------+-------+\n```\n\nMulti-scale + flip (`\\*_ms.py`)\n```\nbash tools/dist_test.sh configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k_ms.py \\\n    https://unilm.blob.core.windows.net/beit/beit_base_patch16_640_pt22k_ft22ktoade20k.pth  4 --eval mIoU\n```\n\nExpected results:\n```\n+--------+-------+-------+------+\n| Scope  | mIoU  | mAcc  | aAcc |\n+--------+-------+-------+------+\n| global | 54.26 | 65.28 | 84.9 |\n+--------+-------+-------+------+\n```\n\n---\n\n## Acknowledgment \n\nThis code is built using the [mmsegmentation](https://github.com/open-mmlab/mmsegmentation) library, [Timm](https://github.com/rwightman/pytorch-image-models) library, the [Swin](https://github.com/microsoft/Swin-Transformer) repository, [XCiT](https://github.com/facebookresearch/xcit) and the [SETR](https://github.com/fudan-zvg/SETR) repository.\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/backbone/beit.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\nimport math\nimport torch\nfrom functools import partial\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom timm.models.layers import drop_path, to_2tuple, trunc_normal_\n\nfrom mmcv_custom import load_checkpoint\nfrom mmseg.utils import get_root_logger\nfrom mmseg.models.builder import BACKBONES\n\n\nclass DropPath(nn.Module):\n    \"\"\"Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).\n    \"\"\"\n    def __init__(self, drop_prob=None):\n        super(DropPath, self).__init__()\n        self.drop_prob = drop_prob\n\n    def forward(self, x):\n        return drop_path(x, self.drop_prob, self.training)\n    \n    def extra_repr(self) -> str:\n        return 'p={}'.format(self.drop_prob)\n\n\nclass Mlp(nn.Module):\n    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        # x = self.drop(x)\n        # commit this for the orignal BERT implement \n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\nclass Attention(nn.Module):\n    def __init__(\n            self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0.,\n            proj_drop=0., window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        if attn_head_dim is not None:\n            head_dim = attn_head_dim\n        all_head_dim = head_dim * self.num_heads\n        # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights\n        self.scale = qk_scale or head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, all_head_dim * 3, bias=False)\n        if qkv_bias:\n            self.q_bias = nn.Parameter(torch.zeros(all_head_dim))\n            self.v_bias = nn.Parameter(torch.zeros(all_head_dim))\n        else:\n            self.q_bias = None\n            self.v_bias = None\n\n        if window_size:\n            self.window_size = window_size\n            self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n            self.relative_position_bias_table = nn.Parameter(\n                torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n            # cls to token & token 2 cls & cls to cls\n\n            # get pair-wise relative position index for each token inside the window\n            coords_h = torch.arange(window_size[0])\n            coords_w = torch.arange(window_size[1])\n            coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n            coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n            relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n            relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n            relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n            relative_coords[:, :, 1] += window_size[1] - 1\n            relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n            relative_position_index = \\\n                torch.zeros(size=(window_size[0] * window_size[1] + 1, ) * 2, dtype=relative_coords.dtype)\n            relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n            relative_position_index[0, 0:] = self.num_relative_distance - 3\n            relative_position_index[0:, 0] = self.num_relative_distance - 2\n            relative_position_index[0, 0] = self.num_relative_distance - 1\n\n            self.register_buffer(\"relative_position_index\", relative_position_index)\n\n            # trunc_normal_(self.relative_position_bias_table, std=.0)\n        else:\n            self.window_size = None\n            self.relative_position_bias_table = None\n            self.relative_position_index = None\n\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(all_head_dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n    def forward(self, x, rel_pos_bias=None):\n        B, N, C = x.shape\n        qkv_bias = None\n        if self.q_bias is not None:\n            qkv_bias = torch.cat((self.q_bias, torch.zeros_like(self.v_bias, requires_grad=False), self.v_bias))\n        # qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)\n        qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias)\n        qkv = qkv.reshape(B, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[2]   # make torchscript happy (cannot use tensor as tuple)\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        if self.relative_position_bias_table is not None:\n            relative_position_bias = \\\n                self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                    self.window_size[0] * self.window_size[1] + 1,\n                    self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n            relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n            attn = attn + relative_position_bias.unsqueeze(0)\n\n        if rel_pos_bias is not None:\n            attn = attn + rel_pos_bias\n        \n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, -1)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n\nclass Block(nn.Module):\n\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,\n                 drop_path=0., init_values=None, act_layer=nn.GELU, norm_layer=nn.LayerNorm,\n                 window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.norm1 = norm_layer(dim)\n        self.attn = Attention(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale,\n            attn_drop=attn_drop, proj_drop=drop, window_size=window_size, attn_head_dim=attn_head_dim)\n        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n        if init_values is not None:\n            self.gamma_1 = nn.Parameter(init_values * torch.ones((dim)),requires_grad=True)\n            self.gamma_2 = nn.Parameter(init_values * torch.ones((dim)),requires_grad=True)\n        else:\n            self.gamma_1, self.gamma_2 = None, None\n\n    def forward(self, x, rel_pos_bias=None):\n        if self.gamma_1 is None:\n            x = x + self.drop_path(self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            x = x + self.drop_path(self.mlp(self.norm2(x)))\n        else:\n            x = x + self.drop_path(self.gamma_1 * self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            x = x + self.drop_path(self.gamma_2 * self.mlp(self.norm2(x)))\n        return x\n\n\nclass PatchEmbed(nn.Module):\n    \"\"\" Image to Patch Embedding\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):\n        super().__init__()\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        num_patches = (img_size[1] // patch_size[1]) * (img_size[0] // patch_size[0])\n        self.patch_shape = (img_size[0] // patch_size[0], img_size[1] // patch_size[1])\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.num_patches = num_patches\n\n        self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n\n    def forward(self, x, **kwargs):\n        B, C, H, W = x.shape\n        # FIXME look at relaxing size constraints\n        # assert H == self.img_size[0] and W == self.img_size[1], \\\n        #     f\"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]}).\"\n        x = self.proj(x)\n        Hp, Wp = x.shape[2], x.shape[3]\n\n        x = x.flatten(2).transpose(1, 2)\n        return x, (Hp, Wp)\n\n\nclass HybridEmbed(nn.Module):\n    \"\"\" CNN Feature Map Embedding\n    Extract feature map from CNN, flatten, project to embedding dim.\n    \"\"\"\n    def __init__(self, backbone, img_size=224, feature_size=None, in_chans=3, embed_dim=768):\n        super().__init__()\n        assert isinstance(backbone, nn.Module)\n        img_size = to_2tuple(img_size)\n        self.img_size = img_size\n        self.backbone = backbone\n        if feature_size is None:\n            with torch.no_grad():\n                # FIXME this is hacky, but most reliable way of determining the exact dim of the output feature\n                # map for all networks, the feature metadata has reliable channel and stride info, but using\n                # stride to calc feature dim requires info about padding of each stage that isn't captured.\n                training = backbone.training\n                if training:\n                    backbone.eval()\n                o = self.backbone(torch.zeros(1, in_chans, img_size[0], img_size[1]))[-1]\n                feature_size = o.shape[-2:]\n                feature_dim = o.shape[1]\n                backbone.train(training)\n        else:\n            feature_size = to_2tuple(feature_size)\n            feature_dim = self.backbone.feature_info.channels()[-1]\n        self.num_patches = feature_size[0] * feature_size[1]\n        self.proj = nn.Linear(feature_dim, embed_dim)\n\n    def forward(self, x):\n        x = self.backbone(x)[-1]\n        x = x.flatten(2).transpose(1, 2)\n        x = self.proj(x)\n        return x\n\n\nclass RelativePositionBias(nn.Module):\n\n    def __init__(self, window_size, num_heads):\n        super().__init__()\n        self.window_size = window_size\n        self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n        self.relative_position_bias_table = nn.Parameter(\n            torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n        # cls to token & token 2 cls & cls to cls\n\n        # get pair-wise relative position index for each token inside the window\n        coords_h = torch.arange(window_size[0])\n        coords_w = torch.arange(window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n        relative_coords[:, :, 1] += window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n        relative_position_index = \\\n            torch.zeros(size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype)\n        relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        relative_position_index[0, 0:] = self.num_relative_distance - 3\n        relative_position_index[0:, 0] = self.num_relative_distance - 2\n        relative_position_index[0, 0] = self.num_relative_distance - 1\n\n        self.register_buffer(\"relative_position_index\", relative_position_index)\n\n        # trunc_normal_(self.relative_position_bias_table, std=.02)\n\n    def forward(self):\n        relative_position_bias = \\\n            self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1] + 1,\n                self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n        return relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n\n\n@BACKBONES.register_module()\nclass BEiT(nn.Module):\n    \"\"\" Vision Transformer with support for patch or hybrid CNN input stage\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, num_classes=80, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., hybrid_backbone=None, norm_layer=None, init_values=None, \n                 use_abs_pos_emb=True, use_rel_pos_bias=False, use_shared_rel_pos_bias=False,\n                 out_indices=[3, 5, 7, 11]):\n        super().__init__()\n        norm_layer = norm_layer or partial(nn.LayerNorm, eps=1e-6)\n        self.num_classes = num_classes\n        self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models\n\n        if hybrid_backbone is not None:\n            self.patch_embed = HybridEmbed(\n                hybrid_backbone, img_size=img_size, in_chans=in_chans, embed_dim=embed_dim)\n        else:\n            self.patch_embed = PatchEmbed(\n                img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n        self.out_indices = out_indices\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        # self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(window_size=self.patch_embed.patch_shape, num_heads=num_heads)\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.use_rel_pos_bias = use_rel_pos_bias\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,\n                init_values=init_values, window_size=self.patch_embed.patch_shape if use_rel_pos_bias else None)\n            for i in range(depth)])\n\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=.02)\n        trunc_normal_(self.cls_token, std=.02)\n        # trunc_normal_(self.mask_token, std=.02)\n        self.out_indices = out_indices\n\n        if patch_size == 16:\n            self.fpn1 = nn.Sequential(\n                nn.ConvTranspose2d(embed_dim, embed_dim, kernel_size=2, stride=2),\n                nn.SyncBatchNorm(embed_dim),\n                nn.GELU(),\n                nn.ConvTranspose2d(embed_dim, embed_dim, kernel_size=2, stride=2),\n            )\n\n            self.fpn2 = nn.Sequential(\n                nn.ConvTranspose2d(embed_dim, embed_dim, kernel_size=2, stride=2),\n            )\n\n            self.fpn3 = nn.Identity()\n\n            self.fpn4 = nn.MaxPool2d(kernel_size=2, stride=2)\n        elif patch_size == 8:\n            self.fpn1 = nn.Sequential(\n                nn.ConvTranspose2d(embed_dim, embed_dim, kernel_size=2, stride=2),\n            )\n\n            self.fpn2 = nn.Identity()\n\n            self.fpn3 = nn.Sequential(\n                nn.MaxPool2d(kernel_size=2, stride=2),\n            )\n\n            self.fpn4 = nn.Sequential(\n                nn.MaxPool2d(kernel_size=4, stride=4),\n            )\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    def init_weights(self, pretrained=None):\n        \"\"\"Initialize the weights in backbone.\n\n        Args:\n            pretrained (str, optional): Path to pre-trained weights.\n                Defaults to None.\n        \"\"\"\n\n        def _init_weights(m):\n            if isinstance(m, nn.Linear):\n                trunc_normal_(m.weight, std=.02)\n                if isinstance(m, nn.Linear) and m.bias is not None:\n                    nn.init.constant_(m.bias, 0)\n            elif isinstance(m, nn.LayerNorm):\n                nn.init.constant_(m.bias, 0)\n                nn.init.constant_(m.weight, 1.0)\n\n        if isinstance(pretrained, str):\n            self.apply(_init_weights)\n            logger = get_root_logger()\n            load_checkpoint(self, pretrained, strict=False, logger=logger)\n        elif pretrained is None:\n            self.apply(_init_weights)\n        else:\n            raise TypeError('pretrained must be a str or None')\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def forward_features(self, x):\n        B, C, H, W = x.shape\n        x, (Hp, Wp) = self.patch_embed(x)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n        features = []\n        for i, blk in enumerate(self.blocks):\n            x = blk(x, rel_pos_bias=rel_pos_bias)\n            if i in self.out_indices:\n                xp = x[:, 1:, :].permute(0, 2, 1).reshape(B, -1, Hp, Wp)\n                features.append(xp.contiguous())\n\n        ops = [self.fpn1, self.fpn2, self.fpn3, self.fpn4]\n        for i in range(len(features)):\n            features[i] = ops[i](features[i])\n\n        return tuple(features)\n\n    def forward(self, x):\n        x = self.forward_features(x)\n        return x\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/_base_/datasets/ade20k.py",
    "content": "# dataset settings\ndataset_type = 'ADE20KDataset'\ndata_root = 'data/ade/ADEChallengeData2016'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (512, 512)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', reduce_zero_label=True),\n    dict(type='Resize', img_scale=(2048, 512), ratio_range=(0.5, 2.0)),\n    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='PhotoMetricDistortion'),\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_semantic_seg']),\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2048, 512),\n        # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    samples_per_gpu=4,\n    workers_per_gpu=4,\n    train=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/training',\n        ann_dir='annotations/training',\n        pipeline=train_pipeline),\n    val=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/validation',\n        ann_dir='annotations/validation',\n        pipeline=test_pipeline),\n    test=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/validation',\n        ann_dir='annotations/validation',\n        pipeline=test_pipeline))\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/_base_/datasets/ade20k_640x640.py",
    "content": "# dataset settings\ndataset_type = 'ADE20KDataset'\ndata_root = 'data/ade/ADEChallengeData2016'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (640, 640)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', reduce_zero_label=True),\n    dict(type='Resize', img_scale=(2560, 640), ratio_range=(0.5, 2.0)),\n    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='PhotoMetricDistortion'),\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_semantic_seg']),\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2560, 640),\n        # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    samples_per_gpu=4,\n    workers_per_gpu=4,\n    train=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/training',\n        ann_dir='annotations/training',\n        pipeline=train_pipeline),\n    val=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/validation',\n        ann_dir='annotations/validation',\n        pipeline=test_pipeline),\n    test=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/validation',\n        ann_dir='annotations/validation',\n        pipeline=test_pipeline))\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/_base_/default_runtime.py",
    "content": "# yapf:disable\nlog_config = dict(\n    interval=50,\n    hooks=[\n        dict(type='TextLoggerHook', by_epoch=False),\n        # dict(type='TensorboardLoggerHook')\n    ])\n# yapf:enable\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\nresume_from = None\nworkflow = [('train', 1)]\ncudnn_benchmark = True\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/_base_/models/upernet_beit.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='EncoderDecoder',\n    pretrained=None,\n    backbone=dict(\n        type='XCiT',\n        patch_size=16,\n        embed_dim=384,\n        depth=12,\n        num_heads=8,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=True,\n        use_rel_pos_bias=False,\n    ),\n    decode_head=dict(\n        type='UPerHead',\n        in_channels=[384, 384, 384, 384],\n        in_index=[0, 1, 2, 3],\n        pool_scales=(1, 2, 3, 6),\n        channels=512,\n        dropout_ratio=0.1,\n        num_classes=19,\n        norm_cfg=norm_cfg,\n        align_corners=False,\n        loss_decode=dict(\n            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)),\n    auxiliary_head=dict(\n        type='FCNHead',\n        in_channels=384,\n        in_index=2,\n        channels=256,\n        num_convs=1,\n        concat_input=False,\n        dropout_ratio=0.1,\n        num_classes=19,\n        norm_cfg=norm_cfg,\n        align_corners=False,\n        loss_decode=dict(\n            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)),\n    # model training and testing settings\n    train_cfg=dict(),\n    test_cfg=dict(mode='whole'))\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/_base_/schedules/schedule_160k.py",
    "content": "# optimizer\noptimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005)\noptimizer_config = dict()\n# learning policy\nlr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)\n# runtime settings\nrunner = dict(type='IterBasedRunner', max_iters=160000)\ncheckpoint_config = dict(by_epoch=False, interval=16000)\nevaluation = dict(interval=16000, metric='mIoU')\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/_base_/schedules/schedule_320k.py",
    "content": "# optimizer\noptimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005)\noptimizer_config = dict()\n# learning policy\nlr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)\n# runtime settings\nrunner = dict(type='IterBasedRunner', max_iters=320000)\ncheckpoint_config = dict(by_epoch=False, interval=32000)\nevaluation = dict(interval=32000, metric='mIoU')\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_base_12_512_slide_160k_ade20k.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (512, 512)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=512,\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=0.1,\n        drop_path_rate=0.1,\n        out_indices=[3, 5, 7, 11]\n    ),\n    decode_head=dict(\n        in_channels=[768, 768, 768, 768],\n        num_classes=150,\n        channels=768,\n    ),\n    auxiliary_head=dict(\n        in_channels=768,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=2)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_base_12_512_slide_160k_ade20k_ms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (512, 512)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=512,\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=0.1,\n        drop_path_rate=0.1,\n        out_indices=[3, 5, 7, 11]\n    ),\n    decode_head=dict(\n        in_channels=[768, 768, 768, 768],\n        num_classes=150,\n        channels=768,\n    ),\n    auxiliary_head=dict(\n        in_channels=768,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata = dict(samples_per_gpu=2)\n\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (512, 512)\n# test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\nfind_unused_parameters = True\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2048, 512),\n        img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=True,\n        transforms=[\n            dict(type='SETR_Resize', keep_ratio=True,\n                 crop_size=crop_size, setr_multi_scale=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    val=dict(pipeline=test_pipeline),\n    test=dict(pipeline=test_pipeline))\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k_640x640.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (640, 640)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=640,\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=0.1,\n        drop_path_rate=0.1,\n        out_indices=[3, 5, 7, 11]\n    ),\n    decode_head=dict(\n        in_channels=[768, 768, 768, 768],\n        num_classes=150,\n        channels=768,\n    ),\n    auxiliary_head=dict(\n        in_channels=768,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(426, 426))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=2)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k_ms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k_640x640.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (640, 640)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=640,\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=0.1,\n        drop_path_rate=0.1,\n        out_indices=[3, 5, 7, 11]\n    ),\n    decode_head=dict(\n        in_channels=[768, 768, 768, 768],\n        num_classes=150,\n        channels=768,\n    ),\n    auxiliary_head=dict(\n        in_channels=768,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(426, 426))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (640, 640)\n# test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\nfind_unused_parameters = True\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2560, 640),\n        img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=True,\n        transforms=[\n            dict(type='SETR_Resize', keep_ratio=True,\n                 crop_size=crop_size, setr_multi_scale=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    val=dict(pipeline=test_pipeline),\n    test=dict(pipeline=test_pipeline), \n    samples_per_gpu=2, \n)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_large_24_512_slide_160k_ade20k.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (512, 512)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=512,\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=1e-6,\n        drop_path_rate=0.2,\n        out_indices=[7, 11, 15, 23],\n    ),\n    decode_head=dict(\n        in_channels=[1024, 1024, 1024, 1024],\n        num_classes=150,\n        channels=1024,\n    ),\n    auxiliary_head=dict(\n        in_channels=1024,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=2e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=24, layer_decay_rate=0.95))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=2)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_large_24_512_slide_160k_ade20k_ms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (512, 512)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=512,\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=1e-6,\n        drop_path_rate=0.2,\n        out_indices=[7, 11, 15, 23],\n    ),\n    decode_head=dict(\n        in_channels=[1024, 1024, 1024, 1024],\n        num_classes=150,\n        channels=1024,\n    ),\n    auxiliary_head=dict(\n        in_channels=1024,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=2e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=24, layer_decay_rate=0.95))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata = dict(samples_per_gpu=2)\n\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (512, 512)\n# test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\nfind_unused_parameters = True\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2048, 512),\n        img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=True,\n        transforms=[\n            dict(type='SETR_Resize', keep_ratio=True,\n                 crop_size=crop_size, setr_multi_scale=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    val=dict(pipeline=test_pipeline),\n    test=dict(pipeline=test_pipeline))\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_large_24_640_slide_160k_ade20k.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k_640x640.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_320k.py'\n]\n# We set samples_per_gpu to 1 and optimizer_config.update_interval to 2, the total update step keep 160k.\ncrop_size = (640, 640)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=640,\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=1e-6,\n        drop_path_rate=0.2,\n        out_indices=[7, 11, 15, 23],\n    ),\n    decode_head=dict(\n        in_channels=[1024, 1024, 1024, 1024],\n        num_classes=150,\n        channels=1024,\n    ),\n    auxiliary_head=dict(\n        in_channels=1024,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(426, 426))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=2e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=24, layer_decay_rate=0.95))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=3000,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=1)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\n# We set samples_per_gpu to 1 and optimizer_config.update_interval to 2, the total update step keep 160k.\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=2,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_large_24_640_slide_160k_ade20k_ms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k_640x640.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_320k.py'\n]\ncrop_size = (640, 640)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=640,\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=1e-6,\n        drop_path_rate=0.2,\n        out_indices=[7, 11, 15, 23],\n    ),\n    decode_head=dict(\n        in_channels=[1024, 1024, 1024, 1024],\n        num_classes=150,\n        channels=1024,\n    ),\n    auxiliary_head=dict(\n        in_channels=1024,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(426, 426))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=2e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=24, layer_decay_rate=0.95))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=3000,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=1)\n\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (640, 640)\n# test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\nfind_unused_parameters = True\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2560, 640),\n        img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=True,\n        transforms=[\n            dict(type='SETR_Resize', keep_ratio=True,\n                 crop_size=crop_size, setr_multi_scale=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    val=dict(pipeline=test_pipeline),\n    test=dict(pipeline=test_pipeline))\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=2,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom .checkpoint import load_checkpoint\nfrom .layer_decay_optimizer_constructor import LayerDecayOptimizerConstructor\nfrom .resize_transform import SETR_Resize\nfrom .apex_runner.optimizer import DistOptimizerHook\nfrom .train_api import train_segmentor\n\n__all__ = ['load_checkpoint', 'LayerDecayOptimizerConstructor', 'SETR_Resize', 'DistOptimizerHook', 'train_segmentor']\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/apex_runner/__init__.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\nfrom .checkpoint import save_checkpoint\nfrom .apex_iter_based_runner import IterBasedRunnerAmp\n\n\n__all__ = [\n    'save_checkpoint', 'IterBasedRunnerAmp', \n]\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/apex_runner/apex_iter_based_runner.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\nimport os.path as osp\nimport platform\nimport shutil\n\nimport torch\nfrom torch.optim import Optimizer\n\nimport mmcv\nfrom mmcv.runner import RUNNERS, IterBasedRunner\nfrom .checkpoint import save_checkpoint\n\ntry:\n    import apex\nexcept:\n    print('apex is not installed')\n\n\n@RUNNERS.register_module()\nclass IterBasedRunnerAmp(IterBasedRunner):\n    \"\"\"Iteration-based Runner with AMP support.\n\n    This runner train models iteration by iteration.\n    \"\"\"\n\n    def save_checkpoint(self,\n                        out_dir,\n                        filename_tmpl='iter_{}.pth',\n                        meta=None,\n                        save_optimizer=True,\n                        create_symlink=False):\n        \"\"\"Save checkpoint to file.\n\n        Args:\n            out_dir (str): Directory to save checkpoint files.\n            filename_tmpl (str, optional): Checkpoint file template.\n                Defaults to 'iter_{}.pth'.\n            meta (dict, optional): Metadata to be saved in checkpoint.\n                Defaults to None.\n            save_optimizer (bool, optional): Whether save optimizer.\n                Defaults to True.\n            create_symlink (bool, optional): Whether create symlink to the\n                latest checkpoint file. Defaults to True.\n        \"\"\"\n        if meta is None:\n            meta = dict(iter=self.iter + 1, epoch=self.epoch + 1)\n        elif isinstance(meta, dict):\n            meta.update(iter=self.iter + 1, epoch=self.epoch + 1)\n        else:\n            raise TypeError(\n                f'meta should be a dict or None, but got {type(meta)}')\n        if self.meta is not None:\n            meta.update(self.meta)\n\n        filename = filename_tmpl.format(self.iter + 1)\n        filepath = osp.join(out_dir, filename)\n        optimizer = self.optimizer if save_optimizer else None\n        save_checkpoint(self.model, filepath, optimizer=optimizer, meta=meta)\n        # in some environments, `os.symlink` is not supported, you may need to\n        # set `create_symlink` to False\n        # if create_symlink:\n        #     dst_file = osp.join(out_dir, 'latest.pth')\n        #     if platform.system() != 'Windows':\n        #         mmcv.symlink(filename, dst_file)\n        #     else:\n        #         shutil.copy(filepath, dst_file)\n\n    def resume(self,\n               checkpoint,\n               resume_optimizer=True,\n               map_location='default'):\n        if map_location == 'default':\n            if torch.cuda.is_available():\n                device_id = torch.cuda.current_device()\n                checkpoint = self.load_checkpoint(\n                    checkpoint,\n                    map_location=lambda storage, loc: storage.cuda(device_id))\n            else:\n                checkpoint = self.load_checkpoint(checkpoint)\n        else:\n            checkpoint = self.load_checkpoint(\n                checkpoint, map_location=map_location)\n\n        self._epoch = checkpoint['meta']['epoch']\n        self._iter = checkpoint['meta']['iter']\n        self._inner_iter = checkpoint['meta']['iter']\n        if 'optimizer' in checkpoint and resume_optimizer:\n            if isinstance(self.optimizer, Optimizer):\n                self.optimizer.load_state_dict(checkpoint['optimizer'])\n            elif isinstance(self.optimizer, dict):\n                for k in self.optimizer.keys():\n                    self.optimizer[k].load_state_dict(\n                        checkpoint['optimizer'][k])\n            else:\n                raise TypeError(\n                    'Optimizer should be dict or torch.optim.Optimizer '\n                    f'but got {type(self.optimizer)}')\n\n        if 'amp' in checkpoint:\n            apex.amp.load_state_dict(checkpoint['amp'])\n            self.logger.info('load amp state dict')\n\n        self.logger.info(f'resumed from epoch: {self.epoch}, iter {self.iter}')\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/apex_runner/checkpoint.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\nimport os.path as osp\nimport time\nfrom tempfile import TemporaryDirectory\n\nimport torch\nfrom torch.optim import Optimizer\n\nimport mmcv\nfrom mmcv.parallel import is_module_wrapper\nfrom mmcv.runner.checkpoint import weights_to_cpu, get_state_dict\n\ntry:\n    import apex\nexcept:\n    print('apex is not installed')\n\n\ndef save_checkpoint(model, filename, optimizer=None, meta=None):\n    \"\"\"Save checkpoint to file.\n\n    The checkpoint will have 4 fields: ``meta``, ``state_dict`` and\n    ``optimizer``, ``amp``. By default ``meta`` will contain version\n    and time info.\n\n    Args:\n        model (Module): Module whose params are to be saved.\n        filename (str): Checkpoint filename.\n        optimizer (:obj:`Optimizer`, optional): Optimizer to be saved.\n        meta (dict, optional): Metadata to be saved in checkpoint.\n    \"\"\"\n    if meta is None:\n        meta = {}\n    elif not isinstance(meta, dict):\n        raise TypeError(f'meta must be a dict or None, but got {type(meta)}')\n    meta.update(mmcv_version=mmcv.__version__, time=time.asctime())\n\n    if is_module_wrapper(model):\n        model = model.module\n\n    if hasattr(model, 'CLASSES') and model.CLASSES is not None:\n        # save class name to the meta\n        meta.update(CLASSES=model.CLASSES)\n\n    checkpoint = {\n        'meta': meta,\n        'state_dict': weights_to_cpu(get_state_dict(model))\n    }\n    # save optimizer state dict in the checkpoint\n    if isinstance(optimizer, Optimizer):\n        checkpoint['optimizer'] = optimizer.state_dict()\n    elif isinstance(optimizer, dict):\n        checkpoint['optimizer'] = {}\n        for name, optim in optimizer.items():\n            checkpoint['optimizer'][name] = optim.state_dict()\n\n    # save amp state dict in the checkpoint\n    checkpoint['amp'] = apex.amp.state_dict()\n\n    if filename.startswith('pavi://'):\n        try:\n            from pavi import modelcloud\n            from pavi.exception import NodeNotFoundError\n        except ImportError:\n            raise ImportError(\n                'Please install pavi to load checkpoint from modelcloud.')\n        model_path = filename[7:]\n        root = modelcloud.Folder()\n        model_dir, model_name = osp.split(model_path)\n        try:\n            model = modelcloud.get(model_dir)\n        except NodeNotFoundError:\n            model = root.create_training_model(model_dir)\n        with TemporaryDirectory() as tmp_dir:\n            checkpoint_file = osp.join(tmp_dir, model_name)\n            with open(checkpoint_file, 'wb') as f:\n                torch.save(checkpoint, f)\n                f.flush()\n            model.create_file(checkpoint_file, name=model_name)\n    else:\n        mmcv.mkdir_or_exist(osp.dirname(filename))\n        # immediately flush buffer\n        with open(filename, 'wb') as f:\n            torch.save(checkpoint, f)\n            f.flush()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/apex_runner/optimizer.py",
    "content": "from mmcv.runner import OptimizerHook, HOOKS\ntry:\n    import apex\nexcept:\n    print('apex is not installed')\n\n\n@HOOKS.register_module()\nclass DistOptimizerHook(OptimizerHook):\n    \"\"\"Optimizer hook for distributed training.\"\"\"\n\n    def __init__(self, update_interval=1, grad_clip=None, coalesce=True, bucket_size_mb=-1, use_fp16=False):\n        self.grad_clip = grad_clip\n        self.coalesce = coalesce\n        self.bucket_size_mb = bucket_size_mb\n        self.update_interval = update_interval\n        self.use_fp16 = use_fp16\n\n    def before_run(self, runner):\n        runner.optimizer.zero_grad()\n\n    def after_train_iter(self, runner):\n        runner.outputs['loss'] /= self.update_interval\n        if self.use_fp16:\n            with apex.amp.scale_loss(runner.outputs['loss'], runner.optimizer) as scaled_loss:\n                scaled_loss.backward()\n        else:\n            runner.outputs['loss'].backward()\n        if self.every_n_iters(runner, self.update_interval):\n            if self.grad_clip is not None:\n                self.clip_grads(runner.model.parameters())\n            runner.optimizer.step()\n            runner.optimizer.zero_grad()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/checkpoint.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\nimport io\nimport os\nimport os.path as osp\nimport pkgutil\nimport time\nimport warnings\nfrom collections import OrderedDict\nfrom importlib import import_module\nfrom tempfile import TemporaryDirectory\n\nimport torch\nimport torchvision\nfrom torch.optim import Optimizer\nfrom torch.utils import model_zoo\nfrom torch.nn import functional as F\n\nimport mmcv\nfrom mmcv.fileio import FileClient\nfrom mmcv.fileio import load as load_file\nfrom mmcv.parallel import is_module_wrapper\nfrom mmcv.utils import mkdir_or_exist\nfrom mmcv.runner import get_dist_info\n\nfrom scipy import interpolate\nimport numpy as np\nimport math\n\nENV_MMCV_HOME = 'MMCV_HOME'\nENV_XDG_CACHE_HOME = 'XDG_CACHE_HOME'\nDEFAULT_CACHE_DIR = '~/.cache'\n\n\ndef _get_mmcv_home():\n    mmcv_home = os.path.expanduser(\n        os.getenv(\n            ENV_MMCV_HOME,\n            os.path.join(\n                os.getenv(ENV_XDG_CACHE_HOME, DEFAULT_CACHE_DIR), 'mmcv')))\n\n    mkdir_or_exist(mmcv_home)\n    return mmcv_home\n\n\ndef load_state_dict(module, state_dict, strict=False, logger=None):\n    \"\"\"Load state_dict to a module.\n\n    This method is modified from :meth:`torch.nn.Module.load_state_dict`.\n    Default value for ``strict`` is set to ``False`` and the message for\n    param mismatch will be shown even if strict is False.\n\n    Args:\n        module (Module): Module that receives the state_dict.\n        state_dict (OrderedDict): Weights.\n        strict (bool): whether to strictly enforce that the keys\n            in :attr:`state_dict` match the keys returned by this module's\n            :meth:`~torch.nn.Module.state_dict` function. Default: ``False``.\n        logger (:obj:`logging.Logger`, optional): Logger to log the error\n            message. If not specified, print function will be used.\n    \"\"\"\n    unexpected_keys = []\n    all_missing_keys = []\n    err_msg = []\n\n    metadata = getattr(state_dict, '_metadata', None)\n    state_dict = state_dict.copy()\n    if metadata is not None:\n        state_dict._metadata = metadata\n\n    # use _load_from_state_dict to enable checkpoint version control\n    def load(module, prefix=''):\n        # recursively check parallel module in case that the model has a\n        # complicated structure, e.g., nn.Module(nn.Module(DDP))\n        if is_module_wrapper(module):\n            module = module.module\n        local_metadata = {} if metadata is None else metadata.get(\n            prefix[:-1], {})\n        module._load_from_state_dict(state_dict, prefix, local_metadata, True,\n                                     all_missing_keys, unexpected_keys,\n                                     err_msg)\n        for name, child in module._modules.items():\n            if child is not None:\n                load(child, prefix + name + '.')\n\n    load(module)\n    load = None  # break load->load reference cycle\n\n    # ignore \"num_batches_tracked\" of BN layers\n    missing_keys = [\n        key for key in all_missing_keys if 'num_batches_tracked' not in key\n    ]\n\n    if unexpected_keys:\n        err_msg.append('unexpected key in source '\n                       f'state_dict: {\", \".join(unexpected_keys)}\\n')\n    if missing_keys:\n        err_msg.append(\n            f'missing keys in source state_dict: {\", \".join(missing_keys)}\\n')\n\n    rank, _ = get_dist_info()\n    if len(err_msg) > 0 and rank == 0:\n        err_msg.insert(\n            0, 'The model and loaded state dict do not match exactly\\n')\n        err_msg = '\\n'.join(err_msg)\n        if strict:\n            raise RuntimeError(err_msg)\n        elif logger is not None:\n            logger.warning(err_msg)\n        else:\n            print(err_msg)\n\n\ndef load_url_dist(url, model_dir=None, map_location=\"cpu\"):\n    \"\"\"In distributed setting, this function only download checkpoint at local\n    rank 0.\"\"\"\n    rank, world_size = get_dist_info()\n    rank = int(os.environ.get('LOCAL_RANK', rank))\n    if rank == 0:\n        checkpoint = model_zoo.load_url(url, model_dir=model_dir, map_location=map_location)\n    if world_size > 1:\n        torch.distributed.barrier()\n        if rank > 0:\n            checkpoint = model_zoo.load_url(url, model_dir=model_dir, map_location=map_location)\n    return checkpoint\n\n\ndef load_pavimodel_dist(model_path, map_location=None):\n    \"\"\"In distributed setting, this function only download checkpoint at local\n    rank 0.\"\"\"\n    try:\n        from pavi import modelcloud\n    except ImportError:\n        raise ImportError(\n            'Please install pavi to load checkpoint from modelcloud.')\n    rank, world_size = get_dist_info()\n    rank = int(os.environ.get('LOCAL_RANK', rank))\n    if rank == 0:\n        model = modelcloud.get(model_path)\n        with TemporaryDirectory() as tmp_dir:\n            downloaded_file = osp.join(tmp_dir, model.name)\n            model.download(downloaded_file)\n            checkpoint = torch.load(downloaded_file, map_location=map_location)\n    if world_size > 1:\n        torch.distributed.barrier()\n        if rank > 0:\n            model = modelcloud.get(model_path)\n            with TemporaryDirectory() as tmp_dir:\n                downloaded_file = osp.join(tmp_dir, model.name)\n                model.download(downloaded_file)\n                checkpoint = torch.load(\n                    downloaded_file, map_location=map_location)\n    return checkpoint\n\n\ndef load_fileclient_dist(filename, backend, map_location):\n    \"\"\"In distributed setting, this function only download checkpoint at local\n    rank 0.\"\"\"\n    rank, world_size = get_dist_info()\n    rank = int(os.environ.get('LOCAL_RANK', rank))\n    allowed_backends = ['ceph']\n    if backend not in allowed_backends:\n        raise ValueError(f'Load from Backend {backend} is not supported.')\n    if rank == 0:\n        fileclient = FileClient(backend=backend)\n        buffer = io.BytesIO(fileclient.get(filename))\n        checkpoint = torch.load(buffer, map_location=map_location)\n    if world_size > 1:\n        torch.distributed.barrier()\n        if rank > 0:\n            fileclient = FileClient(backend=backend)\n            buffer = io.BytesIO(fileclient.get(filename))\n            checkpoint = torch.load(buffer, map_location=map_location)\n    return checkpoint\n\n\ndef get_torchvision_models():\n    model_urls = dict()\n    for _, name, ispkg in pkgutil.walk_packages(torchvision.models.__path__):\n        if ispkg:\n            continue\n        _zoo = import_module(f'torchvision.models.{name}')\n        if hasattr(_zoo, 'model_urls'):\n            _urls = getattr(_zoo, 'model_urls')\n            model_urls.update(_urls)\n    return model_urls\n\n\ndef get_external_models():\n    mmcv_home = _get_mmcv_home()\n    default_json_path = osp.join(mmcv.__path__[0], 'model_zoo/open_mmlab.json')\n    default_urls = load_file(default_json_path)\n    assert isinstance(default_urls, dict)\n    external_json_path = osp.join(mmcv_home, 'open_mmlab.json')\n    if osp.exists(external_json_path):\n        external_urls = load_file(external_json_path)\n        assert isinstance(external_urls, dict)\n        default_urls.update(external_urls)\n\n    return default_urls\n\n\ndef get_mmcls_models():\n    mmcls_json_path = osp.join(mmcv.__path__[0], 'model_zoo/mmcls.json')\n    mmcls_urls = load_file(mmcls_json_path)\n\n    return mmcls_urls\n\n\ndef get_deprecated_model_names():\n    deprecate_json_path = osp.join(mmcv.__path__[0],\n                                   'model_zoo/deprecated.json')\n    deprecate_urls = load_file(deprecate_json_path)\n    assert isinstance(deprecate_urls, dict)\n\n    return deprecate_urls\n\n\ndef _process_mmcls_checkpoint(checkpoint):\n    state_dict = checkpoint['state_dict']\n    new_state_dict = OrderedDict()\n    for k, v in state_dict.items():\n        if k.startswith('backbone.'):\n            new_state_dict[k[9:]] = v\n    new_checkpoint = dict(state_dict=new_state_dict)\n\n    return new_checkpoint\n\n\ndef _load_checkpoint(filename, map_location=None):\n    \"\"\"Load checkpoint from somewhere (modelzoo, file, url).\n\n    Args:\n        filename (str): Accept local filepath, URL, ``torchvision://xxx``,\n            ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for\n            details.\n        map_location (str | None): Same as :func:`torch.load`. Default: None.\n\n    Returns:\n        dict | OrderedDict: The loaded checkpoint. It can be either an\n            OrderedDict storing model weights or a dict containing other\n            information, which depends on the checkpoint.\n    \"\"\"\n    if filename.startswith('modelzoo://'):\n        warnings.warn('The URL scheme of \"modelzoo://\" is deprecated, please '\n                      'use \"torchvision://\" instead')\n        model_urls = get_torchvision_models()\n        model_name = filename[11:]\n        checkpoint = load_url_dist(model_urls[model_name])\n    elif filename.startswith('torchvision://'):\n        model_urls = get_torchvision_models()\n        model_name = filename[14:]\n        checkpoint = load_url_dist(model_urls[model_name])\n    elif filename.startswith('open-mmlab://'):\n        model_urls = get_external_models()\n        model_name = filename[13:]\n        deprecated_urls = get_deprecated_model_names()\n        if model_name in deprecated_urls:\n            warnings.warn(f'open-mmlab://{model_name} is deprecated in favor '\n                          f'of open-mmlab://{deprecated_urls[model_name]}')\n            model_name = deprecated_urls[model_name]\n        model_url = model_urls[model_name]\n        # check if is url\n        if model_url.startswith(('http://', 'https://')):\n            checkpoint = load_url_dist(model_url)\n        else:\n            filename = osp.join(_get_mmcv_home(), model_url)\n            if not osp.isfile(filename):\n                raise IOError(f'{filename} is not a checkpoint file')\n            checkpoint = torch.load(filename, map_location=map_location)\n    elif filename.startswith('mmcls://'):\n        model_urls = get_mmcls_models()\n        model_name = filename[8:]\n        checkpoint = load_url_dist(model_urls[model_name])\n        checkpoint = _process_mmcls_checkpoint(checkpoint)\n    elif filename.startswith(('http://', 'https://')):\n        checkpoint = load_url_dist(filename)\n    elif filename.startswith('pavi://'):\n        model_path = filename[7:]\n        checkpoint = load_pavimodel_dist(model_path, map_location=map_location)\n    elif filename.startswith('s3://'):\n        checkpoint = load_fileclient_dist(\n            filename, backend='ceph', map_location=map_location)\n    else:\n        if not osp.isfile(filename):\n            raise IOError(f'{filename} is not a checkpoint file')\n        checkpoint = torch.load(filename, map_location=map_location)\n    return checkpoint\n\n\ndef cosine_scheduler(base_value, final_value, epochs, niter_per_ep, warmup_epochs=0,\n                     start_warmup_value=0, warmup_steps=-1):\n    warmup_schedule = np.array([])\n    warmup_iters = warmup_epochs * niter_per_ep\n    if warmup_steps > 0:\n        warmup_iters = warmup_steps\n    print(\"Set warmup steps = %d\" % warmup_iters)\n    if warmup_epochs > 0:\n        warmup_schedule = np.linspace(start_warmup_value, base_value, warmup_iters)\n\n    iters = np.arange(epochs * niter_per_ep - warmup_iters)\n    schedule = np.array(\n        [final_value + 0.5 * (base_value - final_value) * (1 + math.cos(math.pi * i / (len(iters)))) for i in iters])\n\n    schedule = np.concatenate((warmup_schedule, schedule))\n\n    assert len(schedule) == epochs * niter_per_ep\n    return schedule\n\n\ndef load_checkpoint(model,\n                    filename,\n                    map_location='cpu',\n                    strict=False,\n                    logger=None):\n    \"\"\"Load checkpoint from a file or URI.\n\n    Args:\n        model (Module): Module to load checkpoint.\n        filename (str): Accept local filepath, URL, ``torchvision://xxx``,\n            ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for\n            details.\n        map_location (str): Same as :func:`torch.load`.\n        strict (bool): Whether to allow different params for the model and\n            checkpoint.\n        logger (:mod:`logging.Logger` or None): The logger for error message.\n\n    Returns:\n        dict or OrderedDict: The loaded checkpoint.\n    \"\"\"\n    checkpoint = _load_checkpoint(filename, map_location)\n    # OrderedDict is a subclass of dict\n    if not isinstance(checkpoint, dict):\n        raise RuntimeError(\n            f'No state_dict found in checkpoint file {filename}')\n    # get state_dict from checkpoint\n    if 'state_dict' in checkpoint:\n        state_dict = checkpoint['state_dict']\n    elif 'model' in checkpoint:\n        state_dict = checkpoint['model']\n    elif 'module' in checkpoint:\n        state_dict = checkpoint['module']\n    else:\n        state_dict = checkpoint\n    # strip prefix of state_dict\n    if list(state_dict.keys())[0].startswith('module.'):\n        state_dict = {k[7:]: v for k, v in state_dict.items()}\n\n    # for MoBY, load model of online branch\n    if sorted(list(state_dict.keys()))[0].startswith('encoder'):\n        state_dict = {k.replace('encoder.', ''): v for k, v in state_dict.items() if k.startswith('encoder.')}\n\n    # reshape absolute position embedding for Swin\n    if state_dict.get('absolute_pos_embed') is not None:\n        absolute_pos_embed = state_dict['absolute_pos_embed']\n        N1, L, C1 = absolute_pos_embed.size()\n        N2, C2, H, W = model.absolute_pos_embed.size()\n        if N1 != N2 or C1 != C2 or L != H*W:\n            logger.warning(\"Error in loading absolute_pos_embed, pass\")\n        else:\n            state_dict['absolute_pos_embed'] = absolute_pos_embed.view(N2, H, W, C2).permute(0, 3, 1, 2)\n\n    rank, _ = get_dist_info()\n    all_keys = list(state_dict.keys())\n    for key in all_keys:\n        if \"relative_position_index\" in key:\n            state_dict.pop(key)\n\n        if \"relative_position_bias_table\" in key:\n            rel_pos_bias = state_dict[key]\n            src_num_pos, num_attn_heads = rel_pos_bias.size()\n            dst_num_pos, _ = model.state_dict()[key].size()\n            dst_patch_shape = model.patch_embed.patch_shape\n            if dst_patch_shape[0] != dst_patch_shape[1]:\n                raise NotImplementedError()\n            num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (dst_patch_shape[1] * 2 - 1)\n            src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n            dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n            if src_size != dst_size:\n                if rank == 0:\n                    print(\"Position interpolate for %s from %dx%d to %dx%d\" % (\n                        key, src_size, src_size, dst_size, dst_size))\n                extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                def geometric_progression(a, r, n):\n                    return a * (1.0 - r ** n) / (1.0 - r)\n\n                left, right = 1.01, 1.5\n                while right - left > 1e-6:\n                    q = (left + right) / 2.0\n                    gp = geometric_progression(1, q, src_size // 2)\n                    if gp > dst_size // 2:\n                        right = q\n                    else:\n                        left = q\n\n                # if q > 1.13492:\n                #     q = 1.13492\n\n                dis = []\n                cur = 1\n                for i in range(src_size // 2):\n                    dis.append(cur)\n                    cur += q ** (i + 1)\n\n                r_ids = [-_ for _ in reversed(dis)]\n\n                x = r_ids + [0] + dis\n                y = r_ids + [0] + dis\n\n                t = dst_size // 2.0\n                dx = np.arange(-t, t + 0.1, 1.0)\n                dy = np.arange(-t, t + 0.1, 1.0)\n                if rank == 0:\n                    print(\"x = {}\".format(x))\n                    print(\"dx = {}\".format(dx))\n\n                all_rel_pos_bias = []\n\n                for i in range(num_attn_heads):\n                    z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                    f = interpolate.interp2d(x, y, z, kind='cubic')\n                    all_rel_pos_bias.append(\n                        torch.Tensor(f(dx, dy)).contiguous().view(-1, 1).to(rel_pos_bias.device))\n\n                rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n                new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                state_dict[key] = new_rel_pos_bias\n\n    if 'pos_embed' in state_dict:\n        pos_embed_checkpoint = state_dict['pos_embed']\n        embedding_size = pos_embed_checkpoint.shape[-1]\n        num_patches = model.patch_embed.num_patches\n        num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n        # height (== width) for the checkpoint position embedding\n        orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n        # height (== width) for the new position embedding\n        new_size = int(num_patches ** 0.5)\n        # class_token and dist_token are kept unchanged\n        if orig_size != new_size:\n            if rank == 0:\n                print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n            extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n            # only the position tokens are interpolated\n            pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n            pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n            pos_tokens = torch.nn.functional.interpolate(\n                pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n            pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n            new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n            state_dict['pos_embed'] = new_pos_embed\n\n    # interpolate position bias table if needed\n    relative_position_bias_table_keys = [k for k in state_dict.keys() if \"relative_position_bias_table\" in k]\n    for table_key in relative_position_bias_table_keys:\n        table_pretrained = state_dict[table_key]\n        table_current = model.state_dict()[table_key]\n        L1, nH1 = table_pretrained.size()\n        L2, nH2 = table_current.size()\n        if nH1 != nH2:\n            logger.warning(f\"Error in loading {table_key}, pass\")\n        else:\n            if L1 != L2:\n                S1 = int(L1 ** 0.5)\n                S2 = int(L2 ** 0.5)\n                table_pretrained_resized = F.interpolate(\n                     table_pretrained.permute(1, 0).view(1, nH1, S1, S1),\n                     size=(S2, S2), mode='bicubic')\n                state_dict[table_key] = table_pretrained_resized.view(nH2, L2).permute(1, 0)\n\n    # load state_dict\n    load_state_dict(model, state_dict, strict, logger)\n    return checkpoint\n\n\ndef weights_to_cpu(state_dict):\n    \"\"\"Copy a model state_dict to cpu.\n\n    Args:\n        state_dict (OrderedDict): Model weights on GPU.\n\n    Returns:\n        OrderedDict: Model weights on GPU.\n    \"\"\"\n    state_dict_cpu = OrderedDict()\n    for key, val in state_dict.items():\n        state_dict_cpu[key] = val.cpu()\n    return state_dict_cpu\n\n\ndef _save_to_state_dict(module, destination, prefix, keep_vars):\n    \"\"\"Saves module state to `destination` dictionary.\n\n    This method is modified from :meth:`torch.nn.Module._save_to_state_dict`.\n\n    Args:\n        module (nn.Module): The module to generate state_dict.\n        destination (dict): A dict where state will be stored.\n        prefix (str): The prefix for parameters and buffers used in this\n            module.\n    \"\"\"\n    for name, param in module._parameters.items():\n        if param is not None:\n            destination[prefix + name] = param if keep_vars else param.detach()\n    for name, buf in module._buffers.items():\n        # remove check of _non_persistent_buffers_set to allow nn.BatchNorm2d\n        if buf is not None:\n            destination[prefix + name] = buf if keep_vars else buf.detach()\n\n\ndef get_state_dict(module, destination=None, prefix='', keep_vars=False):\n    \"\"\"Returns a dictionary containing a whole state of the module.\n\n    Both parameters and persistent buffers (e.g. running averages) are\n    included. Keys are corresponding parameter and buffer names.\n\n    This method is modified from :meth:`torch.nn.Module.state_dict` to\n    recursively check parallel module in case that the model has a complicated\n    structure, e.g., nn.Module(nn.Module(DDP)).\n\n    Args:\n        module (nn.Module): The module to generate state_dict.\n        destination (OrderedDict): Returned dict for the state of the\n            module.\n        prefix (str): Prefix of the key.\n        keep_vars (bool): Whether to keep the variable property of the\n            parameters. Default: False.\n\n    Returns:\n        dict: A dictionary containing a whole state of the module.\n    \"\"\"\n    # recursively check parallel module in case that the model has a\n    # complicated structure, e.g., nn.Module(nn.Module(DDP))\n    if is_module_wrapper(module):\n        module = module.module\n\n    # below is the same as torch.nn.Module.state_dict()\n    if destination is None:\n        destination = OrderedDict()\n        destination._metadata = OrderedDict()\n    destination._metadata[prefix[:-1]] = local_metadata = dict(\n        version=module._version)\n    _save_to_state_dict(module, destination, prefix, keep_vars)\n    for name, child in module._modules.items():\n        if child is not None:\n            get_state_dict(\n                child, destination, prefix + name + '.', keep_vars=keep_vars)\n    for hook in module._state_dict_hooks.values():\n        hook_result = hook(module, destination, prefix, local_metadata)\n        if hook_result is not None:\n            destination = hook_result\n    return destination\n\n\ndef save_checkpoint(model, filename, optimizer=None, meta=None):\n    \"\"\"Save checkpoint to file.\n\n    The checkpoint will have 3 fields: ``meta``, ``state_dict`` and\n    ``optimizer``. By default ``meta`` will contain version and time info.\n\n    Args:\n        model (Module): Module whose params are to be saved.\n        filename (str): Checkpoint filename.\n        optimizer (:obj:`Optimizer`, optional): Optimizer to be saved.\n        meta (dict, optional): Metadata to be saved in checkpoint.\n    \"\"\"\n    if meta is None:\n        meta = {}\n    elif not isinstance(meta, dict):\n        raise TypeError(f'meta must be a dict or None, but got {type(meta)}')\n    meta.update(mmcv_version=mmcv.__version__, time=time.asctime())\n\n    if is_module_wrapper(model):\n        model = model.module\n\n    if hasattr(model, 'CLASSES') and model.CLASSES is not None:\n        # save class name to the meta\n        meta.update(CLASSES=model.CLASSES)\n\n    checkpoint = {\n        'meta': meta,\n        'state_dict': weights_to_cpu(get_state_dict(model))\n    }\n    # save optimizer state dict in the checkpoint\n    if isinstance(optimizer, Optimizer):\n        checkpoint['optimizer'] = optimizer.state_dict()\n    elif isinstance(optimizer, dict):\n        checkpoint['optimizer'] = {}\n        for name, optim in optimizer.items():\n            checkpoint['optimizer'][name] = optim.state_dict()\n\n    if filename.startswith('pavi://'):\n        try:\n            from pavi import modelcloud\n            from pavi.exception import NodeNotFoundError\n        except ImportError:\n            raise ImportError(\n                'Please install pavi to load checkpoint from modelcloud.')\n        model_path = filename[7:]\n        root = modelcloud.Folder()\n        model_dir, model_name = osp.split(model_path)\n        try:\n            model = modelcloud.get(model_dir)\n        except NodeNotFoundError:\n            model = root.create_training_model(model_dir)\n        with TemporaryDirectory() as tmp_dir:\n            checkpoint_file = osp.join(tmp_dir, model_name)\n            with open(checkpoint_file, 'wb') as f:\n                torch.save(checkpoint, f)\n                f.flush()\n            model.create_file(checkpoint_file, name=model_name)\n    else:\n        mmcv.mkdir_or_exist(osp.dirname(filename))\n        # immediately flush buffer\n        with open(filename, 'wb') as f:\n            torch.save(checkpoint, f)\n            f.flush()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/layer_decay_optimizer_constructor.py",
    "content": "import json\nfrom mmcv.runner import OPTIMIZER_BUILDERS, DefaultOptimizerConstructor\nfrom mmcv.runner import get_dist_info\n\n\ndef get_num_layer_for_vit(var_name, num_max_layer):\n    if var_name in (\"backbone.cls_token\", \"backbone.mask_token\", \"backbone.pos_embed\"):\n        return 0\n    elif var_name.startswith(\"backbone.patch_embed\"):\n        return 0\n    elif var_name.startswith(\"backbone.blocks\"):\n        layer_id = int(var_name.split('.')[2])\n        return layer_id + 1\n    else:\n        return num_max_layer - 1\n\n\n@OPTIMIZER_BUILDERS.register_module()\nclass LayerDecayOptimizerConstructor(DefaultOptimizerConstructor):\n    def add_params(self, params, module, prefix='', is_dcn_module=None):\n        \"\"\"Add all parameters of module to the params list.\n        The parameters of the given module will be added to the list of param\n        groups, with specific rules defined by paramwise_cfg.\n        Args:\n            params (list[dict]): A list of param groups, it will be modified\n                in place.\n            module (nn.Module): The module to be added.\n            prefix (str): The prefix of the module\n            is_dcn_module (int|float|None): If the current module is a\n                submodule of DCN, `is_dcn_module` will be passed to\n                control conv_offset layer's learning rate. Defaults to None.\n        \"\"\"\n        parameter_groups = {}\n        print(self.paramwise_cfg)\n        num_layers = self.paramwise_cfg.get('num_layers') + 2\n        layer_decay_rate = self.paramwise_cfg.get('layer_decay_rate')\n        print(\"Build LayerDecayOptimizerConstructor %f - %d\" % (layer_decay_rate, num_layers))\n        weight_decay = self.base_wd\n\n        for name, param in module.named_parameters():\n            if not param.requires_grad:\n                continue  # frozen weights\n            if len(param.shape) == 1 or name.endswith(\".bias\") or name in ('pos_embed', 'cls_token'):\n                group_name = \"no_decay\"\n                this_weight_decay = 0.\n            else:\n                group_name = \"decay\"\n                this_weight_decay = weight_decay\n\n            layer_id = get_num_layer_for_vit(name, num_layers)\n            group_name = \"layer_%d_%s\" % (layer_id, group_name)\n\n            if group_name not in parameter_groups:\n                scale = layer_decay_rate ** (num_layers - layer_id - 1)\n\n                parameter_groups[group_name] = {\n                    \"weight_decay\": this_weight_decay,\n                    \"params\": [],\n                    \"param_names\": [], \n                    \"lr_scale\": scale, \n                    \"group_name\": group_name, \n                    \"lr\": scale * self.base_lr, \n                }\n\n            parameter_groups[group_name][\"params\"].append(param)\n            parameter_groups[group_name][\"param_names\"].append(name)\n        rank, _ = get_dist_info()\n        if rank == 0:\n            to_display = {}\n            for key in parameter_groups:\n                to_display[key] = {\n                    \"param_names\": parameter_groups[key][\"param_names\"], \n                    \"lr_scale\": parameter_groups[key][\"lr_scale\"], \n                    \"lr\": parameter_groups[key][\"lr\"], \n                    \"weight_decay\": parameter_groups[key][\"weight_decay\"], \n                }\n            print(\"Param groups = %s\" % json.dumps(to_display, indent=2))\n        \n        # state_dict = module.state_dict()\n        # for group_name in parameter_groups:\n        #     group = parameter_groups[group_name]\n        #     for name in group[\"param_names\"]:\n        #         group[\"params\"].append(state_dict[name])\n        params.extend(parameter_groups.values())\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/resize_transform.py",
    "content": "import mmcv\nimport numpy as np\n\nfrom mmseg.datasets.builder import PIPELINES\n\n\n@PIPELINES.register_module()\nclass SETR_Resize(object):\n    \"\"\"Resize images & seg.\n\n    This transform resizes the input image to some scale. If the input dict\n    contains the key \"scale\", then the scale in the input dict is used,\n    otherwise the specified scale in the init method is used.\n\n    ``img_scale`` can either be a tuple (single-scale) or a list of tuple\n    (multi-scale). There are 3 multiscale modes:\n\n    - ``ratio_range is not None``: randomly sample a ratio from the ratio range\n    and multiply it with the image scale.\n\n    - ``ratio_range is None and multiscale_mode == \"range\"``: randomly sample a\n    scale from the a range.\n\n    - ``ratio_range is None and multiscale_mode == \"value\"``: randomly sample a\n    scale from multiple scales.\n\n    Args:\n        img_scale (tuple or list[tuple]): Images scales for resizing.\n        multiscale_mode (str): Either \"range\" or \"value\".\n        ratio_range (tuple[float]): (min_ratio, max_ratio)\n        keep_ratio (bool): Whether to keep the aspect ratio when resizing the\n            image.\n    \"\"\"\n\n    def __init__(self,\n                 img_scale=None,\n                 multiscale_mode='range',\n                 ratio_range=None,\n                 keep_ratio=True,\n                 crop_size=None,\n                 setr_multi_scale=False):\n\n        if img_scale is None:\n            self.img_scale = None\n        else:\n            if isinstance(img_scale, list):\n                self.img_scale = img_scale\n            else:\n                self.img_scale = [img_scale]\n            # assert mmcv.is_list_of(self.img_scale, tuple)\n\n        if ratio_range is not None:\n            # mode 1: given a scale and a range of image ratio\n            assert len(self.img_scale) == 1\n        else:\n            # mode 2: given multiple scales or a range of scales\n            assert multiscale_mode in ['value', 'range']\n\n        self.multiscale_mode = multiscale_mode\n        self.ratio_range = ratio_range\n        self.keep_ratio = keep_ratio\n        self.crop_size = crop_size\n        self.setr_multi_scale = setr_multi_scale\n\n    @staticmethod\n    def random_select(img_scales):\n        \"\"\"Randomly select an img_scale from given candidates.\n\n        Args:\n            img_scales (list[tuple]): Images scales for selection.\n\n        Returns:\n            (tuple, int): Returns a tuple ``(img_scale, scale_dix)``,\n                where ``img_scale`` is the selected image scale and\n                ``scale_idx`` is the selected index in the given candidates.\n        \"\"\"\n\n        assert mmcv.is_list_of(img_scales, tuple)\n        scale_idx = np.random.randint(len(img_scales))\n        img_scale = img_scales[scale_idx]\n        return img_scale, scale_idx\n\n    @staticmethod\n    def random_sample(img_scales):\n        \"\"\"Randomly sample an img_scale when ``multiscale_mode=='range'``.\n\n        Args:\n            img_scales (list[tuple]): Images scale range for sampling.\n                There must be two tuples in img_scales, which specify the lower\n                and uper bound of image scales.\n\n        Returns:\n            (tuple, None): Returns a tuple ``(img_scale, None)``, where\n                ``img_scale`` is sampled scale and None is just a placeholder\n                to be consistent with :func:`random_select`.\n        \"\"\"\n\n        assert mmcv.is_list_of(img_scales, tuple) and len(img_scales) == 2\n        img_scale_long = [max(s) for s in img_scales]\n        img_scale_short = [min(s) for s in img_scales]\n        long_edge = np.random.randint(\n            min(img_scale_long),\n            max(img_scale_long) + 1)\n        short_edge = np.random.randint(\n            min(img_scale_short),\n            max(img_scale_short) + 1)\n        img_scale = (long_edge, short_edge)\n        return img_scale, None\n\n    @staticmethod\n    def random_sample_ratio(img_scale, ratio_range):\n        \"\"\"Randomly sample an img_scale when ``ratio_range`` is specified.\n\n        A ratio will be randomly sampled from the range specified by\n        ``ratio_range``. Then it would be multiplied with ``img_scale`` to\n        generate sampled scale.\n\n        Args:\n            img_scale (tuple): Images scale base to multiply with ratio.\n            ratio_range (tuple[float]): The minimum and maximum ratio to scale\n                the ``img_scale``.\n\n        Returns:\n            (tuple, None): Returns a tuple ``(scale, None)``, where\n                ``scale`` is sampled ratio multiplied with ``img_scale`` and\n                None is just a placeholder to be consistent with\n                :func:`random_select`.\n        \"\"\"\n\n        assert isinstance(img_scale, tuple) and len(img_scale) == 2\n        min_ratio, max_ratio = ratio_range\n        assert min_ratio <= max_ratio\n        ratio = np.random.random_sample() * (max_ratio - min_ratio) + min_ratio\n        scale = int(img_scale[0] * ratio), int(img_scale[1] * ratio)\n        return scale, None\n\n    def _random_scale(self, results):\n        \"\"\"Randomly sample an img_scale according to ``ratio_range`` and\n        ``multiscale_mode``.\n\n        If ``ratio_range`` is specified, a ratio will be sampled and be\n        multiplied with ``img_scale``.\n        If multiple scales are specified by ``img_scale``, a scale will be\n        sampled according to ``multiscale_mode``.\n        Otherwise, single scale will be used.\n\n        Args:\n            results (dict): Result dict from :obj:`dataset`.\n\n        Returns:\n            dict: Two new keys 'scale` and 'scale_idx` are added into\n                ``results``, which would be used by subsequent pipelines.\n        \"\"\"\n\n        if self.ratio_range is not None:\n            scale, scale_idx = self.random_sample_ratio(\n                self.img_scale[0], self.ratio_range)\n        elif len(self.img_scale) == 1:\n            scale, scale_idx = self.img_scale[0], 0\n        elif self.multiscale_mode == 'range':\n            scale, scale_idx = self.random_sample(self.img_scale)\n        elif self.multiscale_mode == 'value':\n            scale, scale_idx = self.random_select(self.img_scale)\n        else:\n            raise NotImplementedError\n\n        results['scale'] = scale\n        results['scale_idx'] = scale_idx\n\n    def _resize_img(self, results):\n        \"\"\"Resize images with ``results['scale']``.\"\"\"\n\n        if self.keep_ratio:\n            if self.setr_multi_scale:\n                if min(results['scale']) < self.crop_size[0]:\n                    new_short = self.crop_size[0]\n                else:\n                    new_short = min(results['scale'])\n                    \n                h, w = results['img'].shape[:2]\n                if h > w:\n                    new_h, new_w = new_short * h / w, new_short\n                else:\n                    new_h, new_w = new_short, new_short * w / h\n                results['scale'] = (new_h, new_w)\n\n            img, scale_factor = mmcv.imrescale(\n                results['img'], results['scale'], return_scale=True)\n            # the w_scale and h_scale has minor difference\n            # a real fix should be done in the mmcv.imrescale in the future\n            new_h, new_w = img.shape[:2]\n            h, w = results['img'].shape[:2]\n            w_scale = new_w / w\n            h_scale = new_h / h\n        else:\n            img, w_scale, h_scale = mmcv.imresize(\n                results['img'], results['scale'], return_scale=True)\n        scale_factor = np.array([w_scale, h_scale, w_scale, h_scale],\n                                dtype=np.float32)\n        results['img'] = img\n        results['img_shape'] = img.shape\n        results['pad_shape'] = img.shape  # in case that there is no padding\n        results['scale_factor'] = scale_factor\n        results['keep_ratio'] = self.keep_ratio\n\n    def _resize_seg(self, results):\n        \"\"\"Resize semantic segmentation map with ``results['scale']``.\"\"\"\n        for key in results.get('seg_fields', []):\n            if self.keep_ratio:\n                gt_seg = mmcv.imrescale(\n                    results[key], results['scale'], interpolation='nearest')\n            else:\n                gt_seg = mmcv.imresize(\n                    results[key], results['scale'], interpolation='nearest')\n            results['gt_semantic_seg'] = gt_seg\n\n    def __call__(self, results):\n        \"\"\"Call function to resize images, bounding boxes, masks, semantic\n        segmentation map.\n\n        Args:\n            results (dict): Result dict from loading pipeline.\n\n        Returns:\n            dict: Resized results, 'img_shape', 'pad_shape', 'scale_factor',\n                'keep_ratio' keys are added into result dict.\n        \"\"\"\n\n        if 'scale' not in results:\n            self._random_scale(results)\n        self._resize_img(results)\n        self._resize_seg(results)\n        return results\n\n    def __repr__(self):\n        repr_str = self.__class__.__name__\n        repr_str += (f'(img_scale={self.img_scale}, '\n                     f'multiscale_mode={self.multiscale_mode}, '\n                     f'ratio_range={self.ratio_range}, '\n                     f'keep_ratio={self.keep_ratio})')\n        return repr_str\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/mmcv_custom/train_api.py",
    "content": "import random\nimport warnings\n\nimport numpy as np\nimport torch\nfrom mmcv.parallel import MMDataParallel, MMDistributedDataParallel\nfrom mmcv.runner import build_optimizer, build_runner\n\nfrom mmseg.core import DistEvalHook, EvalHook\nfrom mmseg.datasets import build_dataloader, build_dataset\nfrom mmseg.utils import get_root_logger\ntry:\n    import apex\nexcept:\n    print('apex is not installed')\n\n\ndef set_random_seed(seed, deterministic=False):\n    \"\"\"Set random seed.\n\n    Args:\n        seed (int): Seed to be used.\n        deterministic (bool): Whether to set the deterministic option for\n            CUDNN backend, i.e., set `torch.backends.cudnn.deterministic`\n            to True and `torch.backends.cudnn.benchmark` to False.\n            Default: False.\n    \"\"\"\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    if deterministic:\n        torch.backends.cudnn.deterministic = True\n        torch.backends.cudnn.benchmark = False\n\n\ndef train_segmentor(model,\n                    dataset,\n                    cfg,\n                    distributed=False,\n                    validate=False,\n                    timestamp=None,\n                    meta=None):\n    \"\"\"Launch segmentor training.\"\"\"\n    logger = get_root_logger(cfg.log_level)\n\n    # prepare data loaders\n    dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset]\n    data_loaders = [\n        build_dataloader(\n            ds,\n            cfg.data.samples_per_gpu,\n            cfg.data.workers_per_gpu,\n            # cfg.gpus will be ignored if distributed\n            len(cfg.gpu_ids),\n            dist=distributed,\n            seed=cfg.seed,\n            drop_last=True) for ds in dataset\n    ]\n\n    # build optimizer\n    optimizer = build_optimizer(model, cfg.optimizer)\n\n    # use apex fp16 optimizer\n    if cfg.optimizer_config.get(\"type\", None) and cfg.optimizer_config[\"type\"] == \"DistOptimizerHook\":\n        if cfg.optimizer_config.get(\"use_fp16\", False):\n            model, optimizer = apex.amp.initialize(\n                model.cuda(), optimizer, opt_level=\"O1\")\n            for m in model.modules():\n                if hasattr(m, \"fp16_enabled\"):\n                    m.fp16_enabled = True\n\n    # put model on gpus\n    if distributed:\n        find_unused_parameters = cfg.get('find_unused_parameters', False)\n        # Sets the `find_unused_parameters` parameter in\n        # torch.nn.parallel.DistributedDataParallel\n        model = MMDistributedDataParallel(\n            model.cuda(),\n            device_ids=[torch.cuda.current_device()],\n            broadcast_buffers=False,\n            find_unused_parameters=find_unused_parameters)\n    else:\n        model = MMDataParallel(\n            model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids)\n\n    if cfg.get('runner') is None:\n        cfg.runner = {'type': 'IterBasedRunner', 'max_iters': cfg.total_iters}\n        warnings.warn(\n            'config is now expected to have a `runner` section, '\n            'please set `runner` in your config.', UserWarning)\n\n    runner = build_runner(\n        cfg.runner,\n        default_args=dict(\n            model=model,\n            batch_processor=None,\n            optimizer=optimizer,\n            work_dir=cfg.work_dir,\n            logger=logger,\n            meta=meta))\n\n    # register hooks\n    runner.register_training_hooks(cfg.lr_config, cfg.optimizer_config,\n                                   cfg.checkpoint_config, cfg.log_config,\n                                   cfg.get('momentum_config', None))\n\n    # an ugly walkaround to make the .log and .log.json filenames the same\n    runner.timestamp = timestamp\n\n    # register eval hooks\n    if validate:\n        val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))\n        val_dataloader = build_dataloader(\n            val_dataset,\n            samples_per_gpu=1,\n            workers_per_gpu=cfg.data.workers_per_gpu,\n            dist=distributed,\n            shuffle=False)\n        eval_cfg = cfg.get('evaluation', {})\n        eval_cfg['by_epoch'] = 'IterBasedRunner' not in cfg.runner['type']\n        eval_hook = DistEvalHook if distributed else EvalHook\n        runner.register_hook(eval_hook(val_dataloader, **eval_cfg))\n\n    if cfg.resume_from:\n        runner.resume(cfg.resume_from)\n    elif cfg.load_from:\n        runner.load_checkpoint(cfg.load_from)\n    runner.run(data_loaders, cfg.workflow)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/tools/dist_test.sh",
    "content": "#!/usr/bin/env bash\n\nCONFIG=$1\nCHECKPOINT=$2\nGPUS=$3\nPORT=${PORT:-29500}\nPYTHONPATH=\"$(dirname $0)/..\":$PYTHONPATH \\\npython -m torch.distributed.launch --nproc_per_node=$GPUS --master_port=$PORT \\\n    $(dirname \"$0\")/test.py $CONFIG $CHECKPOINT --launcher pytorch ${@:4}\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/tools/dist_train.sh",
    "content": "#!/usr/bin/env bash\n\nCONFIG=$1\nGPUS=$2\nPORT=${PORT:-29500}\n\nPYTHONPATH=\"$(dirname $0)/..\":$PYTHONPATH \\\npython -m torch.distributed.launch --nproc_per_node=$GPUS --master_port=$PORT \\\n    $(dirname \"$0\")/train.py $CONFIG --launcher pytorch ${@:3}\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/tools/test.py",
    "content": "import argparse\nimport os\n\nimport mmcv\nimport torch\nfrom mmcv.parallel import MMDataParallel, MMDistributedDataParallel\nfrom mmcv.runner import get_dist_info, init_dist, load_checkpoint\nfrom mmcv.utils import DictAction\n\nfrom mmseg.apis import multi_gpu_test, single_gpu_test\nfrom mmseg.datasets import build_dataloader, build_dataset\nfrom mmseg.models import build_segmentor\n\nfrom backbone import beit\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='mmseg test (and eval) a model')\n    parser.add_argument('config', help='test config file path')\n    parser.add_argument('checkpoint', help='checkpoint file')\n    parser.add_argument(\n        '--aug-test', action='store_true', help='Use Flip and Multi scale aug')\n    parser.add_argument('--out', help='output result file in pickle format')\n    parser.add_argument(\n        '--format-only',\n        action='store_true',\n        help='Format the output results without perform evaluation. It is'\n        'useful when you want to format the result to a specific format and '\n        'submit it to the test server')\n    parser.add_argument(\n        '--eval',\n        type=str,\n        nargs='+',\n        help='evaluation metrics, which depends on the dataset, e.g., \"mIoU\"'\n        ' for generic datasets, and \"cityscapes\" for Cityscapes')\n    parser.add_argument('--show', action='store_true', help='show results')\n    parser.add_argument(\n        '--show-dir', help='directory where painted images will be saved')\n    parser.add_argument(\n        '--gpu-collect',\n        action='store_true',\n        help='whether to use gpu to collect results.')\n    parser.add_argument(\n        '--tmpdir',\n        help='tmp directory used for collecting results from multiple '\n        'workers, available when gpu_collect is not specified')\n    parser.add_argument(\n        '--options', nargs='+', action=DictAction, help='custom options')\n    parser.add_argument(\n        '--eval-options',\n        nargs='+',\n        action=DictAction,\n        help='custom options for evaluation')\n    parser.add_argument(\n        '--launcher',\n        choices=['none', 'pytorch', 'slurm', 'mpi'],\n        default='none',\n        help='job launcher')\n    parser.add_argument('--local_rank', type=int, default=0)\n    args = parser.parse_args()\n    if 'LOCAL_RANK' not in os.environ:\n        os.environ['LOCAL_RANK'] = str(args.local_rank)\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    assert args.out or args.eval or args.format_only or args.show \\\n        or args.show_dir, \\\n        ('Please specify at least one operation (save/eval/format/show the '\n         'results / save the results) with the argument \"--out\", \"--eval\"'\n         ', \"--format-only\", \"--show\" or \"--show-dir\"')\n\n    if args.eval and args.format_only:\n        raise ValueError('--eval and --format_only cannot be both specified')\n\n    if args.out is not None and not args.out.endswith(('.pkl', '.pickle')):\n        raise ValueError('The output file must be a pkl file.')\n\n    cfg = mmcv.Config.fromfile(args.config)\n    if args.options is not None:\n        cfg.merge_from_dict(args.options)\n    # set cudnn_benchmark\n    if cfg.get('cudnn_benchmark', False):\n        torch.backends.cudnn.benchmark = True\n    if args.aug_test:\n        # hard code index\n        cfg.data.test.pipeline[1].img_ratios = [\n            0.5, 0.75, 1.0, 1.25, 1.5, 1.75\n        ]\n        cfg.data.test.pipeline[1].flip = True\n    cfg.model.pretrained = None\n    cfg.data.test.test_mode = True\n\n    # init distributed env first, since logger depends on the dist info.\n    if args.launcher == 'none':\n        distributed = False\n    else:\n        distributed = True\n        init_dist(args.launcher, **cfg.dist_params)\n\n    # build the dataloader\n    # TODO: support multiple images per gpu (only minor changes are needed)\n    dataset = build_dataset(cfg.data.test)\n    data_loader = build_dataloader(\n        dataset,\n        samples_per_gpu=1,\n        workers_per_gpu=cfg.data.workers_per_gpu,\n        dist=distributed,\n        shuffle=False)\n\n    # build the model and load checkpoint\n    cfg.model.train_cfg = None\n    model = build_segmentor(cfg.model, test_cfg=cfg.get('test_cfg'))\n    checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu')\n    model.CLASSES = checkpoint['meta']['CLASSES']\n    model.PALETTE = checkpoint['meta']['PALETTE']\n\n    efficient_test = False\n    if args.eval_options is not None:\n        efficient_test = args.eval_options.get('efficient_test', False)\n\n    if not distributed:\n        model = MMDataParallel(model, device_ids=[0])\n        outputs = single_gpu_test(model, data_loader, args.show, args.show_dir,\n                                  efficient_test)\n    else:\n        model = MMDistributedDataParallel(\n            model.cuda(),\n            device_ids=[torch.cuda.current_device()],\n            broadcast_buffers=False)\n        outputs = multi_gpu_test(model, data_loader, args.tmpdir,\n                                 args.gpu_collect, efficient_test)\n\n    rank, _ = get_dist_info()\n    if rank == 0:\n        if args.out:\n            print(f'\\nwriting results to {args.out}')\n            mmcv.dump(outputs, args.out)\n        kwargs = {} if args.eval_options is None else args.eval_options\n        if args.format_only:\n            dataset.format_results(outputs, **kwargs)\n        if args.eval:\n            dataset.evaluate(outputs, args.eval, **kwargs)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/semantic_segmentation/tools/train.py",
    "content": "import argparse\nimport copy\nimport os\nimport os.path as osp\nimport time\n\nimport mmcv\nimport mmcv_custom\nimport torch\nfrom mmcv.runner import init_dist\nfrom mmcv.utils import Config, DictAction, get_git_hash\n\nfrom mmseg import __version__\nfrom mmseg.apis import set_random_seed\nfrom mmcv_custom import train_segmentor\nfrom mmseg.datasets import build_dataset\nfrom mmseg.models import build_segmentor\nfrom mmseg.utils import collect_env, get_root_logger\n\nfrom backbone import beit\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Train a segmentor')\n    parser.add_argument('config', help='train config file path')\n    parser.add_argument('--work-dir', help='the dir to save logs and models')\n    parser.add_argument(\n        '--load-from', help='the checkpoint file to load weights from')\n    parser.add_argument(\n        '--resume-from', help='the checkpoint file to resume from')\n    parser.add_argument(\n        '--no-validate',\n        action='store_true',\n        help='whether not to evaluate the checkpoint during training')\n    group_gpus = parser.add_mutually_exclusive_group()\n    group_gpus.add_argument(\n        '--gpus',\n        type=int,\n        help='number of gpus to use '\n        '(only applicable to non-distributed training)')\n    group_gpus.add_argument(\n        '--gpu-ids',\n        type=int,\n        nargs='+',\n        help='ids of gpus to use '\n        '(only applicable to non-distributed training)')\n    parser.add_argument('--seed', type=int, default=None, help='random seed')\n    parser.add_argument(\n        '--deterministic',\n        action='store_true',\n        help='whether to set deterministic options for CUDNN backend.')\n    parser.add_argument(\n        '--options', nargs='+', action=DictAction, help='custom options')\n    parser.add_argument(\n        '--launcher',\n        choices=['none', 'pytorch', 'slurm', 'mpi'],\n        default='none',\n        help='job launcher')\n    parser.add_argument('--local_rank', type=int, default=0)\n    args = parser.parse_args()\n    if 'LOCAL_RANK' not in os.environ:\n        os.environ['LOCAL_RANK'] = str(args.local_rank)\n\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    cfg = Config.fromfile(args.config)\n    if args.options is not None:\n        cfg.merge_from_dict(args.options)\n    # set cudnn_benchmark\n    if cfg.get('cudnn_benchmark', False):\n        torch.backends.cudnn.benchmark = True\n\n    # work_dir is determined in this priority: CLI > segment in file > filename\n    if args.work_dir is not None:\n        # update configs according to CLI args if args.work_dir is not None\n        cfg.work_dir = args.work_dir\n    elif cfg.get('work_dir', None) is None:\n        # use config filename as default work_dir if cfg.work_dir is None\n        cfg.work_dir = osp.join('./work_dirs',\n                                osp.splitext(osp.basename(args.config))[0])\n    if args.load_from is not None:\n        cfg.load_from = args.load_from\n    if args.resume_from is not None:\n        cfg.resume_from = args.resume_from\n    if args.gpu_ids is not None:\n        cfg.gpu_ids = args.gpu_ids\n    else:\n        cfg.gpu_ids = range(1) if args.gpus is None else range(args.gpus)\n\n    # init distributed env first, since logger depends on the dist info.\n    if args.launcher == 'none':\n        distributed = False\n    else:\n        distributed = True\n        init_dist(args.launcher, **cfg.dist_params)\n\n    # create work_dir\n    mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))\n    # dump config\n    cfg.dump(osp.join(cfg.work_dir, osp.basename(args.config)))\n    # init the logger before other steps\n    timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())\n    log_file = osp.join(cfg.work_dir, f'{timestamp}.log')\n    logger = get_root_logger(log_file=log_file, log_level=cfg.log_level)\n\n    # init the meta dict to record some important information such as\n    # environment info and seed, which will be logged\n    meta = dict()\n    # log env info\n    env_info_dict = collect_env()\n    env_info = '\\n'.join([f'{k}: {v}' for k, v in env_info_dict.items()])\n    dash_line = '-' * 60 + '\\n'\n    logger.info('Environment info:\\n' + dash_line + env_info + '\\n' +\n                dash_line)\n    meta['env_info'] = env_info\n\n    # log some basic info\n    logger.info(f'Distributed training: {distributed}')\n    logger.info(f'Config:\\n{cfg.pretty_text}')\n\n    # set random seeds\n    if args.seed is not None:\n        logger.info(f'Set random seed to {args.seed}, deterministic: '\n                    f'{args.deterministic}')\n        set_random_seed(args.seed, deterministic=args.deterministic)\n    cfg.seed = args.seed\n    meta['seed'] = args.seed\n    meta['exp_name'] = osp.basename(args.config)\n\n    model = build_segmentor(\n        cfg.model,\n        train_cfg=cfg.get('train_cfg'),\n        test_cfg=cfg.get('test_cfg'))\n\n    logger.info(model)\n\n    datasets = [build_dataset(cfg.data.train)]\n    if len(cfg.workflow) == 2:\n        val_dataset = copy.deepcopy(cfg.data.val)\n        val_dataset.pipeline = cfg.data.train.pipeline\n        datasets.append(build_dataset(val_dataset))\n    if cfg.checkpoint_config is not None:\n        # save mmseg version, config file content and class names in\n        # checkpoints as meta data\n        cfg.checkpoint_config.meta = dict(\n            mmseg_version=f'{__version__}+{get_git_hash()[:7]}',\n            config=cfg.pretty_text,\n            CLASSES=datasets[0].CLASSES,\n            PALETTE=datasets[0].PALETTE)\n    # add an attribute for visualization convenience\n    model.CLASSES = datasets[0].CLASSES\n    train_segmentor(\n        model,\n        datasets,\n        cfg,\n        distributed=distributed,\n        validate=(not args.no_validate),\n        timestamp=timestamp,\n        meta=meta)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/transforms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport torch\nimport torchvision.transforms.functional as F\nfrom PIL import Image\nimport warnings\nimport math\nimport random\nimport numpy as np\n\n\nclass ToNumpy:\n\n    def __call__(self, pil_img):\n        np_img = np.array(pil_img, dtype=np.uint8)\n        if np_img.ndim < 3:\n            np_img = np.expand_dims(np_img, axis=-1)\n        np_img = np.rollaxis(np_img, 2)  # HWC to CHW\n        return np_img\n\n\nclass ToTensor:\n\n    def __init__(self, dtype=torch.float32):\n        self.dtype = dtype\n\n    def __call__(self, pil_img):\n        np_img = np.array(pil_img, dtype=np.uint8)\n        if np_img.ndim < 3:\n            np_img = np.expand_dims(np_img, axis=-1)\n        np_img = np.rollaxis(np_img, 2)  # HWC to CHW\n        return torch.from_numpy(np_img).to(dtype=self.dtype)\n\n\n_pil_interpolation_to_str = {\n    Image.NEAREST: 'PIL.Image.NEAREST',\n    Image.BILINEAR: 'PIL.Image.BILINEAR',\n    Image.BICUBIC: 'PIL.Image.BICUBIC',\n    Image.LANCZOS: 'PIL.Image.LANCZOS',\n    Image.HAMMING: 'PIL.Image.HAMMING',\n    Image.BOX: 'PIL.Image.BOX',\n}\n\n\ndef _pil_interp(method):\n    if method == 'bicubic':\n        return Image.BICUBIC\n    elif method == 'lanczos':\n        return Image.LANCZOS\n    elif method == 'hamming':\n        return Image.HAMMING\n    else:\n        # default bilinear, do we want to allow nearest?\n        return Image.BILINEAR\n\n\n_RANDOM_INTERPOLATION = (Image.BILINEAR, Image.BICUBIC)\n\n\nclass RandomResizedCropAndInterpolationWithTwoPic:\n    \"\"\"Crop the given PIL Image to random size and aspect ratio with random interpolation.\n\n    A crop of random size (default: of 0.08 to 1.0) of the original size and a random\n    aspect ratio (default: of 3/4 to 4/3) of the original aspect ratio is made. This crop\n    is finally resized to given size.\n    This is popularly used to train the Inception networks.\n\n    Args:\n        size: expected output size of each edge\n        scale: range of size of the origin size cropped\n        ratio: range of aspect ratio of the origin aspect ratio cropped\n        interpolation: Default: PIL.Image.BILINEAR\n    \"\"\"\n\n    def __init__(self, size, second_size=None, scale=(0.08, 1.0), ratio=(3. / 4., 4. / 3.),\n                 interpolation='bilinear', second_interpolation='lanczos'):\n        if isinstance(size, tuple):\n            self.size = size\n        else:\n            self.size = (size, size)\n        if second_size is not None:\n            if isinstance(second_size, tuple):\n                self.second_size = second_size\n            else:\n                self.second_size = (second_size, second_size)\n        else:\n            self.second_size = None\n        if (scale[0] > scale[1]) or (ratio[0] > ratio[1]):\n            warnings.warn(\"range should be of kind (min, max)\")\n\n        if interpolation == 'random':\n            self.interpolation = _RANDOM_INTERPOLATION\n        else:\n            self.interpolation = _pil_interp(interpolation)\n\n        self.second_interpolation = _pil_interp(second_interpolation) if second_interpolation is not None else None\n        self.scale = scale\n        self.ratio = ratio\n\n    @staticmethod\n    def get_params(img, scale, ratio):\n        \"\"\"Get parameters for ``crop`` for a random sized crop.\n\n        Args:\n            img (PIL Image): Image to be cropped.\n            scale (tuple): range of size of the origin size cropped\n            ratio (tuple): range of aspect ratio of the origin aspect ratio cropped\n\n        Returns:\n            tuple: params (i, j, h, w) to be passed to ``crop`` for a random\n                sized crop.\n        \"\"\"\n        area = img.size[0] * img.size[1]\n\n        for attempt in range(10):\n            target_area = random.uniform(*scale) * area\n            log_ratio = (math.log(ratio[0]), math.log(ratio[1]))\n            aspect_ratio = math.exp(random.uniform(*log_ratio))\n\n            w = int(round(math.sqrt(target_area * aspect_ratio)))\n            h = int(round(math.sqrt(target_area / aspect_ratio)))\n\n            if w <= img.size[0] and h <= img.size[1]:\n                i = random.randint(0, img.size[1] - h)\n                j = random.randint(0, img.size[0] - w)\n                return i, j, h, w\n\n        # Fallback to central crop\n        in_ratio = img.size[0] / img.size[1]\n        if in_ratio < min(ratio):\n            w = img.size[0]\n            h = int(round(w / min(ratio)))\n        elif in_ratio > max(ratio):\n            h = img.size[1]\n            w = int(round(h * max(ratio)))\n        else:  # whole image\n            w = img.size[0]\n            h = img.size[1]\n        i = (img.size[1] - h) // 2\n        j = (img.size[0] - w) // 2\n        return i, j, h, w\n\n    def __call__(self, img):\n        \"\"\"\n        Args:\n            img (PIL Image): Image to be cropped and resized.\n\n        Returns:\n            PIL Image: Randomly cropped and resized image.\n        \"\"\"\n        i, j, h, w = self.get_params(img, self.scale, self.ratio)\n        if isinstance(self.interpolation, (tuple, list)):\n            interpolation = random.choice(self.interpolation)\n        else:\n            interpolation = self.interpolation\n        if self.second_size is None:\n            return F.resized_crop(img, i, j, h, w, self.size, interpolation)\n        else:\n            return F.resized_crop(img, i, j, h, w, self.size, interpolation), \\\n                   F.resized_crop(img, i, j, h, w, self.second_size, self.second_interpolation)\n\n    def __repr__(self):\n        if isinstance(self.interpolation, (tuple, list)):\n            interpolate_str = ' '.join([_pil_interpolation_to_str[x] for x in self.interpolation])\n        else:\n            interpolate_str = _pil_interpolation_to_str[self.interpolation]\n        format_string = self.__class__.__name__ + '(size={0}'.format(self.size)\n        format_string += ', scale={0}'.format(tuple(round(s, 4) for s in self.scale))\n        format_string += ', ratio={0}'.format(tuple(round(r, 4) for r in self.ratio))\n        format_string += ', interpolation={0}'.format(interpolate_str)\n        if self.second_size is not None:\n            format_string += ', second_size={0}'.format(self.second_size)\n            format_string += ', second_interpolation={0}'.format(_pil_interpolation_to_str[self.second_interpolation])\n        format_string += ')'\n        return format_string\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/data2vec/utils.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport io\nimport os\nimport math\nimport time\nimport json\nfrom collections import defaultdict, deque\nimport datetime\nimport numpy as np\nfrom timm.utils import get_state_dict\n\nfrom pathlib import Path\n\nimport torch\nimport torch.distributed as dist\nfrom torch._six import inf\nfrom .modeling_discrete_vae import Dalle_VAE, DiscreteVAE\n\nfrom tensorboardX import SummaryWriter\n\n\nclass SmoothedValue(object):\n    \"\"\"Track a series of values and provide access to smoothed values over a\n    window or the global series average.\n    \"\"\"\n\n    def __init__(self, window_size=20, fmt=None):\n        if fmt is None:\n            fmt = \"{median:.4f} ({global_avg:.4f})\"\n        self.deque = deque(maxlen=window_size)\n        self.total = 0.0\n        self.count = 0\n        self.fmt = fmt\n\n    def update(self, value, n=1):\n        self.deque.append(value)\n        self.count += n\n        self.total += value * n\n\n    def synchronize_between_processes(self):\n        \"\"\"\n        Warning: does not synchronize the deque!\n        \"\"\"\n        if not is_dist_avail_and_initialized():\n            return\n        t = torch.tensor([self.count, self.total], dtype=torch.float64, device='cuda')\n        dist.barrier()\n        dist.all_reduce(t)\n        t = t.tolist()\n        self.count = int(t[0])\n        self.total = t[1]\n\n    @property\n    def median(self):\n        d = torch.tensor(list(self.deque))\n        return d.median().item()\n\n    @property\n    def avg(self):\n        d = torch.tensor(list(self.deque), dtype=torch.float32)\n        return d.mean().item()\n\n    @property\n    def global_avg(self):\n        return self.total / self.count\n\n    @property\n    def max(self):\n        return max(self.deque)\n\n    @property\n    def value(self):\n        return self.deque[-1]\n\n    def __str__(self):\n        return self.fmt.format(\n            median=self.median,\n            avg=self.avg,\n            global_avg=self.global_avg,\n            max=self.max,\n            value=self.value)\n\n\nclass MetricLogger(object):\n    def __init__(self, delimiter=\"\\t\"):\n        self.meters = defaultdict(SmoothedValue)\n        self.delimiter = delimiter\n\n    def update(self, **kwargs):\n        for k, v in kwargs.items():\n            if v is None:\n                continue\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.meters[k].update(v)\n\n    def __getattr__(self, attr):\n        if attr in self.meters:\n            return self.meters[attr]\n        if attr in self.__dict__:\n            return self.__dict__[attr]\n        raise AttributeError(\"'{}' object has no attribute '{}'\".format(\n            type(self).__name__, attr))\n\n    def __str__(self):\n        loss_str = []\n        for name, meter in self.meters.items():\n            loss_str.append(\n                \"{}: {}\".format(name, str(meter))\n            )\n        return self.delimiter.join(loss_str)\n\n    def synchronize_between_processes(self):\n        for meter in self.meters.values():\n            meter.synchronize_between_processes()\n\n    def add_meter(self, name, meter):\n        self.meters[name] = meter\n\n    def log_every(self, iterable, print_freq, header=None):\n        i = 0\n        if not header:\n            header = ''\n        start_time = time.time()\n        end = time.time()\n        iter_time = SmoothedValue(fmt='{avg:.4f}')\n        data_time = SmoothedValue(fmt='{avg:.4f}')\n        space_fmt = ':' + str(len(str(len(iterable)))) + 'd'\n        log_msg = [\n            header,\n            '[{0' + space_fmt + '}/{1}]',\n            'eta: {eta}',\n            '{meters}',\n            'time: {time}',\n            'data: {data}'\n        ]\n        if torch.cuda.is_available():\n            log_msg.append('max mem: {memory:.0f}')\n        log_msg = self.delimiter.join(log_msg)\n        MB = 1024.0 * 1024.0\n        for obj in iterable:\n            data_time.update(time.time() - end)\n            yield obj\n            iter_time.update(time.time() - end)\n            if i % print_freq == 0 or i == len(iterable) - 1:\n                eta_seconds = iter_time.global_avg * (len(iterable) - i)\n                eta_string = str(datetime.timedelta(seconds=int(eta_seconds)))\n                if torch.cuda.is_available():\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time),\n                        memory=torch.cuda.max_memory_allocated() / MB))\n                else:\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time)))\n            i += 1\n            end = time.time()\n        total_time = time.time() - start_time\n        total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n        print('{} Total time: {} ({:.4f} s / it)'.format(\n            header, total_time_str, total_time / len(iterable)))\n\n\nclass TensorboardLogger(object):\n    def __init__(self, log_dir):\n        self.writer = SummaryWriter(logdir=log_dir)\n        self.step = 0\n\n    def set_step(self, step=None):\n        if step is not None:\n            self.step = step\n        else:\n            self.step += 1\n\n    def update(self, head='scalar', step=None, **kwargs):\n        for k, v in kwargs.items():\n            if v is None:\n                continue\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.writer.add_scalar(head + \"/\" + k, v, self.step if step is None else step)\n\n    def flush(self):\n        self.writer.flush()\n\n\ndef _load_checkpoint_for_ema(model_ema, checkpoint):\n    \"\"\"\n    Workaround for ModelEma._load_checkpoint to accept an already-loaded object\n    \"\"\"\n\n    if hasattr(model_ema, \"module\"):\n        model_ema.module.load_state_dict(checkpoint['model_ema'])\n    else:\n        mem_file = io.BytesIO()\n        torch.save(checkpoint, mem_file)\n        mem_file.seek(0)\n        model_ema._load_checkpoint(mem_file)\n\n\ndef setup_for_distributed(is_master):\n    \"\"\"\n    This function disables printing when not in master process\n    \"\"\"\n    import builtins as __builtin__\n    builtin_print = __builtin__.print\n\n    def print(*args, **kwargs):\n        force = kwargs.pop('force', False)\n        if is_master or force:\n            builtin_print(*args, **kwargs)\n\n    __builtin__.print = print\n\n\ndef is_dist_avail_and_initialized():\n    if not dist.is_available():\n        return False\n    if not dist.is_initialized():\n        return False\n    return True\n\n\ndef get_world_size():\n    if not is_dist_avail_and_initialized():\n        return 1\n    return dist.get_world_size()\n\n\ndef get_rank():\n    if not is_dist_avail_and_initialized():\n        return 0\n    return dist.get_rank()\n\n\ndef is_main_process():\n    return get_rank() == 0\n\n\ndef save_on_master(*args, **kwargs):\n    if is_main_process():\n        torch.save(*args, **kwargs)\n\n\ndef init_distributed_mode(args):\n    if args.dist_on_itp:\n        args.rank = int(os.environ['OMPI_COMM_WORLD_RANK'])\n        args.world_size = int(os.environ['OMPI_COMM_WORLD_SIZE'])\n        args.gpu = int(os.environ['OMPI_COMM_WORLD_LOCAL_RANK'])\n        args.dist_url = \"tcp://%s:%s\" % (os.environ['MASTER_ADDR'], os.environ['MASTER_PORT'])\n        os.environ['LOCAL_RANK'] = str(args.gpu)\n        os.environ['RANK'] = str(args.rank)\n        os.environ['WORLD_SIZE'] = str(args.world_size)\n        # [\"RANK\", \"WORLD_SIZE\", \"MASTER_ADDR\", \"MASTER_PORT\", \"LOCAL_RANK\"]\n    elif 'RANK' in os.environ and 'WORLD_SIZE' in os.environ and 'SLURM_NODEID' not in os.environ:\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ['WORLD_SIZE'])\n        args.gpu = int(os.environ['LOCAL_RANK'])\n    elif 'RANK' in os.environ and 'WORLD_SIZE' in os.environ and 'SLURM_NODEID' in os.environ:\n        # args.rank = int(os.environ[\"RANK\"])\n        # print(os.environ)\n\n        gpus_per_node = torch.cuda.device_count()\n        node_id = int(os.environ.get(\"SLURM_NODEID\"))\n        args.rank = int(os.environ[\"RANK\"]) + node_id * gpus_per_node\n\n        args.world_size = int(os.environ['WORLD_SIZE'])\n        args.gpu = int(os.environ['LOCAL_RANK'])\n    elif 'SLURM_PROCID' in os.environ:\n        os.environ['RANK'] = os.environ['SLURM_PROCID']\n        args.rank = int(os.environ['SLURM_PROCID'])\n        os.environ['LOCAL_RANK'] = str(args.rank % torch.cuda.device_count())\n        args.gpu = args.rank % torch.cuda.device_count()\n        print(\"utils.py SLURM_PROCID in os.environ\")\n        print(\"args.rank \"+str(args.rank))\n        print(\"args.gpu \"+str(args.gpu))\n        print(\"args.world_size \"+str(args.world_size))\n        print(\"SLURM_NTASKS \"+str(os.environ['SLURM_NTASKS']))\n        assert int(args.world_size) == int(os.environ['SLURM_NTASKS'])\n        os.environ['WORLD_SIZE'] = str(args.world_size)\n    else:\n        print('Not using distributed mode')\n        args.distributed = False\n        return\n\n    args.distributed = True\n\n    torch.cuda.set_device(args.gpu)\n    args.dist_backend = 'nccl'\n    print('| distributed init (rank {}): {}, gpu {}, world_size {}'.format(\n        args.rank, args.dist_url, args.gpu, args.world_size), flush=True)\n    torch.distributed.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                         world_size=args.world_size, rank=args.rank)\n    # torch.distributed.init_process_group(backend=args.dist_backend, init_method='env://')\n    setup_for_distributed(args.rank == 0)\n\n\ndef load_state_dict(model, state_dict, prefix='', ignore_missing=\"relative_position_index\"):\n    missing_keys = []\n    unexpected_keys = []\n    error_msgs = []\n    # copy state_dict so _load_from_state_dict can modify it\n    metadata = getattr(state_dict, '_metadata', None)\n    state_dict = state_dict.copy()\n    if metadata is not None:\n        state_dict._metadata = metadata\n\n    def load(module, prefix=''):\n        local_metadata = {} if metadata is None else metadata.get(\n            prefix[:-1], {})\n        module._load_from_state_dict(\n            state_dict, prefix, local_metadata, True, missing_keys, unexpected_keys, error_msgs)\n        for name, child in module._modules.items():\n            if child is not None:\n                load(child, prefix + name + '.')\n\n    load(model, prefix=prefix)\n\n    warn_missing_keys = []\n    ignore_missing_keys = []\n    for key in missing_keys:\n        keep_flag = True\n        for ignore_key in ignore_missing.split('|'):\n            if ignore_key in key:\n                keep_flag = False\n                break\n        if keep_flag:\n            warn_missing_keys.append(key)\n        else:\n            ignore_missing_keys.append(key)\n\n    missing_keys = warn_missing_keys\n\n    if len(missing_keys) > 0:\n        print(\"Weights of {} not initialized from pretrained model: {}\".format(\n            model.__class__.__name__, missing_keys))\n    if len(unexpected_keys) > 0:\n        print(\"Weights from pretrained model not used in {}: {}\".format(\n            model.__class__.__name__, unexpected_keys))\n    if len(ignore_missing_keys) > 0:\n        print(\"Ignored weights of {} not initialized from pretrained model: {}\".format(\n            model.__class__.__name__, ignore_missing_keys))\n    if len(error_msgs) > 0:\n        print('\\n'.join(error_msgs))\n\n\nclass NativeScalerWithGradNormCount:\n    state_dict_key = \"amp_scaler\"\n\n    def __init__(self):\n        self._scaler = torch.cuda.amp.GradScaler()\n\n    def __call__(self, loss, optimizer, clip_grad=None, parameters=None, create_graph=False, update_grad=True):\n        self._scaler.scale(loss).backward(create_graph=create_graph)\n        if update_grad:\n            if clip_grad is not None:\n                assert parameters is not None\n                self._scaler.unscale_(optimizer)  # unscale the gradients of optimizer's assigned params in-place\n                norm = torch.nn.utils.clip_grad_norm_(parameters, clip_grad)\n            else:\n                self._scaler.unscale_(optimizer)\n                norm = get_grad_norm_(parameters)\n            self._scaler.step(optimizer)\n            self._scaler.update()\n        else:\n            norm = None\n        return norm\n\n    def state_dict(self):\n        return self._scaler.state_dict()\n\n    def load_state_dict(self, state_dict):\n        self._scaler.load_state_dict(state_dict)\n\n\ndef get_grad_norm_(parameters, norm_type: float = 2.0) -> torch.Tensor:\n    if isinstance(parameters, torch.Tensor):\n        parameters = [parameters]\n    parameters = [p for p in parameters if p.grad is not None]\n    norm_type = float(norm_type)\n    if len(parameters) == 0:\n        return torch.tensor(0.)\n    device = parameters[0].grad.device\n    if norm_type == inf:\n        total_norm = max(p.grad.detach().abs().max().to(device) for p in parameters)\n    else:\n        total_norm = torch.norm(torch.stack([torch.norm(p.grad.detach(), norm_type).to(device) for p in parameters]), norm_type)\n    return total_norm\n\n\ndef cosine_scheduler(base_value, final_value, epochs, niter_per_ep, warmup_epochs=0,\n                     start_warmup_value=0, warmup_steps=-1):\n    warmup_schedule = np.array([])\n    warmup_iters = warmup_epochs * niter_per_ep\n    if warmup_steps > 0:\n        warmup_iters = warmup_steps\n    print(\"Set warmup steps = %d\" % warmup_iters)\n    if warmup_epochs > 0:\n        warmup_schedule = np.linspace(start_warmup_value, base_value, warmup_iters)\n\n    iters = np.arange(epochs * niter_per_ep - warmup_iters)\n    schedule = np.array(\n        [final_value + 0.5 * (base_value - final_value) * (1 + math.cos(math.pi * i / (len(iters)))) for i in iters])\n\n    schedule = np.concatenate((warmup_schedule, schedule))\n\n    assert len(schedule) == epochs * niter_per_ep\n    return schedule\n\ndef tri_phase_scheduler(base_value, final_value, epochs, niter_per_ep, warmup_perc=0.05, decay_perc=0.05,\n                     start_warmup_value=0):\n\n    assert warmup_perc + decay_perc <= 1\n\n    total_updates = int(epochs * niter_per_ep)\n\n    warmup_iters = int(warmup_perc * total_updates)\n    decay_iters = int(decay_perc * total_updates)\n    hold_iters = total_updates - warmup_iters - decay_iters\n\n    print(\"Set warmup steps = %d\" % warmup_iters)\n    if warmup_iters > 0:\n        warmup_schedule = np.linspace(start_warmup_value, base_value, warmup_iters)\n    else:\n        warmup_schedule = np.array([])\n\n    if hold_iters > 0:\n        hold_schedule = np.full(hold_iters, base_value)\n    else:\n        hold_schedule = np.array([])\n\n    if decay_iters > 0:\n        decay_schedule = np.linspace(base_value, final_value, decay_iters)\n    else:\n        decay_schedule = np.array([])\n\n    schedule = np.concatenate((warmup_schedule, hold_schedule, decay_schedule))\n\n    assert len(schedule) == epochs * niter_per_ep, \\\n        f\"e: {epochs}, it: {niter_per_ep}, tot: {epochs*niter_per_ep}, \" \\\n        f\"w: {warmup_iters}, h: {hold_iters}, d: {decay_iters}, len: {len(schedule)}\"\n    return schedule\n\n\ndef save_model(args, epoch, model, model_without_ddp, optimizer, loss_scaler, model_ema=None):\n    output_dir = Path(args.output_dir)\n    epoch_name = str(epoch)\n    if loss_scaler is not None:\n        checkpoint_paths = [output_dir / ('checkpoint-%s.pth' % epoch_name)]\n        for checkpoint_path in checkpoint_paths:\n            to_save = {\n                'model': model_without_ddp.state_dict(),\n                'optimizer': optimizer.state_dict(),\n                'epoch': epoch,\n                'scaler': loss_scaler.state_dict(),\n                'args': args,\n            }\n\n            if model_ema is not None:\n                to_save['model_ema'] = get_state_dict(model_ema)\n\n            save_on_master(to_save, checkpoint_path)\n    else:\n        client_state = {'epoch': epoch}\n        if model_ema is not None:\n            client_state['model_ema'] = get_state_dict(model_ema)\n        model.save_checkpoint(save_dir=args.output_dir, tag=\"checkpoint-%s\" % epoch_name, client_state=client_state)\n\n\ndef auto_load_model(args, model, model_without_ddp, optimizer, loss_scaler, model_ema=None):\n    output_dir = Path(args.output_dir)\n    if loss_scaler is not None:\n        # torch.amp\n        if args.auto_resume and len(args.resume) == 0:\n            import glob\n            all_checkpoints = glob.glob(os.path.join(glob.escape(output_dir), 'checkpoint-*.pth'))\n            latest_ckpt = -1\n            for ckpt in all_checkpoints:\n                t = ckpt.split('-')[-1].split('.')[0]\n                if t.isdigit():\n                    latest_ckpt = max(int(t), latest_ckpt)\n\n            print(output_dir, latest_ckpt, all_checkpoints)\n\n            if latest_ckpt >= 0:\n                args.resume = os.path.join(output_dir, 'checkpoint-%d.pth' % latest_ckpt)\n            print(\"Auto resume checkpoint: %s\" % args.resume)\n\n        if args.resume:\n            if args.resume.startswith('https'):\n                checkpoint = torch.hub.load_state_dict_from_url(\n                    args.resume, map_location='cpu', check_hash=True)\n            else:\n                checkpoint = torch.load(args.resume, map_location='cpu')\n            model_without_ddp.load_state_dict(checkpoint['model'])\n            print(\"Resume checkpoint %s\" % args.resume)\n            if 'optimizer' in checkpoint and 'epoch' in checkpoint and not getattr(args, \"reset_resume\", False): # and len(getattr(args, \"seed_model\", '') or []) == 0:\n                optimizer.load_state_dict(checkpoint['optimizer'])\n                args.start_epoch = checkpoint['epoch'] + 1\n                if hasattr(args, 'model_ema') and args.model_ema:\n                    _load_checkpoint_for_ema(model_ema, checkpoint['model_ema'])\n                if 'scaler' in checkpoint:\n                    loss_scaler.load_state_dict(checkpoint['scaler'])\n                print(\"With optim & sched!\")\n    else:\n        # deepspeed, only support '--auto_resume'.\n        if args.auto_resume:\n            import glob\n            all_checkpoints = glob.glob(os.path.join(output_dir, 'checkpoint-*'))\n            latest_ckpt = -1\n            for ckpt in all_checkpoints:\n                t = ckpt.split('-')[-1].split('.')[0]\n                if t.isdigit():\n                    latest_ckpt = max(int(t), latest_ckpt)\n            if latest_ckpt >= 0:\n                args.resume = os.path.join(output_dir, 'checkpoint-%d' % latest_ckpt)\n                print(\"Auto resume checkpoint: %d\" % latest_ckpt)\n                _, client_states = model.load_checkpoint(args.output_dir, tag='checkpoint-%d' % latest_ckpt)\n                args.start_epoch = client_states['epoch'] + 1\n                if model_ema is not None:\n                    if args.model_ema:\n                        _load_checkpoint_for_ema(model_ema, client_states['model_ema'])\n\n\ndef create_d_vae(weight_path, d_vae_type, image_size, device):\n    if d_vae_type == \"dall-e\":\n        return get_dalle_vae(weight_path, image_size, device)\n    elif d_vae_type == \"customized\":\n        return get_d_vae(weight_path, image_size, device)\n    else:\n        raise NotImplementedError()\n\n\ndef get_dalle_vae(weight_path, image_size, device):\n    vae = Dalle_VAE(image_size)\n    vae.load_model(model_dir=weight_path, device=device)\n    return vae\n\n\ndef get_d_vae(weight_path, image_size, device):\n    NUM_TOKENS = 8192\n    NUM_LAYERS = 3\n    EMB_DIM = 512\n    HID_DIM = 256\n\n    state_dict = torch.load(os.path.join(weight_path, \"pytorch_model.bin\"), map_location=\"cpu\")[\"weights\"]\n\n    model = DiscreteVAE(\n        image_size=image_size,\n        num_layers=NUM_LAYERS,\n        num_tokens=NUM_TOKENS,\n        codebook_dim=EMB_DIM,\n        hidden_dim=HID_DIM,\n    ).to(device)\n\n    model.load_state_dict(state_dict)\n    return model\n\n\ndef create_ds_config(args):\n    args.deepspeed_config = os.path.join(args.output_dir, \"deepspeed_config.json\")\n    with open(args.deepspeed_config, mode=\"w\") as writer:\n        ds_config = {\n            \"train_batch_size\": args.batch_size * args.update_freq * get_world_size(),\n            \"train_micro_batch_size_per_gpu\": args.batch_size,\n            \"steps_per_print\": 1000,\n            \"optimizer\": {\n                \"type\": \"Adam\",\n                \"adam_w_mode\": True,\n                \"params\": {\n                    \"lr\": args.lr,\n                    \"weight_decay\": args.weight_decay,\n                    \"bias_correction\": True,\n                    \"betas\": [\n                        0.9,\n                        0.999\n                    ],\n                    \"eps\": 1e-8\n                }\n            },\n            \"fp16\": {\n                \"enabled\": True,\n                \"loss_scale\": 0,\n                \"initial_scale_power\": 7,\n                \"loss_scale_window\": 128\n            }\n        }\n\n        writer.write(json.dumps(ds_config, indent=2))\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/dino/utils.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#     http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nMisc functions.\n\nMostly copy-paste from torchvision references or other public repos like DETR:\nhttps://github.com/facebookresearch/detr/blob/master/util/misc.py\n\"\"\"\nimport os\nimport sys\nimport time\nimport math\nimport random\nimport datetime\nimport subprocess\nfrom collections import defaultdict, deque\n\nimport numpy as np\nimport torch\nfrom torch import nn\nimport torch.distributed as dist\nfrom PIL import ImageFilter, ImageOps\n\nimport cv2\n\nclass GaussianBlur(object):\n    \"\"\"\n    Apply Gaussian Blur to the PIL image.\n    \"\"\"\n    def __init__(self, p=0.5, radius_min=0.1, radius_max=2.):\n        self.prob = p\n        self.radius_min = radius_min\n        self.radius_max = radius_max\n\n    def __call__(self, img):\n        do_it = random.random() <= self.prob\n        if not do_it:\n            return img\n\n        return img.filter(\n            ImageFilter.GaussianBlur(\n                radius=random.uniform(self.radius_min, self.radius_max)\n            )\n        )\n\n\nclass cvGaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, p=0.5, sigma=[.1, 2.]):\n        self.sigma = sigma\n        self.prob = p\n\n    def __call__(self, x):\n        do_it = random.random() <= self.prob\n        if not do_it:\n            return x        \n    \n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)\n\n\n\n\nclass Solarization(object):\n    \"\"\"\n    Apply Solarization to the PIL image.\n    \"\"\"\n    def __init__(self, p):\n        self.p = p\n\n    def __call__(self, img):\n        if random.random() < self.p:\n            return ImageOps.solarize(img)\n        else:\n            return img\n\n\ndef load_pretrained_weights(model, pretrained_weights, checkpoint_key, model_name, patch_size):\n    if os.path.isfile(pretrained_weights):\n        state_dict = torch.load(pretrained_weights, map_location=\"cpu\")\n        if checkpoint_key is not None and checkpoint_key in state_dict:\n            print(f\"Take key {checkpoint_key} in provided checkpoint dict\")\n            state_dict = state_dict[checkpoint_key]\n        # remove `module.` prefix\n        state_dict = {k.replace(\"module.\", \"\"): v for k, v in state_dict.items()}\n        # remove `backbone.` prefix induced by multicrop wrapper\n        state_dict = {k.replace(\"backbone.\", \"\"): v for k, v in state_dict.items()}\n        msg = model.load_state_dict(state_dict, strict=False)\n        print('Pretrained weights found at {} and loaded with msg: {}'.format(pretrained_weights, msg))\n    else:\n        print(\"Please use the `--pretrained_weights` argument to indicate the path of the checkpoint to evaluate.\")\n        url = None\n        if model_name == \"vit_small\" and patch_size == 16:\n            url = \"dino_deitsmall16_pretrain/dino_deitsmall16_pretrain.pth\"\n        elif model_name == \"vit_small\" and patch_size == 8:\n            url = \"dino_deitsmall8_pretrain/dino_deitsmall8_pretrain.pth\"\n        elif model_name == \"vit_base\" and patch_size == 16:\n            url = \"dino_vitbase16_pretrain/dino_vitbase16_pretrain.pth\"\n        elif model_name == \"vit_base\" and patch_size == 8:\n            url = \"dino_vitbase8_pretrain/dino_vitbase8_pretrain.pth\"\n        elif model_name == \"xcit_small_12_p16\":\n            url = \"dino_xcit_small_12_p16_pretrain/dino_xcit_small_12_p16_pretrain.pth\"\n        elif model_name == \"xcit_small_12_p8\":\n            url = \"dino_xcit_small_12_p8_pretrain/dino_xcit_small_12_p8_pretrain.pth\"\n        elif model_name == \"xcit_medium_24_p16\":\n            url = \"dino_xcit_medium_24_p16_pretrain/dino_xcit_medium_24_p16_pretrain.pth\"\n        elif model_name == \"xcit_medium_24_p8\":\n            url = \"dino_xcit_medium_24_p8_pretrain/dino_xcit_medium_24_p8_pretrain.pth\"\n        elif model_name == \"resnet50\":\n            url = \"dino_resnet50_pretrain/dino_resnet50_pretrain.pth\"\n        if url is not None:\n            print(\"Since no pretrained weights have been provided, we load the reference pretrained DINO weights.\")\n            state_dict = torch.hub.load_state_dict_from_url(url=\"https://dl.fbaipublicfiles.com/dino/\" + url)\n            model.load_state_dict(state_dict, strict=True)\n        else:\n            print(\"There is no reference weights available for this model => We use random weights.\")\n\n\ndef load_pretrained_linear_weights(linear_classifier, model_name, patch_size):\n    url = None\n    if model_name == \"vit_small\" and patch_size == 16:\n        url = \"dino_deitsmall16_pretrain/dino_deitsmall16_linearweights.pth\"\n    elif model_name == \"vit_small\" and patch_size == 8:\n        url = \"dino_deitsmall8_pretrain/dino_deitsmall8_linearweights.pth\"\n    elif model_name == \"vit_base\" and patch_size == 16:\n        url = \"dino_vitbase16_pretrain/dino_vitbase16_linearweights.pth\"\n    elif model_name == \"vit_base\" and patch_size == 8:\n        url = \"dino_vitbase8_pretrain/dino_vitbase8_linearweights.pth\"\n    elif model_name == \"resnet50\":\n        url = \"dino_resnet50_pretrain/dino_resnet50_linearweights.pth\"\n    if url is not None:\n        print(\"We load the reference pretrained linear weights.\")\n        state_dict = torch.hub.load_state_dict_from_url(url=\"https://dl.fbaipublicfiles.com/dino/\" + url)[\"state_dict\"]\n        linear_classifier.load_state_dict(state_dict, strict=True)\n    else:\n        print(\"We use random linear weights.\")\n\n\ndef clip_gradients(model, clip):\n    norms = []\n    for name, p in model.named_parameters():\n        if p.grad is not None:\n            param_norm = p.grad.data.norm(2)\n            norms.append(param_norm.item())\n            clip_coef = clip / (param_norm + 1e-6)\n            if clip_coef < 1:\n                p.grad.data.mul_(clip_coef)\n    return norms\n\n\ndef cancel_gradients_last_layer(epoch, model, freeze_last_layer):\n    if epoch >= freeze_last_layer:\n        return\n    for n, p in model.named_parameters():\n        if \"last_layer\" in n:\n            p.grad = None\n\n\ndef restart_from_checkpoint(ckp_path, run_variables=None, **kwargs):\n    \"\"\"\n    Re-start from checkpoint\n    \"\"\"\n    if not os.path.isfile(ckp_path):\n        return\n    print(\"Found checkpoint at {}\".format(ckp_path))\n\n    # open checkpoint file\n    checkpoint = torch.load(ckp_path, map_location=\"cpu\")\n\n    # key is what to look for in the checkpoint file\n    # value is the object to load\n    # example: {'state_dict': model}\n    for key, value in kwargs.items():\n        if key in checkpoint and value is not None:\n            try:\n                msg = value.load_state_dict(checkpoint[key], strict=False)\n                print(\"=> loaded '{}' from checkpoint '{}' with msg {}\".format(key, ckp_path, msg))\n            except TypeError:\n                try:\n                    msg = value.load_state_dict(checkpoint[key])\n                    print(\"=> loaded '{}' from checkpoint: '{}'\".format(key, ckp_path))\n                except ValueError:\n                    print(\"=> failed to load '{}' from checkpoint: '{}'\".format(key, ckp_path))\n        else:\n            print(\"=> key '{}' not found in checkpoint: '{}'\".format(key, ckp_path))\n\n    # re load variable important for the run\n    if run_variables is not None:\n        for var_name in run_variables:\n            if var_name in checkpoint:\n                run_variables[var_name] = checkpoint[var_name]\n\n\ndef cosine_scheduler(base_value, final_value, epochs, niter_per_ep, warmup_epochs=0, start_warmup_value=0):\n    warmup_schedule = np.array([])\n    warmup_iters = warmup_epochs * niter_per_ep\n    if warmup_epochs > 0:\n        warmup_schedule = np.linspace(start_warmup_value, base_value, warmup_iters)\n\n    iters = np.arange(epochs * niter_per_ep - warmup_iters)\n    schedule = final_value + 0.5 * (base_value - final_value) * (1 + np.cos(np.pi * iters / len(iters)))\n\n    schedule = np.concatenate((warmup_schedule, schedule))\n    assert len(schedule) == epochs * niter_per_ep\n    return schedule\n\n\ndef bool_flag(s):\n    \"\"\"\n    Parse boolean arguments from the command line.\n    \"\"\"\n    FALSY_STRINGS = {\"off\", \"false\", \"0\"}\n    TRUTHY_STRINGS = {\"on\", \"true\", \"1\"}\n    if s.lower() in FALSY_STRINGS:\n        return False\n    elif s.lower() in TRUTHY_STRINGS:\n        return True\n    else:\n        raise argparse.ArgumentTypeError(\"invalid value for a boolean flag\")\n\n\ndef fix_random_seeds(seed=31):\n    \"\"\"\n    Fix random seeds.\n    \"\"\"\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    np.random.seed(seed)\n\n\nclass SmoothedValue(object):\n    \"\"\"Track a series of values and provide access to smoothed values over a\n    window or the global series average.\n    \"\"\"\n\n    def __init__(self, window_size=20, fmt=None):\n        if fmt is None:\n            fmt = \"{median:.6f} ({global_avg:.6f})\"\n        self.deque = deque(maxlen=window_size)\n        self.total = 0.0\n        self.count = 0\n        self.fmt = fmt\n\n    def update(self, value, n=1):\n        self.deque.append(value)\n        self.count += n\n        self.total += value * n\n\n    def synchronize_between_processes(self):\n        \"\"\"\n        Warning: does not synchronize the deque!\n        \"\"\"\n        if not is_dist_avail_and_initialized():\n            return\n        t = torch.tensor([self.count, self.total], dtype=torch.float64, device='cuda')\n        dist.barrier()\n        dist.all_reduce(t)\n        t = t.tolist()\n        self.count = int(t[0])\n        self.total = t[1]\n\n    @property\n    def median(self):\n        d = torch.tensor(list(self.deque))\n        return d.median().item()\n\n    @property\n    def avg(self):\n        d = torch.tensor(list(self.deque), dtype=torch.float32)\n        return d.mean().item()\n\n    @property\n    def global_avg(self):\n        return self.total / self.count\n\n    @property\n    def max(self):\n        return max(self.deque)\n\n    @property\n    def value(self):\n        return self.deque[-1]\n\n    def __str__(self):\n        return self.fmt.format(\n            median=self.median,\n            avg=self.avg,\n            global_avg=self.global_avg,\n            max=self.max,\n            value=self.value)\n\n\ndef reduce_dict(input_dict, average=True):\n    \"\"\"\n    Args:\n        input_dict (dict): all the values will be reduced\n        average (bool): whether to do average or sum\n    Reduce the values in the dictionary from all processes so that all processes\n    have the averaged results. Returns a dict with the same fields as\n    input_dict, after reduction.\n    \"\"\"\n    world_size = get_world_size()\n    if world_size < 2:\n        return input_dict\n    with torch.no_grad():\n        names = []\n        values = []\n        # sort the keys so that they are consistent across processes\n        for k in sorted(input_dict.keys()):\n            names.append(k)\n            values.append(input_dict[k])\n        values = torch.stack(values, dim=0)\n        dist.all_reduce(values)\n        if average:\n            values /= world_size\n        reduced_dict = {k: v for k, v in zip(names, values)}\n    return reduced_dict\n\n\nclass MetricLogger(object):\n    def __init__(self, delimiter=\"\\t\"):\n        self.meters = defaultdict(SmoothedValue)\n        self.delimiter = delimiter\n\n    def update(self, **kwargs):\n        for k, v in kwargs.items():\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.meters[k].update(v)\n\n    def __getattr__(self, attr):\n        if attr in self.meters:\n            return self.meters[attr]\n        if attr in self.__dict__:\n            return self.__dict__[attr]\n        raise AttributeError(\"'{}' object has no attribute '{}'\".format(\n            type(self).__name__, attr))\n\n    def __str__(self):\n        loss_str = []\n        for name, meter in self.meters.items():\n            loss_str.append(\n                \"{}: {}\".format(name, str(meter))\n            )\n        return self.delimiter.join(loss_str)\n\n    def synchronize_between_processes(self):\n        for meter in self.meters.values():\n            meter.synchronize_between_processes()\n\n    def add_meter(self, name, meter):\n        self.meters[name] = meter\n\n    def log_every(self, iterable, print_freq, header=None):\n        i = 0\n        if not header:\n            header = ''\n        start_time = time.time()\n        end = time.time()\n        iter_time = SmoothedValue(fmt='{avg:.6f}')\n        data_time = SmoothedValue(fmt='{avg:.6f}')\n        space_fmt = ':' + str(len(str(len(iterable)))) + 'd'\n        if torch.cuda.is_available():\n            log_msg = self.delimiter.join([\n                header,\n                '[{0' + space_fmt + '}/{1}]',\n                'eta: {eta}',\n                '{meters}',\n                'time: {time}',\n                'data: {data}',\n                'max mem: {memory:.0f}'\n            ])\n        else:\n            log_msg = self.delimiter.join([\n                header,\n                '[{0' + space_fmt + '}/{1}]',\n                'eta: {eta}',\n                '{meters}',\n                'time: {time}',\n                'data: {data}'\n            ])\n        MB = 1024.0 * 1024.0\n        for obj in iterable:\n            data_time.update(time.time() - end)\n            yield obj\n            iter_time.update(time.time() - end)\n            if i % print_freq == 0 or i == len(iterable) - 1:\n                eta_seconds = iter_time.global_avg * (len(iterable) - i)\n                eta_string = str(datetime.timedelta(seconds=int(eta_seconds)))\n                if torch.cuda.is_available():\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time),\n                        memory=torch.cuda.max_memory_allocated() / MB))\n                else:\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time)))\n            i += 1\n            end = time.time()\n        total_time = time.time() - start_time\n        total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n        print('{} Total time: {} ({:.6f} s / it)'.format(\n            header, total_time_str, total_time / len(iterable)))\n\n\ndef get_sha():\n    cwd = os.path.dirname(os.path.abspath(__file__))\n\n    def _run(command):\n        return subprocess.check_output(command, cwd=cwd).decode('ascii').strip()\n    sha = 'N/A'\n    diff = \"clean\"\n    branch = 'N/A'\n    try:\n        sha = _run(['git', 'rev-parse', 'HEAD'])\n        subprocess.check_output(['git', 'diff'], cwd=cwd)\n        diff = _run(['git', 'diff-index', 'HEAD'])\n        diff = \"has uncommited changes\" if diff else \"clean\"\n        branch = _run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])\n    except Exception:\n        pass\n    message = f\"sha: {sha}, status: {diff}, branch: {branch}\"\n    return message\n\n\ndef is_dist_avail_and_initialized():\n    if not dist.is_available():\n        return False\n    if not dist.is_initialized():\n        return False\n    return True\n\n\ndef get_world_size():\n    if not is_dist_avail_and_initialized():\n        return 1\n    return dist.get_world_size()\n\n\ndef get_rank():\n    if not is_dist_avail_and_initialized():\n        return 0\n    return dist.get_rank()\n\n\ndef is_main_process():\n    return get_rank() == 0\n\n\ndef save_on_master(*args, **kwargs):\n    if is_main_process():\n        torch.save(*args, **kwargs)\n\n\ndef setup_for_distributed(is_master):\n    \"\"\"\n    This function disables printing when not in master process\n    \"\"\"\n    import builtins as __builtin__\n    builtin_print = __builtin__.print\n\n    def print(*args, **kwargs):\n        force = kwargs.pop('force', False)\n        if is_master or force:\n            builtin_print(*args, **kwargs)\n\n    __builtin__.print = print\n\n\ndef init_distributed_mode(args):\n    # launched with torch.distributed.launch\n    if 'RANK' in os.environ and 'WORLD_SIZE' in os.environ:\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ['WORLD_SIZE'])\n        args.gpu = int(os.environ['LOCAL_RANK'])\n    # launched with submitit on a slurm cluster\n    elif 'SLURM_PROCID' in os.environ:\n        args.rank = int(os.environ['SLURM_PROCID'])\n        args.gpu = args.rank % torch.cuda.device_count()\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(os.environ[\"SLURM_TASKS_PER_NODE\"][0])\n        args.is_slurm_job = True\n\n    # launched naively with `python main_dino.py`\n    # we manually add MASTER_ADDR and MASTER_PORT to env variables\n    elif torch.cuda.is_available():\n        print('Will run the code on one GPU.')\n        args.rank, args.gpu, args.world_size = 0, 0, 1\n        os.environ['MASTER_ADDR'] = '127.0.0.1'\n        os.environ['MASTER_PORT'] = '29500'\n    else:\n        print('Does not support training without GPU.')\n        sys.exit(1)\n\n    dist.init_process_group(\n        backend=\"nccl\",\n        init_method=args.dist_url,\n        world_size=args.world_size,\n        rank=args.rank,\n    )\n\n    torch.cuda.set_device(args.gpu)\n    #print('| distributed init (rank {}): {}'.format(\n    #    args.rank, args.dist_url), flush=True)\n    #dist.barrier()\n    #setup_for_distributed(args.rank == 0)\n\n\ndef accuracy(output, target, topk=(1,)):\n    \"\"\"Computes the accuracy over the k top predictions for the specified values of k\"\"\"\n    maxk = max(topk)\n    batch_size = target.size(0)\n    _, pred = output.topk(maxk, 1, True, True)\n    pred = pred.t()\n    correct = pred.eq(target.reshape(1, -1).expand_as(pred))\n    return [correct[:k].reshape(-1).float().sum(0) * 100. / batch_size for k in topk]\n\n\ndef _no_grad_trunc_normal_(tensor, mean, std, a, b):\n    # Cut & paste from PyTorch official master until it's in a few official releases - RW\n    # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf\n    def norm_cdf(x):\n        # Computes standard normal cumulative distribution function\n        return (1. + math.erf(x / math.sqrt(2.))) / 2.\n\n    if (mean < a - 2 * std) or (mean > b + 2 * std):\n        warnings.warn(\"mean is more than 2 std from [a, b] in nn.init.trunc_normal_. \"\n                      \"The distribution of values may be incorrect.\",\n                      stacklevel=2)\n\n    with torch.no_grad():\n        # Values are generated by using a truncated uniform distribution and\n        # then using the inverse CDF for the normal distribution.\n        # Get upper and lower cdf values\n        l = norm_cdf((a - mean) / std)\n        u = norm_cdf((b - mean) / std)\n\n        # Uniformly fill tensor with values from [l, u], then translate to\n        # [2l-1, 2u-1].\n        tensor.uniform_(2 * l - 1, 2 * u - 1)\n\n        # Use inverse cdf transform for normal distribution to get truncated\n        # standard normal\n        tensor.erfinv_()\n\n        # Transform to proper mean, std\n        tensor.mul_(std * math.sqrt(2.))\n        tensor.add_(mean)\n\n        # Clamp to ensure it's in the proper range\n        tensor.clamp_(min=a, max=b)\n        return tensor\n\n\ndef trunc_normal_(tensor, mean=0., std=1., a=-2., b=2.):\n    # type: (Tensor, float, float, float, float) -> Tensor\n    return _no_grad_trunc_normal_(tensor, mean, std, a, b)\n\n\nclass LARS(torch.optim.Optimizer):\n    \"\"\"\n    Almost copy-paste from https://github.com/facebookresearch/barlowtwins/blob/main/main.py\n    \"\"\"\n    def __init__(self, params, lr=0, weight_decay=0, momentum=0.9, eta=0.001,\n                 weight_decay_filter=None, lars_adaptation_filter=None):\n        defaults = dict(lr=lr, weight_decay=weight_decay, momentum=momentum,\n                        eta=eta, weight_decay_filter=weight_decay_filter,\n                        lars_adaptation_filter=lars_adaptation_filter)\n        super().__init__(params, defaults)\n\n    @torch.no_grad()\n    def step(self):\n        for g in self.param_groups:\n            for p in g['params']:\n                dp = p.grad\n\n                if dp is None:\n                    continue\n\n                if p.ndim != 1:\n                    dp = dp.add(p, alpha=g['weight_decay'])\n\n                if p.ndim != 1:\n                    param_norm = torch.norm(p)\n                    update_norm = torch.norm(dp)\n                    one = torch.ones_like(param_norm)\n                    q = torch.where(param_norm > 0.,\n                                    torch.where(update_norm > 0,\n                                                (g['eta'] * param_norm / update_norm), one), one)\n                    dp = dp.mul(q)\n\n                param_state = self.state[p]\n                if 'mu' not in param_state:\n                    param_state['mu'] = torch.zeros_like(p)\n                mu = param_state['mu']\n                mu.mul_(g['momentum']).add_(dp)\n\n                p.add_(mu, alpha=-g['lr'])\n\n\nclass MultiCropWrapper(nn.Module):\n    \"\"\"\n    Perform forward pass separately on each resolution input.\n    The inputs corresponding to a single resolution are clubbed and single\n    forward is run on the same resolution inputs. Hence we do several\n    forward passes = number of different resolutions used. We then\n    concatenate all the output features and run the head forward on these\n    concatenated features.\n    \"\"\"\n    def __init__(self, backbone, head):\n        super(MultiCropWrapper, self).__init__()\n        # disable layers dedicated to ImageNet labels classification\n        backbone.fc, backbone.head = nn.Identity(), nn.Identity()\n        self.backbone = backbone\n        self.head = head\n\n    def forward(self, x):\n        # convert to list\n        if not isinstance(x, list):\n            x = [x]\n        idx_crops = torch.cumsum(torch.unique_consecutive(\n            torch.tensor([inp.shape[-1] for inp in x]),\n            return_counts=True,\n        )[1], 0)\n        start_idx, output = 0, torch.empty(0).to(x[0].device)\n        for end_idx in idx_crops:\n            _out = self.backbone(torch.cat(x[start_idx: end_idx]))\n            # The output is a tuple with XCiT model. See:\n            # https://github.com/facebookresearch/xcit/blob/master/xcit.py#L404-L405\n            if isinstance(_out, tuple):\n                _out = _out[0]\n            # accumulate outputs\n            output = torch.cat((output, _out))\n            start_idx = end_idx\n        # Run the head forward on the concatenated features.\n        return self.head(output)\n\n\ndef get_params_groups(model):\n    regularized = []\n    not_regularized = []\n    for name, param in model.named_parameters():\n        if not param.requires_grad:\n            continue\n        # we do not regularize biases nor Norm parameters\n        if name.endswith(\".bias\") or len(param.shape) == 1:\n            not_regularized.append(param)\n        else:\n            regularized.append(param)\n    return [{'params': regularized}, {'params': not_regularized, 'weight_decay': 0.}]\n\n\ndef has_batchnorms(model):\n    bn_types = (nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d, nn.SyncBatchNorm)\n    for name, module in model.named_modules():\n        if isinstance(module, bn_types):\n            return True\n    return False\n\n\nclass PCA():\n    \"\"\"\n    Class to  compute and apply PCA.\n    \"\"\"\n    def __init__(self, dim=256, whit=0.5):\n        self.dim = dim\n        self.whit = whit\n        self.mean = None\n\n    def train_pca(self, cov):\n        \"\"\"\n        Takes a covariance matrix (np.ndarray) as input.\n        \"\"\"\n        d, v = np.linalg.eigh(cov)\n        eps = d.max() * 1e-5\n        n_0 = (d < eps).sum()\n        if n_0 > 0:\n            d[d < eps] = eps\n\n        # total energy\n        totenergy = d.sum()\n\n        # sort eigenvectors with eigenvalues order\n        idx = np.argsort(d)[::-1][:self.dim]\n        d = d[idx]\n        v = v[:, idx]\n\n        print(\"keeping %.2f %% of the energy\" % (d.sum() / totenergy * 100.0))\n\n        # for the whitening\n        d = np.diag(1. / d**self.whit)\n\n        # principal components\n        self.dvt = np.dot(d, v.T)\n\n    def apply(self, x):\n        # input is from numpy\n        if isinstance(x, np.ndarray):\n            if self.mean is not None:\n                x -= self.mean\n            return np.dot(self.dvt, x.T).T\n\n        # input is from torch and is on GPU\n        if x.is_cuda:\n            if self.mean is not None:\n                x -= torch.cuda.FloatTensor(self.mean)\n            return torch.mm(torch.cuda.FloatTensor(self.dvt), x.transpose(0, 1)).transpose(0, 1)\n\n        # input if from torch, on CPU\n        if self.mean is not None:\n            x -= torch.FloatTensor(self.mean)\n        return torch.mm(torch.FloatTensor(self.dvt), x.transpose(0, 1)).transpose(0, 1)\n\n\ndef compute_ap(ranks, nres):\n    \"\"\"\n    Computes average precision for given ranked indexes.\n    Arguments\n    ---------\n    ranks : zerro-based ranks of positive images\n    nres  : number of positive images\n    Returns\n    -------\n    ap    : average precision\n    \"\"\"\n\n    # number of images ranked by the system\n    nimgranks = len(ranks)\n\n    # accumulate trapezoids in PR-plot\n    ap = 0\n\n    recall_step = 1. / nres\n\n    for j in np.arange(nimgranks):\n        rank = ranks[j]\n\n        if rank == 0:\n            precision_0 = 1.\n        else:\n            precision_0 = float(j) / rank\n\n        precision_1 = float(j + 1) / (rank + 1)\n\n        ap += (precision_0 + precision_1) * recall_step / 2.\n\n    return ap\n\n\ndef compute_map(ranks, gnd, kappas=[]):\n    \"\"\"\n    Computes the mAP for a given set of returned results.\n         Usage:\n           map = compute_map (ranks, gnd)\n                 computes mean average precsion (map) only\n           map, aps, pr, prs = compute_map (ranks, gnd, kappas)\n                 computes mean average precision (map), average precision (aps) for each query\n                 computes mean precision at kappas (pr), precision at kappas (prs) for each query\n         Notes:\n         1) ranks starts from 0, ranks.shape = db_size X #queries\n         2) The junk results (e.g., the query itself) should be declared in the gnd stuct array\n         3) If there are no positive images for some query, that query is excluded from the evaluation\n    \"\"\"\n\n    map = 0.\n    nq = len(gnd) # number of queries\n    aps = np.zeros(nq)\n    pr = np.zeros(len(kappas))\n    prs = np.zeros((nq, len(kappas)))\n    nempty = 0\n\n    for i in np.arange(nq):\n        qgnd = np.array(gnd[i]['ok'])\n\n        # no positive images, skip from the average\n        if qgnd.shape[0] == 0:\n            aps[i] = float('nan')\n            prs[i, :] = float('nan')\n            nempty += 1\n            continue\n\n        try:\n            qgndj = np.array(gnd[i]['junk'])\n        except:\n            qgndj = np.empty(0)\n\n        # sorted positions of positive and junk images (0 based)\n        pos  = np.arange(ranks.shape[0])[np.in1d(ranks[:,i], qgnd)]\n        junk = np.arange(ranks.shape[0])[np.in1d(ranks[:,i], qgndj)]\n\n        k = 0;\n        ij = 0;\n        if len(junk):\n            # decrease positions of positives based on the number of\n            # junk images appearing before them\n            ip = 0\n            while (ip < len(pos)):\n                while (ij < len(junk) and pos[ip] > junk[ij]):\n                    k += 1\n                    ij += 1\n                pos[ip] = pos[ip] - k\n                ip += 1\n\n        # compute ap\n        ap = compute_ap(pos, len(qgnd))\n        map = map + ap\n        aps[i] = ap\n\n        # compute precision @ k\n        pos += 1 # get it to 1-based\n        for j in np.arange(len(kappas)):\n            kq = min(max(pos), kappas[j]); \n            prs[i, j] = (pos <= kq).sum() / kq\n        pr = pr + prs[i, :]\n\n    map = map / (nq - nempty)\n    pr = pr / (nq - nempty)\n\n    return map, aps, pr, prs\n\n\ndef multi_scale(samples, model):\n    v = None\n    for s in [1, 1/2**(1/2), 1/2]:  # we use 3 different scales\n        if s == 1:\n            inp = samples.clone()\n        else:\n            inp = nn.functional.interpolate(samples, scale_factor=s, mode='bilinear', align_corners=False)\n        feats = model(inp).clone()\n        if v is None:\n            v = feats\n        else:\n            v += feats\n    v /= 3\n    v /= v.norm()\n    return v\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/dino/vision_transformer.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#     http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nMostly copy-paste from timm library.\nhttps://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py\n\"\"\"\nimport math\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\n\nfrom models.dino.utils import trunc_normal_\n\n\ndef drop_path(x, drop_prob: float = 0., training: bool = False):\n    if drop_prob == 0. or not training:\n        return x\n    keep_prob = 1 - drop_prob\n    shape = (x.shape[0],) + (1,) * (x.ndim - 1)  # work with diff dim tensors, not just 2D ConvNets\n    random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device)\n    random_tensor.floor_()  # binarize\n    output = x.div(keep_prob) * random_tensor\n    return output\n\n\nclass DropPath(nn.Module):\n    \"\"\"Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).\n    \"\"\"\n    def __init__(self, drop_prob=None):\n        super(DropPath, self).__init__()\n        self.drop_prob = drop_prob\n\n    def forward(self, x):\n        return drop_path(x, self.drop_prob, self.training)\n\n\nclass Mlp(nn.Module):\n    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        x = self.drop(x)\n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\nclass Attention(nn.Module):\n    def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        self.scale = qk_scale or head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n    def forward(self, x):\n        B, N, C = x.shape\n        qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[2]\n\n        attn = (q @ k.transpose(-2, -1)) * self.scale\n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, C)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x, attn\n\n\nclass Block(nn.Module):\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,\n                 drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm):\n        super().__init__()\n        self.norm1 = norm_layer(dim)\n        self.attn = Attention(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n    def forward(self, x, return_attention=False):\n        y, attn = self.attn(self.norm1(x))\n        if return_attention:\n            return attn\n        x = x + self.drop_path(y)\n        x = x + self.drop_path(self.mlp(self.norm2(x)))\n        return x\n\n\nclass PatchEmbed(nn.Module):\n    \"\"\" Image to Patch Embedding\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):\n        super().__init__()\n        num_patches = (img_size // patch_size) * (img_size // patch_size)\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.num_patches = num_patches\n\n        self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n        x = self.proj(x).flatten(2).transpose(1, 2)\n        return x\n\n\nclass VisionTransformer(nn.Module):\n    \"\"\" Vision Transformer \"\"\"\n    def __init__(self, img_size=[224], patch_size=16, in_chans=3, num_classes=0, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., norm_layer=nn.LayerNorm, **kwargs):\n        super().__init__()\n        self.num_features = self.embed_dim = embed_dim\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size[0], patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer)\n            for i in range(depth)])\n        self.norm = norm_layer(embed_dim)\n\n        # Classifier head\n        self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n        trunc_normal_(self.pos_embed, std=.02)\n        trunc_normal_(self.cls_token, std=.02)\n        self.apply(self._init_weights)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    def interpolate_pos_encoding(self, x, w, h):\n        npatch = x.shape[1] - 1\n        N = self.pos_embed.shape[1] - 1\n        if npatch == N and w == h:\n            return self.pos_embed\n        class_pos_embed = self.pos_embed[:, 0]\n        patch_pos_embed = self.pos_embed[:, 1:]\n        dim = x.shape[-1]\n        w0 = w // self.patch_embed.patch_size\n        h0 = h // self.patch_embed.patch_size\n        # we add a small number to avoid floating point error in the interpolation\n        # see discussion at https://github.com/facebookresearch/dino/issues/8\n        w0, h0 = w0 + 0.1, h0 + 0.1\n        patch_pos_embed = nn.functional.interpolate(\n            patch_pos_embed.reshape(1, int(math.sqrt(N)), int(math.sqrt(N)), dim).permute(0, 3, 1, 2),\n            scale_factor=(w0 / math.sqrt(N), h0 / math.sqrt(N)),\n            mode='bicubic',\n        )\n        assert int(w0) == patch_pos_embed.shape[-2] and int(h0) == patch_pos_embed.shape[-1]\n        patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)\n        return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1)\n\n    def prepare_tokens(self, x):\n        B, nc, w, h = x.shape\n        x = self.patch_embed(x)  # patch linear embedding\n\n        # add the [CLS] token to the embed patch tokens\n        cls_tokens = self.cls_token.expand(B, -1, -1)\n        x = torch.cat((cls_tokens, x), dim=1)\n\n        # add positional encoding to each token\n        x = x + self.interpolate_pos_encoding(x, w, h)\n\n        return self.pos_drop(x)\n\n    def forward(self, x):\n        x = self.prepare_tokens(x)\n        for blk in self.blocks:\n            x = blk(x)\n        x = self.norm(x)\n        return x[:, 0]\n\n    def get_last_selfattention(self, x):\n        x = self.prepare_tokens(x)\n        for i, blk in enumerate(self.blocks):\n            if i < len(self.blocks) - 1:\n                x = blk(x)\n            else:\n                # return attention of the last block\n                return blk(x, return_attention=True)\n\n    def get_intermediate_layers(self, x, n=1):\n        x = self.prepare_tokens(x)\n        # we return the output tokens from the `n` last blocks\n        output = []\n        for i, blk in enumerate(self.blocks):\n            x = blk(x)\n            if len(self.blocks) - i <= n:\n                output.append(self.norm(x))\n        return output\n\n\ndef vit_tiny(patch_size=16, **kwargs):\n    model = VisionTransformer(\n        patch_size=patch_size, embed_dim=192, depth=12, num_heads=3, mlp_ratio=4,\n        qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef vit_small(patch_size=16, **kwargs):\n    model = VisionTransformer(\n        patch_size=patch_size, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4,\n        qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef vit_base(patch_size=16, **kwargs):\n    model = VisionTransformer(\n        patch_size=patch_size, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,\n        qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\nclass DINOHead(nn.Module):\n    def __init__(self, in_dim, out_dim, use_bn=False, norm_last_layer=True, nlayers=3, hidden_dim=2048, bottleneck_dim=256):\n        super().__init__()\n        nlayers = max(nlayers, 1)\n        if nlayers == 1:\n            self.mlp = nn.Linear(in_dim, bottleneck_dim)\n        else:\n            layers = [nn.Linear(in_dim, hidden_dim)]\n            if use_bn:\n                layers.append(nn.BatchNorm1d(hidden_dim))\n            layers.append(nn.GELU())\n            for _ in range(nlayers - 2):\n                layers.append(nn.Linear(hidden_dim, hidden_dim))\n                if use_bn:\n                    layers.append(nn.BatchNorm1d(hidden_dim))\n                layers.append(nn.GELU())\n            layers.append(nn.Linear(hidden_dim, bottleneck_dim))\n            self.mlp = nn.Sequential(*layers)\n        self.apply(self._init_weights)\n        self.last_layer = nn.utils.weight_norm(nn.Linear(bottleneck_dim, out_dim, bias=False))\n        self.last_layer.weight_g.data.fill_(1)\n        if norm_last_layer:\n            self.last_layer.weight_g.requires_grad = False\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n    def forward(self, x):\n        x = self.mlp(x)\n        x = nn.functional.normalize(x, dim=-1, p=2)\n        x = self.last_layer(x)\n        return x\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/engine_finetune.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy\n\nimport util.misc as misc\nimport util.lr_sched as lr_sched\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n\n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n\n        with torch.cuda.amp.autocast():\n            outputs = model(samples)\n            loss = criterion(outputs, targets)\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, clip_grad=max_norm,\n                    parameters=model.parameters(), create_graph=False,\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', max_lr, epoch_1000x)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device):\n    criterion = torch.nn.CrossEntropyLoss()\n\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n        images = batch[0]\n        target = batch[-1]\n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, target)\n\n        acc1, acc5 = accuracy(output, target, topk=(1, 5))\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/engine_finetune_BE.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy\n\n#import util.misc as misc\n#import util.lr_sched as lr_sched\nfrom .util import misc\nfrom .util import lr_sched\n\nfrom sklearn.metrics import average_precision_score\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n\n        b_zeros = torch.zeros((samples.shape[0],1,samples.shape[2],samples.shape[3]),dtype=torch.float32)\n        samples = torch.cat((samples[:,:10,:,:],b_zeros,samples[:,10:,:,:]),dim=1)\n            \n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n        \n        #print(samples.shape,samples.dtype,targets.shape,targets.dtype)\n        with torch.cuda.amp.autocast():\n            outputs = model(samples)\n            loss = criterion(outputs, targets.long())\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, clip_grad=max_norm,\n                    parameters=model.parameters(), create_graph=False,\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', max_lr, epoch_1000x)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device, criterion):\n    #criterion = torch.nn.CrossEntropyLoss()\n\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n        images = batch[0]\n        target = batch[-1]\n        \n        b_zeros = torch.zeros((images.shape[0],1,images.shape[2],images.shape[3]),dtype=torch.float32)\n        images = torch.cat((images[:,:10,:,:],b_zeros,images[:,10:,:,:]),dim=1)  \n        \n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        #print(images.shape,images.dtype,target.shape,target.dtype)\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, target)\n\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = average_precision_score(target.cpu(), score, average='micro') * 100.0\n        acc5 = acc1\n        #acc1, acc5 = accuracy(output, target, topk=(1, 5))\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/engine_finetune_EU.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy\n\n#import util.misc as misc\n#import util.lr_sched as lr_sched\nfrom .util import misc\nfrom .util import lr_sched\n\nfrom sklearn.metrics import accuracy_score\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n            \n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n        \n        #print(samples.shape,samples.dtype,targets.shape,targets.dtype)\n        with torch.cuda.amp.autocast():\n            outputs = model(samples)\n            loss = criterion(outputs, targets.long())\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, clip_grad=max_norm,\n                    parameters=model.parameters(), create_graph=False,\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', max_lr, epoch_1000x)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device, criterion):\n    #criterion = torch.nn.CrossEntropyLoss()\n\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n        images = batch[0]\n        target = batch[-1] \n        \n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        #print(images.shape,images.dtype,target.shape,target.dtype)\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, target)\n\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = accuracy_score(target.cpu(), torch.argmax(score,axis=1)) * 100.0\n        acc5 = acc1\n        #acc1, acc5 = accuracy(output, target, topk=(1, 5))\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/engine_finetune_SS.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy\n\n#import util.misc as misc\n#import util.lr_sched as lr_sched\nfrom .util import misc\nfrom .util import lr_sched\n\nfrom sklearn.metrics import accuracy_score\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n            \n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n        \n        #print(samples.shape,samples.dtype,targets.shape,targets.dtype)\n        with torch.cuda.amp.autocast():\n            outputs = model(samples)\n            loss = criterion(outputs, torch.argmax(targets,axis=1).long())\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, clip_grad=max_norm,\n                    parameters=model.parameters(), create_graph=False,\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', max_lr, epoch_1000x)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device, criterion):\n    #criterion = torch.nn.CrossEntropyLoss()\n\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n        images = batch[0]\n        target = batch[-1] \n        \n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        #print(images.shape,images.dtype,target.shape,target.dtype)\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, torch.argmax(target,axis=1).long())\n\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = accuracy_score(torch.argmax(target,axis=1).cpu(), torch.argmax(score,axis=1)) * 100.0\n        acc5 = acc1\n        #acc1, acc5 = accuracy(output, target, topk=(1, 5))\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/engine_pretrain.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\nimport math\nimport sys\nfrom typing import Iterable\n\nimport torch\n\n#import util.misc as misc\n#import util.lr_sched as lr_sched\nfrom .util import misc\nfrom .util import lr_sched\n\n\ndef train_one_epoch(model: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler,\n                    log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, samples in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n\n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n\n        with torch.cuda.amp.autocast():\n            loss, _, _ = model(samples, mask_ratio=args.mask_ratio)\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, parameters=model.parameters(),\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n\n        lr = optimizer.param_groups[0][\"lr\"]\n        metric_logger.update(lr=lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('train_loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', lr, epoch_1000x)\n\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/main_finetune.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\n\nimport timm\n\nassert timm.__version__ == \"0.3.2\" # version check\nfrom timm.models.layers import trunc_normal_\nfrom timm.data.mixup import Mixup\nfrom timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy\n\nimport util.lr_decay as lrd\nimport util.misc as misc\nfrom util.datasets import build_dataset\nfrom util.pos_embed import interpolate_pos_embed\nfrom util.misc import NativeScalerWithGradNormCount as NativeScaler\n\nimport models_vit\n\nfrom engine_finetune import train_one_epoch, evaluate\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE fine-tuning for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=50, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    # Optimizer parameters\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=1e-3, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n    parser.add_argument('--layer_decay', type=float, default=0.75,\n                        help='layer-wise lr decay from ELECTRA/BEiT')\n\n    parser.add_argument('--min_lr', type=float, default=1e-6, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=None, metavar='PCT',\n                        help='Color jitter factor (enabled only when not using Auto/RandAug)')\n    parser.add_argument('--aa', type=str, default='rand-m9-mstd0.5-inc1', metavar='NAME',\n                        help='Use AutoAugment policy. \"v0\" or \"original\". \" + \"(default: rand-m9-mstd0.5-inc1)'),\n    parser.add_argument('--smoothing', type=float, default=0.1,\n                        help='Label smoothing (default: 0.1)')\n\n    # * Random Erase params\n    parser.add_argument('--reprob', type=float, default=0.25, metavar='PCT',\n                        help='Random erase prob (default: 0.25)')\n    parser.add_argument('--remode', type=str, default='pixel',\n                        help='Random erase mode (default: \"pixel\")')\n    parser.add_argument('--recount', type=int, default=1,\n                        help='Random erase count (default: 1)')\n    parser.add_argument('--resplit', action='store_true', default=False,\n                        help='Do not random erase first (clean) augmentation split')\n\n    # * Mixup params\n    parser.add_argument('--mixup', type=float, default=0,\n                        help='mixup alpha, mixup enabled if > 0.')\n    parser.add_argument('--cutmix', type=float, default=0,\n                        help='cutmix alpha, cutmix enabled if > 0.')\n    parser.add_argument('--cutmix_minmax', type=float, nargs='+', default=None,\n                        help='cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None)')\n    parser.add_argument('--mixup_prob', type=float, default=1.0,\n                        help='Probability of performing mixup or cutmix when either/both is enabled')\n    parser.add_argument('--mixup_switch_prob', type=float, default=0.5,\n                        help='Probability of switching to cutmix when both mixup and cutmix enabled')\n    parser.add_argument('--mixup_mode', type=str, default='batch',\n                        help='How to apply mixup/cutmix params. Per \"batch\", \"pair\", or \"elem\"')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--global_pool', action='store_true')\n    parser.set_defaults(global_pool=True)\n    parser.add_argument('--cls_token', action='store_false', dest='global_pool',\n                        help='Use class token instead of global pool for classification')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--nb_classes', default=1000, type=int,\n                        help='number of the classification types')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation (recommended during training for faster monitor')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    return parser\n\n\ndef main(args):\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n\n    dataset_train = build_dataset(is_train=True, args=args)\n    dataset_val = build_dataset(is_train=False, args=args)\n\n    if True:  # args.distributed:\n        num_tasks = misc.get_world_size()\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=True)  # shuffle=True to reduce monitor bias\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None and not args.eval:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    data_loader_val = torch.utils.data.DataLoader(\n        dataset_val, sampler=sampler_val,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=False\n    )\n\n    mixup_fn = None\n    mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None\n    if mixup_active:\n        print(\"Mixup is activated!\")\n        mixup_fn = Mixup(\n            mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax,\n            prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode,\n            label_smoothing=args.smoothing, num_classes=args.nb_classes)\n    \n    model = models_vit.__dict__[args.model](\n        num_classes=args.nb_classes,\n        drop_path_rate=args.drop_path,\n        global_pool=args.global_pool,\n    )\n\n    if args.finetune and not args.eval:\n        checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load pre-trained checkpoint from: %s\" % args.finetune)\n        checkpoint_model = checkpoint['model']\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        # interpolate position embedding\n        interpolate_pos_embed(model, checkpoint_model)\n\n        # load pre-trained model\n        msg = model.load_state_dict(checkpoint_model, strict=False)\n        print(msg)\n\n        if args.global_pool:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias', 'fc_norm.weight', 'fc_norm.bias'}\n        else:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias'}\n\n        # manually initialize fc layer\n        trunc_normal_(model.head.weight, std=2e-5)\n\n    model.to(device)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params (M): %.2f' % (n_parameters / 1.e6))\n\n    eff_batch_size = args.batch_size * args.accum_iter * misc.get_world_size()\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        model_without_ddp = model.module\n\n    # build optimizer with layer-wise lr decay (lrd)\n    param_groups = lrd.param_groups_lrd(model_without_ddp, args.weight_decay,\n        no_weight_decay_list=model_without_ddp.no_weight_decay(),\n        layer_decay=args.layer_decay\n    )\n    optimizer = torch.optim.AdamW(param_groups, lr=args.lr)\n    loss_scaler = NativeScaler()\n\n    if mixup_fn is not None:\n        # smoothing is handled with mixup label transform\n        criterion = SoftTargetCrossEntropy()\n    elif args.smoothing > 0.:\n        criterion = LabelSmoothingCrossEntropy(smoothing=args.smoothing)\n    else:\n        criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            args.clip_grad, mixup_fn,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir:\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        max_accuracy = max(max_accuracy, test_stats[\"acc1\"])\n        print(f'Max accuracy: {max_accuracy:.2f}%')\n\n        if log_writer is not None:\n            log_writer.add_scalar('perf/test_acc1', test_stats['acc1'], epoch)\n            log_writer.add_scalar('perf/test_acc5', test_stats['acc5'], epoch)\n            log_writer.add_scalar('perf/test_loss', test_stats['loss'], epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        **{f'test_{k}': v for k, v in test_stats.items()},\n                        'epoch': epoch,\n                        'n_parameters': n_parameters}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/main_linprobe.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# MoCo v3: https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\n\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\n\nimport timm\n\nassert timm.__version__ == \"0.3.2\" # version check\nfrom timm.models.layers import trunc_normal_\n\nimport util.misc as misc\nfrom util.pos_embed import interpolate_pos_embed\nfrom util.misc import NativeScalerWithGradNormCount as NativeScaler\nfrom util.lars import LARS\nfrom util.crop import RandomResizedCrop\n\nimport models_vit\n\nfrom engine_finetune import train_one_epoch, evaluate\n\n\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb_s2_uint8 import LMDBDataset,random_subset\nfrom cvtorchvision import cvtransforms\nfrom sklearn.metrics import average_precision_score\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE linear probing for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=512, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=90, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    # Optimizer parameters\n    parser.add_argument('--weight_decay', type=float, default=0,\n                        help='weight decay (default: 0 for linear probe following MoCo v1)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=0.1, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n\n    parser.add_argument('--min_lr', type=float, default=0., metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=10, metavar='N',\n                        help='epochs to warmup LR')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--global_pool', action='store_true')\n    parser.set_defaults(global_pool=False)\n    parser.add_argument('--cls_token', action='store_false', dest='global_pool',\n                        help='Use class token instead of global pool for classification')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--nb_classes', default=1000, type=int,\n                        help='number of the classification types')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation (recommended during training for faster monitor')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    return parser\n\n\ndef main(args):\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n\n    # linear probe: weak augmentation\n    transform_train = transforms.Compose([\n            RandomResizedCrop(224, interpolation=3),\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    transform_val = transforms.Compose([\n            transforms.Resize(256, interpolation=3),\n            transforms.CenterCrop(224),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    dataset_train = datasets.ImageFolder(os.path.join(args.data_path, 'train'), transform=transform_train)\n    dataset_val = datasets.ImageFolder(os.path.join(args.data_path, 'val'), transform=transform_val)\n    print(dataset_train)\n    print(dataset_val)\n\n    if True:  # args.distributed:\n        num_tasks = misc.get_world_size()\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=True)  # shuffle=True to reduce monitor bias\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None and not args.eval:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    data_loader_val = torch.utils.data.DataLoader(\n        dataset_val, sampler=sampler_val,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=False\n    )\n\n    model = models_vit.__dict__[args.model](\n        num_classes=args.nb_classes,\n        global_pool=args.global_pool,\n    )\n\n    if args.finetune and not args.eval:\n        checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load pre-trained checkpoint from: %s\" % args.finetune)\n        checkpoint_model = checkpoint['model']\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        # interpolate position embedding\n        interpolate_pos_embed(model, checkpoint_model)\n\n        # load pre-trained model\n        msg = model.load_state_dict(checkpoint_model, strict=False)\n        print(msg)\n\n        if args.global_pool:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias', 'fc_norm.weight', 'fc_norm.bias'}\n        else:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias'}\n\n        # manually initialize fc layer: following MoCo v3\n        trunc_normal_(model.head.weight, std=0.01)\n\n    # for linear prob only\n    # hack: revise model's head with BN\n    model.head = torch.nn.Sequential(torch.nn.BatchNorm1d(model.head.in_features, affine=False, eps=1e-6), model.head)\n    # freeze all but the head\n    for _, p in model.named_parameters():\n        p.requires_grad = False\n    for _, p in model.head.named_parameters():\n        p.requires_grad = True\n\n    model.to(device)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params (M): %.2f' % (n_parameters / 1.e6))\n\n    eff_batch_size = args.batch_size * args.accum_iter * misc.get_world_size()\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        model_without_ddp = model.module\n\n    optimizer = LARS(model_without_ddp.head.parameters(), lr=args.lr, weight_decay=args.weight_decay)\n    print(optimizer)\n    loss_scaler = NativeScaler()\n\n    criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            max_norm=None,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir:\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        max_accuracy = max(max_accuracy, test_stats[\"acc1\"])\n        print(f'Max accuracy: {max_accuracy:.2f}%')\n\n        if log_writer is not None:\n            log_writer.add_scalar('perf/test_acc1', test_stats['acc1'], epoch)\n            log_writer.add_scalar('perf/test_acc5', test_stats['acc5'], epoch)\n            log_writer.add_scalar('perf/test_loss', test_stats['loss'], epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        **{f'test_{k}': v for k, v in test_stats.items()},\n                        'epoch': epoch,\n                        'n_parameters': n_parameters}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/main_pretrain.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\n\nimport timm\n\nassert timm.__version__ == \"0.3.2\"  # version check\nimport timm.optim.optim_factory as optim_factory\n\nimport util.misc as misc\nfrom util.misc import NativeScalerWithGradNormCount as NativeScaler\n\nimport models_mae\n\nfrom engine_pretrain import train_one_epoch\n\nfrom ..datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\nfrom cvtorchvision import cvtransforms\n\n\nclass SeasonTransform:\n\n    def __init__(self, base_transform, season='fixed'):\n        self.base_transform = base_transform\n        self.season = season\n\n    def __call__(self, x):\n\n        if self.season=='augment':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = np.random.choice([0,1,2,3])\n            \n            x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n            x2 = np.transpose(x[season2,:,:,:],(1,2,0))            \n            image = self.base_transform(x1)\n            target = self.base_transform2(x2)\n            return image, target\n            \n        elif self.season=='fixed':\n            np.random.seed(42)\n            season1 = np.random.choice([0,1,2,3])\n\n        elif self.season=='random':\n            season1 = np.random.choice([0,1,2,3])\n\n        x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n        image = self.base_transform(x1)\n        \n        return q\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE pre-training', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=400, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='mae_vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--mask_ratio', default=0.75, type=float,\n                        help='Masking ratio (percentage of removed patches).')\n\n    parser.add_argument('--norm_pix_loss', action='store_true',\n                        help='Use (per-patch) normalized pixels as targets for computing loss')\n    parser.set_defaults(norm_pix_loss=False)\n\n    # Optimizer parameters\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=1e-3, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n    parser.add_argument('--min_lr', type=float, default=0., metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=40, metavar='N',\n                        help='epochs to warmup LR')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n    # new                    \n    parser.add_argument('--rank', default=-1, type=int,\n                        help='node rank for distributed training')                        \n    parser.add_argument('--dist-backend', default='nccl', type=str,\n                        help='distributed backend')\n                        \n    parser.add_argument('--normalize', action='store_true', default=False)\n    parser.add_argument('--mode', nargs='*', default=['s2c'])\n    parser.add_argument('--dtype', type=str, default='uint8')\n    parser.add_argument('--season', type=str, default='augment')\n\n    return parser\n\n\ndef main(args):\n    # slurm setting\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n    '''\n    # simple augmentation\n    transform_train = transforms.Compose([\n            transforms.RandomResizedCrop(args.input_size, scale=(0.2, 1.0), interpolation=3),  # 3 is bicubic\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    dataset_train = datasets.ImageFolder(os.path.join(args.data_path, 'train'), transform=transform_train)\n    print(dataset_train)\n    '''\n\n    transform_train = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.input_size, scale=(0.2, 1.0), interpolation=3),  # 3 is bicubic\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n    \n    \n    dataset_train = LMDBDataset(\n        lmdb_file=args.data_path,\n        s2c_transform=SeasonTransform(base_transform=transform_train,season=args.season),\n        is_slurm_job=args.is_slurm_job,\n        normalize=args.normalize,\n        dtype=args.dtype,\n        mode=args.mode\n    )\n\n\n    if True:  # args.distributed:\n        num_tasks = misc.get_world_size()\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n    \n    # define the model\n    model = models_mae.__dict__[args.model](norm_pix_loss=args.norm_pix_loss)\n\n    model.to(device)\n\n    model_without_ddp = model\n    print(\"Model = %s\" % str(model_without_ddp))\n\n    eff_batch_size = args.batch_size * args.accum_iter * misc.get_world_size()\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n        model_without_ddp = model.module\n    \n    # following timm: set wd as 0 for bias and norm layers\n    param_groups = optim_factory.add_weight_decay(model_without_ddp, args.weight_decay)\n    optimizer = torch.optim.AdamW(param_groups, lr=args.lr, betas=(0.9, 0.95))\n    print(optimizer)\n    loss_scaler = NativeScaler()\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir and (epoch % 20 == 0 or epoch + 1 == args.epochs):\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        'epoch': epoch,}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/models_mae.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# timm: https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# DeiT: https://github.com/facebookresearch/deit\n# --------------------------------------------------------\n\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\n\nfrom timm.models.vision_transformer import PatchEmbed, Block\n\nfrom .util.pos_embed import get_2d_sincos_pos_embed\n\n\nclass MaskedAutoencoderViT(nn.Module):\n    \"\"\" Masked Autoencoder with VisionTransformer backbone\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3,\n                 embed_dim=1024, depth=24, num_heads=16,\n                 decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n                 mlp_ratio=4., norm_layer=nn.LayerNorm, norm_pix_loss=False):\n        super().__init__()\n\n        self.in_chans = in_chans\n        \n        # --------------------------------------------------------------------------\n        # MAE encoder specifics\n        self.patch_embed = PatchEmbed(img_size, patch_size, in_chans, embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim), requires_grad=False)  # fixed sin-cos embedding\n\n        self.blocks = nn.ModuleList([\n            Block(embed_dim, num_heads, mlp_ratio, qkv_bias=True, norm_layer=norm_layer)\n            for i in range(depth)])\n        self.norm = norm_layer(embed_dim)\n        # --------------------------------------------------------------------------\n\n        # --------------------------------------------------------------------------\n        # MAE decoder specifics\n        self.decoder_embed = nn.Linear(embed_dim, decoder_embed_dim, bias=True)\n\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, decoder_embed_dim))\n\n        self.decoder_pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, decoder_embed_dim), requires_grad=False)  # fixed sin-cos embedding\n\n        self.decoder_blocks = nn.ModuleList([\n            Block(decoder_embed_dim, decoder_num_heads, mlp_ratio, qkv_bias=True, norm_layer=norm_layer)\n            for i in range(decoder_depth)])\n\n        self.decoder_norm = norm_layer(decoder_embed_dim)\n        self.decoder_pred = nn.Linear(decoder_embed_dim, patch_size**2 * in_chans, bias=True) # decoder to patch\n        # --------------------------------------------------------------------------\n\n        self.norm_pix_loss = norm_pix_loss\n\n        self.initialize_weights()\n\n    def initialize_weights(self):\n        # initialization\n        # initialize (and freeze) pos_embed by sin-cos embedding\n        pos_embed = get_2d_sincos_pos_embed(self.pos_embed.shape[-1], int(self.patch_embed.num_patches**.5), cls_token=True)\n        self.pos_embed.data.copy_(torch.from_numpy(pos_embed).float().unsqueeze(0))\n\n        decoder_pos_embed = get_2d_sincos_pos_embed(self.decoder_pos_embed.shape[-1], int(self.patch_embed.num_patches**.5), cls_token=True)\n        self.decoder_pos_embed.data.copy_(torch.from_numpy(decoder_pos_embed).float().unsqueeze(0))\n\n        # initialize patch_embed like nn.Linear (instead of nn.Conv2d)\n        w = self.patch_embed.proj.weight.data\n        torch.nn.init.xavier_uniform_(w.view([w.shape[0], -1]))\n\n        # timm's trunc_normal_(std=.02) is effectively normal_(std=0.02) as cutoff is too big (2.)\n        torch.nn.init.normal_(self.cls_token, std=.02)\n        torch.nn.init.normal_(self.mask_token, std=.02)\n\n        # initialize nn.Linear and nn.LayerNorm\n        self.apply(self._init_weights)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            # we use xavier_uniform following official JAX ViT:\n            torch.nn.init.xavier_uniform_(m.weight)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    def patchify(self, imgs):\n        \"\"\"\n        imgs: (N, 3, H, W)\n        x: (N, L, patch_size**2 *3)\n        \"\"\"\n        p = self.patch_embed.patch_size[0]\n        assert imgs.shape[2] == imgs.shape[3] and imgs.shape[2] % p == 0\n\n        h = w = imgs.shape[2] // p\n        x = imgs.reshape(shape=(imgs.shape[0], self.in_chans, h, p, w, p))\n        x = torch.einsum('nchpwq->nhwpqc', x)\n        x = x.reshape(shape=(imgs.shape[0], h * w, p**2 * self.in_chans))\n        return x\n\n    def unpatchify(self, x):\n        \"\"\"\n        x: (N, L, patch_size**2 *3)\n        imgs: (N, 3, H, W)\n        \"\"\"\n        p = self.patch_embed.patch_size[0]\n        h = w = int(x.shape[1]**.5)\n        assert h * w == x.shape[1]\n        \n        x = x.reshape(shape=(x.shape[0], h, w, p, p, self.in_chans))\n        x = torch.einsum('nhwpqc->nchpwq', x)\n        imgs = x.reshape(shape=(x.shape[0], self.in_chans, h * p, h * p))\n        return imgs\n\n    def random_masking(self, x, mask_ratio):\n        \"\"\"\n        Perform per-sample random masking by per-sample shuffling.\n        Per-sample shuffling is done by argsort random noise.\n        x: [N, L, D], sequence\n        \"\"\"\n        N, L, D = x.shape  # batch, length, dim\n        len_keep = int(L * (1 - mask_ratio))\n        \n        noise = torch.rand(N, L, device=x.device)  # noise in [0, 1]\n        \n        # sort noise for each sample\n        ids_shuffle = torch.argsort(noise, dim=1)  # ascend: small is keep, large is remove\n        ids_restore = torch.argsort(ids_shuffle, dim=1)\n\n        # keep the first subset\n        ids_keep = ids_shuffle[:, :len_keep]\n        x_masked = torch.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))\n\n        # generate the binary mask: 0 is keep, 1 is remove\n        mask = torch.ones([N, L], device=x.device)\n        mask[:, :len_keep] = 0\n        # unshuffle to get the binary mask\n        mask = torch.gather(mask, dim=1, index=ids_restore)\n\n        return x_masked, mask, ids_restore\n\n    def forward_encoder(self, x, mask_ratio):\n        # embed patches\n        x = self.patch_embed(x)\n\n        # add pos embed w/o cls token\n        x = x + self.pos_embed[:, 1:, :]\n\n        # masking: length -> length * mask_ratio\n        x, mask, ids_restore = self.random_masking(x, mask_ratio)\n\n        # append cls token\n        cls_token = self.cls_token + self.pos_embed[:, :1, :]\n        cls_tokens = cls_token.expand(x.shape[0], -1, -1)\n        x = torch.cat((cls_tokens, x), dim=1)\n\n        # apply Transformer blocks\n        for blk in self.blocks:\n            x = blk(x)\n        x = self.norm(x)\n\n        return x, mask, ids_restore\n\n    def forward_decoder(self, x, ids_restore):\n        # embed tokens\n        x = self.decoder_embed(x)\n\n        # append mask tokens to sequence\n        mask_tokens = self.mask_token.repeat(x.shape[0], ids_restore.shape[1] + 1 - x.shape[1], 1)\n        x_ = torch.cat([x[:, 1:, :], mask_tokens], dim=1)  # no cls token\n        x_ = torch.gather(x_, dim=1, index=ids_restore.unsqueeze(-1).repeat(1, 1, x.shape[2]))  # unshuffle\n        x = torch.cat([x[:, :1, :], x_], dim=1)  # append cls token\n\n        # add pos embed\n        x = x + self.decoder_pos_embed\n\n        # apply Transformer blocks\n        for blk in self.decoder_blocks:\n            x = blk(x)\n        x = self.decoder_norm(x)\n\n        # predictor projection\n        x = self.decoder_pred(x)\n\n        # remove cls token\n        x = x[:, 1:, :]\n\n        return x\n\n    def forward_loss(self, imgs, pred, mask):\n        \"\"\"\n        imgs: [N, 3, H, W]\n        pred: [N, L, p*p*3]\n        mask: [N, L], 0 is keep, 1 is remove, \n        \"\"\"\n        target = self.patchify(imgs)\n        if self.norm_pix_loss:\n            mean = target.mean(dim=-1, keepdim=True)\n            var = target.var(dim=-1, keepdim=True)\n            target = (target - mean) / (var + 1.e-6)**.5\n\n        loss = (pred - target) ** 2\n        loss = loss.mean(dim=-1)  # [N, L], mean loss per patch\n\n        loss = (loss * mask).sum() / mask.sum()  # mean loss on removed patches\n        return loss\n\n    def forward(self, imgs, mask_ratio=0.75):\n        latent, mask, ids_restore = self.forward_encoder(imgs, mask_ratio)\n        pred = self.forward_decoder(latent, ids_restore)  # [N, L, p*p*3]\n        loss = self.forward_loss(imgs, pred, mask)\n        return loss, pred, mask\n\n\ndef mae_vit_small_patch16_dec512d8b(**kwargs):\n    model = MaskedAutoencoderViT(\n        patch_size=16, embed_dim=384, depth=12, num_heads=6,\n        decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n        mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\ndef mae_vit_base_patch16_dec512d8b(**kwargs):\n    model = MaskedAutoencoderViT(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12,\n        decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n        mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef mae_vit_large_patch16_dec512d8b(**kwargs):\n    model = MaskedAutoencoderViT(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16,\n        decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n        mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef mae_vit_huge_patch14_dec512d8b(**kwargs):\n    model = MaskedAutoencoderViT(\n        patch_size=14, embed_dim=1280, depth=32, num_heads=16,\n        decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n        mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\n# set recommended archs\nmae_vit_base_patch16 = mae_vit_base_patch16_dec512d8b  # decoder: 512 dim, 8 blocks\nmae_vit_large_patch16 = mae_vit_large_patch16_dec512d8b  # decoder: 512 dim, 8 blocks\nmae_vit_huge_patch14 = mae_vit_huge_patch14_dec512d8b  # decoder: 512 dim, 8 blocks\n# new\nmae_vit_small_patch16 = mae_vit_small_patch16_dec512d8b  # decoder: 512 dim, 8 blocks"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/models_vit.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# timm: https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# DeiT: https://github.com/facebookresearch/deit\n# --------------------------------------------------------\n\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\n\nimport timm.models.vision_transformer\n\n\nclass VisionTransformer(timm.models.vision_transformer.VisionTransformer):\n    \"\"\" Vision Transformer with support for global average pooling\n    \"\"\"\n    def __init__(self, global_pool=False, **kwargs):\n        super(VisionTransformer, self).__init__(**kwargs)\n\n        self.global_pool = global_pool\n        if self.global_pool:\n            norm_layer = kwargs['norm_layer']\n            embed_dim = kwargs['embed_dim']\n            self.fc_norm = norm_layer(embed_dim)\n\n            del self.norm  # remove the original norm\n\n    def forward_features(self, x):\n        B = x.shape[0]\n        x = self.patch_embed(x)\n\n        cls_tokens = self.cls_token.expand(B, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n        x = torch.cat((cls_tokens, x), dim=1)\n        x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        for blk in self.blocks:\n            x = blk(x)\n\n        if self.global_pool:\n            x = x[:, 1:, :].mean(dim=1)  # global pool without cls token\n            outcome = self.fc_norm(x)\n        else:\n            x = self.norm(x)\n            outcome = x[:, 0]\n\n        return outcome\n\ndef vit_small_patch16(**kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\ndef vit_base_patch16(**kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef vit_large_patch16(**kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef vit_huge_patch14(**kwargs):\n    model = VisionTransformer(\n        patch_size=14, embed_dim=1280, depth=32, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/submitit_finetune.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# A script to run multinode training with submitit.\n# --------------------------------------------------------\n\nimport argparse\nimport os\nimport uuid\nfrom pathlib import Path\n\nimport main_finetune as classification\nimport submitit\n\n\ndef parse_args():\n    classification_parser = classification.get_args_parser()\n    parser = argparse.ArgumentParser(\"Submitit for MAE finetune\", parents=[classification_parser])\n    parser.add_argument(\"--ngpus\", default=8, type=int, help=\"Number of gpus to request on each node\")\n    parser.add_argument(\"--nodes\", default=2, type=int, help=\"Number of nodes to request\")\n    parser.add_argument(\"--timeout\", default=4320, type=int, help=\"Duration of the job\")\n    parser.add_argument(\"--job_dir\", default=\"\", type=str, help=\"Job dir. Leave empty for automatic.\")\n\n    parser.add_argument(\"--partition\", default=\"learnfair\", type=str, help=\"Partition where to submit\")\n    parser.add_argument(\"--use_volta32\", action='store_true', help=\"Request 32G V100 GPUs\")\n    parser.add_argument('--comment', default=\"\", type=str, help=\"Comment to pass to scheduler\")\n    return parser.parse_args()\n\n\ndef get_shared_folder() -> Path:\n    user = os.getenv(\"USER\")\n    if Path(\"/checkpoint/\").is_dir():\n        p = Path(f\"/checkpoint/{user}/experiments\")\n        p.mkdir(exist_ok=True)\n        return p\n    raise RuntimeError(\"No shared folder available\")\n\n\ndef get_init_file():\n    # Init file must not exist, but it's parent dir must exist.\n    os.makedirs(str(get_shared_folder()), exist_ok=True)\n    init_file = get_shared_folder() / f\"{uuid.uuid4().hex}_init\"\n    if init_file.exists():\n        os.remove(str(init_file))\n    return init_file\n\n\nclass Trainer(object):\n    def __init__(self, args):\n        self.args = args\n\n    def __call__(self):\n        import main_finetune as classification\n\n        self._setup_gpu_args()\n        classification.main(self.args)\n\n    def checkpoint(self):\n        import os\n        import submitit\n\n        self.args.dist_url = get_init_file().as_uri()\n        checkpoint_file = os.path.join(self.args.output_dir, \"checkpoint.pth\")\n        if os.path.exists(checkpoint_file):\n            self.args.resume = checkpoint_file\n        print(\"Requeuing \", self.args)\n        empty_trainer = type(self)(self.args)\n        return submitit.helpers.DelayedSubmission(empty_trainer)\n\n    def _setup_gpu_args(self):\n        import submitit\n        from pathlib import Path\n\n        job_env = submitit.JobEnvironment()\n        self.args.output_dir = Path(str(self.args.output_dir).replace(\"%j\", str(job_env.job_id)))\n        self.args.log_dir = self.args.output_dir\n        self.args.gpu = job_env.local_rank\n        self.args.rank = job_env.global_rank\n        self.args.world_size = job_env.num_tasks\n        print(f\"Process group: {job_env.num_tasks} tasks, rank: {job_env.global_rank}\")\n\n\ndef main():\n    args = parse_args()\n    if args.job_dir == \"\":\n        args.job_dir = get_shared_folder() / \"%j\"\n\n    # Note that the folder will depend on the job_id, to easily track experiments\n    executor = submitit.AutoExecutor(folder=args.job_dir, slurm_max_num_timeout=30)\n\n    num_gpus_per_node = args.ngpus\n    nodes = args.nodes\n    timeout_min = args.timeout\n\n    partition = args.partition\n    kwargs = {}\n    if args.use_volta32:\n        kwargs['slurm_constraint'] = 'volta32gb'\n    if args.comment:\n        kwargs['slurm_comment'] = args.comment\n\n    executor.update_parameters(\n        mem_gb=40 * num_gpus_per_node,\n        gpus_per_node=num_gpus_per_node,\n        tasks_per_node=num_gpus_per_node, # one task per GPU\n        cpus_per_task=10,\n        nodes=nodes,\n        timeout_min=timeout_min,\n        # Below are cluster dependent parameters\n        slurm_partition=partition,\n        slurm_signal_delay_s=120,\n        **kwargs\n    )\n\n    executor.update_parameters(name=\"mae\")\n\n    args.dist_url = get_init_file().as_uri()\n    args.output_dir = args.job_dir\n\n    trainer = Trainer(args)\n    job = executor.submit(trainer)\n\n    # print(\"Submitted job_id:\", job.job_id)\n    print(job.job_id)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/submitit_linprobe.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# A script to run multinode training with submitit.\n# --------------------------------------------------------\n\nimport argparse\nimport os\nimport uuid\nfrom pathlib import Path\n\nimport main_linprobe as classification\nimport submitit\n\n\ndef parse_args():\n    classification_parser = classification.get_args_parser()\n    parser = argparse.ArgumentParser(\"Submitit for MAE linear probe\", parents=[classification_parser])\n    parser.add_argument(\"--ngpus\", default=8, type=int, help=\"Number of gpus to request on each node\")\n    parser.add_argument(\"--nodes\", default=2, type=int, help=\"Number of nodes to request\")\n    parser.add_argument(\"--timeout\", default=4320, type=int, help=\"Duration of the job\")\n    parser.add_argument(\"--job_dir\", default=\"\", type=str, help=\"Job dir. Leave empty for automatic.\")\n\n    parser.add_argument(\"--partition\", default=\"learnfair\", type=str, help=\"Partition where to submit\")\n    parser.add_argument(\"--use_volta32\", action='store_true', help=\"Request 32G V100 GPUs\")\n    parser.add_argument('--comment', default=\"\", type=str, help=\"Comment to pass to scheduler\")\n    return parser.parse_args()\n\n\ndef get_shared_folder() -> Path:\n    user = os.getenv(\"USER\")\n    if Path(\"/checkpoint/\").is_dir():\n        p = Path(f\"/checkpoint/{user}/experiments\")\n        p.mkdir(exist_ok=True)\n        return p\n    raise RuntimeError(\"No shared folder available\")\n\n\ndef get_init_file():\n    # Init file must not exist, but it's parent dir must exist.\n    os.makedirs(str(get_shared_folder()), exist_ok=True)\n    init_file = get_shared_folder() / f\"{uuid.uuid4().hex}_init\"\n    if init_file.exists():\n        os.remove(str(init_file))\n    return init_file\n\n\nclass Trainer(object):\n    def __init__(self, args):\n        self.args = args\n\n    def __call__(self):\n        import main_linprobe as classification\n\n        self._setup_gpu_args()\n        classification.main(self.args)\n\n    def checkpoint(self):\n        import os\n        import submitit\n\n        self.args.dist_url = get_init_file().as_uri()\n        checkpoint_file = os.path.join(self.args.output_dir, \"checkpoint.pth\")\n        if os.path.exists(checkpoint_file):\n            self.args.resume = checkpoint_file\n        print(\"Requeuing \", self.args)\n        empty_trainer = type(self)(self.args)\n        return submitit.helpers.DelayedSubmission(empty_trainer)\n\n    def _setup_gpu_args(self):\n        import submitit\n        from pathlib import Path\n\n        job_env = submitit.JobEnvironment()\n        self.args.output_dir = Path(str(self.args.output_dir).replace(\"%j\", str(job_env.job_id)))\n        self.args.log_dir = self.args.output_dir\n        self.args.gpu = job_env.local_rank\n        self.args.rank = job_env.global_rank\n        self.args.world_size = job_env.num_tasks\n        print(f\"Process group: {job_env.num_tasks} tasks, rank: {job_env.global_rank}\")\n\n\ndef main():\n    args = parse_args()\n    if args.job_dir == \"\":\n        args.job_dir = get_shared_folder() / \"%j\"\n\n    # Note that the folder will depend on the job_id, to easily track experiments\n    executor = submitit.AutoExecutor(folder=args.job_dir, slurm_max_num_timeout=30)\n\n    num_gpus_per_node = args.ngpus\n    nodes = args.nodes\n    timeout_min = args.timeout\n\n    partition = args.partition\n    kwargs = {}\n    if args.use_volta32:\n        kwargs['slurm_constraint'] = 'volta32gb'\n    if args.comment:\n        kwargs['slurm_comment'] = args.comment\n\n    executor.update_parameters(\n        mem_gb=40 * num_gpus_per_node,\n        gpus_per_node=num_gpus_per_node,\n        tasks_per_node=num_gpus_per_node, # one task per GPU\n        cpus_per_task=10,\n        nodes=nodes,\n        timeout_min=timeout_min,\n        # Below are cluster dependent parameters\n        slurm_partition=partition,\n        slurm_signal_delay_s=120,\n        **kwargs\n    )\n\n    executor.update_parameters(name=\"mae\")\n\n    args.dist_url = get_init_file().as_uri()\n    args.output_dir = args.job_dir\n\n    trainer = Trainer(args)\n    job = executor.submit(trainer)\n\n    # print(\"Submitted job_id:\", job.job_id)\n    print(job.job_id)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/submitit_pretrain.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# A script to run multinode training with submitit.\n# --------------------------------------------------------\n\nimport argparse\nimport os\nimport uuid\nfrom pathlib import Path\n\nimport main_pretrain as trainer\nimport submitit\n\n\ndef parse_args():\n    trainer_parser = trainer.get_args_parser()\n    parser = argparse.ArgumentParser(\"Submitit for MAE pretrain\", parents=[trainer_parser])\n    parser.add_argument(\"--ngpus\", default=8, type=int, help=\"Number of gpus to request on each node\")\n    parser.add_argument(\"--nodes\", default=2, type=int, help=\"Number of nodes to request\")\n    parser.add_argument(\"--timeout\", default=4320, type=int, help=\"Duration of the job\")\n    parser.add_argument(\"--job_dir\", default=\"\", type=str, help=\"Job dir. Leave empty for automatic.\")\n\n    parser.add_argument(\"--partition\", default=\"learnfair\", type=str, help=\"Partition where to submit\")\n    parser.add_argument(\"--use_volta32\", action='store_true', help=\"Request 32G V100 GPUs\")\n    parser.add_argument('--comment', default=\"\", type=str, help=\"Comment to pass to scheduler\")\n    return parser.parse_args()\n\n\ndef get_shared_folder() -> Path:\n    user = os.getenv(\"USER\")\n    if Path(\"/checkpoint/\").is_dir():\n        p = Path(f\"/checkpoint/{user}/experiments\")\n        p.mkdir(exist_ok=True)\n        return p\n    raise RuntimeError(\"No shared folder available\")\n\n\ndef get_init_file():\n    # Init file must not exist, but it's parent dir must exist.\n    os.makedirs(str(get_shared_folder()), exist_ok=True)\n    init_file = get_shared_folder() / f\"{uuid.uuid4().hex}_init\"\n    if init_file.exists():\n        os.remove(str(init_file))\n    return init_file\n\n\nclass Trainer(object):\n    def __init__(self, args):\n        self.args = args\n\n    def __call__(self):\n        import main_pretrain as trainer\n\n        self._setup_gpu_args()\n        trainer.main(self.args)\n\n    def checkpoint(self):\n        import os\n        import submitit\n\n        self.args.dist_url = get_init_file().as_uri()\n        checkpoint_file = os.path.join(self.args.output_dir, \"checkpoint.pth\")\n        if os.path.exists(checkpoint_file):\n            self.args.resume = checkpoint_file\n        print(\"Requeuing \", self.args)\n        empty_trainer = type(self)(self.args)\n        return submitit.helpers.DelayedSubmission(empty_trainer)\n\n    def _setup_gpu_args(self):\n        import submitit\n        from pathlib import Path\n\n        job_env = submitit.JobEnvironment()\n        self.args.output_dir = Path(str(self.args.output_dir).replace(\"%j\", str(job_env.job_id)))\n        self.args.log_dir = self.args.output_dir\n        self.args.gpu = job_env.local_rank\n        self.args.rank = job_env.global_rank\n        self.args.world_size = job_env.num_tasks\n        print(f\"Process group: {job_env.num_tasks} tasks, rank: {job_env.global_rank}\")\n\n\ndef main():\n    args = parse_args()\n    if args.job_dir == \"\":\n        args.job_dir = get_shared_folder() / \"%j\"\n\n    # Note that the folder will depend on the job_id, to easily track experiments\n    executor = submitit.AutoExecutor(folder=args.job_dir, slurm_max_num_timeout=30)\n\n    num_gpus_per_node = args.ngpus\n    nodes = args.nodes\n    timeout_min = args.timeout\n\n    partition = args.partition\n    kwargs = {}\n    if args.use_volta32:\n        kwargs['slurm_constraint'] = 'volta32gb'\n    if args.comment:\n        kwargs['slurm_comment'] = args.comment\n\n    executor.update_parameters(\n        mem_gb=40 * num_gpus_per_node,\n        gpus_per_node=num_gpus_per_node,\n        tasks_per_node=num_gpus_per_node,  # one task per GPU\n        cpus_per_task=10,\n        nodes=nodes,\n        timeout_min=timeout_min,  # max is 60 * 72\n        # Below are cluster dependent parameters\n        slurm_partition=partition,\n        slurm_signal_delay_s=120,\n        **kwargs\n    )\n\n    executor.update_parameters(name=\"mae\")\n\n    args.dist_url = get_init_file().as_uri()\n    args.output_dir = args.job_dir\n\n    trainer = Trainer(args)\n    job = executor.submit(trainer)\n\n    # print(\"Submitted job_id:\", job.job_id)\n    print(job.job_id)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/util/__init__.py",
    "content": ""
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/util/crop.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport math\n\nimport torch\n\nfrom torchvision import transforms\nfrom torchvision.transforms import functional as F\n\n\nclass RandomResizedCrop(transforms.RandomResizedCrop):\n    \"\"\"\n    RandomResizedCrop for matching TF/TPU implementation: no for-loop is used.\n    This may lead to results different with torchvision's version.\n    Following BYOL's TF code:\n    https://github.com/deepmind/deepmind-research/blob/master/byol/utils/dataset.py#L206\n    \"\"\"\n    @staticmethod\n    def get_params(img, scale, ratio):\n        width, height = F._get_image_size(img)\n        area = height * width\n\n        target_area = area * torch.empty(1).uniform_(scale[0], scale[1]).item()\n        log_ratio = torch.log(torch.tensor(ratio))\n        aspect_ratio = torch.exp(\n            torch.empty(1).uniform_(log_ratio[0], log_ratio[1])\n        ).item()\n\n        w = int(round(math.sqrt(target_area * aspect_ratio)))\n        h = int(round(math.sqrt(target_area / aspect_ratio)))\n\n        w = min(w, width)\n        h = min(h, height)\n\n        i = torch.randint(0, height - h + 1, size=(1,)).item()\n        j = torch.randint(0, width - w + 1, size=(1,)).item()\n\n        return i, j, h, w"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/util/datasets.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# --------------------------------------------------------\n\nimport os\nimport PIL\n\nfrom torchvision import datasets, transforms\n\nfrom timm.data import create_transform\nfrom timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD\n\n\ndef build_dataset(is_train, args):\n    transform = build_transform(is_train, args)\n\n    root = os.path.join(args.data_path, 'train' if is_train else 'val')\n    dataset = datasets.ImageFolder(root, transform=transform)\n\n    print(dataset)\n\n    return dataset\n\n\ndef build_transform(is_train, args):\n    mean = IMAGENET_DEFAULT_MEAN\n    std = IMAGENET_DEFAULT_STD\n    # train transform\n    if is_train:\n        # this should always dispatch to transforms_imagenet_train\n        transform = create_transform(\n            input_size=args.input_size,\n            is_training=True,\n            color_jitter=args.color_jitter,\n            auto_augment=args.aa,\n            interpolation='bicubic',\n            re_prob=args.reprob,\n            re_mode=args.remode,\n            re_count=args.recount,\n            mean=mean,\n            std=std,\n        )\n        return transform\n\n    # eval transform\n    t = []\n    if args.input_size <= 224:\n        crop_pct = 224 / 256\n    else:\n        crop_pct = 1.0\n    size = int(args.input_size / crop_pct)\n    t.append(\n        transforms.Resize(size, interpolation=PIL.Image.BICUBIC),  # to maintain same ratio w.r.t. 224 images\n    )\n    t.append(transforms.CenterCrop(args.input_size))\n\n    t.append(transforms.ToTensor())\n    t.append(transforms.Normalize(mean, std))\n    return transforms.Compose(t)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/util/lars.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# LARS optimizer, implementation from MoCo v3:\n# https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\n\nimport torch\n\n\nclass LARS(torch.optim.Optimizer):\n    \"\"\"\n    LARS optimizer, no rate scaling or weight decay for parameters <= 1D.\n    \"\"\"\n    def __init__(self, params, lr=0, weight_decay=0, momentum=0.9, trust_coefficient=0.001):\n        defaults = dict(lr=lr, weight_decay=weight_decay, momentum=momentum, trust_coefficient=trust_coefficient)\n        super().__init__(params, defaults)\n\n    @torch.no_grad()\n    def step(self):\n        for g in self.param_groups:\n            for p in g['params']:\n                dp = p.grad\n\n                if dp is None:\n                    continue\n\n                if p.ndim > 1: # if not normalization gamma/beta or bias\n                    dp = dp.add(p, alpha=g['weight_decay'])\n                    param_norm = torch.norm(p)\n                    update_norm = torch.norm(dp)\n                    one = torch.ones_like(param_norm)\n                    q = torch.where(param_norm > 0.,\n                                    torch.where(update_norm > 0,\n                                    (g['trust_coefficient'] * param_norm / update_norm), one),\n                                    one)\n                    dp = dp.mul(q)\n\n                param_state = self.state[p]\n                if 'mu' not in param_state:\n                    param_state['mu'] = torch.zeros_like(p)\n                mu = param_state['mu']\n                mu.mul_(g['momentum']).add_(dp)\n                p.add_(mu, alpha=-g['lr'])"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/util/lr_decay.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# ELECTRA https://github.com/google-research/electra\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport json\n\n\ndef param_groups_lrd(model, weight_decay=0.05, no_weight_decay_list=[], layer_decay=.75):\n    \"\"\"\n    Parameter groups for layer-wise lr decay\n    Following BEiT: https://github.com/microsoft/unilm/blob/master/beit/optim_factory.py#L58\n    \"\"\"\n    param_group_names = {}\n    param_groups = {}\n\n    num_layers = len(model.blocks) + 1\n\n    layer_scales = list(layer_decay ** (num_layers - i) for i in range(num_layers + 1))\n\n    for n, p in model.named_parameters():\n        if not p.requires_grad:\n            continue\n\n        # no decay: all 1D parameters and model specific ones\n        if p.ndim == 1 or n in no_weight_decay_list:\n            g_decay = \"no_decay\"\n            this_decay = 0.\n        else:\n            g_decay = \"decay\"\n            this_decay = weight_decay\n            \n        layer_id = get_layer_id_for_vit(n, num_layers)\n        group_name = \"layer_%d_%s\" % (layer_id, g_decay)\n\n        if group_name not in param_group_names:\n            this_scale = layer_scales[layer_id]\n\n            param_group_names[group_name] = {\n                \"lr_scale\": this_scale,\n                \"weight_decay\": this_decay,\n                \"params\": [],\n            }\n            param_groups[group_name] = {\n                \"lr_scale\": this_scale,\n                \"weight_decay\": this_decay,\n                \"params\": [],\n            }\n\n        param_group_names[group_name][\"params\"].append(n)\n        param_groups[group_name][\"params\"].append(p)\n\n    # print(\"parameter groups: \\n%s\" % json.dumps(param_group_names, indent=2))\n\n    return list(param_groups.values())\n\n\ndef get_layer_id_for_vit(name, num_layers):\n    \"\"\"\n    Assign a parameter with its layer id\n    Following BEiT: https://github.com/microsoft/unilm/blob/master/beit/optim_factory.py#L33\n    \"\"\"\n    if name in ['cls_token', 'pos_embed']:\n        return 0\n    elif name.startswith('patch_embed'):\n        return 0\n    elif name.startswith('blocks'):\n        return int(name.split('.')[1]) + 1\n    else:\n        return num_layers"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/util/lr_sched.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport math\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate with half-cycle cosine after warmup\"\"\"\n    if epoch < args.warmup_epochs:\n        lr = args.lr * epoch / args.warmup_epochs \n    else:\n        lr = args.min_lr + (args.lr - args.min_lr) * 0.5 * \\\n            (1. + math.cos(math.pi * (epoch - args.warmup_epochs) / (args.epochs - args.warmup_epochs)))\n    for param_group in optimizer.param_groups:\n        if \"lr_scale\" in param_group:\n            param_group[\"lr\"] = lr * param_group[\"lr_scale\"]\n        else:\n            param_group[\"lr\"] = lr\n    return lr\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/util/misc.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport builtins\nimport datetime\nimport os\nimport time\nfrom collections import defaultdict, deque\nfrom pathlib import Path\n\nimport torch\nimport torch.distributed as dist\nfrom torch._six import inf\n\n\nclass SmoothedValue(object):\n    \"\"\"Track a series of values and provide access to smoothed values over a\n    window or the global series average.\n    \"\"\"\n\n    def __init__(self, window_size=20, fmt=None):\n        if fmt is None:\n            fmt = \"{median:.4f} ({global_avg:.4f})\"\n        self.deque = deque(maxlen=window_size)\n        self.total = 0.0\n        self.count = 0\n        self.fmt = fmt\n\n    def update(self, value, n=1):\n        self.deque.append(value)\n        self.count += n\n        self.total += value * n\n\n    def synchronize_between_processes(self):\n        \"\"\"\n        Warning: does not synchronize the deque!\n        \"\"\"\n        if not is_dist_avail_and_initialized():\n            return\n        t = torch.tensor([self.count, self.total], dtype=torch.float64, device='cuda')\n        dist.barrier()\n        dist.all_reduce(t)\n        t = t.tolist()\n        self.count = int(t[0])\n        self.total = t[1]\n\n    @property\n    def median(self):\n        d = torch.tensor(list(self.deque))\n        return d.median().item()\n\n    @property\n    def avg(self):\n        d = torch.tensor(list(self.deque), dtype=torch.float32)\n        return d.mean().item()\n\n    @property\n    def global_avg(self):\n        return self.total / self.count\n\n    @property\n    def max(self):\n        return max(self.deque)\n\n    @property\n    def value(self):\n        return self.deque[-1]\n\n    def __str__(self):\n        return self.fmt.format(\n            median=self.median,\n            avg=self.avg,\n            global_avg=self.global_avg,\n            max=self.max,\n            value=self.value)\n\n\nclass MetricLogger(object):\n    def __init__(self, delimiter=\"\\t\"):\n        self.meters = defaultdict(SmoothedValue)\n        self.delimiter = delimiter\n\n    def update(self, **kwargs):\n        for k, v in kwargs.items():\n            if v is None:\n                continue\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.meters[k].update(v)\n\n    def __getattr__(self, attr):\n        if attr in self.meters:\n            return self.meters[attr]\n        if attr in self.__dict__:\n            return self.__dict__[attr]\n        raise AttributeError(\"'{}' object has no attribute '{}'\".format(\n            type(self).__name__, attr))\n\n    def __str__(self):\n        loss_str = []\n        for name, meter in self.meters.items():\n            loss_str.append(\n                \"{}: {}\".format(name, str(meter))\n            )\n        return self.delimiter.join(loss_str)\n\n    def synchronize_between_processes(self):\n        for meter in self.meters.values():\n            meter.synchronize_between_processes()\n\n    def add_meter(self, name, meter):\n        self.meters[name] = meter\n\n    def log_every(self, iterable, print_freq, header=None):\n        i = 0\n        if not header:\n            header = ''\n        start_time = time.time()\n        end = time.time()\n        iter_time = SmoothedValue(fmt='{avg:.4f}')\n        data_time = SmoothedValue(fmt='{avg:.4f}')\n        space_fmt = ':' + str(len(str(len(iterable)))) + 'd'\n        log_msg = [\n            header,\n            '[{0' + space_fmt + '}/{1}]',\n            'eta: {eta}',\n            '{meters}',\n            'time: {time}',\n            'data: {data}'\n        ]\n        if torch.cuda.is_available():\n            log_msg.append('max mem: {memory:.0f}')\n        log_msg = self.delimiter.join(log_msg)\n        MB = 1024.0 * 1024.0\n        for obj in iterable:\n            data_time.update(time.time() - end)\n            yield obj\n            iter_time.update(time.time() - end)\n            if i % print_freq == 0 or i == len(iterable) - 1:\n                eta_seconds = iter_time.global_avg * (len(iterable) - i)\n                eta_string = str(datetime.timedelta(seconds=int(eta_seconds)))\n                if torch.cuda.is_available():\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time),\n                        memory=torch.cuda.max_memory_allocated() / MB))\n                else:\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time)))\n            i += 1\n            end = time.time()\n        total_time = time.time() - start_time\n        total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n        print('{} Total time: {} ({:.4f} s / it)'.format(\n            header, total_time_str, total_time / len(iterable)))\n\n\ndef setup_for_distributed(is_master):\n    \"\"\"\n    This function disables printing when not in master process\n    \"\"\"\n    builtin_print = builtins.print\n\n    def print(*args, **kwargs):\n        force = kwargs.pop('force', False)\n        force = force or (get_world_size() > 8)\n        if is_master or force:\n            now = datetime.datetime.now().time()\n            builtin_print('[{}] '.format(now), end='')  # print with time stamp\n            builtin_print(*args, **kwargs)\n\n    builtins.print = print\n\n\ndef is_dist_avail_and_initialized():\n    if not dist.is_available():\n        return False\n    if not dist.is_initialized():\n        return False\n    return True\n\n\ndef get_world_size():\n    if not is_dist_avail_and_initialized():\n        return 1\n    return dist.get_world_size()\n\n\ndef get_rank():\n    if not is_dist_avail_and_initialized():\n        return 0\n    return dist.get_rank()\n\n\ndef is_main_process():\n    return get_rank() == 0\n\n\ndef save_on_master(*args, **kwargs):\n    if is_main_process():\n        torch.save(*args, **kwargs)\n\n\ndef init_distributed_mode(args):\n    if args.dist_on_itp:\n        args.rank = int(os.environ['OMPI_COMM_WORLD_RANK'])\n        args.world_size = int(os.environ['OMPI_COMM_WORLD_SIZE'])\n        args.gpu = int(os.environ['OMPI_COMM_WORLD_LOCAL_RANK'])\n        args.dist_url = \"tcp://%s:%s\" % (os.environ['MASTER_ADDR'], os.environ['MASTER_PORT'])\n        os.environ['LOCAL_RANK'] = str(args.gpu)\n        os.environ['RANK'] = str(args.rank)\n        os.environ['WORLD_SIZE'] = str(args.world_size)\n        # [\"RANK\", \"WORLD_SIZE\", \"MASTER_ADDR\", \"MASTER_PORT\", \"LOCAL_RANK\"]\n    elif 'RANK' in os.environ and 'WORLD_SIZE' in os.environ:\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ['WORLD_SIZE'])\n        args.gpu = int(os.environ['LOCAL_RANK'])\n    elif 'SLURM_PROCID' in os.environ:\n        args.rank = int(os.environ['SLURM_PROCID'])\n        args.gpu = args.rank % torch.cuda.device_count()\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n    else:\n        print('Not using distributed mode')\n        setup_for_distributed(is_master=True)  # hack\n        args.distributed = False\n        return\n\n    args.distributed = True\n\n    torch.cuda.set_device(args.gpu)\n    args.dist_backend = 'nccl'\n    print('World Size {} | distributed init (rank {}): {}, gpu {}'.format(args.world_size, args.rank, args.dist_url, args.gpu), flush=True)\n    torch.distributed.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                         world_size=args.world_size, rank=args.rank)\n    torch.distributed.barrier()\n    setup_for_distributed(args.rank == 0)\n\n\nclass NativeScalerWithGradNormCount:\n    state_dict_key = \"amp_scaler\"\n\n    def __init__(self):\n        self._scaler = torch.cuda.amp.GradScaler()\n\n    def __call__(self, loss, optimizer, clip_grad=None, parameters=None, create_graph=False, update_grad=True):\n        self._scaler.scale(loss).backward(create_graph=create_graph)\n        if update_grad:\n            if clip_grad is not None:\n                assert parameters is not None\n                self._scaler.unscale_(optimizer)  # unscale the gradients of optimizer's assigned params in-place\n                norm = torch.nn.utils.clip_grad_norm_(parameters, clip_grad)\n            else:\n                self._scaler.unscale_(optimizer)\n                norm = get_grad_norm_(parameters)\n            self._scaler.step(optimizer)\n            self._scaler.update()\n        else:\n            norm = None\n        return norm\n\n    def state_dict(self):\n        return self._scaler.state_dict()\n\n    def load_state_dict(self, state_dict):\n        self._scaler.load_state_dict(state_dict)\n\n\ndef get_grad_norm_(parameters, norm_type: float = 2.0) -> torch.Tensor:\n    if isinstance(parameters, torch.Tensor):\n        parameters = [parameters]\n    parameters = [p for p in parameters if p.grad is not None]\n    norm_type = float(norm_type)\n    if len(parameters) == 0:\n        return torch.tensor(0.)\n    device = parameters[0].grad.device\n    if norm_type == inf:\n        total_norm = max(p.grad.detach().abs().max().to(device) for p in parameters)\n    else:\n        total_norm = torch.norm(torch.stack([torch.norm(p.grad.detach(), norm_type).to(device) for p in parameters]), norm_type)\n    return total_norm\n\n\ndef save_model(args, epoch, model, model_without_ddp, optimizer, loss_scaler):\n    output_dir = Path(args.output_dir)\n    epoch_name = str(epoch)\n    if loss_scaler is not None:\n        checkpoint_paths = [output_dir / ('checkpoint-%s.pth' % epoch_name)]\n        for checkpoint_path in checkpoint_paths:\n            to_save = {\n                'model': model_without_ddp.state_dict(),\n                'optimizer': optimizer.state_dict(),\n                'epoch': epoch,\n                'scaler': loss_scaler.state_dict(),\n                'args': args,\n            }\n\n            save_on_master(to_save, checkpoint_path)\n    else:\n        client_state = {'epoch': epoch}\n        model.save_checkpoint(save_dir=args.output_dir, tag=\"checkpoint-%s\" % epoch_name, client_state=client_state)\n\n\ndef load_model(args, model_without_ddp, optimizer, loss_scaler):\n    if args.resume:\n        if args.resume.startswith('https'):\n            checkpoint = torch.hub.load_state_dict_from_url(\n                args.resume, map_location='cpu', check_hash=True)\n        else:\n            checkpoint = torch.load(args.resume, map_location='cpu')\n        model_without_ddp.load_state_dict(checkpoint['model'])\n        print(\"Resume checkpoint %s\" % args.resume)\n        if 'optimizer' in checkpoint and 'epoch' in checkpoint and not (hasattr(args, 'eval') and args.eval):\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            args.start_epoch = checkpoint['epoch'] + 1\n            if 'scaler' in checkpoint:\n                loss_scaler.load_state_dict(checkpoint['scaler'])\n            print(\"With optim & sched!\")\n\n\ndef all_reduce_mean(x):\n    world_size = get_world_size()\n    if world_size > 1:\n        x_reduce = torch.tensor(x).cuda()\n        dist.all_reduce(x_reduce)\n        x_reduce /= world_size\n        return x_reduce.item()\n    else:\n        return x"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/mae/util/pos_embed.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# Position embedding utils\n# --------------------------------------------------------\n\nimport numpy as np\n\nimport torch\n\n# --------------------------------------------------------\n# 2D sine-cosine position embedding\n# References:\n# Transformer: https://github.com/tensorflow/models/blob/master/official/nlp/transformer/model_utils.py\n# MoCo v3: https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\ndef get_2d_sincos_pos_embed(embed_dim, grid_size, cls_token=False):\n    \"\"\"\n    grid_size: int of the grid height and width\n    return:\n    pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)\n    \"\"\"\n    grid_h = np.arange(grid_size, dtype=np.float32)\n    grid_w = np.arange(grid_size, dtype=np.float32)\n    grid = np.meshgrid(grid_w, grid_h)  # here w goes first\n    grid = np.stack(grid, axis=0)\n\n    grid = grid.reshape([2, 1, grid_size, grid_size])\n    pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid)\n    if cls_token:\n        pos_embed = np.concatenate([np.zeros([1, embed_dim]), pos_embed], axis=0)\n    return pos_embed\n\n\ndef get_2d_sincos_pos_embed_from_grid(embed_dim, grid):\n    assert embed_dim % 2 == 0\n\n    # use half of dimensions to encode grid_h\n    emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0])  # (H*W, D/2)\n    emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1])  # (H*W, D/2)\n\n    emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D)\n    return emb\n\n\ndef get_1d_sincos_pos_embed_from_grid(embed_dim, pos):\n    \"\"\"\n    embed_dim: output dimension for each position\n    pos: a list of positions to be encoded: size (M,)\n    out: (M, D)\n    \"\"\"\n    assert embed_dim % 2 == 0\n    omega = np.arange(embed_dim // 2, dtype=np.float)\n    omega /= embed_dim / 2.\n    omega = 1. / 10000**omega  # (D/2,)\n\n    pos = pos.reshape(-1)  # (M,)\n    out = np.einsum('m,d->md', pos, omega)  # (M, D/2), outer product\n\n    emb_sin = np.sin(out) # (M, D/2)\n    emb_cos = np.cos(out) # (M, D/2)\n\n    emb = np.concatenate([emb_sin, emb_cos], axis=1)  # (M, D)\n    return emb\n\n\n# --------------------------------------------------------\n# Interpolate position embeddings for high-resolution\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# --------------------------------------------------------\ndef interpolate_pos_embed(model, checkpoint_model):\n    if 'pos_embed' in checkpoint_model:\n        pos_embed_checkpoint = checkpoint_model['pos_embed']\n        embedding_size = pos_embed_checkpoint.shape[-1]\n        num_patches = model.patch_embed.num_patches\n        num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n        # height (== width) for the checkpoint position embedding\n        orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n        # height (== width) for the new position embedding\n        new_size = int(num_patches ** 0.5)\n        # class_token and dist_token are kept unchanged\n        if orig_size != new_size:\n            print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n            extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n            # only the position tokens are interpolated\n            pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n            pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n            pos_tokens = torch.nn.functional.interpolate(\n                pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n            pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n            new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n            checkpoint_model['pos_embed'] = new_pos_embed\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco/builder.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport torch\nimport torch.nn as nn\n\n\nclass MoCo(nn.Module):\n    \"\"\"\n    Build a MoCo model with: a query encoder, a key encoder, and a queue\n    https://arxiv.org/abs/1911.05722\n    \"\"\"\n    def __init__(self, base_encoder, dim=128, K=65536, m=0.999, T=0.07, mlp=False, bands='all'):\n        \"\"\"\n        dim: feature dimension (default: 128)\n        K: queue size; number of negative keys (default: 65536)\n        m: moco momentum of updating key encoder (default: 0.999)\n        T: softmax temperature (default: 0.07)\n        \"\"\"\n        super(MoCo, self).__init__()\n\n        self.K = K\n        self.m = m\n        self.T = T\n\n        # create the encoders\n        # num_classes is the output fc dimension\n        self.encoder_q = base_encoder(num_classes=dim)\n        self.encoder_k = base_encoder(num_classes=dim)\n\n        if bands=='B12':\n            self.encoder_q.conv1 = torch.nn.Conv2d(12,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(12,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n        elif bands=='B13':\n            #self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            #self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n        elif bands=='B15':\n            #self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            #self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            self.encoder_q.conv1 = torch.nn.Conv2d(15,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(15,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n        elif bands=='B2':\n            #self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            #self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            self.encoder_q.conv1 = torch.nn.Conv2d(2,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(2,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            \n            \n            #self.encoder_q.maxpool = torch.nn.Identity()\n            #self.encoder_k.maxpool = torch.nn.Identity()\n\n        if mlp:  # hack: brute-force replacement\n            dim_mlp = self.encoder_q.fc.weight.shape[1]\n            self.encoder_q.fc = nn.Sequential(nn.Linear(dim_mlp, dim_mlp), nn.ReLU(), self.encoder_q.fc)\n            self.encoder_k.fc = nn.Sequential(nn.Linear(dim_mlp, dim_mlp), nn.ReLU(), self.encoder_k.fc)\n\n        for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):\n            param_k.data.copy_(param_q.data)  # initialize\n            param_k.requires_grad = False  # not update by gradient\n\n        # create the queue\n        self.register_buffer(\"queue\", torch.randn(dim, K))\n        self.queue = nn.functional.normalize(self.queue, dim=0)\n\n        self.register_buffer(\"queue_ptr\", torch.zeros(1, dtype=torch.long))\n\n    @torch.no_grad()\n    def _momentum_update_key_encoder(self):\n        \"\"\"\n        Momentum update of the key encoder\n        \"\"\"\n        for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):\n            param_k.data = param_k.data * self.m + param_q.data * (1. - self.m)\n\n    @torch.no_grad()\n    def _dequeue_and_enqueue(self, keys):\n        # gather keys before updating queue\n        keys = concat_all_gather(keys)\n\n        batch_size = keys.shape[0]\n\n        ptr = int(self.queue_ptr)\n        assert self.K % batch_size == 0  # for simplicity\n\n        # replace the keys at ptr (dequeue and enqueue)\n        self.queue[:, ptr:ptr + batch_size] = keys.T\n        ptr = (ptr + batch_size) % self.K  # move pointer\n\n        self.queue_ptr[0] = ptr\n\n    @torch.no_grad()\n    def _batch_shuffle_ddp(self, x):\n        \"\"\"\n        Batch shuffle, for making use of BatchNorm.\n        *** Only support DistributedDataParallel (DDP) model. ***\n        \"\"\"\n        # gather from all gpus\n        batch_size_this = x.shape[0]\n        x_gather = concat_all_gather(x)\n        batch_size_all = x_gather.shape[0]\n\n        num_gpus = batch_size_all // batch_size_this\n\n        # random shuffle index\n        idx_shuffle = torch.randperm(batch_size_all).cuda()\n\n        # broadcast to all gpus\n        torch.distributed.broadcast(idx_shuffle, src=0)\n\n        # index for restoring\n        idx_unshuffle = torch.argsort(idx_shuffle)\n\n        # shuffled index for this gpu\n        gpu_idx = torch.distributed.get_rank()\n        idx_this = idx_shuffle.view(num_gpus, -1)[gpu_idx]\n\n        return x_gather[idx_this], idx_unshuffle\n\n    @torch.no_grad()\n    def _batch_unshuffle_ddp(self, x, idx_unshuffle):\n        \"\"\"\n        Undo batch shuffle.\n        *** Only support DistributedDataParallel (DDP) model. ***\n        \"\"\"\n        # gather from all gpus\n        batch_size_this = x.shape[0]\n        x_gather = concat_all_gather(x)\n        batch_size_all = x_gather.shape[0]\n\n        num_gpus = batch_size_all // batch_size_this\n\n        # restored index for this gpu\n        gpu_idx = torch.distributed.get_rank()\n        idx_this = idx_unshuffle.view(num_gpus, -1)[gpu_idx]\n\n        return x_gather[idx_this]\n\n    def forward(self, im_q, im_k):\n        \"\"\"\n        Input:\n            im_q: a batch of query images\n            im_k: a batch of key images\n        Output:\n            logits, targets\n        \"\"\"\n\n        # compute query features\n        q = self.encoder_q(im_q)  # queries: NxC\n        q = nn.functional.normalize(q, dim=1)\n\n        # compute key features\n        with torch.no_grad():  # no gradient to keys\n            self._momentum_update_key_encoder()  # update the key encoder\n\n            # shuffle for making use of BN\n            im_k, idx_unshuffle = self._batch_shuffle_ddp(im_k)\n\n            k = self.encoder_k(im_k)  # keys: NxC\n            k = nn.functional.normalize(k, dim=1)\n\n            # undo shuffle\n            k = self._batch_unshuffle_ddp(k, idx_unshuffle)\n\n        # compute logits\n        # Einstein sum is more intuitive\n        # positive logits: Nx1\n        l_pos = torch.einsum('nc,nc->n', [q, k]).unsqueeze(-1)\n        # negative logits: NxK\n        l_neg = torch.einsum('nc,ck->nk', [q, self.queue.clone().detach()])\n\n        # logits: Nx(1+K)\n        logits = torch.cat([l_pos, l_neg], dim=1)\n\n        # apply temperature\n        logits /= self.T\n\n        # labels: positive key indicators\n        labels = torch.zeros(logits.shape[0], dtype=torch.long).cuda()\n\n        # dequeue and enqueue\n        self._dequeue_and_enqueue(k)\n\n        return logits, labels\n\n\n# utils\n@torch.no_grad()\ndef concat_all_gather(tensor):\n    \"\"\"\n    Performs all_gather operation on the provided tensors.\n    *** Warning ***: torch.distributed.all_gather has no gradient.\n    \"\"\"\n    tensors_gather = [torch.ones_like(tensor)\n        for _ in range(torch.distributed.get_world_size())]\n    torch.distributed.all_gather(tensors_gather, tensor, async_op=False)\n\n    output = torch.cat(tensors_gather, dim=0)\n    return output\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco/loader.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nfrom PIL import ImageFilter\nimport random\nimport cv2\n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n    def __init__(self, base_transform):\n        self.base_transform = base_transform\n\n    def __call__(self, x):\n        q = self.base_transform(x)\n        k = self.base_transform(x)\n        return [q, k]\n\n\nclass GaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, sigma=[.1, 2.]):\n        self.sigma = sigma\n\n    def __call__(self, x):\n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/README.md",
    "content": "## MoCo: Momentum Contrast for Unsupervised Visual Representation Learning\n\n<p align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/11435359/71603927-0ca98d00-2b14-11ea-9fd8-10d984a2de45.png\" width=\"300\">\n</p>\n\nThis is a PyTorch implementation of the [MoCo paper](https://arxiv.org/abs/1911.05722):\n```\n@Article{he2019moco,\n  author  = {Kaiming He and Haoqi Fan and Yuxin Wu and Saining Xie and Ross Girshick},\n  title   = {Momentum Contrast for Unsupervised Visual Representation Learning},\n  journal = {arXiv preprint arXiv:1911.05722},\n  year    = {2019},\n}\n```\nIt also includes the implementation of the [MoCo v2 paper](https://arxiv.org/abs/2003.04297):\n```\n@Article{chen2020mocov2,\n  author  = {Xinlei Chen and Haoqi Fan and Ross Girshick and Kaiming He},\n  title   = {Improved Baselines with Momentum Contrastive Learning},\n  journal = {arXiv preprint arXiv:2003.04297},\n  year    = {2020},\n}\n```\n\n\n### Preparation\n\nInstall PyTorch and ImageNet dataset following the [official PyTorch ImageNet training code](https://github.com/pytorch/examples/tree/master/imagenet).\n\nThis repo aims to be minimal modifications on that code. Check the modifications by:\n```\ndiff main_moco.py <(curl https://raw.githubusercontent.com/pytorch/examples/master/imagenet/main.py)\ndiff main_lincls.py <(curl https://raw.githubusercontent.com/pytorch/examples/master/imagenet/main.py)\n```\n\n\n### Unsupervised Training\n\nThis implementation only supports **multi-gpu**, **DistributedDataParallel** training, which is faster and simpler; single-gpu or DataParallel training is not supported.\n\nTo do unsupervised pre-training of a ResNet-50 model on ImageNet in an 8-gpu machine, run:\n```\npython main_moco.py \\\n  -a resnet50 \\\n  --lr 0.03 \\\n  --batch-size 256 \\\n  --dist-url 'tcp://localhost:10001' --multiprocessing-distributed --world-size 1 --rank 0 \\\n  [your imagenet-folder with train and val folders]\n```\nThis script uses all the default hyper-parameters as described in the MoCo v1 paper. To run MoCo v2, set `--mlp --moco-t 0.2 --aug-plus --cos`.\n\n***Note***: for 4-gpu training, we recommend following the [linear lr scaling recipe](https://arxiv.org/abs/1706.02677): `--lr 0.015 --batch-size 128` with 4 gpus. We got similar results using this setting.\n\n\n### Linear Classification\n\nWith a pre-trained model, to train a supervised linear classifier on frozen features/weights in an 8-gpu machine, run:\n```\npython main_lincls.py \\\n  -a resnet50 \\\n  --lr 30.0 \\\n  --batch-size 256 \\\n  --pretrained [your checkpoint path]/checkpoint_0199.pth.tar \\\n  --dist-url 'tcp://localhost:10001' --multiprocessing-distributed --world-size 1 --rank 0 \\\n  [your imagenet-folder with train and val folders]\n```\n\nLinear classification results on ImageNet using this repo with 8 NVIDIA V100 GPUs :\n<table><tbody>\n<!-- START TABLE -->\n<!-- TABLE HEADER -->\n<th valign=\"bottom\"></th>\n<th valign=\"bottom\">pre-train<br/>epochs</th>\n<th valign=\"bottom\">pre-train<br/>time</th>\n<th valign=\"bottom\">MoCo v1<br/>top-1 acc.</th>\n<th valign=\"bottom\">MoCo v2<br/>top-1 acc.</th>\n<!-- TABLE BODY -->\n<tr><td align=\"left\">ResNet-50</td>\n<td align=\"center\">200</td>\n<td align=\"center\">53 hours</td>\n<td align=\"center\">60.8&plusmn;0.2</td>\n<td align=\"center\">67.5&plusmn;0.1</td>\n</tr>\n</tbody></table>\n\nHere we run 5 trials (of pre-training and linear classification) and report mean&plusmn;std: the 5 results of MoCo v1 are {60.6, 60.6, 60.7, 60.9, 61.1}, and of MoCo v2 are {67.7, 67.6, 67.4, 67.6, 67.3}.\n\n\n### Models\n\nOur pre-trained ResNet-50 models can be downloaded as following:\n<table><tbody>\n<!-- START TABLE -->\n<!-- TABLE HEADER -->\n<th valign=\"bottom\"></th>\n<th valign=\"bottom\">epochs</th>\n<th valign=\"bottom\">mlp</th>\n<th valign=\"bottom\">aug+</th>\n<th valign=\"bottom\">cos</th>\n<th valign=\"bottom\">top-1 acc.</th>\n<th valign=\"bottom\">model</th>\n<th valign=\"bottom\">md5</th>\n<!-- TABLE BODY -->\n<tr><td align=\"left\"><a href=\"https://arxiv.org/abs/1911.05722\">MoCo v1</a></td>\n<td align=\"center\">200</td>\n<td align=\"center\"></td>\n<td align=\"center\"></td>\n<td align=\"center\"></td>\n<td align=\"center\">60.6</td>\n<td align=\"center\"><a href=\"https://dl.fbaipublicfiles.com/moco/moco_checkpoints/moco_v1_200ep/moco_v1_200ep_pretrain.pth.tar\">download</a></td>\n<td align=\"center\"><tt>b251726a</tt></td>\n</tr>\n<tr><td align=\"left\"><a href=\"https://arxiv.org/abs/2003.04297\">MoCo v2</a></td>\n<td align=\"center\">200</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">67.7</td>\n<td align=\"center\"><a href=\"https://dl.fbaipublicfiles.com/moco/moco_checkpoints/moco_v2_200ep/moco_v2_200ep_pretrain.pth.tar\">download</a></td>\n<td align=\"center\"><tt>59fd9945</tt></td>\n</tr>\n<tr><td align=\"left\"><a href=\"https://arxiv.org/abs/2003.04297\">MoCo v2</a></td>\n<td align=\"center\">800</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">71.1</td>\n<td align=\"center\"><a href=\"https://dl.fbaipublicfiles.com/moco/moco_checkpoints/moco_v2_800ep/moco_v2_800ep_pretrain.pth.tar\">download</a></td>\n<td align=\"center\"><tt>a04e12f8</tt></td>\n</tr>\n</tbody></table>\n\n\n### Transferring to Object Detection\n\nSee [./detection](detection).\n\n\n### License\n\nThis project is under the CC-BY-NC 4.0 license. See [LICENSE](LICENSE) for details.\n\n### See Also\n* [moco.tensorflow](https://github.com/ppwwyyxx/moco.tensorflow): A TensorFlow re-implementation.\n* [Colab notebook](https://colab.research.google.com/github/facebookresearch/moco/blob/colab-notebook/colab/moco_cifar10_demo.ipynb): CIFAR demo on Colab GPU.\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/__init__.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/builder.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport torch\nimport torch.nn as nn\n\n\nclass MoCo(nn.Module):\n    \"\"\"\n    Build a MoCo model with: a query encoder, a key encoder, and a queue\n    https://arxiv.org/abs/1911.05722\n    \"\"\"\n    def __init__(self, base_encoder, dim=128, K=65536, m=0.999, T=0.07, mlp=False, bands='all'):\n        \"\"\"\n        dim: feature dimension (default: 128)\n        K: queue size; number of negative keys (default: 65536)\n        m: moco momentum of updating key encoder (default: 0.999)\n        T: softmax temperature (default: 0.07)\n        \"\"\"\n        super(MoCo, self).__init__()\n\n        self.K = K\n        self.m = m\n        self.T = T\n\n        # create the encoders\n        # num_classes is the output fc dimension\n        self.encoder_q = base_encoder(num_classes=dim)\n        self.encoder_k = base_encoder(num_classes=dim)\n\n        if bands=='B12':\n            self.encoder_q.conv1 = torch.nn.Conv2d(12,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(12,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n        elif bands=='B13':\n            #self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            #self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            \n            #self.encoder_q.maxpool = torch.nn.Identity()\n            #self.encoder_k.maxpool = torch.nn.Identity()\n\n        if mlp:  # hack: brute-force replacement\n            dim_mlp = self.encoder_q.fc.weight.shape[1]\n            self.encoder_q.fc = nn.Sequential(nn.Linear(dim_mlp, dim_mlp), nn.ReLU(), self.encoder_q.fc)\n            self.encoder_k.fc = nn.Sequential(nn.Linear(dim_mlp, dim_mlp), nn.ReLU(), self.encoder_k.fc)\n\n        for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):\n            param_k.data.copy_(param_q.data)  # initialize\n            param_k.requires_grad = False  # not update by gradient\n\n        # create the queue\n        self.register_buffer(\"queue\", torch.randn(dim, K))\n        self.queue = nn.functional.normalize(self.queue, dim=0)\n\n        self.register_buffer(\"queue_ptr\", torch.zeros(1, dtype=torch.long))\n\n    @torch.no_grad()\n    def _momentum_update_key_encoder(self):\n        \"\"\"\n        Momentum update of the key encoder\n        \"\"\"\n        for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):\n            param_k.data = param_k.data * self.m + param_q.data * (1. - self.m)\n\n    @torch.no_grad()\n    def _dequeue_and_enqueue(self, keys):\n        # gather keys before updating queue\n        keys = concat_all_gather(keys)\n\n        batch_size = keys.shape[0]\n\n        ptr = int(self.queue_ptr)\n        assert self.K % batch_size == 0  # for simplicity\n\n        # replace the keys at ptr (dequeue and enqueue)\n        self.queue[:, ptr:ptr + batch_size] = keys.T\n        ptr = (ptr + batch_size) % self.K  # move pointer\n\n        self.queue_ptr[0] = ptr\n\n    @torch.no_grad()\n    def _batch_shuffle_ddp(self, x):\n        \"\"\"\n        Batch shuffle, for making use of BatchNorm.\n        *** Only support DistributedDataParallel (DDP) model. ***\n        \"\"\"\n        # gather from all gpus\n        batch_size_this = x.shape[0]\n        x_gather = concat_all_gather(x)\n        batch_size_all = x_gather.shape[0]\n\n        num_gpus = batch_size_all // batch_size_this\n\n        # random shuffle index\n        idx_shuffle = torch.randperm(batch_size_all).cuda()\n\n        # broadcast to all gpus\n        torch.distributed.broadcast(idx_shuffle, src=0)\n\n        # index for restoring\n        idx_unshuffle = torch.argsort(idx_shuffle)\n\n        # shuffled index for this gpu\n        gpu_idx = torch.distributed.get_rank()\n        idx_this = idx_shuffle.view(num_gpus, -1)[gpu_idx]\n\n        return x_gather[idx_this], idx_unshuffle\n\n    @torch.no_grad()\n    def _batch_unshuffle_ddp(self, x, idx_unshuffle):\n        \"\"\"\n        Undo batch shuffle.\n        *** Only support DistributedDataParallel (DDP) model. ***\n        \"\"\"\n        # gather from all gpus\n        batch_size_this = x.shape[0]\n        x_gather = concat_all_gather(x)\n        batch_size_all = x_gather.shape[0]\n\n        num_gpus = batch_size_all // batch_size_this\n\n        # restored index for this gpu\n        gpu_idx = torch.distributed.get_rank()\n        idx_this = idx_unshuffle.view(num_gpus, -1)[gpu_idx]\n\n        return x_gather[idx_this]\n\n    def forward(self, im_q, im_k):\n        \"\"\"\n        Input:\n            im_q: a batch of query images\n            im_k: a batch of key images\n        Output:\n            logits, targets\n        \"\"\"\n\n        # compute query features\n        q = self.encoder_q(im_q)  # queries: NxC\n        q = nn.functional.normalize(q, dim=1)\n\n        # compute key features\n        with torch.no_grad():  # no gradient to keys\n            self._momentum_update_key_encoder()  # update the key encoder\n\n            # shuffle for making use of BN\n            im_k, idx_unshuffle = self._batch_shuffle_ddp(im_k)\n\n            k = self.encoder_k(im_k)  # keys: NxC\n            k = nn.functional.normalize(k, dim=1)\n\n            # undo shuffle\n            k = self._batch_unshuffle_ddp(k, idx_unshuffle)\n\n        # compute logits\n        # Einstein sum is more intuitive\n        # positive logits: Nx1\n        l_pos = torch.einsum('nc,nc->n', [q, k]).unsqueeze(-1)\n        # negative logits: NxK\n        l_neg = torch.einsum('nc,ck->nk', [q, self.queue.clone().detach()])\n\n        # logits: Nx(1+K)\n        logits = torch.cat([l_pos, l_neg], dim=1)\n\n        # apply temperature\n        logits /= self.T\n\n        # labels: positive key indicators\n        labels = torch.zeros(logits.shape[0], dtype=torch.long).cuda()\n\n        # dequeue and enqueue\n        self._dequeue_and_enqueue(k)\n\n        return logits, labels\n\n\n# utils\n@torch.no_grad()\ndef concat_all_gather(tensor):\n    \"\"\"\n    Performs all_gather operation on the provided tensors.\n    *** Warning ***: torch.distributed.all_gather has no gradient.\n    \"\"\"\n    tensors_gather = [torch.ones_like(tensor)\n        for _ in range(torch.distributed.get_world_size())]\n    torch.distributed.all_gather(tensors_gather, tensor, async_op=False)\n\n    output = torch.cat(tensors_gather, dim=0)\n    return output\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/detection/README.md",
    "content": "\n## MoCo: Transferring to Detection\n\nThe `train_net.py` script reproduces the object detection experiments on Pascal VOC and COCO.\n\n### Instruction\n\n1. Install [detectron2](https://github.com/facebookresearch/detectron2/blob/master/INSTALL.md).\n\n1. Convert a pre-trained MoCo model to detectron2's format:\n   ```\n   python3 convert-pretrain-to-detectron2.py input.pth.tar output.pkl\n   ```\n\n1. Put dataset under \"./datasets\" directory,\n   following the [directory structure](https://github.com/facebookresearch/detectron2/tree/master/datasets)\n\t requried by detectron2.\n\n1. Run training:\n   ```\n   python train_net.py --config-file configs/pascal_voc_R_50_C4_24k_moco.yaml \\\n\t--num-gpus 8 MODEL.WEIGHTS ./output.pkl\n   ```\n\n### Results\n\nBelow are the results on Pascal VOC 2007 test, fine-tuned on 2007+2012 trainval for 24k iterations using Faster R-CNN with a R50-C4 backbone:\n\n<table><tbody>\n<!-- START TABLE -->\n<!-- TABLE HEADER -->\n<th valign=\"bottom\">pretrain</th>\n<th valign=\"bottom\">AP50</th>\n<th valign=\"bottom\">AP</th>\n<th valign=\"bottom\">AP75</th>\n<!-- TABLE BODY -->\n<tr><td align=\"left\">ImageNet-1M, supervised</td>\n<td align=\"center\">81.3</td>\n<td align=\"center\">53.5</td>\n<td align=\"center\">58.8</td>\n</tr>\n<tr><td align=\"left\">ImageNet-1M, MoCo v1, 200ep</td>\n<td align=\"center\">81.5</td>\n<td align=\"center\">55.9</td>\n<td align=\"center\">62.6</td>\n</tr>\n</tr>\n<tr><td align=\"left\">ImageNet-1M, MoCo v2, 200ep</td>\n<td align=\"center\">82.4</td>\n<td align=\"center\">57.0</td>\n<td align=\"center\">63.6</td>\n</tr>\n</tr>\n<tr><td align=\"left\">ImageNet-1M, MoCo v2, 800ep</td>\n<td align=\"center\">82.5</td>\n<td align=\"center\">57.4</td>\n<td align=\"center\">64.0</td>\n</tr>\n</tbody></table>\n\n***Note:*** These results are means of 5 trials. Variation on Pascal VOC is large: the std of AP50, AP, AP75 is expected to be 0.2, 0.2, 0.4 in most cases. We recommend to run 5 trials and compute means.\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/detection/configs/Base-RCNN-C4-BN.yaml",
    "content": "MODEL:\n  META_ARCHITECTURE: \"GeneralizedRCNN\"\n  RPN:\n    PRE_NMS_TOPK_TEST: 6000\n    POST_NMS_TOPK_TEST: 1000\n  ROI_HEADS:\n    NAME: \"Res5ROIHeadsExtraNorm\"\n  BACKBONE:\n    FREEZE_AT: 0\n  RESNETS:\n    NORM: \"SyncBN\"\nTEST:\n  PRECISE_BN:\n    ENABLED: True\nSOLVER:\n  IMS_PER_BATCH: 16\n  BASE_LR: 0.02\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/detection/configs/coco_R_50_C4_2x.yaml",
    "content": "_BASE_: \"Base-RCNN-C4-BN.yaml\"\nMODEL:\n  MASK_ON: True\n  WEIGHTS: \"detectron2://ImageNetPretrained/MSRA/R-50.pkl\"\nINPUT:\n  MIN_SIZE_TRAIN: (640, 672, 704, 736, 768, 800)\n  MIN_SIZE_TEST: 800\nDATASETS:\n  TRAIN: (\"coco_2017_train\",)\n  TEST: (\"coco_2017_val\",)\nSOLVER:\n  STEPS: (120000, 160000)\n  MAX_ITER: 180000\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/detection/configs/coco_R_50_C4_2x_moco.yaml",
    "content": "_BASE_: \"coco_R_50_C4_2x.yaml\"\nMODEL:\n  PIXEL_MEAN: [123.675, 116.280, 103.530]\n  PIXEL_STD: [58.395, 57.120, 57.375]\n  WEIGHTS: \"See Instructions\"\n  RESNETS:\n    STRIDE_IN_1X1: False\nINPUT:\n  FORMAT: \"RGB\"\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/detection/configs/pascal_voc_R_50_C4_24k.yaml",
    "content": "_BASE_: \"Base-RCNN-C4-BN.yaml\"\nMODEL:\n  MASK_ON: False\n  WEIGHTS: \"detectron2://ImageNetPretrained/MSRA/R-50.pkl\"\n  ROI_HEADS:\n    NUM_CLASSES: 20\nINPUT:\n  MIN_SIZE_TRAIN: (480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800)\n  MIN_SIZE_TEST: 800\nDATASETS:\n  TRAIN: ('voc_2007_trainval', 'voc_2012_trainval')\n  TEST: ('voc_2007_test',)\nSOLVER:\n  STEPS: (18000, 22000)\n  MAX_ITER: 24000\n  WARMUP_ITERS: 100\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/detection/configs/pascal_voc_R_50_C4_24k_moco.yaml",
    "content": "_BASE_: \"pascal_voc_R_50_C4_24k.yaml\"\nMODEL:\n  PIXEL_MEAN: [123.675, 116.280, 103.530]\n  PIXEL_STD: [58.395, 57.120, 57.375]\n  WEIGHTS: \"See Instructions\"\n  RESNETS:\n    STRIDE_IN_1X1: False\nINPUT:\n  FORMAT: \"RGB\"\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/detection/convert-pretrain-to-detectron2.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n\nimport pickle as pkl\nimport sys\nimport torch\n\nif __name__ == \"__main__\":\n    input = sys.argv[1]\n\n    obj = torch.load(input, map_location=\"cpu\")\n    obj = obj[\"state_dict\"]\n\n    newmodel = {}\n    for k, v in obj.items():\n        if not k.startswith(\"module.encoder_q.\"):\n            continue\n        old_k = k\n        k = k.replace(\"module.encoder_q.\", \"\")\n        if \"layer\" not in k:\n            k = \"stem.\" + k\n        for t in [1, 2, 3, 4]:\n            k = k.replace(\"layer{}\".format(t), \"res{}\".format(t + 1))\n        for t in [1, 2, 3]:\n            k = k.replace(\"bn{}\".format(t), \"conv{}.norm\".format(t))\n        k = k.replace(\"downsample.0\", \"shortcut\")\n        k = k.replace(\"downsample.1\", \"shortcut.norm\")\n        print(old_k, \"->\", k)\n        newmodel[k] = v.numpy()\n\n    res = {\"model\": newmodel, \"__author__\": \"MOCO\", \"matching_heuristics\": True}\n\n    with open(sys.argv[2], \"wb\") as f:\n        pkl.dump(res, f)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/detection/train_net.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n\nimport os\n\nfrom detectron2.checkpoint import DetectionCheckpointer\nfrom detectron2.config import get_cfg\nfrom detectron2.engine import DefaultTrainer, default_argument_parser, default_setup, launch\nfrom detectron2.evaluation import COCOEvaluator, PascalVOCDetectionEvaluator\nfrom detectron2.layers import get_norm\nfrom detectron2.modeling.roi_heads import ROI_HEADS_REGISTRY, Res5ROIHeads\n\n\n@ROI_HEADS_REGISTRY.register()\nclass Res5ROIHeadsExtraNorm(Res5ROIHeads):\n    \"\"\"\n    As described in the MOCO paper, there is an extra BN layer\n    following the res5 stage.\n    \"\"\"\n    def _build_res5_block(self, cfg):\n        seq, out_channels = super()._build_res5_block(cfg)\n        norm = cfg.MODEL.RESNETS.NORM\n        norm = get_norm(norm, out_channels)\n        seq.add_module(\"norm\", norm)\n        return seq, out_channels\n\n\nclass Trainer(DefaultTrainer):\n    @classmethod\n    def build_evaluator(cls, cfg, dataset_name, output_folder=None):\n        if output_folder is None:\n            output_folder = os.path.join(cfg.OUTPUT_DIR, \"inference\")\n        if \"coco\" in dataset_name:\n            return COCOEvaluator(dataset_name, cfg, True, output_folder)\n        else:\n            assert \"voc\" in dataset_name\n            return PascalVOCDetectionEvaluator(dataset_name)\n\n\ndef setup(args):\n    cfg = get_cfg()\n    cfg.merge_from_file(args.config_file)\n    cfg.merge_from_list(args.opts)\n    cfg.freeze()\n    default_setup(cfg, args)\n    return cfg\n\n\ndef main(args):\n    cfg = setup(args)\n\n    if args.eval_only:\n        model = Trainer.build_model(cfg)\n        DetectionCheckpointer(model, save_dir=cfg.OUTPUT_DIR).resume_or_load(\n            cfg.MODEL.WEIGHTS, resume=args.resume\n        )\n        res = Trainer.test(cfg, model)\n        return res\n\n    trainer = Trainer(cfg)\n    trainer.resume_or_load(resume=args.resume)\n    return trainer.train()\n\n\nif __name__ == \"__main__\":\n    args = default_argument_parser().parse_args()\n    print(\"Command Line Args:\", args)\n    launch(\n        main,\n        args.num_gpus,\n        num_machines=args.num_machines,\n        machine_rank=args.machine_rank,\n        dist_url=args.dist_url,\n        args=(args,),\n    )\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/loader.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nfrom PIL import ImageFilter\nimport random\nimport cv2\n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n    def __init__(self, base_transform):\n        self.base_transform = base_transform\n\n    def __call__(self, x):\n        q = self.base_transform(x)\n        k = self.base_transform(x)\n        return [q, k]\n\n\nclass GaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, sigma=[.1, 2.]):\n        self.sigma = sigma\n\n    def __call__(self, x):\n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v2/main_lincls.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport argparse\nimport builtins\nimport os\nimport random\nimport shutil\nimport time\nimport warnings\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.parallel\nimport torch.backends.cudnn as cudnn\nimport torch.distributed as dist\nimport torch.optim\nimport torch.multiprocessing as mp\nimport torch.utils.data\nimport torch.utils.data.distributed\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\nimport torchvision.models as models\n\nmodel_names = sorted(name for name in models.__dict__\n    if name.islower() and not name.startswith(\"__\")\n    and callable(models.__dict__[name]))\n\nparser = argparse.ArgumentParser(description='PyTorch ImageNet Training')\nparser.add_argument('data', metavar='DIR',\n                    help='path to dataset')\nparser.add_argument('-a', '--arch', metavar='ARCH', default='resnet50',\n                    choices=model_names,\n                    help='model architecture: ' +\n                        ' | '.join(model_names) +\n                        ' (default: resnet50)')\nparser.add_argument('-j', '--workers', default=32, type=int, metavar='N',\n                    help='number of data loading workers (default: 32)')\nparser.add_argument('--epochs', default=100, type=int, metavar='N',\n                    help='number of total epochs to run')\nparser.add_argument('--start-epoch', default=0, type=int, metavar='N',\n                    help='manual epoch number (useful on restarts)')\nparser.add_argument('-b', '--batch-size', default=256, type=int,\n                    metavar='N',\n                    help='mini-batch size (default: 256), this is the total '\n                         'batch size of all GPUs on the current node when '\n                         'using Data Parallel or Distributed Data Parallel')\nparser.add_argument('--lr', '--learning-rate', default=30., type=float,\n                    metavar='LR', help='initial learning rate', dest='lr')\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by a ratio)')\nparser.add_argument('--momentum', default=0.9, type=float, metavar='M',\n                    help='momentum')\nparser.add_argument('--wd', '--weight-decay', default=0., type=float,\n                    metavar='W', help='weight decay (default: 0.)',\n                    dest='weight_decay')\nparser.add_argument('-p', '--print-freq', default=10, type=int,\n                    metavar='N', help='print frequency (default: 10)')\nparser.add_argument('--resume', default='', type=str, metavar='PATH',\n                    help='path to latest checkpoint (default: none)')\nparser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',\n                    help='evaluate model on validation set')\nparser.add_argument('--world-size', default=-1, type=int,\n                    help='number of nodes for distributed training')\nparser.add_argument('--rank', default=-1, type=int,\n                    help='node rank for distributed training')\nparser.add_argument('--dist-url', default='tcp://224.66.41.62:23456', type=str,\n                    help='url used to set up distributed training')\nparser.add_argument('--dist-backend', default='nccl', type=str,\n                    help='distributed backend')\nparser.add_argument('--seed', default=None, type=int,\n                    help='seed for initializing training. ')\nparser.add_argument('--gpu', default=None, type=int,\n                    help='GPU id to use.')\nparser.add_argument('--multiprocessing-distributed', action='store_true',\n                    help='Use multi-processing distributed training to launch '\n                         'N processes per node, which has N GPUs. This is the '\n                         'fastest way to use PyTorch for either single node or '\n                         'multi node data parallel training')\n\nparser.add_argument('--pretrained', default='', type=str,\n                    help='path to moco pretrained checkpoint')\n\nbest_acc1 = 0\n\n\ndef main():\n    args = parser.parse_args()\n\n    if args.seed is not None:\n        random.seed(args.seed)\n        torch.manual_seed(args.seed)\n        cudnn.deterministic = True\n        warnings.warn('You have chosen to seed training. '\n                      'This will turn on the CUDNN deterministic setting, '\n                      'which can slow down your training considerably! '\n                      'You may see unexpected behavior when restarting '\n                      'from checkpoints.')\n\n    if args.gpu is not None:\n        warnings.warn('You have chosen a specific GPU. This will completely '\n                      'disable data parallelism.')\n\n    if args.dist_url == \"env://\" and args.world_size == -1:\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n    args.distributed = args.world_size > 1 or args.multiprocessing_distributed\n\n    ngpus_per_node = torch.cuda.device_count()\n    if args.multiprocessing_distributed:\n        # Since we have ngpus_per_node processes per node, the total world_size\n        # needs to be adjusted accordingly\n        args.world_size = ngpus_per_node * args.world_size\n        # Use torch.multiprocessing.spawn to launch distributed processes: the\n        # main_worker process function\n        mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args))\n    else:\n        # Simply call main_worker function\n        main_worker(args.gpu, ngpus_per_node, args)\n\n\ndef main_worker(gpu, ngpus_per_node, args):\n    global best_acc1\n    args.gpu = gpu\n\n    # suppress printing if not master\n    if args.multiprocessing_distributed and args.gpu != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n\n    if args.gpu is not None:\n        print(\"Use GPU: {} for training\".format(args.gpu))\n\n    if args.distributed:\n        if args.dist_url == \"env://\" and args.rank == -1:\n            args.rank = int(os.environ[\"RANK\"])\n        if args.multiprocessing_distributed:\n            # For multiprocessing distributed training, rank needs to be the\n            # global rank among all the processes\n            args.rank = args.rank * ngpus_per_node + gpu\n        dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                world_size=args.world_size, rank=args.rank)\n    # create model\n    print(\"=> creating model '{}'\".format(args.arch))\n    model = models.__dict__[args.arch]()\n\n    # freeze all layers but the last fc\n    for name, param in model.named_parameters():\n        if name not in ['fc.weight', 'fc.bias']:\n            param.requires_grad = False\n    # init the fc layer\n    model.fc.weight.data.normal_(mean=0.0, std=0.01)\n    model.fc.bias.data.zero_()\n\n    # load from pre-trained, before DistributedDataParallel constructor\n    if args.pretrained:\n        if os.path.isfile(args.pretrained):\n            print(\"=> loading checkpoint '{}'\".format(args.pretrained))\n            checkpoint = torch.load(args.pretrained, map_location=\"cpu\")\n\n            # rename moco pre-trained keys\n            state_dict = checkpoint['state_dict']\n            for k in list(state_dict.keys()):\n                # retain only encoder_q up to before the embedding layer\n                if k.startswith('module.encoder_q') and not k.startswith('module.encoder_q.fc'):\n                    # remove prefix\n                    state_dict[k[len(\"module.encoder_q.\"):]] = state_dict[k]\n                # delete renamed or unused k\n                del state_dict[k]\n\n            args.start_epoch = 0\n            msg = model.load_state_dict(state_dict, strict=False)\n            assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\n\n            print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.pretrained))\n\n    if args.distributed:\n        # For multiprocessing distributed, DistributedDataParallel constructor\n        # should always set the single device scope, otherwise,\n        # DistributedDataParallel will use all available devices.\n        if args.gpu is not None:\n            torch.cuda.set_device(args.gpu)\n            model.cuda(args.gpu)\n            # When using a single GPU per process and per\n            # DistributedDataParallel, we need to divide the batch size\n            # ourselves based on the total number of GPUs we have\n            args.batch_size = int(args.batch_size / ngpus_per_node)\n            args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node)\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        else:\n            model.cuda()\n            # DistributedDataParallel will divide and allocate batch_size to all\n            # available GPUs if device_ids are not set\n            model = torch.nn.parallel.DistributedDataParallel(model)\n    elif args.gpu is not None:\n        torch.cuda.set_device(args.gpu)\n        model = model.cuda(args.gpu)\n    else:\n        # DataParallel will divide and allocate batch_size to all available GPUs\n        if args.arch.startswith('alexnet') or args.arch.startswith('vgg'):\n            model.features = torch.nn.DataParallel(model.features)\n            model.cuda()\n        else:\n            model = torch.nn.DataParallel(model).cuda()\n\n    # define loss function (criterion) and optimizer\n    criterion = nn.CrossEntropyLoss().cuda(args.gpu)\n\n    # optimize only the linear classifier\n    parameters = list(filter(lambda p: p.requires_grad, model.parameters()))\n    assert len(parameters) == 2  # fc.weight, fc.bias\n    optimizer = torch.optim.SGD(parameters, args.lr,\n                                momentum=args.momentum,\n                                weight_decay=args.weight_decay)\n\n    # optionally resume from a checkpoint\n    if args.resume:\n        if os.path.isfile(args.resume):\n            print(\"=> loading checkpoint '{}'\".format(args.resume))\n            if args.gpu is None:\n                checkpoint = torch.load(args.resume)\n            else:\n                # Map model to be loaded to specified single gpu.\n                loc = 'cuda:{}'.format(args.gpu)\n                checkpoint = torch.load(args.resume, map_location=loc)\n            args.start_epoch = checkpoint['epoch']\n            best_acc1 = checkpoint['best_acc1']\n            if args.gpu is not None:\n                # best_acc1 may be from a checkpoint from a different GPU\n                best_acc1 = best_acc1.to(args.gpu)\n            model.load_state_dict(checkpoint['state_dict'])\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            print(\"=> loaded checkpoint '{}' (epoch {})\"\n                  .format(args.resume, checkpoint['epoch']))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.resume))\n\n    cudnn.benchmark = True\n\n    # Data loading code\n    traindir = os.path.join(args.data, 'train')\n    valdir = os.path.join(args.data, 'val')\n    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                     std=[0.229, 0.224, 0.225])\n\n    train_dataset = datasets.ImageFolder(\n        traindir,\n        transforms.Compose([\n            transforms.RandomResizedCrop(224),\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            normalize,\n        ]))\n\n    if args.distributed:\n        train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)\n    else:\n        train_sampler = None\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None),\n        num_workers=args.workers, pin_memory=True, sampler=train_sampler)\n\n    val_loader = torch.utils.data.DataLoader(\n        datasets.ImageFolder(valdir, transforms.Compose([\n            transforms.Resize(256),\n            transforms.CenterCrop(224),\n            transforms.ToTensor(),\n            normalize,\n        ])),\n        batch_size=args.batch_size, shuffle=False,\n        num_workers=args.workers, pin_memory=True)\n\n    if args.evaluate:\n        validate(val_loader, model, criterion, args)\n        return\n\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            train_sampler.set_epoch(epoch)\n        adjust_learning_rate(optimizer, epoch, args)\n\n        # train for one epoch\n        train(train_loader, model, criterion, optimizer, epoch, args)\n\n        # evaluate on validation set\n        acc1 = validate(val_loader, model, criterion, args)\n\n        # remember best acc@1 and save checkpoint\n        is_best = acc1 > best_acc1\n        best_acc1 = max(acc1, best_acc1)\n\n        if not args.multiprocessing_distributed or (args.multiprocessing_distributed\n                and args.rank % ngpus_per_node == 0):\n            save_checkpoint({\n                'epoch': epoch + 1,\n                'arch': args.arch,\n                'state_dict': model.state_dict(),\n                'best_acc1': best_acc1,\n                'optimizer' : optimizer.state_dict(),\n            }, is_best)\n            if epoch == args.start_epoch:\n                sanity_check(model.state_dict(), args.pretrained)\n\n\ndef train(train_loader, model, criterion, optimizer, epoch, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    data_time = AverageMeter('Data', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(train_loader),\n        [batch_time, data_time, losses, top1, top5],\n        prefix=\"Epoch: [{}]\".format(epoch))\n\n    \"\"\"\n    Switch to eval mode:\n    Under the protocol of linear classification on frozen features/models,\n    it is not legitimate to change any part of the pre-trained model.\n    BatchNorm in train mode may revise running mean/std (even if it receives\n    no gradient), which are part of the model parameters too.\n    \"\"\"\n    model.eval()\n\n    end = time.time()\n    for i, (images, target) in enumerate(train_loader):\n        # measure data loading time\n        data_time.update(time.time() - end)\n\n        if args.gpu is not None:\n            images = images.cuda(args.gpu, non_blocking=True)\n        target = target.cuda(args.gpu, non_blocking=True)\n\n        # compute output\n        output = model(images)\n        loss = criterion(output, target)\n\n        # measure accuracy and record loss\n        acc1, acc5 = accuracy(output, target, topk=(1, 5))\n        losses.update(loss.item(), images.size(0))\n        top1.update(acc1[0], images.size(0))\n        top5.update(acc5[0], images.size(0))\n\n        # compute gradient and do SGD step\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        # measure elapsed time\n        batch_time.update(time.time() - end)\n        end = time.time()\n\n        if i % args.print_freq == 0:\n            progress.display(i)\n\n\ndef validate(val_loader, model, criterion, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(val_loader),\n        [batch_time, losses, top1, top5],\n        prefix='Test: ')\n\n    # switch to evaluate mode\n    model.eval()\n\n    with torch.no_grad():\n        end = time.time()\n        for i, (images, target) in enumerate(val_loader):\n            if args.gpu is not None:\n                images = images.cuda(args.gpu, non_blocking=True)\n            target = target.cuda(args.gpu, non_blocking=True)\n\n            # compute output\n            output = model(images)\n            loss = criterion(output, target)\n\n            # measure accuracy and record loss\n            acc1, acc5 = accuracy(output, target, topk=(1, 5))\n            losses.update(loss.item(), images.size(0))\n            top1.update(acc1[0], images.size(0))\n            top5.update(acc5[0], images.size(0))\n\n            # measure elapsed time\n            batch_time.update(time.time() - end)\n            end = time.time()\n\n            if i % args.print_freq == 0:\n                progress.display(i)\n\n        # TODO: this should also be done with the ProgressMeter\n        print(' * Acc@1 {top1.avg:.3f} Acc@5 {top5.avg:.3f}'\n              .format(top1=top1, top5=top5))\n\n    return top1.avg\n\n\ndef save_checkpoint(state, is_best, filename='checkpoint.pth.tar'):\n    torch.save(state, filename)\n    if is_best:\n        shutil.copyfile(filename, 'model_best.pth.tar')\n\n\ndef sanity_check(state_dict, pretrained_weights):\n    \"\"\"\n    Linear classifier should not change any weights other than the linear layer.\n    This sanity check asserts nothing wrong happens (e.g., BN stats updated).\n    \"\"\"\n    print(\"=> loading '{}' for sanity check\".format(pretrained_weights))\n    checkpoint = torch.load(pretrained_weights, map_location=\"cpu\")\n    state_dict_pre = checkpoint['state_dict']\n\n    for k in list(state_dict.keys()):\n        # only ignore fc layer\n        if 'fc.weight' in k or 'fc.bias' in k:\n            continue\n\n        # name in pretrained model\n        k_pre = 'module.encoder_q.' + k[len('module.'):] \\\n            if k.startswith('module.') else 'module.encoder_q.' + k\n\n        assert ((state_dict[k].cpu() == state_dict_pre[k_pre]).all()), \\\n            '{} is changed in linear classifier training.'.format(k)\n\n    print(\"=> sanity check passed.\")\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self, name, fmt=':f'):\n        self.name = name\n        self.fmt = fmt\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count\n\n    def __str__(self):\n        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'\n        return fmtstr.format(**self.__dict__)\n\n\nclass ProgressMeter(object):\n    def __init__(self, num_batches, meters, prefix=\"\"):\n        self.batch_fmtstr = self._get_batch_fmtstr(num_batches)\n        self.meters = meters\n        self.prefix = prefix\n\n    def display(self, batch):\n        entries = [self.prefix + self.batch_fmtstr.format(batch)]\n        entries += [str(meter) for meter in self.meters]\n        print('\\t'.join(entries))\n\n    def _get_batch_fmtstr(self, num_batches):\n        num_digits = len(str(num_batches // 1))\n        fmt = '{:' + str(num_digits) + 'd}'\n        return '[' + fmt + '/' + fmt.format(num_batches) + ']'\n\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    for milestone in args.schedule:\n        lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef accuracy(output, target, topk=(1,)):\n    \"\"\"Computes the accuracy over the k top predictions for the specified values of k\"\"\"\n    with torch.no_grad():\n        maxk = max(topk)\n        batch_size = target.size(0)\n\n        _, pred = output.topk(maxk, 1, True, True)\n        pred = pred.t()\n        correct = pred.eq(target.view(1, -1).expand_as(pred))\n\n        res = []\n        for k in topk:\n            correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)\n            res.append(correct_k.mul_(100.0 / batch_size))\n        return res\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v3/__init__.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v3/builder.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport torch\nimport torch.nn as nn\n\n\nclass MoCo(nn.Module):\n    \"\"\"\n    Build a MoCo model with a base encoder, a momentum encoder, and two MLPs\n    https://arxiv.org/abs/1911.05722\n    \"\"\"\n    def __init__(self, base_encoder, dim=256, mlp_dim=4096, T=1.0):\n        \"\"\"\n        dim: feature dimension (default: 256)\n        mlp_dim: hidden dimension in MLPs (default: 4096)\n        T: softmax temperature (default: 1.0)\n        \"\"\"\n        super(MoCo, self).__init__()\n\n        self.T = T\n\n        # build encoders\n        self.base_encoder = base_encoder(num_classes=mlp_dim)\n        self.momentum_encoder = base_encoder(num_classes=mlp_dim)\n\n        self._build_projector_and_predictor_mlps(dim, mlp_dim)\n\n        for param_b, param_m in zip(self.base_encoder.parameters(), self.momentum_encoder.parameters()):\n            param_m.data.copy_(param_b.data)  # initialize\n            param_m.requires_grad = False  # not update by gradient\n\n    def _build_mlp(self, num_layers, input_dim, mlp_dim, output_dim, last_bn=True):\n        mlp = []\n        for l in range(num_layers):\n            dim1 = input_dim if l == 0 else mlp_dim\n            dim2 = output_dim if l == num_layers - 1 else mlp_dim\n\n            mlp.append(nn.Linear(dim1, dim2, bias=False))\n\n            if l < num_layers - 1:\n                mlp.append(nn.BatchNorm1d(dim2))\n                mlp.append(nn.ReLU(inplace=True))\n            elif last_bn:\n                # follow SimCLR's design: https://github.com/google-research/simclr/blob/master/model_util.py#L157\n                # for simplicity, we further removed gamma in BN\n                mlp.append(nn.BatchNorm1d(dim2, affine=False))\n\n        return nn.Sequential(*mlp)\n\n    def _build_projector_and_predictor_mlps(self, dim, mlp_dim):\n        pass\n\n    @torch.no_grad()\n    def _update_momentum_encoder(self, m):\n        \"\"\"Momentum update of the momentum encoder\"\"\"\n        for param_b, param_m in zip(self.base_encoder.parameters(), self.momentum_encoder.parameters()):\n            param_m.data = param_m.data * m + param_b.data * (1. - m)\n\n    def contrastive_loss(self, q, k):\n        # normalize\n        q = nn.functional.normalize(q, dim=1)\n        k = nn.functional.normalize(k, dim=1)\n        # gather all targets\n        k = concat_all_gather(k)\n        # Einstein sum is more intuitive\n        logits = torch.einsum('nc,mc->nm', [q, k]) / self.T\n        N = logits.shape[0]  # batch size per GPU\n        labels = (torch.arange(N, dtype=torch.long) + N * torch.distributed.get_rank()).cuda()\n        return nn.CrossEntropyLoss()(logits, labels) * (2 * self.T)\n\n    def forward(self, x1, x2, m):\n        \"\"\"\n        Input:\n            x1: first views of images\n            x2: second views of images\n            m: moco momentum\n        Output:\n            loss\n        \"\"\"\n\n        # compute features\n        q1 = self.predictor(self.base_encoder(x1))\n        q2 = self.predictor(self.base_encoder(x2))\n\n        with torch.no_grad():  # no gradient\n            self._update_momentum_encoder(m)  # update the momentum encoder\n\n            # compute momentum features as targets\n            k1 = self.momentum_encoder(x1)\n            k2 = self.momentum_encoder(x2)\n\n        return self.contrastive_loss(q1, k2) + self.contrastive_loss(q2, k1)\n\n\nclass MoCo_ResNet(MoCo):\n    def _build_projector_and_predictor_mlps(self, dim, mlp_dim):\n        hidden_dim = self.base_encoder.fc.weight.shape[1]\n        del self.base_encoder.fc, self.momentum_encoder.fc # remove original fc layer\n\n        # projectors\n        self.base_encoder.fc = self._build_mlp(2, hidden_dim, mlp_dim, dim)\n        self.momentum_encoder.fc = self._build_mlp(2, hidden_dim, mlp_dim, dim)\n\n        # predictor\n        self.predictor = self._build_mlp(2, dim, mlp_dim, dim, False)\n\n\nclass MoCo_ViT(MoCo):\n    def _build_projector_and_predictor_mlps(self, dim, mlp_dim):\n        hidden_dim = self.base_encoder.head.weight.shape[1]\n        del self.base_encoder.head, self.momentum_encoder.head # remove original fc layer\n\n        # projectors\n        self.base_encoder.head = self._build_mlp(3, hidden_dim, mlp_dim, dim)\n        self.momentum_encoder.head = self._build_mlp(3, hidden_dim, mlp_dim, dim)\n\n        # predictor\n        self.predictor = self._build_mlp(2, dim, mlp_dim, dim)\n\n\n# utils\n@torch.no_grad()\ndef concat_all_gather(tensor):\n    \"\"\"\n    Performs all_gather operation on the provided tensors.\n    *** Warning ***: torch.distributed.all_gather has no gradient.\n    \"\"\"\n    tensors_gather = [torch.ones_like(tensor)\n        for _ in range(torch.distributed.get_world_size())]\n    torch.distributed.all_gather(tensors_gather, tensor, async_op=False)\n\n    output = torch.cat(tensors_gather, dim=0)\n    return output\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v3/loader.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nfrom PIL import Image, ImageFilter, ImageOps\nimport math\nimport random\nimport torchvision.transforms.functional as tf\n\nimport cv2\n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image\"\"\"\n\n    def __init__(self, base_transform1, base_transform2):\n        self.base_transform1 = base_transform1\n        self.base_transform2 = base_transform2\n\n    def __call__(self, x):\n        im1 = self.base_transform1(x)\n        im2 = self.base_transform2(x)\n        return [im1, im2]\n\n\nclass GaussianBlur(object):\n    \"\"\"Gaussian blur augmentation from SimCLR: https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, sigma=[.1, 2.]):\n        self.sigma = sigma\n\n    def __call__(self, x):\n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)\n\n\nclass Solarize(object):\n    \"\"\"Solarize augmentation from BYOL: https://arxiv.org/abs/2006.07733\"\"\"\n\n    def __call__(self, x):\n        return ImageOps.solarize(x)\n        \n        \n        \n        \n        \nclass cvGaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, p=0.5, sigma=[.1, 2.]):\n        self.sigma = sigma\n        self.prob = p\n\n    def __call__(self, x):\n        do_it = random.random() <= self.prob\n        if not do_it:\n            return x        \n    \n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v3/optimizer.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport torch\n\n\nclass LARS(torch.optim.Optimizer):\n    \"\"\"\n    LARS optimizer, no rate scaling or weight decay for parameters <= 1D.\n    \"\"\"\n    def __init__(self, params, lr=0, weight_decay=0, momentum=0.9, trust_coefficient=0.001):\n        defaults = dict(lr=lr, weight_decay=weight_decay, momentum=momentum, trust_coefficient=trust_coefficient)\n        super().__init__(params, defaults)\n\n    @torch.no_grad()\n    def step(self):\n        for g in self.param_groups:\n            for p in g['params']:\n                dp = p.grad\n\n                if dp is None:\n                    continue\n\n                if p.ndim > 1: # if not normalization gamma/beta or bias\n                    dp = dp.add(p, alpha=g['weight_decay'])\n                    param_norm = torch.norm(p)\n                    update_norm = torch.norm(dp)\n                    one = torch.ones_like(param_norm)\n                    q = torch.where(param_norm > 0.,\n                                    torch.where(update_norm > 0,\n                                    (g['trust_coefficient'] * param_norm / update_norm), one),\n                                    one)\n                    dp = dp.mul(q)\n\n                param_state = self.state[p]\n                if 'mu' not in param_state:\n                    param_state['mu'] = torch.zeros_like(p)\n                mu = param_state['mu']\n                mu.mul_(g['momentum']).add_(dp)\n                p.add_(mu, alpha=-g['lr'])\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/moco_v3/vits.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport math\nimport torch\nimport torch.nn as nn\nfrom functools import partial, reduce\nfrom operator import mul\n\nfrom timm.models.vision_transformer import VisionTransformer, _cfg\nfrom timm.models.layers.helpers import to_2tuple\nfrom timm.models.layers import PatchEmbed\n\n__all__ = [\n    'vit_small', \n    'vit_base',\n    'vit_conv_small',\n    'vit_conv_base',\n]\n\n\nclass VisionTransformerMoCo(VisionTransformer):\n    def __init__(self, stop_grad_conv1=False, **kwargs):\n        super().__init__(**kwargs)\n        # Use fixed 2D sin-cos position embedding\n        self.build_2d_sincos_position_embedding()\n\n        # weight initialization\n        for name, m in self.named_modules():\n            if isinstance(m, nn.Linear):\n                if 'qkv' in name:\n                    # treat the weights of Q, K, V separately\n                    val = math.sqrt(6. / float(m.weight.shape[0] // 3 + m.weight.shape[1]))\n                    nn.init.uniform_(m.weight, -val, val)\n                else:\n                    nn.init.xavier_uniform_(m.weight)\n                nn.init.zeros_(m.bias)\n        nn.init.normal_(self.cls_token, std=1e-6)\n\n        if isinstance(self.patch_embed, PatchEmbed):\n            # xavier_uniform initialization\n            val = math.sqrt(6. / float(3 * reduce(mul, self.patch_embed.patch_size, 1) + self.embed_dim))\n            nn.init.uniform_(self.patch_embed.proj.weight, -val, val)\n            nn.init.zeros_(self.patch_embed.proj.bias)\n\n            if stop_grad_conv1:\n                self.patch_embed.proj.weight.requires_grad = False\n                self.patch_embed.proj.bias.requires_grad = False\n\n    def build_2d_sincos_position_embedding(self, temperature=10000.):\n        h, w = self.patch_embed.grid_size\n        grid_w = torch.arange(w, dtype=torch.float32)\n        grid_h = torch.arange(h, dtype=torch.float32)\n        grid_w, grid_h = torch.meshgrid(grid_w, grid_h)\n        assert self.embed_dim % 4 == 0, 'Embed dimension must be divisible by 4 for 2D sin-cos position embedding'\n        pos_dim = self.embed_dim // 4\n        omega = torch.arange(pos_dim, dtype=torch.float32) / pos_dim\n        omega = 1. / (temperature**omega)\n        out_w = torch.einsum('m,d->md', [grid_w.flatten(), omega])\n        out_h = torch.einsum('m,d->md', [grid_h.flatten(), omega])\n        pos_emb = torch.cat([torch.sin(out_w), torch.cos(out_w), torch.sin(out_h), torch.cos(out_h)], dim=1)[None, :, :]\n\n        assert self.num_tokens == 1, 'Assuming one and only one token, [cls]'\n        pe_token = torch.zeros([1, 1, self.embed_dim], dtype=torch.float32)\n        self.pos_embed = nn.Parameter(torch.cat([pe_token, pos_emb], dim=1))\n        self.pos_embed.requires_grad = False\n\n\nclass ConvStem(nn.Module):\n    \"\"\" \n    ConvStem, from Early Convolutions Help Transformers See Better, Tete et al. https://arxiv.org/abs/2106.14881\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768, norm_layer=None, flatten=True):\n        super().__init__()\n\n        assert patch_size == 16, 'ConvStem only supports patch size of 16'\n        assert embed_dim % 8 == 0, 'Embed dimension must be divisible by 8 for ConvStem'\n\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.grid_size = (img_size[0] // patch_size[0], img_size[1] // patch_size[1])\n        self.num_patches = self.grid_size[0] * self.grid_size[1]\n        self.flatten = flatten\n\n        # build stem, similar to the design in https://arxiv.org/abs/2106.14881\n        stem = []\n        input_dim, output_dim = 3, embed_dim // 8\n        for l in range(4):\n            stem.append(nn.Conv2d(input_dim, output_dim, kernel_size=3, stride=2, padding=1, bias=False))\n            stem.append(nn.BatchNorm2d(output_dim))\n            stem.append(nn.ReLU(inplace=True))\n            input_dim = output_dim\n            output_dim *= 2\n        stem.append(nn.Conv2d(input_dim, embed_dim, kernel_size=1))\n        self.proj = nn.Sequential(*stem)\n\n        self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n        assert H == self.img_size[0] and W == self.img_size[1], \\\n            f\"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]}).\"\n        x = self.proj(x)\n        if self.flatten:\n            x = x.flatten(2).transpose(1, 2)  # BCHW -> BNC\n        x = self.norm(x)\n        return x\n\n## original moco_v3 has 12 num_heads\ndef vit_small(**kwargs):\n    model = VisionTransformerMoCo(\n        patch_size=16, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\ndef vit_base(**kwargs):\n    model = VisionTransformerMoCo(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\ndef vit_conv_small(**kwargs):\n    # minus one ViT block\n    model = VisionTransformerMoCo(\n        patch_size=16, embed_dim=384, depth=11, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), embed_layer=ConvStem, **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\ndef vit_conv_base(**kwargs):\n    # minus one ViT block\n    model = VisionTransformerMoCo(\n        patch_size=16, embed_dim=768, depth=11, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), embed_layer=ConvStem, **kwargs)\n    model.default_cfg = _cfg()\n    return model"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/rs_transforms_float32.py",
    "content": "import numpy as np\nimport torch\nimport random\n\n\n\nclass RandomBrightness(object):\n    \"\"\" Random Brightness \"\"\"\n    \n    def __init__(self, brightness=0.4):\n        self.brightness = brightness\n\n    def __call__(self, sample):\n        s = np.random.uniform(max(0, 1 - self.brightness), 1 + self.brightness)\n        img = sample * s\n        \n        return img\n    \nclass RandomContrast(object):\n    \"\"\" Random Contrast \"\"\"\n    \n    def __init__(self, contrast=0.4):\n        self.contrast = contrast\n\n    def __call__(self, sample):\n        s = np.random.uniform(max(0, 1 - self.contrast), 1 + self.contrast)\n        mean = np.mean(sample, axis=(0, 1))\n        \n        return ((sample - mean) * s + mean)\n    \nclass ToGray(object):\n    def __init__(self, out_channels):\n        self.out_channels = out_channels\n    def __call__(self,sample):\n        gray_img = np.mean(sample, axis=-1)\n        gray_img = np.tile(gray_img, (self.out_channels, 1, 1))\n        gray_img = np.transpose(gray_img, [1, 2, 0])\n        return gray_img\n        \n        \nclass RandomChannelDrop(object):\n    \"\"\" Random Channel Drop \"\"\"\n    \n    def __init__(self, min_n_drop=1, max_n_drop=8):\n        self.min_n_drop = min_n_drop\n        self.max_n_drop = max_n_drop\n\n    def __call__(self, sample):\n        n_channels = random.randint(self.min_n_drop, self.max_n_drop)\n        channels = np.random.choice(range(sample.shape[0]), size=n_channels, replace=False)\n\n        for c in channels:\n            sample[c, :, :] = 0        \n        return sample        \n\n\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/models/rs_transforms_uint8.py",
    "content": "import numpy as np\nimport torch\nimport random\nimport cv2\n\n\nclass RandomBrightness(object):\n    \"\"\" Random Brightness \"\"\"\n    \n    def __init__(self, brightness=0.4):\n        self.brightness = brightness\n\n    def __call__(self, sample):\n        s = np.random.uniform(max(0, 1 - self.brightness), 1 + self.brightness)\n        img = sample * s\n        \n        return img.astype(np.uint8)\n    \nclass RandomContrast(object):\n    \"\"\" Random Contrast \"\"\"\n    \n    def __init__(self, contrast=0.4):\n        self.contrast = contrast\n\n    def __call__(self, sample):\n        s = np.random.uniform(max(0, 1 - self.contrast), 1 + self.contrast)\n        mean = np.mean(sample, axis=(0, 1))\n        \n        return ((sample - mean) * s + mean).astype(np.uint8)\n    \nclass ToGray(object):\n    def __init__(self, out_channels):\n        self.out_channels = out_channels\n    def __call__(self,sample):\n        gray_img = np.mean(sample, axis=-1)\n        gray_img = np.tile(gray_img, (self.out_channels, 1, 1))\n        gray_img = np.transpose(gray_img, [1, 2, 0])\n        return gray_img.astype(np.uint8)\n        \n        \nclass RandomChannelDrop(object):\n    \"\"\" Random Channel Drop \"\"\"\n    \n    def __init__(self, min_n_drop=1, max_n_drop=8):\n        self.min_n_drop = min_n_drop\n        self.max_n_drop = max_n_drop\n\n    def __call__(self, sample):\n        n_channels = random.randint(self.min_n_drop, self.max_n_drop)\n        channels = np.random.choice(range(sample.shape[0]), size=n_channels, replace=False)\n\n        for c in channels:\n            sample[c, :, :] = 0        \n        return sample        \n\n\nclass GaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, sigma=[.1, 2.]):\n        self.sigma = sigma\n\n    def __call__(self, x):\n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)\n        \n        \nclass Solarize(object):\n\n    def __init__(self, threshold=0.5):\n        self.threshold = threshold\n        \n    def __call__(self, x):\n        x1 = x.copy()          \n        one = np.ones(x.shape) * 255\n        x1[x<self.threshold] = one[x<self.threshold] - x[x<self.threshold]\n        \n        return x1.astype(np.uint8)\n        \nclass RandomSensorDrop_S1S2(object):\n    \"\"\" Random Channel Drop \"\"\"\n    \n    def __init__(self):\n        pass\n\n    def __call__(self, sample):\n        sensor = np.random.choice([1,2], replace=False)\n\n        if sensor==2:\n            sample[:13, :, :] = 0\n        elif sensor==1:\n            sample[13:,:,:] = 0\n        \n        return sample\n    \nclass SensorDrop_S1S2(object):\n    def __init__(self, sensor):\n        self.sensor = sensor\n    def __call__(self,sample):\n        if self.sensor == 'S1':\n            sample[13:,:,:] = 0\n        elif self.sensor == 'S2':\n            sample[:13,:,:] = 0\n        return sample\n    \n    \nclass RandomSensorDrop_RGBD(object):\n    \"\"\" Random Channel Drop \"\"\"\n    \n    def __init__(self):\n        pass\n\n    def __call__(self, sample):\n        sensor = np.random.choice([1,2], replace=False, p=[0.8,0.2])\n\n        if sensor==2:\n            sample[:3, :, :] = 0\n        elif sensor==1:\n            sample[3:,:,:] = 0\n        \n        return sample\n    \nclass SensorDrop_RGBD(object):\n    def __init__(self, sensor):\n        self.sensor = sensor\n    def __call__(self,sample):\n        if self.sensor == 'D':\n            sample[3:,:,:] = 0\n        elif self.sensor == 'RGB':\n            sample[:3,:,:] = 0\n        return sample"
  },
  {
    "path": "src/benchmark/pretrain_ssl/pretrain_data2vec.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\nimport timm\nfrom pathlib import Path\n\nfrom timm.models import create_model\nfrom timm.utils import ModelEmaV2\n\nfrom models.data2vec.optim_factory import create_optimizer\n\nfrom models.data2vec.datasets import build_beit_pretraining_dataset\nfrom models.data2vec.engine_for_cyclical import train_one_epoch\nfrom models.data2vec.utils import NativeScalerWithGradNormCount as NativeScaler\nimport models.data2vec.utils as utils\nfrom scipy import interpolate\nimport models.data2vec.modeling_cyclical as modeling_cyclical\n#from models import beit_base_patch16_224\n\n\ndef get_args():\n    print(timm.__version__)\n    print(torch.__version__)\n    parser = argparse.ArgumentParser(\"BEiT pre-training script\", add_help=False)\n    parser.add_argument(\"--batch_size\", default=64, type=int)\n    parser.add_argument(\"--epochs\", default=300, type=int)\n    parser.add_argument(\"--save_ckpt_freq\", default=10, type=int)\n    # Model parameters\n    parser.add_argument(\n        \"--model\",\n        default=\"deit_base_patch16_224\",\n        type=str,\n        metavar=\"MODEL\",\n        help=\"Name of model to train\",\n    )\n    parser.add_argument(\"--rel_pos_bias\", action=\"store_true\")\n    parser.add_argument(\n        \"--disable_rel_pos_bias\", action=\"store_false\", dest=\"rel_pos_bias\"\n    )\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument(\"--abs_pos_emb\", action=\"store_true\")\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument(\n        \"--layer_scale_init_value\",\n        default=0.1,\n        type=float,\n        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\",\n    )\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=75,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n\n    parser.add_argument(\n        \"--input_size\", default=224, type=int, help=\"images input size for backbone\"\n    )\n\n    parser.add_argument(\n        \"--drop_path\",\n        type=float,\n        default=0.1,\n        metavar=\"PCT\",\n        help=\"Drop path rate (default: 0.1)\",\n    )\n\n    # Optimizer parameters\n    parser.add_argument(\n        \"--opt\",\n        default=\"adamw\",\n        type=str,\n        metavar=\"OPTIMIZER\",\n        help='Optimizer (default: \"adamw\"',\n    )\n    parser.add_argument(\n        \"--opt_eps\",\n        default=1e-8,\n        type=float,\n        metavar=\"EPSILON\",\n        help=\"Optimizer Epsilon (default: 1e-8)\",\n    )\n    parser.add_argument(\n        \"--opt_betas\",\n        default=None,\n        type=float,\n        nargs=\"+\",\n        metavar=\"BETA\",\n        help=\"Optimizer Betas (default: None, use opt default)\",\n    )\n    parser.add_argument(\n        \"--clip_grad\",\n        type=float,\n        default=None,\n        metavar=\"NORM\",\n        help=\"Clip gradient norm (default: None, no clipping)\",\n    )\n    parser.add_argument(\n        \"--momentum\",\n        type=float,\n        default=0.9,\n        metavar=\"M\",\n        help=\"SGD momentum (default: 0.9)\",\n    )\n    parser.add_argument(\n        \"--weight_decay\", type=float, default=0.05, help=\"weight decay (default: 0.05)\"\n    )\n    parser.add_argument(\n        \"--weight_decay_end\",\n        type=float,\n        default=None,\n        help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD. \n        (Set the same value with args.weight_decay to keep weight decay no change)\"\"\",\n    )\n\n    parser.add_argument(\n        \"--lr\",\n        type=float,\n        default=5e-4,\n        metavar=\"LR\",\n        help=\"learning rate (default: 5e-4)\",\n    )\n    parser.add_argument(\n        \"--warmup_lr\",\n        type=float,\n        default=1e-6,\n        metavar=\"LR\",\n        help=\"warmup learning rate (default: 1e-6)\",\n    )\n    parser.add_argument(\n        \"--min_lr\",\n        type=float,\n        default=1e-5,\n        metavar=\"LR\",\n        help=\"lower lr bound for cyclic schedulers that hit 0 (1e-5)\",\n    )\n\n    parser.add_argument(\n        \"--tri_phase_schedule\",\n        type=str,\n        default=None,\n        help=\"string containing a tuple with phase ratios for warmup and decay. e.g. '(0.05,0.15) means 5% warmup, 80% hold, 15% decay\",\n    )\n\n    parser.add_argument(\n        \"--warmup_epochs\",\n        type=int,\n        default=5,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n    parser.add_argument(\n        \"--warmup_steps\",\n        type=int,\n        default=-1,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n\n    # Augmentation parameters\n    parser.add_argument(\n        \"--color_jitter\",\n        type=float,\n        default=0.4,\n        metavar=\"PCT\",\n        help=\"Color jitter factor (default: 0.4)\",\n    )\n    parser.add_argument(\n        \"--train_interpolation\",\n        type=str,\n        default=\"bicubic\",\n        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")',\n    )\n    parser.add_argument(\"--aug_level\", default=0, type=int)\n\n\n    parser.add_argument(\n        \"--target_layers\", type=str, default=\"[]\", help=\"target layers (python list)\"\n    )\n\n    # Dataset parameters\n    parser.add_argument(\n        \"--data_path\",\n        default=\"/datasets01/imagenet_full_size/061417/\",\n        type=str,\n        help=\"dataset path\",\n    )\n    parser.add_argument(\n        \"--imagenet_default_mean_and_std\", default=False, action=\"store_true\"\n    )\n\n    parser.add_argument(\n        \"--output_dir\", default=\"\", help=\"path where to save, empty for no saving\"\n    )\n    parser.add_argument(\"--log_dir\", default=None, help=\"path where to tensorboard log\")\n    parser.add_argument(\n        \"--device\", default=\"cuda\", help=\"device to use for training / testing\"\n    )\n    parser.add_argument(\"--seed\", default=0, type=int)\n    parser.add_argument(\"--resume\", default=\"\", help=\"resume from checkpoint\")\n    parser.add_argument(\"--auto_resume\", action=\"store_true\")\n    parser.add_argument(\"--no_auto_resume\", action=\"store_false\", dest=\"auto_resume\")\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument(\"--ema_decay_init\", default=0.999, type=float)\n    parser.add_argument(\"--ema_decay\", default=0.9998, type=float)\n    parser.add_argument(\"--ema_start_at\", default=25000, type=int)\n\n    parser.add_argument(\n        \"--start_epoch\", default=0, type=int, metavar=\"N\", help=\"start epoch\"\n    )\n    parser.add_argument(\"--num_workers\", default=10, type=int)\n    parser.add_argument(\n        \"--pin_mem\",\n        action=\"store_true\",\n        help=\"Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.\",\n    )\n    parser.add_argument(\"--no_pin_mem\", action=\"store_false\", dest=\"pin_mem\", help=\"\")\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument(\n        \"--world_size\", default=1, type=int, help=\"number of distributed processes\"\n    )\n    parser.add_argument(\"--local_rank\", default=-1, type=int)\n    parser.add_argument(\"--dist_on_itp\", action=\"store_true\")\n    parser.add_argument(\n        \"--dist_url\", default=\"env://\", help=\"url used to set up distributed training\"\n    )\n\n    parser.add_argument(\"--seed_model\", default=None, type=str, help=\"seed model\")\n    parser.add_argument(\"--model_key\", default=\"model|module\", type=str)\n    parser.add_argument(\"--model_prefix\", default=\"\", type=str)\n\n    parser.add_argument(\"--l2_loss\", default=False, action=\"store_true\")\n    parser.add_argument(\"--l1_beta\", default=0.12, type=float)\n\n    parser.add_argument(\"--layer_results\", default=\"end\", type=str)\n\n    parser.add_argument(\"--var_w0\", default=0., type=float)\n    parser.add_argument(\"--var_w1\", default=0., type=float)\n    parser.add_argument(\"--var_margin0\", default=0.5, type=float)\n    parser.add_argument(\"--var_margin1\", default=0.5, type=float)\n    parser.add_argument(\"--skip_ema_during_lr_decay_for_tri\", action=\"store_true\")\n    parser.add_argument(\"--loss_scale\", default=-1, type=float)\n    parser.add_argument(\"--ema_annealing_till_end\", default=False, action=\"store_true\")\n    parser.add_argument(\"--attn_drop_rate\", default=0.0, type=float)\n    parser.add_argument(\"--mask_dropout_prob\", default=-1.0, type=float, help=\"prob of flipping already masked position to unmasked\")\n\n    #target_layer_norm_last=True, target_batch_norm=False, target_instance_norm=False\n    parser.add_argument(\"--no_target_layer_norm_last\", default=False, action=\"store_true\")\n    parser.add_argument(\"--target_batch_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--target_instance_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--post_target_instance_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--post_target_layer_norm\", default=False, action=\"store_true\")\n    \n    \n    parser.add_argument('--mode', nargs='*', default=['s2c'])\n    parser.add_argument('--dtype', type=str, default='uint8')\n    parser.add_argument('--season', type=str, default='random')\n    parser.add_argument('--in_size', type=int, default=224)\n    \n    parser.add_argument('--crop-min', default=0.2, type=float,\n                    help='minimum scale for random cropping (default: 0.08)')\n\n    parser.add_argument('--bands', type=str, default='all', help=\"input bands\")\n    parser.add_argument(\"--lmdb\", action='store_true', help=\"use lmdb dataset\")\n\n    return parser.parse_args()\n\n\ndef get_model(args):\n    print(f\"Creating model: {args.model}\")\n    if args.model == 'beit_base_patch16_224' and False:\n        model = beit_base_patch16_224(drop_path_rate=args.drop_path,\n        #drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        attn_drop_rate=args.attn_drop_rate)\n    \n    model = create_model(\n        args.model,\n        pretrained=False,\n        drop_path_rate=args.drop_path,\n        drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        attn_drop_rate=args.attn_drop_rate,\n    )\n\n    return model\n\n\ndef main(args):\n    utils.init_distributed_mode(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    model = get_model(args)\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (\n        args.input_size // patch_size[0],\n        args.input_size // patch_size[1],\n    )\n    args.patch_size = patch_size\n\n    if args.seed_model:\n        checkpoint = torch.load(args.seed_model, map_location=\"cpu\")\n        print(\"Load ckpt from %s\" % args.seed_model)\n\n        checkpoint_model = None\n        for model_key in args.model_key.split(\"|\"):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in [\"head.weight\", \"head.bias\"]:\n            if (\n                k in checkpoint_model\n                and checkpoint_model[k].shape != state_dict[k].shape\n            ):\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (\n                    dst_patch_shape[1] * 2 - 1\n                )\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\n                        \"Position interpolate for %s from %dx%d to %dx%d\"\n                        % (key, src_size, src_size, dst_size, dst_size)\n                    )\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind=\"cubic\")\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy))\n                            .contiguous()\n                            .view(-1, 1)\n                            .to(rel_pos_bias.device)\n                        )\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if \"pos_embed\" in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model[\"pos_embed\"]\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\n                    \"Position interpolate from %dx%d to %dx%d\"\n                    % (orig_size, orig_size, new_size, new_size)\n                )\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(\n                    -1, orig_size, orig_size, embedding_size\n                ).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens,\n                    size=(new_size, new_size),\n                    mode=\"bicubic\",\n                    align_corners=False,\n                )\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model[\"pos_embed\"] = new_pos_embed\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n\n    # get dataset\n    \n    \n    dataset_train = build_beit_pretraining_dataset(args)\n    print(dataset_train)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_rank = global_rank\n        num_training_steps_per_epoch = (\n            len(dataset_train) // args.batch_size // num_tasks\n        )\n\n        print(\"pre-sampler\", num_tasks, global_rank, sampler_rank)\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=sampler_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train,\n        sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    model.to(device)\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print(\"number of params:\", n_parameters)\n\n    model_ema = ModelEmaV2(model, decay=args.ema_decay)\n    print(\"Using EMA with decay = %.8f\" % args.ema_decay)\n\n    total_batch_size = args.batch_size * utils.get_world_size()\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Number of training steps = %d\" % num_training_steps_per_epoch)\n    print(\n        \"Number of training examples per epoch = %d\"\n        % (total_batch_size * num_training_steps_per_epoch)\n    )\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(\n            model, device_ids=[args.gpu], find_unused_parameters=True\n        )\n        model_without_ddp = model.module\n\n    optimizer = create_optimizer(args, model_without_ddp)\n    loss_scaler = NativeScaler()\n\n    start_lr_decay_at_step = -1\n    if args.tri_phase_schedule is not None:\n        from ast import literal_eval\n        warmup_phase, decay_phase = literal_eval(args.tri_phase_schedule)\n        print(\"Use tri phase lr schedule!\", warmup_phase, decay_phase)\n        lr_schedule_values = utils.tri_phase_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_perc=warmup_phase,\n            decay_perc=decay_phase,\n        )\n        if args.skip_ema_during_lr_decay_for_tri:\n            start_lr_decay_at_step= (1-decay_phase)*args.epochs*num_training_steps_per_epoch\n            print(\"ema will be skipped after \"+str(start_lr_decay_at_step)+\" updates\")\n    else:\n        print(\"Use step level LR & WD scheduler!\")\n        lr_schedule_values = utils.cosine_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_epochs=args.warmup_epochs,\n            warmup_steps=args.warmup_steps,\n        )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay,\n        args.weight_decay_end,\n        args.epochs,\n        num_training_steps_per_epoch,\n    )\n    print(\n        \"Max WD = %.7f, Min WD = %.7f\"\n        % (max(wd_schedule_values), min(wd_schedule_values))\n    )\n\n    utils.auto_load_model(\n        args=args,\n        model=model,\n        model_without_ddp=model_without_ddp,\n        optimizer=optimizer,\n        loss_scaler=loss_scaler,\n        model_ema=model_ema,\n    )\n\n    from ast import literal_eval\n\n    target_layers = literal_eval(args.target_layers)\n    assert len(target_layers) > 0\n    print(f\"target layers: {target_layers}\")\n\n    print(f\"Start training for {args.epochs} epochs\")\n\n    if args.ema_annealing_till_end:\n        args.ema_start_at = args.epochs * num_training_steps_per_epoch\n        print(f\"EMA annealing till the end activated\")\n\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch)\n        train_stats = train_one_epoch(\n            model,\n            model_ema,\n            args.ema_start_at,\n            args.ema_decay_init,\n            args.ema_decay,\n            target_layers,\n            data_loader_train,\n            optimizer,\n            device,\n            epoch,\n            loss_scaler,\n            args.clip_grad,\n            l1_beta=args.l1_beta,\n            log_writer=log_writer,\n            start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values,\n            wd_schedule_values=wd_schedule_values,\n            l2_loss=args.l2_loss,\n            layer_results=args.layer_results,\n            var_w0=args.var_w0, var_w1=args.var_w1, \n            var_margin0=args.var_margin0, var_margin1=args.var_margin1,\n            start_lr_decay_at_step=start_lr_decay_at_step,\n            loss_scale=args.loss_scale,\n            mask_dropout_prob=args.mask_dropout_prob,\n            target_layer_norm_last=not args.no_target_layer_norm_last, target_batch_norm=args.target_batch_norm, target_instance_norm=args.target_instance_norm,\n            post_target_instance_norm=args.post_target_instance_norm,\n            post_target_layer_norm=args.post_target_layer_norm\n        )\n\n        if args.output_dir:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args,\n                    model=model,\n                    model_without_ddp=model_without_ddp,\n                    optimizer=optimizer,\n                    loss_scaler=loss_scaler,\n                    epoch=epoch,\n                    model_ema=model_ema,\n                )\n\n        log_stats = {\n            **{f\"train_{k}\": v for k, v in train_stats.items()},\n            \"epoch\": epoch,\n            \"n_parameters\": n_parameters,\n        }\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(\n                os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\"\n            ) as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print(\"Training time {}\".format(total_time_str))\n\n\nif __name__ == \"__main__\":\n    opts = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/pretrain_dino_s2c.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#     http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport argparse\nimport os\nimport sys\nimport datetime\nimport time\nimport math\nimport json\nfrom pathlib import Path\nimport builtins\n\nimport numpy as np\nfrom PIL import Image\nimport torch\nimport torch.nn as nn\nimport torch.distributed as dist\nimport torch.backends.cudnn as cudnn\nimport torch.nn.functional as F\nfrom torchvision import datasets, transforms\nfrom torchvision import models as torchvision_models\n\nfrom models.dino import utils\nimport models.dino.vision_transformer as vits\nfrom models.dino.vision_transformer import DINOHead\n\n\nfrom datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\nfrom cvtorchvision import cvtransforms\nfrom models.rs_transforms_uint8 import RandomChannelDrop, GaussianBlur, Solarize, RandomBrightness, RandomContrast, ToGray, RandomSensorDrop_S1S2\n### end of change ###\nimport pdb\n\nfrom torch.utils.tensorboard import SummaryWriter\n\n#import warnings\n#warnings.filterwarnings(\"error\")\n\ntorchvision_archs = sorted(name for name in torchvision_models.__dict__\n    if name.islower() and not name.startswith(\"__\")\n    and callable(torchvision_models.__dict__[name]))\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('DINO', add_help=False)\n\n    # Model parameters\n    parser.add_argument('--arch', default='vit_small', type=str,\n        choices=['vit_tiny', 'vit_small', 'vit_base', 'xcit', 'deit_tiny', 'deit_small'] \\\n                + torchvision_archs, help=\"\"\"Name of architecture to train. For quick experiments with ViTs, we recommend using vit_tiny or vit_small.\"\"\")\n    parser.add_argument('--patch_size', default=16, type=int, help=\"\"\"Size in pixels\n        of input square patches - default 16 (for 16x16 patches). Using smaller\n        values leads to better performance but requires more memory. Applies only\n        for ViTs (vit_tiny, vit_small and vit_base). If <16, we recommend disabling\n        mixed precision training (--use_fp16 false) to avoid unstabilities.\"\"\")\n    parser.add_argument('--out_dim', default=65536, type=int, help=\"\"\"Dimensionality of\n        the DINO head output. For complex and large datasets large values (like 65k) work well.\"\"\")\n    parser.add_argument('--norm_last_layer', default=True, type=utils.bool_flag,\n        help=\"\"\"Whether or not to weight normalize the last layer of the DINO head.\n        Not normalizing leads to better performance but can make the training unstable.\n        In our experiments, we typically set this paramater to False with vit_small and True with vit_base.\"\"\")\n    parser.add_argument('--momentum_teacher', default=0.996, type=float, help=\"\"\"Base EMA\n        parameter for teacher update. The value is increased to 1 during training with cosine schedule.\n        We recommend setting a higher value with small batches: for example use 0.9995 with batch size of 256.\"\"\")\n    parser.add_argument('--use_bn_in_head', default=False, type=utils.bool_flag,\n        help=\"Whether to use batch normalizations in projection head (Default: False)\")\n\n    # Temperature teacher parameters\n    parser.add_argument('--warmup_teacher_temp', default=0.04, type=float,\n        help=\"\"\"Initial value for the teacher temperature: 0.04 works well in most cases.\n        Try decreasing it if the training loss does not decrease.\"\"\")\n    parser.add_argument('--teacher_temp', default=0.04, type=float, help=\"\"\"Final value (after linear warmup)\n        of the teacher temperature. For most experiments, anything above 0.07 is unstable. We recommend\n        starting with the default value of 0.04 and increase this slightly if needed.\"\"\")\n    parser.add_argument('--warmup_teacher_temp_epochs', default=0, type=int,\n        help='Number of warmup epochs for the teacher temperature (Default: 30).')\n\n    # Training/Optimization parameters\n    parser.add_argument('--use_fp16', type=utils.bool_flag, default=True, help=\"\"\"Whether or not\n        to use half precision for training. Improves training time and memory requirements,\n        but can provoke instability and slight decay of performance. We recommend disabling\n        mixed precision if the loss is unstable, if reducing the patch size or if training with bigger ViTs.\"\"\")\n    parser.add_argument('--weight_decay', type=float, default=0.04, help=\"\"\"Initial value of the\n        weight decay. With ViT, a smaller value at the beginning of training works well.\"\"\")\n    parser.add_argument('--weight_decay_end', type=float, default=0.4, help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD and using a larger decay by\n        the end of training improves performance for ViTs.\"\"\")\n    parser.add_argument('--clip_grad', type=float, default=3.0, help=\"\"\"Maximal parameter\n        gradient norm if using gradient clipping. Clipping with norm .3 ~ 1.0 can\n        help optimization for larger ViT architectures. 0 for disabling.\"\"\")\n    parser.add_argument('--batch_size_per_gpu', default=64, type=int,\n        help='Per-GPU batch-size : number of distinct images loaded on one GPU.')\n    parser.add_argument('--epochs', default=100, type=int, help='Number of epochs of training.')\n    parser.add_argument('--freeze_last_layer', default=1, type=int, help=\"\"\"Number of epochs\n        during which we keep the output layer fixed. Typically doing so during\n        the first epoch helps training. Try increasing this value if the loss does not decrease.\"\"\")\n    parser.add_argument(\"--lr\", default=0.0005, type=float, help=\"\"\"Learning rate at the end of\n        linear warmup (highest LR used during training). The learning rate is linearly scaled\n        with the batch size, and specified here for a reference batch size of 256.\"\"\")\n    parser.add_argument(\"--warmup_epochs\", default=10, type=int,\n        help=\"Number of epochs for the linear learning-rate warm up.\")\n    parser.add_argument('--min_lr', type=float, default=1e-6, help=\"\"\"Target LR at the\n        end of optimization. We use a cosine LR schedule with linear warmup.\"\"\")\n    parser.add_argument('--optimizer', default='adamw', type=str,\n        choices=['adamw', 'sgd', 'lars'], help=\"\"\"Type of optimizer. We recommend using adamw with ViTs.\"\"\")\n    parser.add_argument('--drop_path_rate', type=float, default=0.1, help=\"stochastic depth rate\")\n\n    # Multi-crop parameters\n    parser.add_argument('--global_crops_scale', type=float, nargs='+', default=(0.4, 1.),\n        help=\"\"\"Scale range of the cropped image before resizing, relatively to the origin image.\n        Used for large global view cropping. When disabling multi-crop (--local_crops_number 0), we\n        recommand using a wider range of scale (\"--global_crops_scale 0.14 1.\" for example)\"\"\")\n    parser.add_argument('--local_crops_number', type=int, default=8, help=\"\"\"Number of small\n        local views to generate. Set this parameter to 0 to disable multi-crop training.\n        When disabling multi-crop we recommend to use \"--global_crops_scale 0.14 1.\" \"\"\")\n    parser.add_argument('--local_crops_scale', type=float, nargs='+', default=(0.05, 0.4),\n        help=\"\"\"Scale range of the cropped image before resizing, relatively to the origin image.\n        Used for small local view cropping of multi-crop.\"\"\")\n\n    # Misc\n    parser.add_argument('--checkpoints_dir', default=\".\", type=str, help='Path to save logs and checkpoints.')\n    parser.add_argument('--saveckp_freq', default=20, type=int, help='Save checkpoint every x epochs.')\n    parser.add_argument('--seed', default=0, type=int, help='Random seed.')\n    parser.add_argument('--num_workers', default=10, type=int, help='Number of data loading workers per GPU.')\n    parser.add_argument(\"--dist_url\", default=\"env://\", type=str, help=\"\"\"url used to set up\n        distributed training; see https://pytorch.org/docs/stable/distributed.html\"\"\")\n    parser.add_argument(\"--local_rank\", default=0, type=int, help=\"Please ignore and do not set this argument.\")\n\n    # new\n    parser.add_argument('--data', default='/path/to/imagenet/', type=str,\n        help='Please specify path to the ImageNet folder.')\n    parser.add_argument('--bands', type=str, default='all', help=\"input bands\")\n    parser.add_argument(\"--lmdb\", action='store_true', help=\"use lmdb dataset\")\n    parser.add_argument(\"--is_slurm_job\", action='store_true', help=\"running in slurm\")\n    parser.add_argument(\"--resume\", action='store_true', help=\"resume from checkpoint\")    \n    \n    \n    parser.add_argument('--normalize', action='store_true', default=False)\n    parser.add_argument('--mode', nargs='*', default=['s2c'])\n    parser.add_argument('--dtype', type=str, default='uint8')\n    parser.add_argument('--season', type=str, default='augment')\n    parser.add_argument('--in_size', type=int, default=224)    \n        \n    \n    return parser\n\n\ndef train_dino(args):\n    utils.init_distributed_mode(args)\n    utils.fix_random_seeds(args.seed)\n    \n    # suppress printing if not master\n    if args.is_slurm_job and args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n    \n    print(\"git:\\n  {}\\n\".format(utils.get_sha()))\n    print(\"\\n\".join(\"%s: %s\" % (k, str(v)) for k, v in sorted(dict(vars(args)).items())))\n    cudnn.benchmark = True\n\n    \n    # ============ preparing data ... ============\n    transform = DataAugmentationDINO_S2(\n        args.global_crops_scale,\n        args.local_crops_scale,\n        args.local_crops_number,\n        args.season\n    )\n    \n    if args.bands == 'RGB':\n        bands = ['B04', 'B03', 'B02']\n        args.n_channels = 3\n    elif args.bands == 'B12':\n        bands = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']        \n        args.n_channels = 12\n    elif args.bands == 'B13':\n        bands = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B10', 'B11', 'B12']        \n        args.n_channels = 13    \n    elif args.bands == 'B2':\n        bands = ['VH', 'VV']\n    elif args.bands == 'B14':\n        bands_s1 = ['VH', 'VV']\n        bands_s2 = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']\n        args.n_channels = 14\n        \n    if args.lmdb:\n        dataset = LMDBDataset(\n            lmdb_file=args.data,\n            s2c_transform=transform,\n            is_slurm_job=args.is_slurm_job,\n            normalize=args.normalize,\n            dtype=args.dtype,\n            mode=args.mode            \n        )\n    \n    sampler = torch.utils.data.DistributedSampler(dataset, shuffle=True)\n    data_loader = torch.utils.data.DataLoader(\n        dataset,\n        sampler=sampler,\n        batch_size=args.batch_size_per_gpu,\n        num_workers=args.num_workers,\n        pin_memory=True,\n        drop_last=True,\n    )\n\n    print(f\"Data loaded: there are {len(dataset)} images.\")\n\n    # ============ building student and teacher networks ... ============\n    # we changed the name DeiT-S for ViT-S to avoid confusions\n    args.arch = args.arch.replace(\"deit\", \"vit\")\n    # if the network is a Vision Transformer (i.e. vit_tiny, vit_small, vit_base)\n    if args.arch in vits.__dict__.keys():\n        student = vits.__dict__[args.arch](\n            patch_size=args.patch_size,\n            drop_path_rate=args.drop_path_rate,  # stochastic depth\n            in_chans=args.n_channels\n        )\n        teacher = vits.__dict__[args.arch](patch_size=args.patch_size, in_chans=args.n_channels)\n        embed_dim = student.embed_dim\n    # otherwise, we check if the architecture is in torchvision models, [yi:need to adjust for more in_channels]\n    elif args.arch in torchvision_models.__dict__.keys():\n        student = torchvision_models.__dict__[args.arch]()\n        teacher = torchvision_models.__dict__[args.arch]()\n        embed_dim = student.fc.weight.shape[1]\n        student.conv1 = nn.Conv2d(args.n_channels, 64, kernel_size=7, stride=2, padding=3, bias=False)\n        teacher.conv1 = nn.Conv2d(args.n_channels, 64, kernel_size=7, stride=2, padding=3, bias=False)\n    # if the network is a XCiT, [yi:need to adjust for more in_channels]\n    elif args.arch in torch.hub.list(\"facebookresearch/xcit:main\"):\n        student = torch.hub.load('facebookresearch/xcit:main', args.arch,\n                                 pretrained=False, drop_path_rate=args.drop_path_rate)\n        teacher = torch.hub.load('facebookresearch/xcit:main', args.arch, pretrained=False)\n        embed_dim = student.embed_dim\n    else:\n        print(f\"Unknow architecture: {args.arch}\")\n\n    # multi-crop wrapper handles forward with inputs of different resolutions\n    student = utils.MultiCropWrapper(student, DINOHead(\n        embed_dim,\n        args.out_dim,\n        use_bn=args.use_bn_in_head,\n        norm_last_layer=args.norm_last_layer,\n    ))\n    teacher = utils.MultiCropWrapper(\n        teacher,\n        DINOHead(embed_dim, args.out_dim, args.use_bn_in_head),\n    )\n    # move networks to gpu\n    student, teacher = student.cuda(), teacher.cuda()\n    # synchronize batch norms (if any)\n    if utils.has_batchnorms(student):\n        student = nn.SyncBatchNorm.convert_sync_batchnorm(student)\n        teacher = nn.SyncBatchNorm.convert_sync_batchnorm(teacher)\n\n        # we need DDP wrapper to have synchro batch norms working...\n        teacher = nn.parallel.DistributedDataParallel(teacher, device_ids=[args.gpu])\n        teacher_without_ddp = teacher.module\n    else:\n        # teacher_without_ddp and teacher are the same thing\n        teacher_without_ddp = teacher\n    student = nn.parallel.DistributedDataParallel(student, device_ids=[args.gpu])\n    # teacher and student start with the same weights\n    teacher_without_ddp.load_state_dict(student.module.state_dict())\n    # there is no backpropagation through the teacher, so no need for gradients\n    for p in teacher.parameters():\n        p.requires_grad = False\n\n    print(f\"Student and Teacher are built: they are both {args.arch} network.\")\n\n    # ============ preparing loss ... ============\n    dino_loss = DINOLoss(\n        args.out_dim,\n        args.local_crops_number + 2,  # total number of crops = 2 global crops + local_crops_number\n        args.warmup_teacher_temp,\n        args.teacher_temp,\n        args.warmup_teacher_temp_epochs,\n        args.epochs,\n    ).cuda()\n\n    # ============ preparing optimizer ... ============\n    params_groups = utils.get_params_groups(student)\n    if args.optimizer == \"adamw\":\n        optimizer = torch.optim.AdamW(params_groups)  # to use with ViTs\n    elif args.optimizer == \"sgd\":\n        optimizer = torch.optim.SGD(params_groups, lr=0, momentum=0.9)  # lr is set by scheduler\n    elif args.optimizer == \"lars\":\n        optimizer = utils.LARS(params_groups)  # to use with convnet and large batches\n    # for mixed precision training\n    fp16_scaler = None\n    if args.use_fp16:\n        fp16_scaler = torch.cuda.amp.GradScaler()\n\n    # ============ init schedulers ... ============\n    lr_schedule = utils.cosine_scheduler(\n        args.lr * (args.batch_size_per_gpu * utils.get_world_size()) / 256.,  # linear scaling rule\n        args.min_lr,\n        args.epochs, len(data_loader),\n        warmup_epochs=args.warmup_epochs,\n    )\n    wd_schedule = utils.cosine_scheduler(\n        args.weight_decay,\n        args.weight_decay_end,\n        args.epochs, len(data_loader),\n    )\n    # momentum parameter is increased to 1. during training with a cosine schedule\n    momentum_schedule = utils.cosine_scheduler(args.momentum_teacher, 1,\n                                               args.epochs, len(data_loader))\n    print(f\"Loss, optimizer and schedulers ready.\")\n\n    # ============ optionally resume training ... ============\n    to_restore = {\"epoch\": 0}\n    if args.resume:\n        utils.restart_from_checkpoint(\n            os.path.join(args.checkpoints_dir, \"checkpoint.pth\"),\n            run_variables=to_restore,\n            student=student,\n            teacher=teacher,\n            optimizer=optimizer,\n            fp16_scaler=fp16_scaler,\n            dino_loss=dino_loss,\n        )\n    start_epoch = to_restore[\"epoch\"]\n\n    start_time = time.time()\n    print(\"Starting DINO training !\")\n\n    for epoch in range(start_epoch, args.epochs):\n        data_loader.sampler.set_epoch(epoch)\n\n        # ============ training one epoch of DINO ... ============\n        train_stats = train_one_epoch(student, teacher, teacher_without_ddp, dino_loss,\n            data_loader, optimizer, lr_schedule, wd_schedule, momentum_schedule,\n            epoch, fp16_scaler, args)\n\n        # ============ writing logs ... ============\n        save_dict = {\n            'student': student.state_dict(),\n            'teacher': teacher.state_dict(),\n            'optimizer': optimizer.state_dict(),\n            'epoch': epoch + 1,\n            'args': args,\n            'dino_loss': dino_loss.state_dict(),\n        }\n        if fp16_scaler is not None:\n            save_dict['fp16_scaler'] = fp16_scaler.state_dict()\n        utils.save_on_master(save_dict, os.path.join(args.checkpoints_dir, 'checkpoint.pth'))\n        if args.saveckp_freq and epoch % args.saveckp_freq == 0:\n            utils.save_on_master(save_dict, os.path.join(args.checkpoints_dir, f'checkpoint{epoch:04}.pth'))\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                     'epoch': epoch}\n        if utils.is_main_process():\n            with (Path(args.checkpoints_dir) / \"log.txt\").open(\"a\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\ndef train_one_epoch(student, teacher, teacher_without_ddp, dino_loss, data_loader,\n                    optimizer, lr_schedule, wd_schedule, momentum_schedule,epoch,\n                    fp16_scaler, args):\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    header = 'Epoch: [{}/{}]'.format(epoch, args.epochs)\n    for it, images in enumerate(metric_logger.log_every(data_loader, 10, header)):\n        \n        #images = [torch.cat((images_s2[i],images_s1[i]),axis=1) for i in range(len(images_s2))]\n        \n        # update weight decay and learning rate according to their schedule\n        it = len(data_loader) * epoch + it  # global training iteration\n        for i, param_group in enumerate(optimizer.param_groups):\n            param_group[\"lr\"] = lr_schedule[it]\n            if i == 0:  # only the first group is regularized\n                param_group[\"weight_decay\"] = wd_schedule[it]\n\n        # move images to gpu\n        images = [im.cuda(non_blocking=True) for im in images]\n        # teacher and student forward passes + compute dino loss\n        with torch.cuda.amp.autocast(fp16_scaler is not None):\n            teacher_output = teacher(images[:2])  # only the 2 global views pass through the teacher\n            student_output = student(images)\n            loss = dino_loss(student_output, teacher_output, epoch)\n\n        if not math.isfinite(loss.item()):\n            print(\"Loss is {}, stopping training\".format(loss.item()), force=True)\n            sys.exit(1)\n\n        # student update\n        optimizer.zero_grad()\n        param_norms = None\n        if fp16_scaler is None:\n            loss.backward()\n            if args.clip_grad:\n                param_norms = utils.clip_gradients(student, args.clip_grad)\n            utils.cancel_gradients_last_layer(epoch, student,\n                                              args.freeze_last_layer)\n            optimizer.step()\n        else:\n            fp16_scaler.scale(loss).backward()\n            if args.clip_grad:\n                fp16_scaler.unscale_(optimizer)  # unscale the gradients of optimizer's assigned params in-place\n                param_norms = utils.clip_gradients(student, args.clip_grad)\n            utils.cancel_gradients_last_layer(epoch, student,\n                                              args.freeze_last_layer)\n            fp16_scaler.step(optimizer)\n            fp16_scaler.update()\n\n        # EMA update for the teacher\n        with torch.no_grad():\n            m = momentum_schedule[it]  # momentum parameter\n            for param_q, param_k in zip(student.module.parameters(), teacher_without_ddp.parameters()):\n                param_k.data.mul_(m).add_((1 - m) * param_q.detach().data)\n\n        # logging\n        torch.cuda.synchronize()\n        metric_logger.update(loss=loss.item())\n        metric_logger.update(lr=optimizer.param_groups[0][\"lr\"])\n        metric_logger.update(wd=optimizer.param_groups[0][\"weight_decay\"])\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\nclass DINOLoss(nn.Module):\n    def __init__(self, out_dim, ncrops, warmup_teacher_temp, teacher_temp,\n                 warmup_teacher_temp_epochs, nepochs, student_temp=0.1,\n                 center_momentum=0.9):\n        super().__init__()\n        self.student_temp = student_temp\n        self.center_momentum = center_momentum\n        self.ncrops = ncrops\n        self.register_buffer(\"center\", torch.zeros(1, out_dim))\n        # we apply a warm up for the teacher temperature because\n        # a too high temperature makes the training instable at the beginning\n        self.teacher_temp_schedule = np.concatenate((\n            np.linspace(warmup_teacher_temp,\n                        teacher_temp, warmup_teacher_temp_epochs),\n            np.ones(nepochs - warmup_teacher_temp_epochs) * teacher_temp\n        ))\n\n    def forward(self, student_output, teacher_output, epoch):\n        \"\"\"\n        Cross-entropy between softmax outputs of the teacher and student networks.\n        \"\"\"\n        student_out = student_output / self.student_temp\n        student_out = student_out.chunk(self.ncrops)\n\n        # teacher centering and sharpening\n        temp = self.teacher_temp_schedule[epoch]\n        teacher_out = F.softmax((teacher_output - self.center) / temp, dim=-1)\n        teacher_out = teacher_out.detach().chunk(2)\n\n        total_loss = 0\n        n_loss_terms = 0\n        for iq, q in enumerate(teacher_out):\n            for v in range(len(student_out)):\n                if v == iq:\n                    # we skip cases where student and teacher operate on the same view\n                    continue\n                loss = torch.sum(-q * F.log_softmax(student_out[v], dim=-1), dim=-1)\n                total_loss += loss.mean()\n                n_loss_terms += 1\n        total_loss /= n_loss_terms\n        self.update_center(teacher_output)\n        return total_loss\n\n    @torch.no_grad()\n    def update_center(self, teacher_output):\n        \"\"\"\n        Update center used for teacher output.\n        \"\"\"\n        batch_center = torch.sum(teacher_output, dim=0, keepdim=True)\n        dist.all_reduce(batch_center)\n        batch_center = batch_center / (len(teacher_output) * dist.get_world_size())\n\n        # ema update\n        self.center = self.center * self.center_momentum + batch_center * (1 - self.center_momentum)\n\n\n\nclass DataAugmentationDINO(object):\n    def __init__(self, global_crops_scale, local_crops_scale, local_crops_number):\n        flip_and_color_jitter = cvtransforms.Compose([\n            cvtransforms.RandomHorizontalFlip(p=0.5),\n            cvtransforms.RandomApply([\n                RandomBrightness(0.4),\n                RandomContrast(0.4)\n            ], p=0.8),\n            cvtransforms.RandomApply([ToGray(14)], p=0.2),\n        ])\n        normalize = cvtransforms.Compose([\n            cvtransforms.ToTensor(),\n            #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n        ])\n        sensor_drop = cvtransforms.RandomApply([RandomSensorDrop_S1S2()], p=0.5)\n\n        # first global crop\n        self.global_transfo1 = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(112, scale=global_crops_scale, interpolation='BICUBIC'),\n            flip_and_color_jitter,\n            cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=1.0),\n            normalize,\n            sensor_drop\n        ])\n        # second global crop\n        self.global_transfo2 = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(112, scale=global_crops_scale, interpolation='BICUBIC'),\n            flip_and_color_jitter,\n            cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.1),\n            cvtransforms.RandomApply([Solarize(128)], p=0.2),\n            normalize,\n            sensor_drop\n        ])\n        # transformation for the local small crops\n        self.local_crops_number = local_crops_number\n        self.local_transfo = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(48, scale=local_crops_scale, interpolation='BICUBIC'),\n            flip_and_color_jitter,\n            cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.5),\n            normalize,\n            sensor_drop\n        ])\n\n    def __call__(self, image):\n        crops = []\n        crops.append(self.global_transfo1(image))\n        crops.append(self.global_transfo2(image))\n        for _ in range(self.local_crops_number):\n            crops.append(self.local_transfo(image))\n        return crops        \n        \n        \n        \n        \n        \n        \n        \n        \nclass DataAugmentationDINO_S2(object):\n    def __init__(self, global_crops_scale, local_crops_scale, local_crops_number, season='fixed'):\n        flip_and_color_jitter = cvtransforms.Compose([\n            cvtransforms.RandomHorizontalFlip(p=0.5),\n            cvtransforms.RandomApply([\n                RandomBrightness(0.4),\n                RandomContrast(0.4)\n            ], p=0.8),\n            cvtransforms.RandomApply([ToGray(13)], p=0.2),\n        ])\n        normalize = cvtransforms.Compose([\n            cvtransforms.ToTensor(),\n            #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n        ])\n        \n        # first global crop\n        self.global_transfo1 = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.in_size, scale=global_crops_scale, interpolation='BICUBIC'),\n            flip_and_color_jitter,\n            cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=1.0),\n            normalize,\n        ])\n        # second global crop\n        self.global_transfo2 = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.in_size, scale=global_crops_scale, interpolation='BICUBIC'),\n            flip_and_color_jitter,\n            cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.1),\n            cvtransforms.RandomApply([Solarize(128)], p=0.2),\n            normalize,\n        ])\n        # transformation for the local small crops\n        self.local_crops_number = local_crops_number\n        self.local_transfo = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(96, scale=local_crops_scale, interpolation='BICUBIC'),\n            flip_and_color_jitter,\n            cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.5),\n            normalize,\n        ])\n        \n        \n        self.season = season\n\n    def __call__(self, image):\n        \n        if self.season=='augment':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = np.random.choice([0,1,2,3])\n            season3 = np.random.choice([0,1,2,3])\n        elif self.season=='fixed':\n            np.random.seed(42)\n            season1 = np.random.choice([0,1,2,3])\n            season2 = season1\n            season3 = season1\n        elif self.season=='random':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = season1\n            season3 = season1\n\n        x1 = np.transpose(image[season1,:,:,:],(1,2,0))\n        x2 = np.transpose(image[season2,:,:,:],(1,2,0))\n        x3 = np.transpose(image[season3,:,:,:],(1,2,0))\n        \n        crops = []\n        crops.append(self.global_transfo1(x1))\n        crops.append(self.global_transfo2(x2))\n        for _ in range(self.local_crops_number):\n            crops.append(self.local_transfo(x3))\n        return crops\n\nclass DataAugmentationDINO_S1(object):\n    def __init__(self, global_crops_scale, local_crops_scale, local_crops_number):\n        flip_and_color_jitter = cvtransforms.Compose([\n            #cvtransforms.RandomHorizontalFlip(p=0.5),\n            #cvtransforms.RandomApply([\n            #    RandomBrightness(0.4),\n            #    RandomContrast(0.4)\n            #], p=0.8),\n            #cvtransforms.RandomApply([ToGray(2)], p=0.2),\n        ])\n        normalize = cvtransforms.Compose([\n            cvtransforms.ToTensor(),\n            #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n        ])\n\n        # first global crop\n        self.global_transfo1 = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(112, scale=global_crops_scale, interpolation='BICUBIC'),\n            #flip_and_color_jitter,\n            #cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=1.0),\n            normalize,\n        ])\n        # second global crop\n        self.global_transfo2 = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(112, scale=global_crops_scale, interpolation='BICUBIC'),\n            #flip_and_color_jitter,\n            #cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.1),\n            #cvtransforms.RandomApply([Solarize(128)], p=0.2),\n            normalize,\n        ])\n        # transformation for the local small crops\n        self.local_crops_number = local_crops_number\n        self.local_transfo = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(48, scale=local_crops_scale, interpolation='BICUBIC'),\n            #flip_and_color_jitter,\n            #cvtransforms.RandomApply([GaussianBlur([.1, 2.])], p=0.5),\n            normalize,\n        ])\n\n    def __call__(self, image):\n        crops = []\n        crops.append(self.global_transfo1(image))\n        crops.append(self.global_transfo2(image))\n        for _ in range(self.local_crops_number):\n            crops.append(self.local_transfo(image))\n        return crops    \n    \n    \n    \n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser('DINO', parents=[get_args_parser()])\n    args = parser.parse_args()\n    \n    \n    \n    Path(args.checkpoints_dir).mkdir(parents=True, exist_ok=True)\n    train_dino(args)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/pretrain_mae_s2c.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\n\nimport timm\n\n#assert timm.__version__ == \"0.3.2\"  # version check\nimport timm.optim.optim_factory as optim_factory\n\nimport models.mae.util.misc as misc\nfrom models.mae.util.misc import NativeScalerWithGradNormCount as NativeScaler\n\nimport models.mae.models_mae as models_mae\n\nfrom models.mae.engine_pretrain import train_one_epoch\n\nfrom datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset,random_subset\nfrom cvtorchvision import cvtransforms\n\n\nclass SeasonTransform:\n\n    def __init__(self, base_transform, season='fixed'):\n        self.base_transform = base_transform\n        self.season = season\n\n    def __call__(self, x):\n\n        if self.season=='augment':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = np.random.choice([0,1,2,3])\n            \n            x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n            x2 = np.transpose(x[season2,:,:,:],(1,2,0))            \n            image1 = self.base_transform(x1)\n            image2 = self.base_transform2(x2)\n            return image1, image2\n            \n        elif self.season=='fixed':\n            np.random.seed(42)\n            season1 = np.random.choice([0,1,2,3])\n\n        elif self.season=='random':\n            season1 = np.random.choice([0,1,2,3])\n\n        x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n        image = self.base_transform(x1)\n        \n        return image\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE pre-training', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=400, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='mae_vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--mask_ratio', default=0.75, type=float,\n                        help='Masking ratio (percentage of removed patches).')\n\n    parser.add_argument('--norm_pix_loss', action='store_true',\n                        help='Use (per-patch) normalized pixels as targets for computing loss')\n    parser.set_defaults(norm_pix_loss=False)\n\n    # Optimizer parameters\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=1e-3, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n    parser.add_argument('--min_lr', type=float, default=0., metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=40, metavar='N',\n                        help='epochs to warmup LR')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n    # new                    \n    parser.add_argument('--rank', default=-1, type=int,\n                        help='node rank for distributed training')                        \n    parser.add_argument('--dist_backend', default='nccl', type=str,\n                        help='distributed backend')\n\n    parser.add_argument('--is_slurm_job', action='store_true', default=False)    \n    parser.add_argument('--normalize', action='store_true', default=False)\n    parser.add_argument('--mode', nargs='*', default=['s2c'])\n    parser.add_argument('--dtype', type=str, default='uint8')\n    parser.add_argument('--season', type=str, default='augment')\n    parser.add_argument('--bands', type=str, default='B13')\n    \n    return parser\n\n\ndef main(args):\n    # slurm setting\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n    '''\n    # simple augmentation\n    transform_train = transforms.Compose([\n            transforms.RandomResizedCrop(args.input_size, scale=(0.2, 1.0), interpolation=3),  # 3 is bicubic\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    dataset_train = datasets.ImageFolder(os.path.join(args.data_path, 'train'), transform=transform_train)\n    print(dataset_train)\n    '''\n\n    transform_train = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.input_size, scale=(0.2, 1.0)),  # 3 is bicubic\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n    \n    \n    dataset_train = LMDBDataset(\n        lmdb_file=args.data_path,\n        s2c_transform=SeasonTransform(base_transform=transform_train,season=args.season),\n        is_slurm_job=args.is_slurm_job,\n        normalize=args.normalize,\n        dtype=args.dtype,\n        mode=args.mode\n    )\n\n    dataset_train = random_subset(dataset_train,frac=1.0,seed=42)\n    \n    if True:  # args.distributed:\n        num_tasks = misc.get_world_size()\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n    \n    # define the model\n    model = models_mae.__dict__[args.model](norm_pix_loss=args.norm_pix_loss, in_chans=13)\n\n    model.to(device)\n\n    model_without_ddp = model\n    print(\"Model = %s\" % str(model_without_ddp))\n\n    eff_batch_size = args.batch_size * args.accum_iter * args.world_size\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n        model_without_ddp = model.module\n    \n    # following timm: set wd as 0 for bias and norm layers\n    param_groups = optim_factory.add_weight_decay(model_without_ddp, args.weight_decay)\n    optimizer = torch.optim.AdamW(param_groups, lr=args.lr, betas=(0.9, 0.95))\n    print(optimizer)\n    loss_scaler = NativeScaler()\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir and (epoch % 20 == 0 or epoch + 1 == args.epochs):\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        'epoch': epoch,}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/pretrain_moco_v2_s2c.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport argparse\nimport builtins\nimport math\nimport os\nimport random\nimport shutil\nimport time\nimport warnings\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.parallel\nimport torch.backends.cudnn as cudnn\nimport torch.distributed as dist\nimport torch.optim\nimport torch.multiprocessing as mp\nimport torch.utils.data\nimport torch.utils.data.distributed\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\nimport torchvision.models as models\n\nfrom models.moco import loader\nfrom models.moco import builder\nimport pdb\n\nfrom torch.utils.tensorboard import SummaryWriter\n\n#from datasets.BigEarthNet.bigearthnet_dataset_seco import Bigearthnet\n#from datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb import LMDBDataset\nfrom datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\n#from models.rs_transforms_uint8 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\nfrom cvtorchvision import cvtransforms\n#from torchsat.transforms import transforms_cls\n\n\nmodel_names = sorted(name for name in models.__dict__\n    if name.islower() and not name.startswith(\"__\")\n    and callable(models.__dict__[name]))\n\nparser = argparse.ArgumentParser(description='PyTorch ImageNet Training')\nparser.add_argument('--data', metavar='DIR',\n                    help='path to dataset')\nparser.add_argument('--checkpoints', metavar='DIR', default='./',\n                    help='path to checkpoints')\nparser.add_argument('--save_path', metavar='DIR', default='./',\n                    help='path to save trained model')\nparser.add_argument('--bands', type=str, default='B12',\n                    help='bands to process')                    \nparser.add_argument('--lmdb', action='store_true',\n                    help='use lmdb dataset') \nparser.add_argument('-a', '--arch', metavar='ARCH', default='resnet50',\n                    choices=model_names,\n                    help='model architecture: ' +\n                        ' | '.join(model_names) +\n                        ' (default: resnet50)')\nparser.add_argument('-j', '--workers', default=32, type=int, metavar='N',\n                    help='number of data loading workers (default: 32)')\nparser.add_argument('--epochs', default=100, type=int, metavar='N',\n                    help='number of total epochs to run')\nparser.add_argument('--start-epoch', default=0, type=int, metavar='N',\n                    help='manual epoch number (useful on restarts)')\nparser.add_argument('-b', '--batch-size', default=256, type=int,\n                    metavar='N',\n                    help='mini-batch size (default: 256), this is the total '\n                         'batch size of all GPUs on the current node when '\n                         'using Data Parallel or Distributed Data Parallel')\nparser.add_argument('--lr', '--learning-rate', default=0.03, type=float,\n                    metavar='LR', help='initial learning rate', dest='lr')\nparser.add_argument('--schedule', default=[120, 160], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by 10x)')\nparser.add_argument('--momentum', default=0.9, type=float, metavar='M',\n                    help='momentum of SGD solver')\nparser.add_argument('--wd', '--weight-decay', default=1e-4, type=float,\n                    metavar='W', help='weight decay (default: 1e-4)',\n                    dest='weight_decay')\nparser.add_argument('-p', '--print-freq', default=10, type=int,\n                    metavar='N', help='print frequency (default: 10)')\nparser.add_argument('--resume', default='', type=str, metavar='PATH',\n                    help='path to latest checkpoint (default: none)')\nparser.add_argument('--world-size', default=-1, type=int,\n                    help='number of nodes for distributed training')\nparser.add_argument('--rank', default=-1, type=int,\n                    help='node rank for distributed training')\nparser.add_argument('--dist-url', default='tcp://224.66.41.62:23456', type=str,\n                    help='url used to set up distributed training')\nparser.add_argument('--dist-backend', default='nccl', type=str,\n                    help='distributed backend')\nparser.add_argument('--seed', default=None, type=int,\n                    help='seed for initializing training. ')\nparser.add_argument('--gpu', default=None, type=int,\n                    help='GPU id to use.')\nparser.add_argument('--multiprocessing-distributed', action='store_true',\n                    help='Use multi-processing distributed training to launch '\n                         'N processes per node, which has N GPUs. This is the '\n                         'fastest way to use PyTorch for either single node or '\n                         'multi node data parallel training')\n\n# moco specific configs:\nparser.add_argument('--moco-dim', default=128, type=int,\n                    help='feature dimension (default: 128)')\nparser.add_argument('--moco-k', default=65536, type=int,\n                    help='queue size; number of negative keys (default: 65536)')\nparser.add_argument('--moco-m', default=0.999, type=float,\n                    help='moco momentum of updating key encoder (default: 0.999)')\nparser.add_argument('--moco-t', default=0.07, type=float,\n                    help='softmax temperature (default: 0.07)')\n\n# options for moco v2\nparser.add_argument('--mlp', action='store_true',\n                    help='use mlp head')\nparser.add_argument('--aug-plus', action='store_true',\n                    help='use moco v2 data augmentation')\nparser.add_argument('--cos', action='store_true',\n                    help='use cosine lr schedule')\n\nparser.add_argument('--normalize', action='store_true', default=False)\nparser.add_argument('--mode', nargs='*', default=['s2c'])\nparser.add_argument('--dtype', type=str, default='uint8')\nparser.add_argument('--season', type=str, default='augment')\n\nparser.add_argument('--in_size', type=int, default=224)\nparser.add_argument(\"--is_slurm_job\", action='store_true', help=\"running in slurm\")\n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n    def __init__(self, base_transform, season='fixed'):\n        self.base_transform = base_transform\n        self.season = season\n\n    def __call__(self, x):\n\n        if self.season=='augment':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = np.random.choice([0,1,2,3])\n        elif self.season=='fixed':\n            np.random.seed(42)\n            season1 = np.random.choice([0,1,2,3])\n            season2 = season1\n        elif self.season=='random':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = season1\n\n        x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n        x2 = np.transpose(x[season2,:,:,:],(1,2,0))\n\n        q = self.base_transform(x1)\n        k = self.base_transform(x2)\n\n        return [q, k]\n\n\ndef main():\n\n    args = parser.parse_args()\n\n    '''\n    if args.rank==0 and not os.path.isdir(args.checkpoints):\n        os.makedirs(args.checkpoints,exist_ok=True)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints,'log'))\n    '''\n\n    if args.seed is not None:\n        random.seed(args.seed)\n        torch.manual_seed(args.seed)\n        torch.cuda.manual_seed_all(args.seed)\n        np.random.seed(args.seed)\n        '''\n        cudnn.deterministic = True\n        warnings.warn('You have chosen to seed training. '\n                      'This will turn on the CUDNN deterministic setting, '\n                      'which can slow down your training considerably! '\n                      'You may see unexpected behavior when restarting '\n                      'from checkpoints.')\n        '''\n    if args.gpu is not None:\n        warnings.warn('You have chosen a specific GPU. This will completely '\n                      'disable data parallelism.')\n\n    if args.dist_url == \"env://\" and args.world_size == -1:\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n\n    ### add slurm option ###\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n\n\n    args.distributed = args.world_size > 1 or args.multiprocessing_distributed\n\n    ngpus_per_node = torch.cuda.device_count()\n    if args.multiprocessing_distributed:\n        # Since we have ngpus_per_node processes per node, the total world_size\n        # needs to be adjusted accordingly\n        args.world_size = ngpus_per_node * args.world_size\n        # Use torch.multiprocessing.spawn to launch distributed processes: the\n        # main_worker process function\n        mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args))\n    else:\n        # Simply call main_worker function\n        main_worker(args.gpu, ngpus_per_node, args)\n\n\ndef main_worker(gpu, ngpus_per_node, args):\n    args.gpu = gpu\n\n    # suppress printing if not master\n    if args.multiprocessing_distributed and args.gpu != 0 or (args.is_slurm_job and args.rank != 0):\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n\n    if args.gpu is not None:\n        print(\"Use GPU: {} for training\".format(args.gpu))\n\n    if args.distributed:\n        if args.dist_url == \"env://\" and args.rank == -1:\n            args.rank = int(os.environ[\"RANK\"])\n        if args.multiprocessing_distributed:\n            # For multiprocessing distributed training, rank needs to be the\n            # global rank among all the processes\n            args.rank = args.rank * ngpus_per_node + gpu\n        dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                world_size=args.world_size, rank=args.rank)\n    \n    # create tb_writer\n    if args.rank==0 and not os.path.isdir(args.checkpoints):\n        os.makedirs(args.checkpoints, exist_ok=True)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints,'log'))    \n        \n    # create model\n    print(\"=> creating model '{}'\".format(args.arch))\n    model = builder.MoCo(\n        models.__dict__[args.arch],\n        args.moco_dim, args.moco_k, args.moco_m, args.moco_t, args.mlp, bands=args.bands)\n    \n    print('model created.')\n\n    if args.distributed:\n        # For multiprocessing distributed, DistributedDataParallel constructor\n        # should always set the single device scope, otherwise,\n        # DistributedDataParallel will use all available devices.\n\n        ### add slurm option ###\n        if args.is_slurm_job:            \n            args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n            torch.cuda.set_device(args.gpu_to_work_on)\n            model.cuda()\n            model = nn.parallel.DistributedDataParallel(model,device_ids=[args.gpu_to_work_on])   \n            print('model distributed.')          \n        elif args.gpu is not None:\n            torch.cuda.set_device(args.gpu)\n            model.cuda(args.gpu)\n            # When using a single GPU per process and per\n            # DistributedDataParallel, we need to divide the batch size\n            # ourselves based on the total number of GPUs we have\n            args.batch_size = int(args.batch_size / ngpus_per_node)\n            args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node)\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        else:\n            model.cuda()\n            # DistributedDataParallel will divide and allocate batch_size to all\n            # available GPUs if device_ids are not set\n            model = torch.nn.parallel.DistributedDataParallel(model)\n    elif args.gpu is not None:\n        torch.cuda.set_device(args.gpu)\n        model = model.cuda(args.gpu)\n        # comment out the following line for debugging\n        raise NotImplementedError(\"Only DistributedDataParallel is supported.\")\n    else:\n        # AllGather implementation (batch shuffle, queue update, etc.) in\n        # this code only supports DistributedDataParallel.\n        raise NotImplementedError(\"Only DistributedDataParallel is supported.\")\n\n    # define loss function (criterion) and optimizer\n    criterion = nn.CrossEntropyLoss().cuda(args.gpu)\n\n    optimizer = torch.optim.SGD(model.parameters(), args.lr,\n                                momentum=args.momentum,\n                                weight_decay=args.weight_decay)\n\n    # optionally resume from a checkpoint\n    if args.resume:\n        if os.path.isfile(args.resume):\n            print(\"=> loading checkpoint '{}'\".format(args.resume))\n            if args.gpu is None:\n                checkpoint = torch.load(args.resume)\n            else:\n                # Map model to be loaded to specified single gpu.\n                loc = 'cuda:{}'.format(args.gpu)\n                checkpoint = torch.load(args.resume, map_location=loc)\n            args.start_epoch = checkpoint['epoch']\n            model.load_state_dict(checkpoint['state_dict'])\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            print(\"=> loaded checkpoint '{}' (epoch {})\"\n                  .format(args.resume, checkpoint['epoch']))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.resume))\n\n    cudnn.benchmark = True\n\n\n    ### load dataset\n    \n    lmdb = args.lmdb\n    \n    if args.bands == 'B13':    \n        n_channels = 13\n    elif args.bands == 'B12':\n        n_channels = 12\n\n    if args.dtype=='uint8':\n        from models.rs_transforms_uint8 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\n    else:\n        from models.rs_transforms_float32 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\n        \n    train_transforms = cvtransforms.Compose([\n        #cvtransforms.Resize(128),\n        cvtransforms.RandomResizedCrop(args.in_size, scale=(0.2, 1.)),\n        cvtransforms.RandomApply([\n            RandomBrightness(0.4),\n            RandomContrast(0.4)\n        ], p=0.8),\n        cvtransforms.RandomApply([ToGray(n_channels)], p=0.2),\n        cvtransforms.RandomApply([loader.GaussianBlur([.1, 2.])], p=0.5),\n        cvtransforms.RandomHorizontalFlip(),       \n        cvtransforms.ToTensor()\n        #cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),        \n        ])\n    \n\n    train_dataset = LMDBDataset(\n        lmdb_file=args.data,\n        s2c_transform=TwoCropsTransform(train_transforms,season=args.season),\n        is_slurm_job=args.is_slurm_job,\n        normalize=args.normalize,\n        dtype=args.dtype,\n        mode=args.mode\n    )   \n    \n        \n    if args.distributed:\n        train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)\n    else:\n        train_sampler = None\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None),\n        num_workers=args.workers, pin_memory=args.is_slurm_job, sampler=train_sampler, drop_last=True)\n\n    print('start training...')\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            train_sampler.set_epoch(epoch)\n        adjust_learning_rate(optimizer, epoch, args)\n\n        # train for one epoch\n        loss,top1,top5 = train(train_loader, model, criterion, optimizer, epoch, args)\n        if args.rank==0:    \n            tb_writer.add_scalar('loss',loss,global_step=epoch,walltime=None)\n            tb_writer.add_scalar('acc1',top1,global_step=epoch,walltime=None)\n            tb_writer.add_scalar('acc5',top5,global_step=epoch,walltime=None)\n\n\n        if epoch%10==9:\n            if args.rank==0:\n                save_checkpoint({\n                    'epoch': epoch + 1,\n                    'arch': args.arch,\n                    'state_dict': model.state_dict(),\n                    'optimizer' : optimizer.state_dict(),\n                }, is_best=False, filename=os.path.join(args.checkpoints,'checkpoint_{:04d}.pth.tar'.format(epoch)))\n    \n    print('Training finished.')\n    if args.rank==0:\n        tb_writer.close()\n\ndef train(train_loader, model, criterion, optimizer, epoch, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    data_time = AverageMeter('Data', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(train_loader),\n        [batch_time, data_time, losses, top1, top5],\n        prefix=\"Epoch: [{}]\".format(epoch))\n\n    # switch to train mode\n    model.train()\n\n    end = time.time()\n    for i, s2c in enumerate(train_loader):\n        images = s2c\n        # measure data loading time\n        data_time.update(time.time() - end)\n\n        if args.gpu is not None:\n            images[0] = images[0].cuda(args.gpu, non_blocking=True)\n            images[1] = images[1].cuda(args.gpu, non_blocking=True)\n\n        # compute output\n        output, target = model(im_q=images[0], im_k=images[1])\n        loss = criterion(output, target)\n\n        # acc1/acc5 are (K+1)-way contrast classifier accuracy\n        # measure accuracy and record loss\n        acc1, acc5 = accuracy(output, target, topk=(1, 5))\n        losses.update(loss.item(), images[0].size(0))\n        top1.update(acc1[0], images[0].size(0))\n        top5.update(acc5[0], images[0].size(0))\n\n        # compute gradient and do SGD step\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        # measure elapsed time\n        batch_time.update(time.time() - end)\n        end = time.time()\n\n        if i % args.print_freq == 0:\n            progress.display(i)\n    '''\n    if args.rank==0:    \n        tb_writer.add_scalar('loss',losses.avg,global_step=epoch,walltime=None)\n        tb_writer.add_scalar('acc1',top1.avg,global_step=epoch,walltime=None)\n        tb_writer.add_scalar('acc5',top5.avg,global_step=epoch,walltime=None)\n    '''\n    return losses.avg, top1.avg, top5.avg\n\ndef save_checkpoint(state, is_best, filename='checkpoint.pth.tar'):\n    torch.save(state, filename)\n    if is_best:\n        shutil.copyfile(filename, 'model_best.pth.tar')\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self, name, fmt=':f'):\n        self.name = name\n        self.fmt = fmt\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count\n\n    def __str__(self):\n        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'\n        return fmtstr.format(**self.__dict__)\n\n\nclass ProgressMeter(object):\n    def __init__(self, num_batches, meters, prefix=\"\"):\n        self.batch_fmtstr = self._get_batch_fmtstr(num_batches)\n        self.meters = meters\n        self.prefix = prefix\n\n    def display(self, batch):\n        entries = [self.prefix + self.batch_fmtstr.format(batch)]\n        entries += [str(meter) for meter in self.meters]\n        print('\\t'.join(entries))\n\n    def _get_batch_fmtstr(self, num_batches):\n        num_digits = len(str(num_batches // 1))\n        fmt = '{:' + str(num_digits) + 'd}'\n        return '[' + fmt + '/' + fmt.format(num_batches) + ']'\n\n                                                        \ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    if args.cos:  # cosine lr schedule\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\n    else:  # stepwise lr schedule\n        for milestone in args.schedule:\n            lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef accuracy(output, target, topk=(1,)):\n    \"\"\"Computes the accuracy over the k top predictions for the specified values of k\"\"\"\n    with torch.no_grad():\n        maxk = max(topk)\n        batch_size = target.size(0)\n\n        _, pred = output.topk(maxk, 1, True, True)\n        pred = pred.t()\n        correct = pred.eq(target.view(1, -1).expand_as(pred))\n\n        res = []\n        for k in topk:\n            correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)\n            res.append(correct_k.mul_(100.0 / batch_size))\n        return res\n\n\nif __name__ == '__main__':\n    ss_time = time.time()\n    \n    # moco-v2\n    #args.mlp = True\n    #args.moco_t = 0.2\n    #args.aug_plus = True\n    #args.cos = True\n    \n    main()\n    print('total time: %s.' % (time.time()-ss_time))\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/pretrain_moco_v2_seco_ms.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport argparse\nimport builtins\nimport math\nimport os\nimport random\nimport shutil\nimport time\nimport warnings\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.parallel\nimport torch.backends.cudnn as cudnn\nimport torch.distributed as dist\nimport torch.optim\nimport torch.multiprocessing as mp\nimport torch.utils.data\nimport torch.utils.data.distributed\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\nimport torchvision.models as models\n\nfrom models.moco import loader\nfrom models.moco import builder\nimport pdb\n\n\nfrom torch.utils.tensorboard import SummaryWriter\n\n#from datasets.BigEarthNet.bigearthnet_dataset_seco import Bigearthnet\n#from datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb import LMDBDataset\n#from datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\n#from models.rs_transforms_uint8 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\nfrom cvtorchvision import cvtransforms\n#from torchsat.transforms import transforms_cls\nfrom glob import glob\nimport rasterio\nimport lmdb\nimport pickle\n\n\nmodel_names = sorted(name for name in models.__dict__\n    if name.islower() and not name.startswith(\"__\")\n    and callable(models.__dict__[name]))\n\nparser = argparse.ArgumentParser(description='PyTorch ImageNet Training')\nparser.add_argument('--data', metavar='DIR',\n                    help='path to dataset')\nparser.add_argument('--checkpoints', metavar='DIR', default='./',\n                    help='path to checkpoints')\nparser.add_argument('--save_path', metavar='DIR', default='./',\n                    help='path to save trained model')\nparser.add_argument('--bands', type=str, default='B12',\n                    help='bands to process')                    \nparser.add_argument('--lmdb', action='store_true',\n                    help='use lmdb dataset') \nparser.add_argument('-a', '--arch', metavar='ARCH', default='resnet50',\n                    choices=model_names,\n                    help='model architecture: ' +\n                        ' | '.join(model_names) +\n                        ' (default: resnet50)')\nparser.add_argument('-j', '--workers', default=32, type=int, metavar='N',\n                    help='number of data loading workers (default: 32)')\nparser.add_argument('--epochs', default=100, type=int, metavar='N',\n                    help='number of total epochs to run')\nparser.add_argument('--start-epoch', default=0, type=int, metavar='N',\n                    help='manual epoch number (useful on restarts)')\nparser.add_argument('-b', '--batch-size', default=256, type=int,\n                    metavar='N',\n                    help='mini-batch size (default: 256), this is the total '\n                         'batch size of all GPUs on the current node when '\n                         'using Data Parallel or Distributed Data Parallel')\nparser.add_argument('--lr', '--learning-rate', default=0.03, type=float,\n                    metavar='LR', help='initial learning rate', dest='lr')\nparser.add_argument('--schedule', default=[120, 160], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by 10x)')\nparser.add_argument('--momentum', default=0.9, type=float, metavar='M',\n                    help='momentum of SGD solver')\nparser.add_argument('--wd', '--weight-decay', default=1e-4, type=float,\n                    metavar='W', help='weight decay (default: 1e-4)',\n                    dest='weight_decay')\nparser.add_argument('-p', '--print-freq', default=10, type=int,\n                    metavar='N', help='print frequency (default: 10)')\nparser.add_argument('--resume', default='', type=str, metavar='PATH',\n                    help='path to latest checkpoint (default: none)')\nparser.add_argument('--world-size', default=-1, type=int,\n                    help='number of nodes for distributed training')\nparser.add_argument('--rank', default=-1, type=int,\n                    help='node rank for distributed training')\nparser.add_argument('--dist-url', default='tcp://224.66.41.62:23456', type=str,\n                    help='url used to set up distributed training')\nparser.add_argument('--dist-backend', default='nccl', type=str,\n                    help='distributed backend')\nparser.add_argument('--seed', default=None, type=int,\n                    help='seed for initializing training. ')\nparser.add_argument('--gpu', default=None, type=int,\n                    help='GPU id to use.')\nparser.add_argument('--multiprocessing-distributed', action='store_true',\n                    help='Use multi-processing distributed training to launch '\n                         'N processes per node, which has N GPUs. This is the '\n                         'fastest way to use PyTorch for either single node or '\n                         'multi node data parallel training')\n\n# moco specific configs:\nparser.add_argument('--moco-dim', default=128, type=int,\n                    help='feature dimension (default: 128)')\nparser.add_argument('--moco-k', default=65536, type=int,\n                    help='queue size; number of negative keys (default: 65536)')\nparser.add_argument('--moco-m', default=0.999, type=float,\n                    help='moco momentum of updating key encoder (default: 0.999)')\nparser.add_argument('--moco-t', default=0.07, type=float,\n                    help='softmax temperature (default: 0.07)')\n\n# options for moco v2\nparser.add_argument('--mlp', action='store_true',\n                    help='use mlp head')\nparser.add_argument('--aug-plus', action='store_true',\n                    help='use moco v2 data augmentation')\nparser.add_argument('--cos', action='store_true',\n                    help='use cosine lr schedule')\n\nparser.add_argument('--normalize', action='store_true', default=False)\nparser.add_argument('--mode', nargs='*', default=['s2c'])\nparser.add_argument('--dtype', type=str, default='uint8')\nparser.add_argument('--season', type=str, default='augment')\n\nparser.add_argument('--in_size', type=int, default=224)\nparser.add_argument(\"--is_slurm_job\", action='store_true', help=\"running in slurm\")\n\n\nALL_BANDS_S2_L2A = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B9', 'B11', 'B12']\nclass SeCoDataset(torch.utils.data.Dataset):\n\n    def __init__(self,root, normalize=False, dtype='uint8'):\n        self.root = root\n        self.normalize = normalize\n        self.dtype = dtype\n        \n        self.ids = os.listdir(self.root)\n        self.length = len(self.ids)\n\n    def __getitem__(self,index):\n        \n        season = random.choice([0,1,2,3,4])\n        img_s2a_1s = self.get_array(self.ids[index], season) # [12,264,264] uint8\n\n        return img_s2a_1s\n        \n    def __len__(self):    \n        return self.length\n\n    def get_array(self, patch_id, season):\n        data_root_patch = os.path.join(self.root, patch_id)\n        patch_seasons = os.listdir(data_root_patch)\n        bands = ALL_BANDS_S2_L2A        \n        patch_id_season = patch_seasons[season]\n        chs = []\n        for i,band in enumerate(bands):\n            patch_path = os.path.join(data_root_patch,patch_id_season,f'{band}.tif')\n            with rasterio.open(patch_path) as dataset:\n                ch = dataset.read(1)\n                ch = cv2.resize(ch, dsize=(264, 264), interpolation=cv2.INTER_LINEAR_EXACT) # [264,264]\n                #ch = (ch / 10000.0 * 255).astype('uint8')                        \n            chs.append(ch)\n        img = np.stack(chs, axis=0) # [C,264,264]\n\n        if self.dtype=='uint8':\n            return (img / 10000.0 * 255.0).astype('uint8')\n        \nclass LMDBDataset(torch.utils.data.Dataset):\n\n    def __init__(self, lmdb_file, is_slurm_job=False, s2a_transform=None):\n        self.lmdb_file = lmdb_file\n        self.s2a_transform = s2a_transform\n        self.is_slurm_job = is_slurm_job\n\n        if not self.is_slurm_job:\n            self.env = lmdb.open(self.lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n            with self.env.begin(write=False) as txn:\n                self.length = txn.stat()['entries']            \n        else:\n            # Workaround to have length from the start since we don't have LMDB at initialization time\n            self.env = None\n            self.length = 160000\n\n    def _init_db(self):\n        \n        self.env = lmdb.open(self.lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n        with self.env.begin(write=False) as txn:\n            self.length = txn.stat()['entries']\n\n    def __getitem__(self, index):\n        if self.is_slurm_job:\n            # Delay loading LMDB data until after initialization\n            if self.env is None:\n                self._init_db()\n\n        with self.env.begin(write=False) as txn:\n            data = txn.get(str(index).encode())\n        \n        s2a_bytes, s2a_shape = pickle.loads(data)\n        sample_s2a = np.frombuffer(s2a_bytes, dtype=np.uint8).reshape(s2a_shape)\n        \n        if self.s2a_transform is not None:\n            sample_s2a = self.s2a_transform(sample_s2a)\n            \n        return sample_s2a\n    \n    def __len__(self):\n        return self.length\n    \n    \n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n    def __init__(self, base_transform):\n        self.base_transform = base_transform\n\n    def __call__(self, x):\n\n        x1 = np.transpose(x,(1,2,0))\n        x2 = np.transpose(x,(1,2,0))\n\n        q = self.base_transform(x1)\n        k = self.base_transform(x2)\n\n        return [q, k]\n\n\ndef main():\n\n    args = parser.parse_args()\n\n    '''\n    if args.rank==0 and not os.path.isdir(args.checkpoints):\n        os.makedirs(args.checkpoints,exist_ok=True)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints,'log'))\n    '''\n\n    if args.seed is not None:\n        random.seed(args.seed)\n        torch.manual_seed(args.seed)\n        torch.cuda.manual_seed_all(args.seed)\n        np.random.seed(args.seed)\n        '''\n        cudnn.deterministic = True\n        warnings.warn('You have chosen to seed training. '\n                      'This will turn on the CUDNN deterministic setting, '\n                      'which can slow down your training considerably! '\n                      'You may see unexpected behavior when restarting '\n                      'from checkpoints.')\n        '''\n    if args.gpu is not None:\n        warnings.warn('You have chosen a specific GPU. This will completely '\n                      'disable data parallelism.')\n\n    if args.dist_url == \"env://\" and args.world_size == -1:\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n\n    ### add slurm option ###\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n\n\n    args.distributed = args.world_size > 1 or args.multiprocessing_distributed\n\n    ngpus_per_node = torch.cuda.device_count()\n    if args.multiprocessing_distributed:\n        # Since we have ngpus_per_node processes per node, the total world_size\n        # needs to be adjusted accordingly\n        args.world_size = ngpus_per_node * args.world_size\n        # Use torch.multiprocessing.spawn to launch distributed processes: the\n        # main_worker process function\n        mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args))\n    else:\n        # Simply call main_worker function\n        main_worker(args.gpu, ngpus_per_node, args)\n\n\ndef main_worker(gpu, ngpus_per_node, args):\n    args.gpu = gpu\n\n    # suppress printing if not master\n    if args.multiprocessing_distributed and args.gpu != 0 or (args.is_slurm_job and args.rank != 0):\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n\n    if args.gpu is not None:\n        print(\"Use GPU: {} for training\".format(args.gpu))\n\n    if args.distributed:\n        if args.dist_url == \"env://\" and args.rank == -1:\n            args.rank = int(os.environ[\"RANK\"])\n        if args.multiprocessing_distributed:\n            # For multiprocessing distributed training, rank needs to be the\n            # global rank among all the processes\n            args.rank = args.rank * ngpus_per_node + gpu\n        dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                world_size=args.world_size, rank=args.rank)\n    \n    # create tb_writer\n    if args.rank==0 and not os.path.isdir(args.checkpoints):\n        os.makedirs(args.checkpoints, exist_ok=True)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints,'log'))    \n        \n    # create model\n    print(\"=> creating model '{}'\".format(args.arch))\n    model = builder.MoCo(\n        models.__dict__[args.arch],\n        args.moco_dim, args.moco_k, args.moco_m, args.moco_t, args.mlp, bands=args.bands)\n    \n    print('model created.')\n\n    if args.distributed:\n        # For multiprocessing distributed, DistributedDataParallel constructor\n        # should always set the single device scope, otherwise,\n        # DistributedDataParallel will use all available devices.\n\n        ### add slurm option ###\n        if args.is_slurm_job:            \n            args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n            torch.cuda.set_device(args.gpu_to_work_on)\n            model.cuda()\n            model = nn.parallel.DistributedDataParallel(model,device_ids=[args.gpu_to_work_on])   \n            print('model distributed.')          \n        elif args.gpu is not None:\n            torch.cuda.set_device(args.gpu)\n            model.cuda(args.gpu)\n            # When using a single GPU per process and per\n            # DistributedDataParallel, we need to divide the batch size\n            # ourselves based on the total number of GPUs we have\n            args.batch_size = int(args.batch_size / ngpus_per_node)\n            args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node)\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        else:\n            model.cuda()\n            # DistributedDataParallel will divide and allocate batch_size to all\n            # available GPUs if device_ids are not set\n            model = torch.nn.parallel.DistributedDataParallel(model)\n    elif args.gpu is not None:\n        torch.cuda.set_device(args.gpu)\n        model = model.cuda(args.gpu)\n        # comment out the following line for debugging\n        raise NotImplementedError(\"Only DistributedDataParallel is supported.\")\n    else:\n        # AllGather implementation (batch shuffle, queue update, etc.) in\n        # this code only supports DistributedDataParallel.\n        raise NotImplementedError(\"Only DistributedDataParallel is supported.\")\n\n    # define loss function (criterion) and optimizer\n    criterion = nn.CrossEntropyLoss().cuda(args.gpu)\n\n    optimizer = torch.optim.SGD(model.parameters(), args.lr,\n                                momentum=args.momentum,\n                                weight_decay=args.weight_decay)\n\n    # optionally resume from a checkpoint\n    if args.resume:\n        if os.path.isfile(args.resume):\n            print(\"=> loading checkpoint '{}'\".format(args.resume))\n            if args.gpu is None:\n                checkpoint = torch.load(args.resume)\n            else:\n                # Map model to be loaded to specified single gpu.\n                loc = 'cuda:{}'.format(args.gpu)\n                checkpoint = torch.load(args.resume, map_location=loc)\n            args.start_epoch = checkpoint['epoch']\n            model.load_state_dict(checkpoint['state_dict'])\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            print(\"=> loaded checkpoint '{}' (epoch {})\"\n                  .format(args.resume, checkpoint['epoch']))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.resume))\n\n    cudnn.benchmark = True\n\n\n    ### load dataset\n    \n    lmdb = args.lmdb\n    \n    if args.bands == 'B12':    \n        n_channels = 12\n    elif args.bands == 'B3':\n        n_channels = 3\n\n    if args.dtype=='uint8':\n        from models.rs_transforms_uint8 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\n    else:\n        from models.rs_transforms_float32 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\n        \n    train_transforms = cvtransforms.Compose([\n        #cvtransforms.Resize(128),\n        cvtransforms.RandomResizedCrop(args.in_size, scale=(0.2, 1.)),\n        cvtransforms.RandomApply([\n            RandomBrightness(0.4),\n            RandomContrast(0.4)\n        ], p=0.8),\n        cvtransforms.RandomApply([ToGray(n_channels)], p=0.2),\n        cvtransforms.RandomApply([loader.GaussianBlur([.1, 2.])], p=0.5),\n        cvtransforms.RandomHorizontalFlip(),       \n        cvtransforms.ToTensor()\n        #cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),        \n        ])\n    \n    '''\n    train_dataset = SEN12MSDataset(\n        root_dir=args.data,\n        transform=TwoCropsTransform(train_transforms),\n        mode=args.mode\n    )   \n    '''\n    train_dataset = LMDBDataset(lmdb_file=args.data, is_slurm_job=True, s2a_transform=TwoCropsTransform(train_transforms))\n        \n    if args.distributed:\n        train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)\n    else:\n        train_sampler = None\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None),\n        num_workers=args.workers, pin_memory=args.is_slurm_job, sampler=train_sampler, drop_last=True)\n\n    print('start training...')\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            train_sampler.set_epoch(epoch)\n        adjust_learning_rate(optimizer, epoch, args)\n\n        # train for one epoch\n        loss,top1,top5 = train(train_loader, model, criterion, optimizer, epoch, args)\n        if args.rank==0:    \n            tb_writer.add_scalar('loss',loss,global_step=epoch,walltime=None)\n            tb_writer.add_scalar('acc1',top1,global_step=epoch,walltime=None)\n            tb_writer.add_scalar('acc5',top5,global_step=epoch,walltime=None)\n\n\n        if epoch%10==9:\n            if args.rank==0:\n                save_checkpoint({\n                    'epoch': epoch + 1,\n                    'arch': args.arch,\n                    'state_dict': model.state_dict(),\n                    'optimizer' : optimizer.state_dict(),\n                }, is_best=False, filename=os.path.join(args.checkpoints,'checkpoint_{:04d}.pth.tar'.format(epoch)))\n    \n    print('Training finished.')\n    if args.rank==0:\n        tb_writer.close()\n\ndef train(train_loader, model, criterion, optimizer, epoch, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    data_time = AverageMeter('Data', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(train_loader),\n        [batch_time, data_time, losses, top1, top5],\n        prefix=\"Epoch: [{}]\".format(epoch))\n\n    # switch to train mode\n    model.train()\n\n    end = time.time()\n    for i, s2a in enumerate(train_loader):\n        images = s2a\n        # measure data loading time\n        data_time.update(time.time() - end)\n\n        if args.gpu is not None:\n            images[0] = images[0].cuda(args.gpu, non_blocking=True)\n            images[1] = images[1].cuda(args.gpu, non_blocking=True)\n\n        # compute output\n        output, target = model(im_q=images[0], im_k=images[1])\n        loss = criterion(output, target)\n\n        # acc1/acc5 are (K+1)-way contrast classifier accuracy\n        # measure accuracy and record loss\n        acc1, acc5 = accuracy(output, target, topk=(1, 5))\n        losses.update(loss.item(), images[0].size(0))\n        top1.update(acc1[0], images[0].size(0))\n        top5.update(acc5[0], images[0].size(0))\n\n        # compute gradient and do SGD step\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        # measure elapsed time\n        batch_time.update(time.time() - end)\n        end = time.time()\n\n        if i % args.print_freq == 0:\n            progress.display(i)\n    '''\n    if args.rank==0:    \n        tb_writer.add_scalar('loss',losses.avg,global_step=epoch,walltime=None)\n        tb_writer.add_scalar('acc1',top1.avg,global_step=epoch,walltime=None)\n        tb_writer.add_scalar('acc5',top5.avg,global_step=epoch,walltime=None)\n    '''\n    return losses.avg, top1.avg, top5.avg\n\ndef save_checkpoint(state, is_best, filename='checkpoint.pth.tar'):\n    torch.save(state, filename)\n    if is_best:\n        shutil.copyfile(filename, 'model_best.pth.tar')\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self, name, fmt=':f'):\n        self.name = name\n        self.fmt = fmt\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count\n\n    def __str__(self):\n        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'\n        return fmtstr.format(**self.__dict__)\n\n\nclass ProgressMeter(object):\n    def __init__(self, num_batches, meters, prefix=\"\"):\n        self.batch_fmtstr = self._get_batch_fmtstr(num_batches)\n        self.meters = meters\n        self.prefix = prefix\n\n    def display(self, batch):\n        entries = [self.prefix + self.batch_fmtstr.format(batch)]\n        entries += [str(meter) for meter in self.meters]\n        print('\\t'.join(entries))\n\n    def _get_batch_fmtstr(self, num_batches):\n        num_digits = len(str(num_batches // 1))\n        fmt = '{:' + str(num_digits) + 'd}'\n        return '[' + fmt + '/' + fmt.format(num_batches) + ']'\n\n                                                        \ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    if args.cos:  # cosine lr schedule\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\n    else:  # stepwise lr schedule\n        for milestone in args.schedule:\n            lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef accuracy(output, target, topk=(1,)):\n    \"\"\"Computes the accuracy over the k top predictions for the specified values of k\"\"\"\n    with torch.no_grad():\n        maxk = max(topk)\n        batch_size = target.size(0)\n\n        _, pred = output.topk(maxk, 1, True, True)\n        pred = pred.t()\n        correct = pred.eq(target.view(1, -1).expand_as(pred))\n\n        res = []\n        for k in topk:\n            correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)\n            res.append(correct_k.mul_(100.0 / batch_size))\n        return res\n\n\nif __name__ == '__main__':\n    ss_time = time.time()\n    \n    # moco-v2\n    #args.mlp = True\n    #args.moco_t = 0.2\n    #args.aug_plus = True\n    #args.cos = True\n    \n    main()\n    print('total time: %s.' % (time.time()-ss_time))\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/pretrain_moco_v2_sen12ms_ms.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport argparse\nimport builtins\nimport math\nimport os\nimport random\nimport shutil\nimport time\nimport warnings\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.parallel\nimport torch.backends.cudnn as cudnn\nimport torch.distributed as dist\nimport torch.optim\nimport torch.multiprocessing as mp\nimport torch.utils.data\nimport torch.utils.data.distributed\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\nimport torchvision.models as models\n\nfrom models.moco import loader\nfrom models.moco import builder\nimport pdb\n\n\nfrom torch.utils.tensorboard import SummaryWriter\n\n#from datasets.BigEarthNet.bigearthnet_dataset_seco import Bigearthnet\n#from datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb import LMDBDataset\n#from datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\n#from models.rs_transforms_uint8 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\nfrom cvtorchvision import cvtransforms\n#from torchsat.transforms import transforms_cls\nfrom glob import glob\nimport rasterio\nimport lmdb\nimport pickle\n\n\nmodel_names = sorted(name for name in models.__dict__\n    if name.islower() and not name.startswith(\"__\")\n    and callable(models.__dict__[name]))\n\nparser = argparse.ArgumentParser(description='PyTorch ImageNet Training')\nparser.add_argument('--data', metavar='DIR',\n                    help='path to dataset')\nparser.add_argument('--checkpoints', metavar='DIR', default='./',\n                    help='path to checkpoints')\nparser.add_argument('--save_path', metavar='DIR', default='./',\n                    help='path to save trained model')\nparser.add_argument('--bands', type=str, default='B12',\n                    help='bands to process')                    \nparser.add_argument('--lmdb', action='store_true',\n                    help='use lmdb dataset') \nparser.add_argument('-a', '--arch', metavar='ARCH', default='resnet50',\n                    choices=model_names,\n                    help='model architecture: ' +\n                        ' | '.join(model_names) +\n                        ' (default: resnet50)')\nparser.add_argument('-j', '--workers', default=32, type=int, metavar='N',\n                    help='number of data loading workers (default: 32)')\nparser.add_argument('--epochs', default=100, type=int, metavar='N',\n                    help='number of total epochs to run')\nparser.add_argument('--start-epoch', default=0, type=int, metavar='N',\n                    help='manual epoch number (useful on restarts)')\nparser.add_argument('-b', '--batch-size', default=256, type=int,\n                    metavar='N',\n                    help='mini-batch size (default: 256), this is the total '\n                         'batch size of all GPUs on the current node when '\n                         'using Data Parallel or Distributed Data Parallel')\nparser.add_argument('--lr', '--learning-rate', default=0.03, type=float,\n                    metavar='LR', help='initial learning rate', dest='lr')\nparser.add_argument('--schedule', default=[120, 160], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by 10x)')\nparser.add_argument('--momentum', default=0.9, type=float, metavar='M',\n                    help='momentum of SGD solver')\nparser.add_argument('--wd', '--weight-decay', default=1e-4, type=float,\n                    metavar='W', help='weight decay (default: 1e-4)',\n                    dest='weight_decay')\nparser.add_argument('-p', '--print-freq', default=10, type=int,\n                    metavar='N', help='print frequency (default: 10)')\nparser.add_argument('--resume', default='', type=str, metavar='PATH',\n                    help='path to latest checkpoint (default: none)')\nparser.add_argument('--world-size', default=-1, type=int,\n                    help='number of nodes for distributed training')\nparser.add_argument('--rank', default=-1, type=int,\n                    help='node rank for distributed training')\nparser.add_argument('--dist-url', default='tcp://224.66.41.62:23456', type=str,\n                    help='url used to set up distributed training')\nparser.add_argument('--dist-backend', default='nccl', type=str,\n                    help='distributed backend')\nparser.add_argument('--seed', default=None, type=int,\n                    help='seed for initializing training. ')\nparser.add_argument('--gpu', default=None, type=int,\n                    help='GPU id to use.')\nparser.add_argument('--multiprocessing-distributed', action='store_true',\n                    help='Use multi-processing distributed training to launch '\n                         'N processes per node, which has N GPUs. This is the '\n                         'fastest way to use PyTorch for either single node or '\n                         'multi node data parallel training')\n\n# moco specific configs:\nparser.add_argument('--moco-dim', default=128, type=int,\n                    help='feature dimension (default: 128)')\nparser.add_argument('--moco-k', default=65536, type=int,\n                    help='queue size; number of negative keys (default: 65536)')\nparser.add_argument('--moco-m', default=0.999, type=float,\n                    help='moco momentum of updating key encoder (default: 0.999)')\nparser.add_argument('--moco-t', default=0.07, type=float,\n                    help='softmax temperature (default: 0.07)')\n\n# options for moco v2\nparser.add_argument('--mlp', action='store_true',\n                    help='use mlp head')\nparser.add_argument('--aug-plus', action='store_true',\n                    help='use moco v2 data augmentation')\nparser.add_argument('--cos', action='store_true',\n                    help='use cosine lr schedule')\n\nparser.add_argument('--normalize', action='store_true', default=False)\nparser.add_argument('--mode', nargs='*', default=['s2c'])\nparser.add_argument('--dtype', type=str, default='uint8')\nparser.add_argument('--season', type=str, default='augment')\n\nparser.add_argument('--in_size', type=int, default=224)\nparser.add_argument(\"--is_slurm_job\", action='store_true', help=\"running in slurm\")\n\n\nclass SEN12MSDataset(torch.utils.data.Dataset):\n    def __init__(self, root_dir, mode, transform):\n        self.fnames = glob(os.path.join(root_dir,'*/*/*.tif'))\n        self.mode = mode\n        self.length = len(self.fnames)\n        self.transform = transform\n        \n    def __getitem__(self,index):\n        fname = self.fnames[index]\n        \n        with rasterio.open(fname) as rf:\n            if self.mode=='rgb':\n                data = rf.read((4,3,2))\n            else:\n                data = rf.read()\n        \n        data = (data / 10000 * 255).astype('uint8')\n        \n        if self.transform is not None:\n            data = self.transform(data)\n        \n        return data\n    \n    def __len__(self):\n        return self.length\n    \n    \nclass LMDBDataset(torch.utils.data.Dataset):\n\n    def __init__(self, lmdb_file, is_slurm_job=False, s2c_transform=None):\n        self.lmdb_file = lmdb_file\n        self.s2c_transform = s2c_transform\n        self.is_slurm_job = is_slurm_job\n\n        if not self.is_slurm_job:\n            self.env = lmdb.open(self.lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n            with self.env.begin(write=False) as txn:\n                self.length = txn.stat()['entries']            \n        else:\n            # Workaround to have length from the start since we don't have LMDB at initialization time\n            self.env = None\n            self.length = 180000\n\n    def _init_db(self):\n        \n        self.env = lmdb.open(self.lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n        with self.env.begin(write=False) as txn:\n            self.length = txn.stat()['entries']\n\n    def __getitem__(self, index):\n        if self.is_slurm_job:\n            # Delay loading LMDB data until after initialization\n            if self.env is None:\n                self._init_db()\n\n        with self.env.begin(write=False) as txn:\n            data = txn.get(str(index).encode())\n        \n        s2c_bytes, s2c_shape = pickle.loads(data)\n        sample_s2c = np.frombuffer(s2c_bytes, dtype=np.uint8).reshape(s2c_shape)\n        \n        if self.s2c_transform is not None:\n            sample_s2c = self.s2c_transform(sample_s2c)\n            \n        return sample_s2c\n    \n    def __len__(self):\n        return self.length\n    \n    \n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n    def __init__(self, base_transform):\n        self.base_transform = base_transform\n\n    def __call__(self, x):\n\n        x1 = np.transpose(x,(1,2,0))\n        x2 = np.transpose(x,(1,2,0))\n\n        q = self.base_transform(x1)\n        k = self.base_transform(x2)\n\n        return [q, k]\n\n\ndef main():\n\n    args = parser.parse_args()\n\n    '''\n    if args.rank==0 and not os.path.isdir(args.checkpoints):\n        os.makedirs(args.checkpoints,exist_ok=True)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints,'log'))\n    '''\n\n    if args.seed is not None:\n        random.seed(args.seed)\n        torch.manual_seed(args.seed)\n        torch.cuda.manual_seed_all(args.seed)\n        np.random.seed(args.seed)\n        '''\n        cudnn.deterministic = True\n        warnings.warn('You have chosen to seed training. '\n                      'This will turn on the CUDNN deterministic setting, '\n                      'which can slow down your training considerably! '\n                      'You may see unexpected behavior when restarting '\n                      'from checkpoints.')\n        '''\n    if args.gpu is not None:\n        warnings.warn('You have chosen a specific GPU. This will completely '\n                      'disable data parallelism.')\n\n    if args.dist_url == \"env://\" and args.world_size == -1:\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n\n    ### add slurm option ###\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n\n\n    args.distributed = args.world_size > 1 or args.multiprocessing_distributed\n\n    ngpus_per_node = torch.cuda.device_count()\n    if args.multiprocessing_distributed:\n        # Since we have ngpus_per_node processes per node, the total world_size\n        # needs to be adjusted accordingly\n        args.world_size = ngpus_per_node * args.world_size\n        # Use torch.multiprocessing.spawn to launch distributed processes: the\n        # main_worker process function\n        mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args))\n    else:\n        # Simply call main_worker function\n        main_worker(args.gpu, ngpus_per_node, args)\n\n\ndef main_worker(gpu, ngpus_per_node, args):\n    args.gpu = gpu\n\n    # suppress printing if not master\n    if args.multiprocessing_distributed and args.gpu != 0 or (args.is_slurm_job and args.rank != 0):\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n\n    if args.gpu is not None:\n        print(\"Use GPU: {} for training\".format(args.gpu))\n\n    if args.distributed:\n        if args.dist_url == \"env://\" and args.rank == -1:\n            args.rank = int(os.environ[\"RANK\"])\n        if args.multiprocessing_distributed:\n            # For multiprocessing distributed training, rank needs to be the\n            # global rank among all the processes\n            args.rank = args.rank * ngpus_per_node + gpu\n        dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                world_size=args.world_size, rank=args.rank)\n    \n    # create tb_writer\n    if args.rank==0 and not os.path.isdir(args.checkpoints):\n        os.makedirs(args.checkpoints, exist_ok=True)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints,'log'))    \n        \n    # create model\n    print(\"=> creating model '{}'\".format(args.arch))\n    model = builder.MoCo(\n        models.__dict__[args.arch],\n        args.moco_dim, args.moco_k, args.moco_m, args.moco_t, args.mlp, bands=args.bands)\n    \n    print('model created.')\n\n    if args.distributed:\n        # For multiprocessing distributed, DistributedDataParallel constructor\n        # should always set the single device scope, otherwise,\n        # DistributedDataParallel will use all available devices.\n\n        ### add slurm option ###\n        if args.is_slurm_job:            \n            args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n            torch.cuda.set_device(args.gpu_to_work_on)\n            model.cuda()\n            model = nn.parallel.DistributedDataParallel(model,device_ids=[args.gpu_to_work_on])   \n            print('model distributed.')          \n        elif args.gpu is not None:\n            torch.cuda.set_device(args.gpu)\n            model.cuda(args.gpu)\n            # When using a single GPU per process and per\n            # DistributedDataParallel, we need to divide the batch size\n            # ourselves based on the total number of GPUs we have\n            args.batch_size = int(args.batch_size / ngpus_per_node)\n            args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node)\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        else:\n            model.cuda()\n            # DistributedDataParallel will divide and allocate batch_size to all\n            # available GPUs if device_ids are not set\n            model = torch.nn.parallel.DistributedDataParallel(model)\n    elif args.gpu is not None:\n        torch.cuda.set_device(args.gpu)\n        model = model.cuda(args.gpu)\n        # comment out the following line for debugging\n        raise NotImplementedError(\"Only DistributedDataParallel is supported.\")\n    else:\n        # AllGather implementation (batch shuffle, queue update, etc.) in\n        # this code only supports DistributedDataParallel.\n        raise NotImplementedError(\"Only DistributedDataParallel is supported.\")\n\n    # define loss function (criterion) and optimizer\n    criterion = nn.CrossEntropyLoss().cuda(args.gpu)\n\n    optimizer = torch.optim.SGD(model.parameters(), args.lr,\n                                momentum=args.momentum,\n                                weight_decay=args.weight_decay)\n\n    # optionally resume from a checkpoint\n    if args.resume:\n        if os.path.isfile(args.resume):\n            print(\"=> loading checkpoint '{}'\".format(args.resume))\n            if args.gpu is None:\n                checkpoint = torch.load(args.resume)\n            else:\n                # Map model to be loaded to specified single gpu.\n                loc = 'cuda:{}'.format(args.gpu)\n                checkpoint = torch.load(args.resume, map_location=loc)\n            args.start_epoch = checkpoint['epoch']\n            model.load_state_dict(checkpoint['state_dict'])\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            print(\"=> loaded checkpoint '{}' (epoch {})\"\n                  .format(args.resume, checkpoint['epoch']))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.resume))\n\n    cudnn.benchmark = True\n\n\n    ### load dataset\n    \n    lmdb = args.lmdb\n    \n    if args.bands == 'B13':    \n        n_channels = 13\n    elif args.bands == 'B3':\n        n_channels = 3\n\n    if args.dtype=='uint8':\n        from models.rs_transforms_uint8 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\n    else:\n        from models.rs_transforms_float32 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\n        \n    train_transforms = cvtransforms.Compose([\n        #cvtransforms.Resize(128),\n        cvtransforms.RandomResizedCrop(args.in_size, scale=(0.2, 1.)),\n        cvtransforms.RandomApply([\n            RandomBrightness(0.4),\n            RandomContrast(0.4)\n        ], p=0.8),\n        cvtransforms.RandomApply([ToGray(n_channels)], p=0.2),\n        cvtransforms.RandomApply([loader.GaussianBlur([.1, 2.])], p=0.5),\n        cvtransforms.RandomHorizontalFlip(),       \n        cvtransforms.ToTensor()\n        #cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),        \n        ])\n    \n    '''\n    train_dataset = SEN12MSDataset(\n        root_dir=args.data,\n        transform=TwoCropsTransform(train_transforms),\n        mode=args.mode\n    )   \n    '''\n    train_dataset = LMDBDataset(lmdb_file=args.data, is_slurm_job=True, s2c_transform=TwoCropsTransform(train_transforms))\n        \n    if args.distributed:\n        train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)\n    else:\n        train_sampler = None\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None),\n        num_workers=args.workers, pin_memory=args.is_slurm_job, sampler=train_sampler, drop_last=True)\n\n    print('start training...')\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            train_sampler.set_epoch(epoch)\n        adjust_learning_rate(optimizer, epoch, args)\n\n        # train for one epoch\n        loss,top1,top5 = train(train_loader, model, criterion, optimizer, epoch, args)\n        if args.rank==0:    \n            tb_writer.add_scalar('loss',loss,global_step=epoch,walltime=None)\n            tb_writer.add_scalar('acc1',top1,global_step=epoch,walltime=None)\n            tb_writer.add_scalar('acc5',top5,global_step=epoch,walltime=None)\n\n\n        if epoch%10==9:\n            if args.rank==0:\n                save_checkpoint({\n                    'epoch': epoch + 1,\n                    'arch': args.arch,\n                    'state_dict': model.state_dict(),\n                    'optimizer' : optimizer.state_dict(),\n                }, is_best=False, filename=os.path.join(args.checkpoints,'checkpoint_{:04d}.pth.tar'.format(epoch)))\n    \n    print('Training finished.')\n    if args.rank==0:\n        tb_writer.close()\n\ndef train(train_loader, model, criterion, optimizer, epoch, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    data_time = AverageMeter('Data', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(train_loader),\n        [batch_time, data_time, losses, top1, top5],\n        prefix=\"Epoch: [{}]\".format(epoch))\n\n    # switch to train mode\n    model.train()\n\n    end = time.time()\n    for i, s2c in enumerate(train_loader):\n        images = s2c\n        # measure data loading time\n        data_time.update(time.time() - end)\n\n        if args.gpu is not None:\n            images[0] = images[0].cuda(args.gpu, non_blocking=True)\n            images[1] = images[1].cuda(args.gpu, non_blocking=True)\n\n        # compute output\n        output, target = model(im_q=images[0], im_k=images[1])\n        loss = criterion(output, target)\n\n        # acc1/acc5 are (K+1)-way contrast classifier accuracy\n        # measure accuracy and record loss\n        acc1, acc5 = accuracy(output, target, topk=(1, 5))\n        losses.update(loss.item(), images[0].size(0))\n        top1.update(acc1[0], images[0].size(0))\n        top5.update(acc5[0], images[0].size(0))\n\n        # compute gradient and do SGD step\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        # measure elapsed time\n        batch_time.update(time.time() - end)\n        end = time.time()\n\n        if i % args.print_freq == 0:\n            progress.display(i)\n    '''\n    if args.rank==0:    \n        tb_writer.add_scalar('loss',losses.avg,global_step=epoch,walltime=None)\n        tb_writer.add_scalar('acc1',top1.avg,global_step=epoch,walltime=None)\n        tb_writer.add_scalar('acc5',top5.avg,global_step=epoch,walltime=None)\n    '''\n    return losses.avg, top1.avg, top5.avg\n\ndef save_checkpoint(state, is_best, filename='checkpoint.pth.tar'):\n    torch.save(state, filename)\n    if is_best:\n        shutil.copyfile(filename, 'model_best.pth.tar')\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self, name, fmt=':f'):\n        self.name = name\n        self.fmt = fmt\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count\n\n    def __str__(self):\n        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'\n        return fmtstr.format(**self.__dict__)\n\n\nclass ProgressMeter(object):\n    def __init__(self, num_batches, meters, prefix=\"\"):\n        self.batch_fmtstr = self._get_batch_fmtstr(num_batches)\n        self.meters = meters\n        self.prefix = prefix\n\n    def display(self, batch):\n        entries = [self.prefix + self.batch_fmtstr.format(batch)]\n        entries += [str(meter) for meter in self.meters]\n        print('\\t'.join(entries))\n\n    def _get_batch_fmtstr(self, num_batches):\n        num_digits = len(str(num_batches // 1))\n        fmt = '{:' + str(num_digits) + 'd}'\n        return '[' + fmt + '/' + fmt.format(num_batches) + ']'\n\n                                                        \ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    if args.cos:  # cosine lr schedule\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\n    else:  # stepwise lr schedule\n        for milestone in args.schedule:\n            lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef accuracy(output, target, topk=(1,)):\n    \"\"\"Computes the accuracy over the k top predictions for the specified values of k\"\"\"\n    with torch.no_grad():\n        maxk = max(topk)\n        batch_size = target.size(0)\n\n        _, pred = output.topk(maxk, 1, True, True)\n        pred = pred.t()\n        correct = pred.eq(target.view(1, -1).expand_as(pred))\n\n        res = []\n        for k in topk:\n            correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)\n            res.append(correct_k.mul_(100.0 / batch_size))\n        return res\n\n\nif __name__ == '__main__':\n    ss_time = time.time()\n    \n    # moco-v2\n    #args.mlp = True\n    #args.moco_t = 0.2\n    #args.aug_plus = True\n    #args.cos = True\n    \n    main()\n    print('total time: %s.' % (time.time()-ss_time))\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/pretrain_moco_v3_s2c.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport argparse\nimport builtins\nimport math\nimport os\nimport random\nimport shutil\nimport time\nimport warnings\nfrom functools import partial\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.parallel\nimport torch.backends.cudnn as cudnn\nimport torch.distributed as dist\nimport torch.optim\nimport torch.multiprocessing as mp\nimport torch.utils.data\nimport torch.utils.data.distributed\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\nimport torchvision.models as torchvision_models\nfrom torch.utils.tensorboard import SummaryWriter\n\nfrom models.moco_v3 import builder as moco_builder\nfrom models.moco_v3 import loader as moco_loader\nfrom models.moco_v3 import optimizer as moco_optimizer\n\nfrom models.moco_v3 import vits\n\n#from datasets.BigEarthNet.bigearthnet_dataset_seco import Bigearthnet\n#from datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb import LMDBDataset\nfrom datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\nfrom cvtorchvision import cvtransforms\n\n\n\ntorchvision_model_names = sorted(name for name in torchvision_models.__dict__\n    if name.islower() and not name.startswith(\"__\")\n    and callable(torchvision_models.__dict__[name]))\n\nmodel_names = ['vit_small', 'vit_base', 'vit_conv_small', 'vit_conv_base'] + torchvision_model_names\n\nparser = argparse.ArgumentParser(description='MoCo ImageNet Pre-Training')\nparser.add_argument('--data', metavar='DIR',\n                    help='path to dataset')\nparser.add_argument('-a', '--arch', metavar='ARCH', default='resnet50',\n                    choices=model_names,\n                    help='model architecture: ' +\n                        ' | '.join(model_names) +\n                        ' (default: resnet50)')\nparser.add_argument('-j', '--workers', default=32, type=int, metavar='N',\n                    help='number of data loading workers (default: 32)')\nparser.add_argument('--epochs', default=100, type=int, metavar='N',\n                    help='number of total epochs to run')\nparser.add_argument('--start-epoch', default=0, type=int, metavar='N',\n                    help='manual epoch number (useful on restarts)')\nparser.add_argument('-b', '--batch-size', default=4096, type=int,\n                    metavar='N',\n                    help='mini-batch size (default: 4096), this is the total '\n                         'batch size of all GPUs on all nodes when '\n                         'using Data Parallel or Distributed Data Parallel')\nparser.add_argument('--lr', '--learning-rate', default=0.6, type=float,\n                    metavar='LR', help='initial (base) learning rate', dest='lr')\nparser.add_argument('--momentum', default=0.9, type=float, metavar='M',\n                    help='momentum')\nparser.add_argument('--wd', '--weight-decay', default=1e-6, type=float,\n                    metavar='W', help='weight decay (default: 1e-6)',\n                    dest='weight_decay')\nparser.add_argument('-p', '--print-freq', default=10, type=int,\n                    metavar='N', help='print frequency (default: 10)')\nparser.add_argument('--resume', default='', type=str, metavar='PATH',\n                    help='path to latest checkpoint (default: none)')\nparser.add_argument('--world-size', default=-1, type=int,\n                    help='number of nodes for distributed training')\nparser.add_argument('--rank', default=-1, type=int,\n                    help='node rank for distributed training')\nparser.add_argument('--dist-url', default='tcp://224.66.41.62:23456', type=str,\n                    help='url used to set up distributed training')\nparser.add_argument('--dist-backend', default='nccl', type=str,\n                    help='distributed backend')\nparser.add_argument('--seed', default=None, type=int,\n                    help='seed for initializing training. ')\nparser.add_argument('--gpu', default=None, type=int,\n                    help='GPU id to use.')\nparser.add_argument('--multiprocessing-distributed', action='store_true',\n                    help='Use multi-processing distributed training to launch '\n                         'N processes per node, which has N GPUs. This is the '\n                         'fastest way to use PyTorch for either single node or '\n                         'multi node data parallel training')\n\n# moco specific configs:\nparser.add_argument('--moco-dim', default=256, type=int,\n                    help='feature dimension (default: 256)')\nparser.add_argument('--moco-mlp-dim', default=4096, type=int,\n                    help='hidden dimension in MLPs (default: 4096)')\nparser.add_argument('--moco-m', default=0.99, type=float,\n                    help='moco momentum of updating momentum encoder (default: 0.99)')\nparser.add_argument('--moco-m-cos', action='store_true',\n                    help='gradually increase moco momentum to 1 with a '\n                         'half-cycle cosine schedule')\nparser.add_argument('--moco-t', default=1.0, type=float,\n                    help='softmax temperature (default: 1.0)')\n\n# vit specific configs:\nparser.add_argument('--stop-grad-conv1', action='store_true',\n                    help='stop-grad after first conv, or patch embedding')\n\n# other upgrades\nparser.add_argument('--optimizer', default='lars', type=str,\n                    choices=['lars', 'adamw'],\n                    help='optimizer used (default: lars)')\nparser.add_argument('--warmup-epochs', default=10, type=int, metavar='N',\n                    help='number of warmup epochs')\nparser.add_argument('--crop-min', default=0.08, type=float,\n                    help='minimum scale for random cropping (default: 0.08)')\n\nparser.add_argument('--bands', type=str, default='all', help=\"input bands\")\nparser.add_argument(\"--lmdb\", action='store_true', help=\"use lmdb dataset\")\nparser.add_argument('--patch-size', default=16, type=int, help='vit patch size')\nparser.add_argument('--checkpoints', metavar='DIR', default='./',\n                    help='path to checkpoints')\n\n\n\nparser.add_argument('--normalize', action='store_true', default=False)\nparser.add_argument('--mode', nargs='*', default=['s2c'])\nparser.add_argument('--dtype', type=str, default='uint8')\nparser.add_argument('--season', type=str, default='augment')\nparser.add_argument('--in_size', type=int, default=224)\n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n    def __init__(self, base_transform1, base_transform2, season='fixed'):\n        self.base_transform1 = base_transform1\n        self.base_transform2 = base_transform2\n        self.season = season\n\n    def __call__(self, x):\n\n        if self.season=='augment':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = np.random.choice([0,1,2,3])\n        elif self.season=='fixed':\n            np.random.seed(42)\n            season1 = np.random.choice([0,1,2,3])\n            season2 = season1\n        elif self.season=='random':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = season1\n\n        x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n        x2 = np.transpose(x[season2,:,:,:],(1,2,0))\n\n        q = self.base_transform1(x1)\n        k = self.base_transform2(x2)\n\n        return [q, k]\n\n\n\ndef main():\n    args = parser.parse_args()\n\n    if args.seed is not None:\n        random.seed(args.seed)\n        torch.manual_seed(args.seed)\n        cudnn.deterministic = True\n        warnings.warn('You have chosen to seed training. '\n                      'This will turn on the CUDNN deterministic setting, '\n                      'which can slow down your training considerably! '\n                      'You may see unexpected behavior when restarting '\n                      'from checkpoints.')\n\n    if args.gpu is not None:\n        warnings.warn('You have chosen a specific GPU. This will completely '\n                      'disable data parallelism.')\n\n    if args.dist_url == \"env://\" and args.world_size == -1:\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n    ### add slurm option ###\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n\n\n    args.distributed = args.world_size > 1 or args.multiprocessing_distributed\n\n    ngpus_per_node = torch.cuda.device_count()\n    if args.multiprocessing_distributed:\n        # Since we have ngpus_per_node processes per node, the total world_size\n        # needs to be adjusted accordingly\n        args.world_size = ngpus_per_node * args.world_size\n        # Use torch.multiprocessing.spawn to launch distributed processes: the\n        # main_worker process function\n        mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args))\n    else:\n        # Simply call main_worker function\n        main_worker(args.gpu, ngpus_per_node, args)\n\n\ndef main_worker(gpu, ngpus_per_node, args):\n    args.gpu = gpu\n\n    # suppress printing if not first GPU on each node\n    if args.is_slurm_job and args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n\n    if args.gpu is not None:\n        print(\"Use GPU: {} for training\".format(args.gpu))\n\n    if args.distributed:\n        if args.dist_url == \"env://\" and args.rank == -1:\n            args.rank = int(os.environ[\"RANK\"])\n        if args.multiprocessing_distributed:\n            # For multiprocessing distributed training, rank needs to be the\n            # global rank among all the processes\n            args.rank = args.rank * ngpus_per_node + gpu\n        dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                world_size=args.world_size, rank=args.rank)\n        torch.distributed.barrier()\n    # create model\n    print(\"=> creating model '{}'\".format(args.arch))\n    if args.arch.startswith('vit'):\n        model = moco_builder.MoCo_ViT(\n            partial(vits.__dict__[args.arch], stop_grad_conv1=args.stop_grad_conv1, in_chans=13),\n            args.moco_dim, args.moco_mlp_dim, args.moco_t)\n    else:\n        model = moco_builder.MoCo_ResNet(\n            partial(torchvision_models.__dict__[args.arch], zero_init_residual=True), \n            args.moco_dim, args.moco_mlp_dim, args.moco_t)\n\n    # infer learning rate before changing batch size\n    #args.lr = args.lr * args.batch_size / 256\n\n    if not torch.cuda.is_available():\n        print('using CPU, this will be slow')\n    elif args.distributed:\n        # apply SyncBN\n        model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(model)\n        # For multiprocessing distributed, DistributedDataParallel constructor\n        # should always set the single device scope, otherwise,\n        # DistributedDataParallel will use all available devices.\n        \n        ### add slurm option ###\n        if args.is_slurm_job:            \n            args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n            torch.cuda.set_device(args.gpu_to_work_on)\n            model.cuda()\n            model = nn.parallel.DistributedDataParallel(model,device_ids=[args.gpu_to_work_on])   \n            print('model distributed.')\n                        \n        elif args.gpu is not None:\n            torch.cuda.set_device(args.gpu)\n            model.cuda(args.gpu)\n            # When using a single GPU per process and per\n            # DistributedDataParallel, we need to divide the batch size\n            # ourselves based on the total number of GPUs we have\n            args.batch_size = int(args.batch_size / args.world_size)\n            args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node)\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        else:\n            model.cuda()\n            # DistributedDataParallel will divide and allocate batch_size to all\n            # available GPUs if device_ids are not set\n            model = torch.nn.parallel.DistributedDataParallel(model)\n    elif args.gpu is not None:\n        torch.cuda.set_device(args.gpu)\n        model = model.cuda(args.gpu)\n        # comment out the following line for debugging\n        #raise NotImplementedError(\"Only DistributedDataParallel is supported.\")\n    else:\n        # AllGather/rank implementation in this code only supports DistributedDataParallel.\n        raise NotImplementedError(\"Only DistributedDataParallel is supported.\")\n    #print(model) # print model after SyncBatchNorm\n\n    if args.optimizer == 'lars':\n        optimizer = moco_optimizer.LARS(model.parameters(), args.lr,\n                                        weight_decay=args.weight_decay,\n                                        momentum=args.momentum)\n    elif args.optimizer == 'adamw':\n        optimizer = torch.optim.AdamW(model.parameters(), args.lr,\n                                weight_decay=args.weight_decay)\n        \n    scaler = torch.cuda.amp.GradScaler()\n    summary_writer = SummaryWriter() if args.rank == 0 else None\n\n    # optionally resume from a checkpoint\n    if args.resume:\n        if os.path.isfile(args.resume):\n            print(\"=> loading checkpoint '{}'\".format(args.resume))\n            if args.gpu is None:\n                checkpoint = torch.load(args.resume)\n            else:\n                # Map model to be loaded to specified single gpu.\n                loc = 'cuda:{}'.format(args.gpu)\n                checkpoint = torch.load(args.resume, map_location=loc)\n            args.start_epoch = checkpoint['epoch']\n            model.load_state_dict(checkpoint['state_dict'])\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            scaler.load_state_dict(checkpoint['scaler'])\n            print(\"=> loaded checkpoint '{}' (epoch {})\"\n                  .format(args.resume, checkpoint['epoch']))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.resume))\n\n    cudnn.benchmark = True\n\n    '''\n    # Data loading code\n    traindir = os.path.join(args.data, 'train')\n    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                     std=[0.229, 0.224, 0.225])\n\n    # follow BYOL's augmentation recipe: https://arxiv.org/abs/2006.07733\n    augmentation1 = [\n        transforms.RandomResizedCrop(224, scale=(args.crop_min, 1.)),\n        transforms.RandomApply([\n            transforms.ColorJitter(0.4, 0.4, 0.2, 0.1)  # not strengthened\n        ], p=0.8),\n        transforms.RandomGrayscale(p=0.2),\n        transforms.RandomApply([moco_loader.GaussianBlur([.1, 2.])], p=1.0),\n        transforms.RandomHorizontalFlip(),\n        transforms.ToTensor(),\n        normalize\n    ]\n\n    augmentation2 = [\n        transforms.RandomResizedCrop(224, scale=(args.crop_min, 1.)),\n        transforms.RandomApply([\n            transforms.ColorJitter(0.4, 0.4, 0.2, 0.1)  # not strengthened\n        ], p=0.8),\n        transforms.RandomGrayscale(p=0.2),\n        transforms.RandomApply([moco_loader.GaussianBlur([.1, 2.])], p=0.1),\n        transforms.RandomApply([moco_loader.Solarize()], p=0.2),\n        transforms.RandomHorizontalFlip(),\n        transforms.ToTensor(),\n        normalize\n    ]\n\n    train_dataset = datasets.ImageFolder(\n        traindir,\n        moco_loader.TwoCropsTransform(transforms.Compose(augmentation1), \n                                      transforms.Compose(augmentation2)))\n    '''\n    \n\n    if args.bands == 'B13':    \n        n_channels = 13\n    elif args.bands == 'B12':\n        n_channels = 12\n\n    if args.dtype=='uint8':\n        from models.rs_transforms_uint8 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\n    else:\n        from models.rs_transforms_float32 import RandomChannelDrop,RandomBrightness,RandomContrast,ToGray\n\n\n    # follow BYOL's augmentation recipe: https://arxiv.org/abs/2006.07733\n    augmentation1 = [\n        cvtransforms.RandomResizedCrop(args.in_size, scale=(args.crop_min, 1.)),\n        cvtransforms.RandomApply([\n            RandomBrightness(0.4),\n            RandomContrast(0.4)\n        ], p=0.8),\n        cvtransforms.RandomApply([ToGray(n_channels)], p=0.2),\n        cvtransforms.RandomApply([moco_loader.GaussianBlur([.1, 2.])], p=1.0),\n        cvtransforms.RandomHorizontalFlip(),\n        cvtransforms.ToTensor(),\n        #cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),           \n        #normalize\n    ]\n\n    \n    augmentation2 = [\n        cvtransforms.RandomResizedCrop(args.in_size, scale=(args.crop_min, 1.)),\n        cvtransforms.RandomApply([\n            RandomBrightness(0.4),\n            RandomContrast(0.4)\n        ], p=0.8),\n        cvtransforms.RandomApply([ToGray(n_channels)], p=0.2),\n        cvtransforms.RandomApply([moco_loader.GaussianBlur([.1, 2.])], p=0.1),\n        cvtransforms.RandomHorizontalFlip(),  \n        cvtransforms.ToTensor(),\n        #cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),         \n        #normalize\n    ]\n    \n    \n    train_dataset = LMDBDataset(\n        lmdb_file=args.data,\n        s2c_transform=TwoCropsTransform(base_transform1=cvtransforms.Compose(augmentation1), base_transform2 = cvtransforms.Compose(augmentation2),season=args.season),\n        is_slurm_job=args.is_slurm_job,\n        normalize=args.normalize,\n        dtype=args.dtype,\n        mode=args.mode\n    )\n    \n\n    if args.distributed:\n        train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)\n    else:\n        train_sampler = None\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None),\n        num_workers=args.workers, pin_memory=True, sampler=train_sampler, drop_last=True)\n\n    os.makedirs(args.checkpoints,exist_ok=True)\n    \n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            train_sampler.set_epoch(epoch)\n\n        # train for one epoch\n        train(train_loader, model, optimizer, scaler, summary_writer, epoch, args)\n        if epoch%5==4:\n            if not args.multiprocessing_distributed or (args.multiprocessing_distributed\n                    and args.rank == 0): # only the first GPU saves checkpoint\n                save_checkpoint({\n                    'epoch': epoch + 1,\n                    'arch': args.arch,\n                    'state_dict': model.state_dict(),\n                    'optimizer' : optimizer.state_dict(),\n                    'scaler': scaler.state_dict(),\n                }, is_best=False, filename=os.path.join(args.checkpoints,'checkpoint_%04d.pth.tar' % epoch))\n\n    if args.rank == 0:\n        summary_writer.close()\n\ndef train(train_loader, model, optimizer, scaler, summary_writer, epoch, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    data_time = AverageMeter('Data', ':6.3f')\n    learning_rates = AverageMeter('LR', ':.4e')\n    losses = AverageMeter('Loss', ':.4e')\n    progress = ProgressMeter(\n        len(train_loader),\n        [batch_time, data_time, learning_rates, losses],\n        prefix=\"Epoch: [{}]\".format(epoch))\n\n    # switch to train mode\n    model.train()\n\n    end = time.time()\n    iters_per_epoch = len(train_loader)\n    moco_m = args.moco_m\n    for i, (images) in enumerate(train_loader):\n        # measure data loading time\n        data_time.update(time.time() - end)\n\n        # adjust learning rate and momentum coefficient per iteration\n        lr = adjust_learning_rate(optimizer, epoch + i / iters_per_epoch, args)\n        learning_rates.update(lr)\n        if args.moco_m_cos:\n            moco_m = adjust_moco_momentum(epoch + i / iters_per_epoch, args)\n\n        if args.gpu is not None:\n            images[0] = images[0].cuda(args.gpu, non_blocking=True)\n            images[1] = images[1].cuda(args.gpu, non_blocking=True)\n        # compute output\n        with torch.cuda.amp.autocast(True):\n            loss = model(images[0], images[1], moco_m)\n\n        losses.update(loss.item(), images[0].size(0))\n        if args.rank == 0:\n            summary_writer.add_scalar(\"loss\", loss.item(), epoch * iters_per_epoch + i)\n\n        # compute gradient and do SGD step\n        optimizer.zero_grad()\n        scaler.scale(loss).backward()\n        scaler.step(optimizer)\n        scaler.update()\n\n        # measure elapsed time\n        batch_time.update(time.time() - end)\n        end = time.time()\n\n        if i % args.print_freq == 0:\n            progress.display(i)\n\n\ndef save_checkpoint(state, is_best, filename='checkpoint.pth.tar'):\n    torch.save(state, filename)\n    if is_best:\n        shutil.copyfile(filename, 'model_best.pth.tar')\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self, name, fmt=':f'):\n        self.name = name\n        self.fmt = fmt\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count\n\n    def __str__(self):\n        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'\n        return fmtstr.format(**self.__dict__)\n\n\nclass ProgressMeter(object):\n    def __init__(self, num_batches, meters, prefix=\"\"):\n        self.batch_fmtstr = self._get_batch_fmtstr(num_batches)\n        self.meters = meters\n        self.prefix = prefix\n\n    def display(self, batch):\n        entries = [self.prefix + self.batch_fmtstr.format(batch)]\n        entries += [str(meter) for meter in self.meters]\n        print('\\t'.join(entries))\n\n    def _get_batch_fmtstr(self, num_batches):\n        num_digits = len(str(num_batches // 1))\n        fmt = '{:' + str(num_digits) + 'd}'\n        return '[' + fmt + '/' + fmt.format(num_batches) + ']'\n\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decays the learning rate with half-cycle cosine after warmup\"\"\"\n    if epoch < args.warmup_epochs:\n        lr = args.lr * epoch / args.warmup_epochs \n    else:\n        lr = args.lr * 0.5 * (1. + math.cos(math.pi * (epoch - args.warmup_epochs) / (args.epochs - args.warmup_epochs)))\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n    return lr\n\n\ndef adjust_moco_momentum(epoch, args):\n    \"\"\"Adjust moco momentum based on current epoch\"\"\"\n    m = 1. - 0.5 * (1. + math.cos(math.pi * epoch / args.epochs)) * (1. - args.moco_m)\n    return m\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/srun_train_SEN12MS_moco_rn50_rgb.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/B3_train_SEN12MS_moco_rn50_%j.out\n#SBATCH --error=srun_outputs/B3_train_SEN12MS_moco_rn50_%j.err\n#SBATCH --time=23:50:00\n#SBATCH --job-name=pretrain_moco_rn50\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u pretrain_moco_v2_sen12ms_ms.py \\\n--is_slurm_job \\\n--data /p/project/hai_ssl4eo/wang_yi/data/SEN12MS/SEN12MS_rgb_uint8.lmdb \\\n--checkpoints /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B3_rn50_224 \\\n--bands B3 \\\n--lmdb \\\n--arch resnet50 \\\n--workers 8 \\\n--batch-size 64 \\\n--epochs 100 \\\n--lr 0.03 \\\n--mlp \\\n--moco-t 0.2 \\\n--aug-plus \\\n--cos \\\n--dist-url $dist_url \\\n--dist-backend 'nccl' \\\n--seed 42 \\\n--mode rgb \\\n--dtype uint8 \\\n--season augment \\\n--in_size 224 \\\n#--resume /p/project/hai_dm4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn18_int16/checkpoint_0059.pth.tar\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/srun_train_SEN12MS_moco_rn50_s2c.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/B13_train_SEN12MS_moco_rn50_%j.out\n#SBATCH --error=srun_outputs/B13_train_SEN12MS_moco_rn50_%j.err\n#SBATCH --time=20:00:00\n#SBATCH --job-name=pretrain_moco_rn50\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u pretrain_moco_v2_sen12ms_ms.py \\\n--is_slurm_job \\\n--data /p/project/hai_ssl4eo/wang_yi/data/SEN12MS/SEN12MS_s2c_uint8.lmdb \\\n--checkpoints /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B13_rn50_224 \\\n--bands B13 \\\n--lmdb \\\n--arch resnet50 \\\n--workers 8 \\\n--batch-size 64 \\\n--epochs 100 \\\n--lr 0.03 \\\n--mlp \\\n--moco-t 0.2 \\\n--aug-plus \\\n--cos \\\n--dist-url $dist_url \\\n--dist-backend 'nccl' \\\n--seed 42 \\\n--mode s2c \\\n--dtype uint8 \\\n--season augment \\\n--in_size 224 \\\n--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B13_rn50_224/checkpoint_0029.pth.tar\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/srun_train_SeCo_moco_rn50_s2a.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/B12_train_SeCo_moco_rn50_%j.out\n#SBATCH --error=srun_outputs/B12_train_SeCo_moco_rn50_%j.err\n#SBATCH --time=23:00:00\n#SBATCH --job-name=pretrain_moco_rn50\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u pretrain_moco_v2_seco_ms.py \\\n--is_slurm_job \\\n--data /p/project/hai_ssl4eo/wang_yi/data/seco/seco_1s_uint8.lmdb \\\n--checkpoints /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SeCo_B12_rn50_224 \\\n--bands B12 \\\n--lmdb \\\n--arch resnet50 \\\n--workers 8 \\\n--batch-size 64 \\\n--epochs 100 \\\n--lr 0.03 \\\n--mlp \\\n--moco-t 0.2 \\\n--aug-plus \\\n--cos \\\n--dist-url $dist_url \\\n--dist-backend 'nccl' \\\n--seed 42 \\\n--mode s2a \\\n--dtype uint8 \\\n--season augment \\\n--in_size 224 \\\n#--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B13_rn50_224/checkpoint_0029.pth.tar\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/srun_train_dino_rn50_s2c.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/B13_train_dino_rn50_%j.out\n#SBATCH --error=srun_outputs/B13_train_dino_rn50_%j.err\n#SBATCH --time=24:00:00\n#SBATCH --job-name=pretrain_dino_rn50\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u pretrain_dino_s2c.py \\\n--is_slurm_job \\\n--data /p/scratch/hai_ssl4eo/data/ssl4eo_s12/ssl4eo_250k_s2c_uint8.lmdb \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_rn50_224 \\\n--bands B13 \\\n--lmdb \\\n--arch resnet50 \\\n--num_workers 10 \\\n--batch_size_per_gpu 64 \\\n--epochs 100 \\\n--warmup_epochs 10 \\\n--lr 0.03 \\\n--optimizer sgd \\\n--weight_decay 1e-4 \\\n--weight_decay_end 1e-4 \\\n--global_crops_scale 0.14 1 \\\n--local_crops_scale 0.05 0.14 \\\n--dist_url $dist_url \\\n--seed 42 \\\n--mode s2c \\\n--dtype uint8 \\\n--season augment \\\n--in_size 224 \\\n#--resume /p/project/hai_dm4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn18_int16/checkpoint_0059.pth.tar\n#--use_fp16 False \\"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/srun_train_dino_vits16_s2c.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/B13_train_dino_vits16_%j.out\n#SBATCH --error=srun_outputs/B13_train_dino_vits16_%j.err\n#SBATCH --time=06:00:00\n#SBATCH --job-name=pretrain_dino_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u pretrain_dino_s2c.py \\\n--is_slurm_job \\\n--data /p/scratch/hai_ssl4eo/data/ssl4eo_s12/ssl4eo_250k_s2c_uint8.lmdb \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_vits16_224 \\\n--bands B13 \\\n--lmdb \\\n--arch vit_small \\\n--patch_size 16 \\\n--num_workers 10 \\\n--batch_size_per_gpu 64 \\\n--epochs 100 \\\n--warmup_epochs 10 \\\n--lr 1.5e-4 \\\n--optimizer adamw \\\n--dist_url $dist_url \\\n--seed 42 \\\n--mode s2c \\\n--dtype uint8 \\\n--season augment \\\n--in_size 224 \\\n--resume \\"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/srun_train_mae_vits16_s2c.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/pretrain/B13_train_mae_vits16_70_ep200_%j.out\n#SBATCH --error=srun_outputs/pretrain/B13_train_mae_vits16_70_ep200_%j.err\n#SBATCH --time=20:00:00\n#SBATCH --job-name=pretrain_mae_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u pretrain_mae_s2c.py \\\n--is_slurm_job \\\n--data_path /p/scratch/hai_ssl4eo/data/ssl4eo_s12/ssl4eo_250k_s2c_uint8.lmdb \\\n--output_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae/B13_vits16_70_ep200 \\\n--log_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae/B13_vits16_70_ep200/log \\\n--bands B13 \\\n--model mae_vit_small_patch16 \\\n--norm_pix_loss \\\n--mask_ratio 0.7 \\\n--num_workers 10 \\\n--batch_size 64 \\\n--epochs 200 \\\n--warmup_epochs 10 \\\n--blr 1.5e-4 \\\n--weight_decay 0.05 \\\n--dist_url $dist_url \\\n--dist_backend 'nccl' \\\n--seed 42 \\\n--mode s2c \\\n--dtype uint8 \\\n--season random \\\n--input_size 224 \\\n#--resume /p/project/hai_dm4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn18_int16/checkpoint_0059.pth.tar\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/srun_train_moco_rn50_s2c.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/B13_train_moco_rn50_%j.out\n#SBATCH --error=srun_outputs/B13_train_moco_rn50_%j.err\n#SBATCH --time=24:00:00\n#SBATCH --job-name=pretrain_moco_rn50\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=8\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u pretrain_moco_v2_s2c.py \\\n--is_slurm_job \\\n--data /p/scratch/hai_ssl4eo/data/ssl4eo_s12/ssl4eo_250k_s2c_uint8.lmdb \\\n--checkpoints /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn50_224 \\\n--bands B13 \\\n--lmdb \\\n--arch resnet50 \\\n--workers 8 \\\n--batch-size 64 \\\n--epochs 100 \\\n--lr 0.03 \\\n--mlp \\\n--moco-t 0.2 \\\n--aug-plus \\\n--cos \\\n--dist-url $dist_url \\\n--dist-backend 'nccl' \\\n--seed 42 \\\n--mode s2c \\\n--dtype uint8 \\\n--season augment \\\n--in_size 224 \\\n#--resume /p/project/hai_dm4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn18_int16/checkpoint_0059.pth.tar\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/srun_train_moco_vits16_s2c.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/B13_train_moco_vits16_%j.out\n#SBATCH --error=srun_outputs/B13_train_moco_vits16_%j.err\n#SBATCH --time=24:00:00\n#SBATCH --job-name=pretrain_moco_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u pretrain_moco_v3_s2c.py \\\n--data /p/scratch/hai_ssl4eo/data/ssl4eo_s12/ssl4eo_250k_s2c_uint8.lmdb \\\n--checkpoints /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_vits16_224 \\\n--bands B13 \\\n--lmdb \\\n--arch vit_small \\\n--workers 10 \\\n--batch-size 64 \\\n--epochs 100 \\\n--warmup-epochs=10 \\\n--lr 1.5e-4 \\\n--weight-decay=.1 \\\n--optimizer adamw \\\n--stop-grad-conv1 \\\n--moco-m-cos \\\n--moco-t 0.2 \\\n--dist-url $dist_url \\\n--dist-backend 'nccl' \\\n--seed 42 \\\n--mode s2c \\\n--dtype uint8 \\\n--season augment \\\n--in_size 224 \\\n#--resume /p/project/hai_dm4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn18_int16/checkpoint_0059.pth.tar\n"
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/submit_pretrain_data2vec.sh",
    "content": "#!/bin/bash -x\n#SBATCH --account=hai_ssl4eo\n#SBATCH --nodes=1\n#SBATCH --output=mpi-out.%j\n#SBATCH --error=mpi-err.%j\n#SBATCH --time=23:30:00\n#SBATCH --partition=booster\n#SBATCH --gres=gpu:4\n\n\n./srun_train_data2vec_vits16_s2c.sh  "
  },
  {
    "path": "src/benchmark/pretrain_ssl/scripts/pretrain/train_data2vec_vits16_s2c.sh",
    "content": "OMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=4 pretrain_data2vec.py \\\n        --data_path '/p/scratch/hai_ssl4eo/data/ssl4eo_s12/ssl4eo_250k_s2c_uint8.lmdb'\\\n        --output_dir '/p/project/hai_ssl4eo/nassim/data2vec/experiments/data2vec/pretrain/output' --log_dir '/p/project/hai_ssl4eo/nassim/data2vec/experiments/data2vec/pretrain/logs' \\\n        --num_mask_patches 120 \\\n        --aug_level 2 \\\n        --model beit_small_patch16_224 \\\n        --seed 0 \\\n        --target_layers [6,7,8,9,10,11] \\\n        --ema_decay 0.9998 --ema_start_at 0 --ema_decay_init 0.999 \\\n        --batch_size 64 --lr 1e-3 --warmup_epochs 1 --epochs 2 \\\n        --clip_grad 3.0 --drop_path 0.25 --layer_scale_init_value 1e-4 \\\n        --layer_results 'end' \\\n        --var_w0 0.0 --var_w1 0.0 \\\n        --max_mask_patches_per_block 196 --min_mask_patches_per_block 16 \\\n        --l1_beta=2.0 \\\n        --weight_decay 0.05 \\\n        --imagenet_default_mean_and_std --dist_url 'tcp://localhost:10001' --loss_scale -1 --mask_dropout_prob -1.0 \\\n        --post_target_layer_norm --world_size 1 --attn_drop_rate 0.05 \n        \n        "
  },
  {
    "path": "src/benchmark/transfer_change_detection/datasets/__init__.py",
    "content": ""
  },
  {
    "path": "src/benchmark/transfer_change_detection/datasets/oscd_datamodule.py",
    "content": "import random\n\nfrom torch.utils.data import DataLoader\nfrom torchvision.transforms import functional as TF\nfrom pytorch_lightning import LightningDataModule\n\nfrom datasets.oscd_dataset import ChangeDetectionDataset\n\n\nALL_BANDS = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B10', 'B11', 'B12']\nS2A_BANDS = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']\nRGB_BANDS = ['B04', 'B03', 'B02']\nBGR_BANDS = ['B02', 'B03', 'B04']\n\nclass RandomFlip:\n\n    def __call__(self, *xs):\n        if random.random() > 0.5:\n            xs = tuple(TF.hflip(x) for x in xs)\n        return xs\n\n\nclass RandomRotation:\n\n    def __init__(self):\n        self.angles = [0, 90, 180, 270]\n\n    def __call__(self, *xs):\n        angle = random.choice(self.angles)\n        return tuple(TF.rotate(x, angle) for x in xs)\n\n\nclass RandomSwap:\n\n    def __call__(self, x1, x2, y):\n        if random.random() > 0.5:\n            return x2, x1, y\n        else:\n            return x1, x2, y\n\n\nclass ToTensor:\n\n    def __call__(self, *xs):\n        return tuple(TF.to_tensor(x) for x in xs)\n\n\nclass Compose:\n\n    def __init__(self, transforms):\n        self.transforms = transforms\n\n    def __call__(self, *xs):\n        for t in self.transforms:\n            xs = t(*xs)\n        return xs\n\n\nclass ChangeDetectionDataModule(LightningDataModule):\n\n    def __init__(self, data_dir, RGB_bands=True, BGR_bands=False, S2A_bands=False,\n                 value_discard=True, patch_size=96, batch_size=32):\n        super().__init__()\n        self.data_dir = data_dir\n        self.patch_size = patch_size\n        self.batch_size = batch_size\n        self.value_discard = value_discard\n        if RGB_bands:\n            if BGR_bands:\n                self.bands = BGR_BANDS \n            else:\n                self.bands = RGB_BANDS\n        elif S2A_bands:\n            self.bands = S2A_BANDS\n        else:\n            self.bands = ALL_BANDS\n            \n\n    def setup(self, stage=None):\n        self.train_dataset = ChangeDetectionDataset(\n            self.data_dir,\n            split='train',\n            bands=self.bands,\n            value_discard=self.value_discard,\n            transform=Compose([ToTensor(), RandomFlip(), RandomRotation()]), # here need first call ToTensor to convert np.array to tensors in order to do following transformations\n            patch_size=self.patch_size\n        )\n        self.val_dataset = ChangeDetectionDataset(\n            self.data_dir,\n            split='test',\n            bands=self.bands,\n            value_discard=self.value_discard,\n            transform=ToTensor(),\n            patch_size=self.patch_size\n        )\n\n    def train_dataloader(self):\n        return DataLoader(\n            self.train_dataset,\n            batch_size=self.batch_size,\n            shuffle=True,\n            num_workers=8,\n            drop_last=True,\n            pin_memory=True\n        )\n\n    def val_dataloader(self):\n        return DataLoader(\n            self.val_dataset,\n            batch_size=274,\n            shuffle=False, # True,\n            num_workers=0,\n            drop_last=False,\n            pin_memory=True\n        )\n"
  },
  {
    "path": "src/benchmark/transfer_change_detection/datasets/oscd_dataset.py",
    "content": "from pathlib import Path\nfrom itertools import product\n\nfrom torch.utils.data import Dataset\nimport rasterio\nimport numpy as np\n# from PIL import Image\n\n# import random\n# import cv2\n# import torch\n\n\nALL_BANDS = ['B01', 'B02', 'B03', 'B04', \n             'B05', 'B06', 'B07', 'B08', \n             'B8A', 'B09', 'B10', 'B11', \n             'B12']\nRGB_BANDS = ['B04', 'B03', 'B02']\n\nQUANTILES_RGB = {\n    'min_q': {\n        'B02': 885.0,\n        'B03': 667.0,\n        'B04': 426.0\n    },\n    'max_q': {\n        'B02': 2620.0,\n        'B03': 2969.0,\n        'B04': 3698.0\n    }\n}\n\nQUANTILES_ALL = {\n    'min_q': {\n        'B01': 1194.0, 'B02': 885.0,  'B03': 667.0,  'B04': 426.0,\n        'B05': 392.0,  'B06': 358.0,  'B07': 349.0,  'B08': 290.0,\n        'B8A': 310.0,  'B09': 96.0,   'B10': 7.0,    'B11': 155.0,\n        'B12': 109.0\n    },\n    'max_q': {\n        'B01': 2456.0, 'B02': 2620.0, 'B03': 2969.0, 'B04': 3698.0,\n        'B05': 3803.0, 'B06': 3994.0, 'B07': 4261.0, 'B08': 4141.0,\n        'B8A': 4435.0, 'B09': 1589.0, 'B10': 51.0,   'B11': 5043.0,\n        'B12': 4238.0\n    }\n}\n\ndef read_image(path, bands, normalize=True, value_discard=True):\n    # # original: read from 'imgs_1' and 'imgs_2' dirs\n    # patch_id = next(path.iterdir()).name[:-8]\n    # # get img shape for interpolation\n    # img_shp = rasterio.open(path / f'{patch_id}_B02.tif').read(1).shape\n    channels = []\n    QUANTILES = QUANTILES_RGB if len(bands)==3 else QUANTILES_ALL\n    for b in bands:\n        # # original: read from 'imgs_1' and 'imgs_2' dirs\n        # ch = rasterio.open(path / f'{patch_id}_{b}.tif').read(1)\n        ch = rasterio.open(path / f'{b}.tif').read(1)\n        \n        # # interpolation\n        # ch = cv2.resize(ch,img_shp,interpolation=cv2.INTER_CUBIC)\n        \n        if normalize:\n            if value_discard:\n                min_v = QUANTILES['min_q'][b]\n                max_v = QUANTILES['max_q'][b]\n                ch = (ch - min_v) / (max_v - min_v)\n            else:\n                ch = ch/10000\n            ch = np.clip(ch, 0, 1)\n            ch = (ch * 255).astype(np.uint8)\n        channels.append(ch)\n    img = np.dstack(channels)\n    # # original: convert np.array to Image object\n    # img = Image.fromarray(img)\n    return img\n\n\n    \n\nclass ChangeDetectionDataset(Dataset):\n\n    def __init__(self, root, split='all', bands=None, transform=None, \n                 value_discard=True, patch_size=96):\n        self.root = Path(root)\n        self.split = split\n        self.bands = bands if bands is not None else ALL_BANDS\n        self.transform = transform\n        self.value_discard = value_discard\n\n        with open(self.root / f'{split}.txt') as f:\n            names = f.read().strip().split(',')\n\n        self.samples = []\n        for name in names:\n            fp = next((self.root / name / 'imgs_1_rect').glob(f'*{self.bands[0]}*'))\n            img = rasterio.open(fp)\n            limits = product(range(0, img.width, patch_size), range(0, img.height, patch_size))\n            for l in limits:\n                if l[0] + patch_size < img.width: \n                    if l[1] + patch_size < img.height:\n                            self.samples.append((self.root / name, (l[0], l[1], l[0] + patch_size, l[1] + patch_size)))\n\n    def __getitem__(self, index):\n        path, limits = self.samples[index]     \n\n        img_1 = read_image(path / 'imgs_1_rect', self.bands, value_discard=self.value_discard)    # Image -> np.array, type: unit8\n        img_2 = read_image(path / 'imgs_2_rect', self.bands, value_discard=self.value_discard)    # Image -> np.array, type: unit8\n        # # original: read cm as an Image object\n        # cm = Image.open(path / 'cm' / 'cm.png').convert('L')\n        cm = rasterio.open(path / 'cm' / 'cm.png').read(1).astype(np.uint8)     # np.array, type: unit8\n\n        # # using crop from PIL for 3 bands\n        # img_1 = img_1.crop(limits)\n        # img_2 = img_2.crop(limits)\n        # cm = cm.crop(limits)\n        \n        # crop for 13 bands\n        img_1 = img_1[limits[1]:limits[3],limits[0]:limits[2],:]\n        img_2 = img_2[limits[1]:limits[3],limits[0]:limits[2],:]\n        cm = cm[limits[1]:limits[3],limits[0]:limits[2]]\n\n        if self.transform is not None:\n            img_1, img_2, cm = self.transform(img_1, img_2, cm)\n        \n        return img_1, img_2, cm\n\n    def __len__(self):\n        return len(self.samples)\n"
  },
  {
    "path": "src/benchmark/transfer_change_detection/main_oscd.py",
    "content": "from pathlib import Path\n# from copy import deepcopy\nfrom argparse import ArgumentParser\n\nimport torch\nfrom torch.nn import BCEWithLogitsLoss\nfrom torchvision.models.resnet import resnet18\nfrom torchvision.models import resnet50\nimport pytorch_lightning as pl\nfrom pytorch_lightning import LightningModule, Trainer\nfrom pytorch_lightning.loggers import TensorBoardLogger\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nfrom torchmetrics import Precision, Recall, F1Score\n\nfrom datasets.oscd_datamodule import ChangeDetectionDataModule\nfrom models.segmentation import get_segmentation_model\n# from models.moco2_module import MocoV2\nfrom pytorch_lightning.callbacks.early_stopping import EarlyStopping\n\n\ndef get_args():\n    parser = ArgumentParser()\n    \n    parser.add_argument('--gpus', type=int, default=1)\n    parser.add_argument('--data_dir', type=str)\n    parser.add_argument('--resnet_type', type=int, default=18)\n    parser.add_argument('--init_type', type=str, default='random')\n    parser.add_argument('--ckp_path', type=str, default=None)\n    parser.add_argument('--n_channels', dest='nc', type=int, default=3)\n    parser.add_argument('--n_epochs', dest='ne', type=int, default=100)\n    parser.add_argument('--learning_rate', dest='lr', type=float, default=0.001)\n    parser.add_argument('--value_discard', type=bool, default=True)\n    parser.add_argument('--patch_size', type=int, default=96)\n    parser.add_argument('--batch_size', type=int, default=32)\n    parser.add_argument('--m_threshold', dest='mth', type=float, default=0.5)\n    parser.add_argument('--result_dir', type=str)\n    \n    args = parser.parse_args()\n    \n    return args\n\n\ndef dice_loss(out,mask,epsilon=1e-5):\n    inter = torch.dot(out.reshape(-1), mask.reshape(-1))\n    sets_sum = torch.sum(out) + torch.sum(mask)\n    return (2 * inter + epsilon) / (sets_sum + epsilon)\n\n\nclass SiamSegment(LightningModule):\n\n    def __init__(self, backbone, feature_indices, feature_channels):\n        super().__init__()\n        self.model = get_segmentation_model(backbone, feature_indices, feature_channels)\n        self.criterion = BCEWithLogitsLoss()\n        self.dice_loss = dice_loss\n        self.prec = Precision(task='binary',threshold=args.mth)\n        self.rec = Recall(task='binary',threshold=args.mth) \n        self.f1 = F1Score(task='binary',threshold=args.mth) \n\n    def forward(self, x1, x2):\n        return self.model(x1, x2)\n\n    def training_step(self, batch, batch_idx):\n        img_1, img_2, mask, pred, loss, prec, rec, f1 = self.shared_step(batch)\n        self.log('train/loss', loss, prog_bar=True,sync_dist=True)\n        self.log('train/precision', prec, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        self.log('train/recall', rec, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        self.log('train/f1', f1, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        tensorboard = self.logger.experiment\n        global_step = self.trainer.global_step\n        #if args.nc == 3:\n        #    tensorboard.add_image('train/img_1', img_1[0], global_step)\n        #    tensorboard.add_image('train/img_2', img_2[0], global_step)\n        #    tensorboard.add_image('train/mask', mask[0], global_step)\n        #    tensorboard.add_image('train/out', pred[0], global_step)\n        #else:\n        #    tensorboard.add_image('train/img_1', img_1[0,1:4,:,:], global_step)\n        #    tensorboard.add_image('train/img_2', img_2[0,1:4,:,:], global_step)\n        #    tensorboard.add_image('train/mask', mask[0], global_step)\n        #    tensorboard.add_image('train/out', pred[0], global_step)\n        return loss\n\n    def validation_step(self, batch, batch_idx):\n        img_1, img_2, mask, pred, loss, prec, rec, f1 = self.shared_step(batch)\n        self.log('val/loss', loss, prog_bar=True,sync_dist=True)\n        self.log('val/precision', prec, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        self.log('val/recall', rec, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        self.log('val/f1', f1, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        tensorboard = self.logger.experiment\n        global_step = self.trainer.global_step\n        #if args.nc == 3:\n        #    tensorboard.add_image('val/img_1', img_1[0], global_step)\n        #    tensorboard.add_image('val/img_2', img_2[0], global_step)\n        #    tensorboard.add_image('val/mask', mask[0], global_step)\n        #    tensorboard.add_image('val/out', pred[0], global_step)\n        #else:\n        #    tensorboard.add_image('val/img_1', img_1[0,1:4,:,:], global_step)\n        #    tensorboard.add_image('val/img_2', img_2[0,1:4,:,:], global_step)\n        #    tensorboard.add_image('val/mask', mask[0], global_step)\n        #    tensorboard.add_image('val/out', pred[0], global_step)\n        return loss\n\n    def shared_step(self, batch):\n        img_1, img_2, mask = batch\n        out = self(img_1, img_2)\n        pred = torch.sigmoid(out)\n        loss = self.criterion(out, mask)\n        # + self.dice_loss(out,mask)\n        prec = self.prec(pred, mask.long())\n        rec = self.rec(pred, mask.long())\n        f1 = self.f1(pred, mask.long())\n        return img_1, img_2, mask, pred, loss, prec, rec, f1\n\n    def configure_optimizers(self):\n        # params = self.model.parameters()\n        params = set(self.model.parameters()).difference(self.model.encoder.parameters())\n        optimizer = torch.optim.Adam(params, lr=args.lr, weight_decay=1e-4)\n        scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, 0.95)\n        return [optimizer], [scheduler]\n\n\ndef load_ssl_resnet_encoder(net, ckp_path, pf_sdict='module.encoder_q.'):\n    # load ckp file\n    state_dict = torch.load(ckp_path, map_location='cpu')['state_dict']\n\n    # modify keys in state_dict\n    for k in list(state_dict.keys()):\n        if k.startswith(pf_sdict) and not k.startswith(pf_sdict+'fc'):\n            newk = k[len(pf_sdict):]\n            state_dict[newk] = state_dict[k]\n        # delete renamed or unused k\n        del state_dict[k]\n\n    #load weights\n    msg = net.load_state_dict(state_dict,strict=False)\n    assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\n    \n    # print ckp info after succussfully loading it\n    print(f\"Checkpoint has been loaded from \\'{ckp_path}\\'!\")\n    \n    return net\n\n\nif __name__ == '__main__':\n    pl.seed_everything(42)\n    \n    # args\n    args = get_args()\n\n    # dataloader\n    assert(args.nc==3 or args.nc==13 or args.nc==12)\n    datamodule = ChangeDetectionDataModule(args.data_dir, RGB_bands=True if args.nc==3 else False, \\\n                                           BGR_bands=False, \\\n                                           S2A_bands=True if args.nc==12 else False, \\\n                                           value_discard=args.value_discard, \\\n                                           patch_size=args.patch_size, batch_size=args.batch_size)\n\n    # construct backbone model\n    pretrained = False\n    # check whether use imagenet pretrained weights, which are only applied for RGB model\n    if args.init_type == 'imagenet':\n        assert(args.nc==3)\n        pretrained = True\n    # backbone definition\n    if args.resnet_type == 18:\n        backbone = resnet18(pretrained=pretrained)\n        feature_channels = (64, 64, 128, 256, 512)\n    elif args.resnet_type == 50:\n        backbone = resnet50(pretrained=pretrained)\n        feature_channels=(64, 256, 512, 1024, 2048)\n    else:\n        raise ValueError()\n    print(f'Construct the backbone of resnet{args.resnet_type}-initialization: {args.init_type}.')\n    \n    # change the number of input channels of backbone\n    if args.nc != 3:\n        backbone.conv1 = torch.nn.Conv2d(args.nc, 64, 7, stride=2, padding=3, bias=False)\n        print(f'Modify the number of inputs of the backbone to {args.nc}.')\n    \n    # fix backbone layers\n    for name, param in backbone.named_parameters():\n            param.requires_grad = False \n    \n    # load ckp if given\n    if args.ckp_path:\n        backbone = load_ssl_resnet_encoder(backbone, args.ckp_path)\n        # args.init_type = 'ssl'\n\n    model = SiamSegment(backbone, feature_indices=(2, 4, 5, 6, 7), feature_channels=feature_channels)\n    # model.example_input_array = (torch.zeros((1, 3, 96, 96)), torch.zeros((1, 3, 96, 96)))\n\n    experiment_name = args.init_type\n    logger = TensorBoardLogger(save_dir=str(Path.cwd() / args.result_dir / 'logs'), name=experiment_name)\n    dir_path=str(Path.cwd() / args.result_dir / 'ckps' / args.init_type)\n    Path(dir_path).mkdir(parents=True, exist_ok=True)\n    checkpoint_callback = ModelCheckpoint(dirpath=dir_path, auto_insert_metric_name=False, filename='{epoch}-{val/loss:.2f}-{val/f1:.2f}', save_weights_only=False)\n    early_stop_callback = EarlyStopping(monitor=\"val/loss\", mode=\"min\")\n    lr_monitor = pl.callbacks.LearningRateMonitor(logging_interval=None)\n    \n    trainer = Trainer(accelerator='gpu', devices=4, strategy=\"ddp\", sync_batchnorm=True, logger=logger, callbacks=[checkpoint_callback,lr_monitor], max_epochs=args.ne, enable_progress_bar=True)\n    trainer.fit(model, datamodule=datamodule)\n    trainer.validate(model, datamodule=datamodule)\n"
  },
  {
    "path": "src/benchmark/transfer_change_detection/models/__init__.py",
    "content": ""
  },
  {
    "path": "src/benchmark/transfer_change_detection/models/segmentation.py",
    "content": "import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n\ndef get_segmentation_model(backbone, feature_indices, feature_channels):\n    \"\"\"Creates a UNet from a pretrained backbone\n\n    Args:\n        backbone (torch.nn.Module): Pre-trained backbone in the form of \"Sequential\"\n        feature_indices (list(int)): Indices in the Sequential backbone from which to extract intermediate features\n        feature_channels ([type]): Number of channels per feature extracted\n\n    Returns:\n        [type]: [description]\n    \"\"\"\n    model = SegmentationEncoder(backbone, feature_indices, diff=True)\n    unet = UNet(model, feature_channels, 1, bilinear=True, concat_mult=1, dropout_rate=0.3)\n    # unet = UNetSmall(model, feature_channels, 1, bilinear=True, concat_mult=1)\n    return unet\n\n\nclass SegmentationEncoder(torch.nn.Module):\n    def __init__(self, backbone, feature_indices, diff=False):\n        super().__init__()\n        self.feature_indices = list(sorted(feature_indices))\n\n        # # A number of channels for each encoder feature tensor, list of integers\n        # self._out_channels = feature_channels  # [3, 16, 64, 128, 256, 512]\n\n        # Default number of input channels in first Conv2d layer for encoder (usually 3)\n        self._in_channels = 13\n\n        # Define encoder modules below\n        self.encoder = backbone\n\n        self.diff = diff\n\n    def forward(self, x1, x2):\n        \"\"\"Produce list of features of different spatial resolutions, each feature is a 4D torch.tensor of\n        shape NCHW (features should be sorted in descending order according to spatial resolution, starting\n        with resolution same as input `x` tensor).\n\n        Input: `x` with shape (1, 3, 64, 64)\n        Output: [f0, f1, f2, f3, f4, f5] - features with corresponding shapes\n                [(1, 3, 64, 64), (1, 64, 32, 32), (1, 128, 16, 16), (1, 256, 8, 8),\n                (1, 512, 4, 4), (1, 1024, 2, 2)] (C - dim may differ)\n\n        also should support number of features according to specified depth, e.g. if depth = 5,\n        number of feature tensors = 6 (one with same resolution as input and 5 downsampled),\n        depth = 3 -> number of feature tensors = 4 (one with same resolution as input and 3 downsampled).\n        \"\"\"\n        feats = [self.concatenate(x1, x2)]\n        for i, module in enumerate(self.encoder.children()):\n            x1 = module(x1)\n            x2 = module(x2)\n            if i in self.feature_indices:\n                feats.append(self.concatenate(x1, x2))\n            if i == self.feature_indices[-1]:\n                break\n\n        return feats\n\n    def concatenate(self, x1, x2):\n        if self.diff:\n            return torch.abs(x1 - x2)\n        else:\n            torch.cat([x1, x2], 1)\n\n\nclass DoubleConv(nn.Module):\n    def __init__(self, in_channels, out_channels, mid_channels=None):\n        super().__init__()\n        if not mid_channels:\n            mid_channels = out_channels\n        self.double_conv = nn.Sequential(\n            nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1),\n            nn.BatchNorm2d(mid_channels),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1),\n            nn.BatchNorm2d(out_channels),\n            nn.ReLU(inplace=True)\n        )\n\n    def forward(self, x):\n        return self.double_conv(x)\n\n\nclass Down(nn.Module):\n    \"\"\"Downscaling with maxpool then double conv\"\"\"\n\n    def __init__(self, in_channels, out_channels):\n        super().__init__()\n        self.maxpool_conv = nn.Sequential(\n            nn.MaxPool2d(2),\n            DoubleConv(in_channels, out_channels)\n        )\n\n    def forward(self, x):\n        return self.maxpool_conv(x)\n\n\nclass Up(nn.Module):\n    \"\"\"Upscaling then double conv\"\"\"\n\n    def __init__(self, in_channels, out_channels, bilinear=True):\n        super().__init__()\n\n        # if bilinear, use the normal convolutions to reduce the number of channels\n        if bilinear:\n            self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)\n            self.conv = DoubleConv(in_channels, out_channels, in_channels // 2)\n        else:\n            self.up = nn.ConvTranspose2d(in_channels, in_channels // 2, kernel_size=2, stride=2)\n            self.conv = DoubleConv(in_channels, out_channels)\n\n    def forward(self, x1, x2):\n        x1 = self.up(x1)\n        # input is CHW\n        diffY = x2.size()[2] - x1.size()[2]\n        diffX = x2.size()[3] - x1.size()[3]\n\n        x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,\n                        diffY // 2, diffY - diffY // 2])\n        # if you have padding issues, see\n        # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a\n        # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd\n        x = torch.cat([x2, x1], dim=1)\n        return self.conv(x)\n\n\nclass OutConv(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(OutConv, self).__init__()\n        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)\n\n    def forward(self, x):\n        return self.conv(x)\n\n\n# class UNet(nn.Module):\n#     def __init__(self, encoder, feature_channels, n_classes, concat_mult=2, bilinear=True):\n#         super(UNet, self).__init__()\n#         self.n_classes = n_classes\n#         self.bilinear = bilinear\n#         factor = 2 if bilinear else 1\n#         self.feature_channels = feature_channels\n#         for i in range(0, len(feature_channels)-1):\n#             in_ch = feature_channels[i + 1] * concat_mult + feature_channels[i] * concat_mult\n#             setattr(self, \"up_%d\" %i, Up(in_ch, feature_channels[i] * concat_mult, bilinear))\n#         self.outc = OutConv(feature_channels[0] * concat_mult, n_classes)\n#         self.encoder = encoder\n#\n#     def forward(self, *in_x):\n#         features = self.encoder(*in_x)\n#         features = features[1:]\n#         x = features[-1]\n#         for i in range(len(features) - 2, -1, -1):\n#             up = getattr(self, 'up_%d' %i)\n#             x = up(x, features[i])\n#         logits = self.outc(x)\n#         return logits\n\n\nclass UNet(nn.Module):\n    def __init__(self, encoder, feature_channels, n_classes, concat_mult=2, bilinear=True, dropout_rate=0.5):\n        \"\"\"Simple segmentation network\n\n        Args:\n            encoder (torch Sequential): The pre-trained encoder\n            feature_channels (list(int)): Number of channels per input feature\n            n_classes (int): output number of classes\n            concat_mult (int, optional): The amount of features being fused. Defaults to 2.\n            bilinear (bool, optional): If use bilinear interpolation (I have defaulted to nearest since it has been shown to be better sometimes). Defaults to True.\n        \"\"\"\n        super(UNet, self).__init__()\n        self.n_classes = n_classes  # 1\n        self.bilinear = bilinear\n        # factor = 2 if bilinear else 1\n        self.feature_channels = feature_channels \n        self.dropout = torch.nn.Dropout2d(dropout_rate)\n        for i in range(0, len(feature_channels) - 1):\n            if i == len(feature_channels) - 2:\n                in_ch = feature_channels[i + 1] * concat_mult\n            else:\n                in_ch = feature_channels[i + 1] * concat_mult\n            setattr(self, 'shrink%d' % i,\n                    nn.Conv2d(in_ch, feature_channels[i] * concat_mult, kernel_size=3, stride=1, padding=1))\n            setattr(self, 'shrink2%d' % i,\n                    nn.Conv2d(feature_channels[i] * concat_mult * 2, feature_channels[i] * concat_mult, kernel_size=3, stride=1, padding=1, bias=False))\n            setattr(self, 'batchnorm%d' % i,\n                    nn.BatchNorm2d(feature_channels[i] * concat_mult))\n        self.outc = OutConv(feature_channels[0] * concat_mult, n_classes)\n        self.encoder = encoder\n\n    def forward(self, *in_x):\n        features = self.encoder(*in_x)\n        features = features[1:]\n        x = features[-1]\n        for i in range(len(features) - 2, -1, -1):\n            conv = getattr(self, 'shrink%d' % i)\n            x = F.upsample_nearest(x, scale_factor=2)\n            x = conv(x)\n            if features[i].shape[-1] != x.shape[-1]:\n                x2 = F.upsample_nearest(features[i], scale_factor=2)\n            else:\n                x2 = features[i]\n            x = torch.cat([x, x2], 1)\n            conv2 = getattr(self, 'shrink2%d' % i)\n            x = conv2(x)\n            bn = getattr(self, 'batchnorm%d' % i)\n            x = bn(x)\n            x = F.relu(x)\n            x = self.dropout(x)\n        x = F.upsample_nearest(x, scale_factor=2)\n        logits = self.outc(x)\n        return logits\n\n\nclass UNetSmall(nn.Module):\n    def __init__(self, encoder, feature_channels, n_classes, concat_mult=2, bilinear=True):\n        \"\"\"Simple segmentation network\n\n        Args:\n            encoder (torch Sequential): The pre-trained encoder\n            feature_channels (list(int)): Number of channels per input feature\n            n_classes (int): output number of classes\n            concat_mult (int, optional): The amount of features being fused. Defaults to 2.\n            bilinear (bool, optional): If use bilinear interpolation (I have defaulted to nearest since it has been shown to be better sometimes). Defaults to True.\n        \"\"\"\n        super(UNetSmall, self).__init__()\n        self.n_classes = n_classes\n        self.bilinear = bilinear\n        factor = 2 if bilinear else 1\n        self.feature_channels = feature_channels\n        for i in range(0, len(feature_channels)):\n            setattr(self, 'shrink%d' % i,\n                    nn.Conv2d(feature_channels[i], feature_channels[0], kernel_size=1, stride=1, padding=0))\n        \n        self.aggregate = nn.Conv2d(len(feature_channels) * feature_channels[0], feature_channels[0], kernel_size=3, stride=1, padding=1, bias=False)\n        self.bn = nn.BatchNorm2d(feature_channels[0])\n        self.outc = OutConv(feature_channels[0], n_classes)\n        self.encoder = encoder\n\n    def forward(self, *in_x):\n        features = self.encoder(*in_x)\n        b, c, h, w = in_x[0].shape\n        features = features[1:]\n        ret = []\n        for i in range(len(features)):\n            conv = getattr(self, 'shrink%d' % i)\n            x = conv(features[i])\n            ratio = h // features[i].shape[-2]\n            ret.append(F.upsample_bilinear(x, scale_factor=ratio))\n        ret = torch.cat(ret, 1)\n        ret = self.aggregate(ret)\n        ret = self.bn(ret)\n        ret = F.relu(ret, True)\n        logits = self.outc(ret)\n        return logits\n"
  },
  {
    "path": "src/benchmark/transfer_change_detection/readme.md",
    "content": "Refer to https://github.com/ElementAI/seasonal-contrast."
  },
  {
    "path": "src/benchmark/transfer_change_detection/test.sh",
    "content": "python validate_oscd.py \\\n--data_dir /p/project/hai_ssl4eo/wang_yi/data/oscd \\\n--resnet_type 50 \\\n--init_type random \\\n--n_channels 12 \\\n--value_discard False \\\n--patch_size 96 \\\n--batch_size 274 \\\n--m_threshold 0.5 \\\n--result_dir results \\\n--ckp_resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_change_detection/results/ckps/seco/99-0.15-0.27.ckpt \\\n#--ckp_resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_change_detection/results/ckps/sen12ms/99-0.15-0.25.ckpt\n#--ckp_resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_change_detection/results/ckps/ssl4eo/99-0.15-0.29.ckpt\n#--ckp_resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_change_detection/results/ckps/random/99-0.15-0.19.ckpt \\\n"
  },
  {
    "path": "src/benchmark/transfer_change_detection/train.sh",
    "content": "python main_oscd.py \\\n--data_dir /p/project/hai_ssl4eo/wang_yi/data/oscd \\\n--resnet_type 50 \\\n--init_type random \\\n--n_channels 13 \\\n--n_epochs 100 \\\n--learning_rate 0.001 \\\n--value_discard False \\\n--patch_size 96 \\\n--batch_size 8 \\\n--m_threshold 0.5 \\\n--result_dir results \\\n#--ckp_path /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SeCo_B12_rn50_224/checkpoint_0099.pth.tar\n#--ckp_path /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B13_rn50_224/checkpoint_0099.pth.tar\n#--ckp_path /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/pretrained-weights/B13_rn50_moco_0099.pth.tar\n\n\n"
  },
  {
    "path": "src/benchmark/transfer_change_detection/utils/__init__.py",
    "content": ""
  },
  {
    "path": "src/benchmark/transfer_change_detection/utils/data.py",
    "content": "import pickle\n\nimport numpy as np\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nimport lmdb\nfrom tqdm import tqdm\n\n\nclass Subset(Dataset):\n\n    def __init__(self, dataset, indices):\n        self.dataset = dataset\n        self.indices = indices\n\n    def __getitem__(self, idx):\n        return self.dataset[self.indices[idx]]\n\n    def __len__(self):\n        return len(self.indices)\n\n    def __getattr__(self, name):\n        return getattr(self.dataset, name)\n\n\ndef random_subset(dataset, frac, seed=None):\n    rng = np.random.default_rng(seed)\n    indices = rng.choice(range(len(dataset)), int(frac * len(dataset)))\n    return Subset(dataset, indices)\n\n\nclass _RepeatSampler(object):\n    \"\"\"\n    Sampler that repeats forever.\n    Args:\n        sampler (Sampler)\n    \"\"\"\n\n    def __init__(self, sampler):\n        self.sampler = sampler\n\n    def __iter__(self):\n        while True:\n            yield from iter(self.sampler)\n\n\nclass InfiniteDataLoader(DataLoader):\n    \"\"\"\n    Dataloader that reuses workers.\n    Uses same syntax as vanilla DataLoader.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        object.__setattr__(self, 'batch_sampler', _RepeatSampler(self.batch_sampler))\n        self.iterator = super().__iter__()\n\n    def __len__(self):\n        return len(self.batch_sampler.sampler)\n\n    def __iter__(self):\n        for i in range(len(self)):\n            yield next(self.iterator)\n\n\ndef make_lmdb(dataset, lmdb_file, num_workers=8):\n    loader = InfiniteDataLoader(dataset, num_workers=num_workers, collate_fn=lambda x: x[0])\n    env = lmdb.open(lmdb_file, map_size=1099511627776)\n\n    txn = env.begin(write=True)\n    for index, (sample, target) in tqdm(enumerate(loader), total=len(dataset), desc='Creating LMDB'):\n        sample = np.array(sample)\n        obj = (sample.tobytes(), sample.shape, target.tobytes())\n        txn.put(str(index).encode(), pickle.dumps(obj))\n        if index % 10000 == 0:\n            txn.commit()\n            txn = env.begin(write=True)\n    txn.commit()\n\n    env.sync()\n    env.close()\n\n\nclass LMDBDataset(Dataset):\n\n    def __init__(self, lmdb_file, transform=None, target_transform=None):\n        self.lmdb_file = lmdb_file\n        self.transform = transform\n        self.target_transform = target_transform\n\n        self.env = lmdb.open(lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n        with self.env.begin(write=False) as txn:\n            self.length = txn.stat()['entries']\n\n    def __getitem__(self, index):\n        with self.env.begin(write=False) as txn:\n            data = txn.get(str(index).encode())\n\n        sample_bytes, sample_shape, target_bytes = pickle.loads(data)\n        sample = np.fromstring(sample_bytes, dtype=np.uint8).reshape(sample_shape)\n        sample = Image.fromarray(sample)\n        target = np.fromstring(target_bytes, dtype=np.float32)\n\n        if self.transform is not None:\n            sample = self.transform(sample)\n        if self.target_transform is not None:\n            target = self.target_transform(target)\n\n        return sample, target\n\n    def __len__(self):\n        return self.length\n"
  },
  {
    "path": "src/benchmark/transfer_change_detection/utils/transforms.py",
    "content": "\nclass Map:\n\n    def __init__(self, transform):\n        self.transform = transform\n\n    def __call__(self, inputs):\n        return [self.transform(x) for x in inputs]\n\n\nclass ApplyN:\n\n    def __init__(self, transform, n):\n        self.transform = transform\n        self.n = n\n\n    def __call__(self, input):\n        return [self.transform(input) for _ in range(self.n)]\n\n\nclass LeaveOneOut:\n\n    def __init__(self, transforms):\n        self.transforms = transforms\n\n    def __call__(self, input):\n        outputs = []\n        for i in range(len(self.transforms)):\n            output = input\n            for j in range(len(self.transforms)):\n                if j != i:\n                    output = self.transforms[j](output)\n            outputs.append(output)\n        return outputs\n\n\nclass AddOne:\n\n    def __init__(self, transforms):\n        self.transforms = transforms\n\n    def __call__(self, input):\n        outputs = []\n        for i in range(len(self.transforms)):\n            output = self.transforms[i](input)\n            outputs.append(output)\n        return outputs\n"
  },
  {
    "path": "src/benchmark/transfer_change_detection/validate_oscd.py",
    "content": "from pathlib import Path\n# from copy import deepcopy\nfrom argparse import ArgumentParser\n\nimport torch\nfrom torch.nn import BCEWithLogitsLoss\nfrom torchvision.models.resnet import resnet18\nfrom torchvision.models import resnet50\nimport pytorch_lightning as pl\nfrom pytorch_lightning import LightningModule, Trainer\nfrom pytorch_lightning.loggers import TensorBoardLogger\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nfrom torchmetrics import Precision, Recall, F1Score\n\nfrom datasets.oscd_datamodule import ChangeDetectionDataModule\nfrom models.segmentation import get_segmentation_model\n# from models.moco2_module import MocoV2\nfrom lightning.pytorch.callbacks.early_stopping import EarlyStopping\n\n\ndef get_args():\n    parser = ArgumentParser()\n    \n    parser.add_argument('--gpus', type=int, default=1)\n    parser.add_argument('--data_dir', type=str)\n    parser.add_argument('--resnet_type', type=int, default=18)\n    parser.add_argument('--init_type', type=str, default='random')\n    parser.add_argument('--ckp_pretrain', type=str, default=None)\n    parser.add_argument('--ckp_resume', type=str, default=None)\n    parser.add_argument('--n_channels', dest='nc', type=int, default=3)\n    parser.add_argument('--n_epochs', dest='ne', type=int, default=100)\n    parser.add_argument('--learning_rate', dest='lr', type=float, default=0.001)\n    parser.add_argument('--value_discard', type=bool, default=True)\n    parser.add_argument('--patch_size', type=int, default=96)\n    parser.add_argument('--batch_size', type=int, default=32)\n    parser.add_argument('--m_threshold', dest='mth', type=float, default=0.5)\n    parser.add_argument('--result_dir', type=str)\n    \n    args = parser.parse_args()\n    \n    return args\n\n\nclass SiamSegment(LightningModule):\n\n    def __init__(self, backbone, feature_indices, feature_channels):\n        super().__init__()\n        self.model = get_segmentation_model(backbone, feature_indices, feature_channels)\n        self.criterion = BCEWithLogitsLoss()\n        self.prec = Precision(task='binary',threshold=args.mth)\n        self.rec = Recall(task='binary',threshold=args.mth) \n        self.f1 = F1Score(task='binary',threshold=args.mth) \n\n    def forward(self, x1, x2):\n        return self.model(x1, x2)\n\n    def training_step(self, batch, batch_idx):\n        img_1, img_2, mask, pred, loss, prec, rec, f1 = self.shared_step(batch)\n        self.log('train/loss', loss, prog_bar=True,sync_dist=True)\n        self.log('train/precision', prec, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        self.log('train/recall', rec, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        self.log('train/f1', f1, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        tensorboard = self.logger.experiment\n        global_step = self.trainer.global_step\n        if args.nc == 3:\n            tensorboard.add_image('train/img_1', img_1[0], global_step)\n            tensorboard.add_image('train/img_2', img_2[0], global_step)\n            tensorboard.add_image('train/mask', mask[0], global_step)\n            tensorboard.add_image('train/out', pred[0], global_step)\n        else:\n            tensorboard.add_image('train/img_1', img_1[0,1:4,:,:], global_step)\n            tensorboard.add_image('train/img_2', img_2[0,1:4,:,:], global_step)\n            tensorboard.add_image('train/mask', mask[0], global_step)\n            tensorboard.add_image('train/out', pred[0], global_step)\n        return loss\n\n    def validation_step(self, batch, batch_idx):\n        img_1, img_2, mask, pred, loss, prec, rec, f1 = self.shared_step(batch)\n        self.log('val/loss', loss, prog_bar=True,sync_dist=True)\n        self.log('val/precision', prec, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        self.log('val/recall', rec, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        self.log('val/f1', f1, on_step=False, on_epoch=True, prog_bar=True,sync_dist=True)\n        tensorboard = self.logger.experiment\n        global_step = self.trainer.global_step\n        if args.nc == 3:\n            tensorboard.add_image('val/img_1', img_1[0], global_step)\n            tensorboard.add_image('val/img_2', img_2[0], global_step)\n            tensorboard.add_image('val/mask', mask[0], global_step)\n            tensorboard.add_image('val/out', pred[0], global_step)\n        else:\n            tensorboard.add_image('val/img_1', img_1[0,1:4,:,:], global_step)\n            tensorboard.add_image('val/img_2', img_2[0,1:4,:,:], global_step)\n            tensorboard.add_image('val/mask', mask[0], global_step)\n            tensorboard.add_image('val/out', pred[0], global_step)\n        return loss\n\n    def shared_step(self, batch):\n        img_1, img_2, mask = batch\n        out = self(img_1, img_2)\n        pred = torch.sigmoid(out)\n        loss = self.criterion(out, mask)\n        prec = self.prec(pred, mask.long())\n        rec = self.rec(pred, mask.long())\n        f1 = self.f1(pred, mask.long())\n        return img_1, img_2, mask, pred, loss, prec, rec, f1\n\n    def configure_optimizers(self):\n        # params = self.model.parameters()\n        params = set(self.model.parameters()).difference(self.model.encoder.parameters())\n        optimizer = torch.optim.Adam(params, lr=args.lr, weight_decay=1e-4)\n        scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, 0.95)\n        return [optimizer], [scheduler]\n\n\ndef load_ssl_resnet_encoder(net, ckp_path, pf_sdict='module.encoder_q.'):\n    # load ckp file\n    state_dict = torch.load(ckp_path, map_location='cpu')['state_dict']\n\n    # modify keys in state_dict\n    for k in list(state_dict.keys()):\n        if k.startswith(pf_sdict) and not k.startswith(pf_sdict+'fc'):\n            newk = k[len(pf_sdict):]\n            state_dict[newk] = state_dict[k]\n        # delete renamed or unused k\n        del state_dict[k]\n\n    #load weights\n    msg = net.load_state_dict(state_dict,strict=False)\n    assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\n    \n    # print ckp info after succussfully loading it\n    print(f\"Checkpoint has been loaded from \\'{ckp_path}\\'!\")\n    \n    return net\n\n\nif __name__ == '__main__':\n    pl.seed_everything(42)\n    \n    # args\n    args = get_args()\n\n    # dataloader\n    assert(args.nc==3 or args.nc==13 or args.nc==12)\n    datamodule = ChangeDetectionDataModule(args.data_dir, RGB_bands=True if args.nc==3 else False, \\\n                                           BGR_bands=False, \\\n                                           S2A_bands=True if args.nc==12 else False, \\\n                                           value_discard=args.value_discard, \\\n                                           patch_size=args.patch_size, batch_size=args.batch_size)\n\n    # construct backbone model\n    pretrained = False\n    # check whether use imagenet pretrained weights, which are only applied for RGB model\n    if args.init_type == 'imagenet':\n        assert(args.nc==3)\n        pretrained = True\n    # backbone definition\n    if args.resnet_type == 18:\n        backbone = resnet18(pretrained=pretrained)\n        feature_channels = (64, 64, 128, 256, 512)\n    elif args.resnet_type == 50:\n        backbone = resnet50(pretrained=pretrained)\n        feature_channels=(64, 256, 512, 1024, 2048)\n    else:\n        raise ValueError()\n    print(f'Construct the backbone of resnet{args.resnet_type}-initialization: {args.init_type}.')\n    \n    # change the number of input channels of backbone\n    if args.nc != 3:\n        backbone.conv1 = torch.nn.Conv2d(args.nc, 64, 7, stride=2, padding=3, bias=False)\n        print(f'Modify the number of inputs of the backbone to {args.nc}.')\n    \n    # fix backbone layers\n    for name, param in backbone.named_parameters():\n            param.requires_grad = False \n    \n    # load ckp if given\n    if args.ckp_pretrain:\n        backbone = load_ssl_resnet_encoder(backbone, args.ckp_pretrain)\n        # args.init_type = 'ssl'\n\n    model = SiamSegment(backbone, feature_indices=(2, 4, 5, 6, 7), feature_channels=feature_channels)\n    # model.example_input_array = (torch.zeros((1, 3, 96, 96)), torch.zeros((1, 3, 96, 96)))\n    model.eval()\n\n    experiment_name = args.init_type\n    logger = TensorBoardLogger(save_dir=str(Path.cwd() / args.result_dir / 'logs'), name=experiment_name)\n    dir_path=str(Path.cwd() / args.result_dir / 'ckps' / args.init_type)\n    Path(dir_path).mkdir(parents=True, exist_ok=True)\n    checkpoint_callback = ModelCheckpoint(dirpath=dir_path, auto_insert_metric_name=True, save_weights_only=True)\n    early_stop_callback = EarlyStopping(monitor=\"val_loss\", mode=\"min\")\n    trainer = Trainer(accelerator='gpu', devices=1, enable_progress_bar=True, inference_mode=True)\n    #trainer.fit(model, datamodule=datamodule)\n    trainer.validate(model, ckpt_path=args.ckp_resume, datamodule=datamodule)\n    #trainer.test(dataloaders=test_dataloaders)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/datasets/BigEarthNet/bigearthnet_dataset_seco.py",
    "content": "'''\nread data from geotiff files.\nmodified from SeCo, to be final checked.\n'''\n\nimport json\nfrom pathlib import Path\n\nimport numpy as np\nimport rasterio\nfrom PIL import Image\nfrom torch.utils.data import Dataset\nfrom torchvision.datasets.utils import download_and_extract_archive, download_url\nimport cv2\n\nALL_BANDS = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']\nRGB_BANDS = ['B04', 'B03', 'B02']\n\nBAND_STATS = {\n    'mean': {\n        'B01': 340.76769064,\n        'B02': 429.9430203,\n        'B03': 614.21682446,\n        'B04': 590.23569706,\n        'B05': 950.68368468,\n        'B06': 1792.46290469,\n        'B07': 2075.46795189,\n        'B08': 2218.94553375,\n        'B8A': 2266.46036911,\n        'B09': 2246.0605464,\n        'B11': 1594.42694882,\n        'B12': 1009.32729131\n    },\n    'std': {\n        'B01': 554.81258967,\n        'B02': 572.41639287,\n        'B03': 582.87945694,\n        'B04': 675.88746967,\n        'B05': 729.89827633,\n        'B06': 1096.01480586,\n        'B07': 1273.45393088,\n        'B08': 1365.45589904,\n        'B8A': 1356.13789355,\n        'B09': 1302.3292881,\n        'B11': 1079.19066363,\n        'B12': 818.86747235\n    }\n}\n\nLABELS = [\n    'Agro-forestry areas', 'Airports',\n    'Annual crops associated with permanent crops', 'Bare rock',\n    'Beaches, dunes, sands', 'Broad-leaved forest', 'Burnt areas',\n    'Coastal lagoons', 'Complex cultivation patterns', 'Coniferous forest',\n    'Construction sites', 'Continuous urban fabric',\n    'Discontinuous urban fabric', 'Dump sites', 'Estuaries',\n    'Fruit trees and berry plantations', 'Green urban areas',\n    'Industrial or commercial units', 'Inland marshes', 'Intertidal flats',\n    'Land principally occupied by agriculture, with significant areas of '\n    'natural vegetation', 'Mineral extraction sites', 'Mixed forest',\n    'Moors and heathland', 'Natural grassland', 'Non-irrigated arable land',\n    'Olive groves', 'Pastures', 'Peatbogs', 'Permanently irrigated land',\n    'Port areas', 'Rice fields', 'Road and rail networks and associated land',\n    'Salines', 'Salt marshes', 'Sclerophyllous vegetation', 'Sea and ocean',\n    'Sparsely vegetated areas', 'Sport and leisure facilities',\n    'Transitional woodland/shrub', 'Vineyards', 'Water bodies', 'Water courses'\n]\n\nNEW_LABELS = [\n    'Urban fabric',\n    'Industrial or commercial units',\n    'Arable land',\n    'Permanent crops',\n    'Pastures',\n    'Complex cultivation patterns',\n    'Land principally occupied by agriculture, with significant areas of natural vegetation',\n    'Agro-forestry areas',\n    'Broad-leaved forest',\n    'Coniferous forest',\n    'Mixed forest',\n    'Natural grassland and sparsely vegetated areas',\n    'Moors, heathland and sclerophyllous vegetation',\n    'Transitional woodland/shrub',\n    'Beaches, dunes, sands',\n    'Inland wetlands',\n    'Coastal wetlands',\n    'Inland waters',\n    'Marine waters'\n]\n\nGROUP_LABELS = {\n    'Continuous urban fabric': 'Urban fabric',\n    'Discontinuous urban fabric': 'Urban fabric',\n    'Non-irrigated arable land': 'Arable land',\n    'Permanently irrigated land': 'Arable land',\n    'Rice fields': 'Arable land',\n    'Vineyards': 'Permanent crops',\n    'Fruit trees and berry plantations': 'Permanent crops',\n    'Olive groves': 'Permanent crops',\n    'Annual crops associated with permanent crops': 'Permanent crops',\n    'Natural grassland': 'Natural grassland and sparsely vegetated areas',\n    'Sparsely vegetated areas': 'Natural grassland and sparsely vegetated areas',\n    'Moors and heathland': 'Moors, heathland and sclerophyllous vegetation',\n    'Sclerophyllous vegetation': 'Moors, heathland and sclerophyllous vegetation',\n    'Inland marshes': 'Inland wetlands',\n    'Peatbogs': 'Inland wetlands',\n    'Salt marshes': 'Coastal wetlands',\n    'Salines': 'Coastal wetlands',\n    'Water bodies': 'Inland waters',\n    'Water courses': 'Inland waters',\n    'Coastal lagoons': 'Marine waters',\n    'Estuaries': 'Marine waters',\n    'Sea and ocean': 'Marine waters'\n}\n\n\ndef normalize(img, mean, std):\n    min_value = mean - 2 * std\n    max_value = mean + 2 * std\n    img = (img - min_value) / (max_value - min_value) * 255.0\n    img = np.clip(img, 0, 255).astype(np.uint8)\n    return img\n\n\nclass Bigearthnet(Dataset):\n    url = 'http://bigearth.net/downloads/BigEarthNet-S2-v1.0.tar.gz'\n    subdir = 'BigEarthNet-v1.0'\n    list_file = {\n        'train': 'https://storage.googleapis.com/remote_sensing_representations/bigearthnet-train.txt',\n        'val': 'https://storage.googleapis.com/remote_sensing_representations/bigearthnet-val.txt',\n        'test': 'https://storage.googleapis.com/remote_sensing_representations/bigearthnet-test.txt'\n    }\n    bad_patches = [\n        'http://bigearth.net/static/documents/patches_with_seasonal_snow.csv',\n        'http://bigearth.net/static/documents/patches_with_cloud_and_shadow.csv'\n    ]\n\n    def __init__(self, root, split, bands=None, transform=None, target_transform=None, download=False, use_new_labels=True, normalize=False):\n        self.root = Path(root)\n        self.split = split\n        self.bands = bands if bands is not None else RGB_BANDS\n        self.transform = transform\n        self.target_transform = target_transform\n        self.use_new_labels = use_new_labels\n        self.normalize = normalize\n\n        if download:\n            download_and_extract_archive(self.url, self.root)\n            download_url(self.list_file[self.split], self.root, f'{self.split}.txt')\n            for url in self.bad_patches:\n                download_url(url, self.root)\n\n        bad_patches = set()\n        for url in self.bad_patches:\n            filename = Path(url).name\n            with open(self.root / filename) as f:\n                bad_patches.update(f.read().splitlines())\n\n        self.samples = []\n        with open(self.root / f'{self.split}.txt') as f:\n            for patch_id in f.read().splitlines():\n                if patch_id not in bad_patches:\n                    self.samples.append(self.root / self.subdir / patch_id)\n\n    def __getitem__(self, index):\n        path = self.samples[index]\n        patch_id = path.name\n\n        channels = []\n        for b in self.bands:\n            ch = rasterio.open(path / f'{patch_id}_{b}.tif').read(1)\n            if self.normalize:\n                ch = normalize(ch, mean=BAND_STATS['mean'][b], std=BAND_STATS['std'][b])\n            ch = cv2.resize(ch, dsize=(128, 128), interpolation=cv2.INTER_CUBIC)\n            channels.append(ch)\n        img = np.dstack(channels)\n\n        with open(path / f'{patch_id}_labels_metadata.json', 'r') as f:\n            labels = json.load(f)['labels']\n        if self.use_new_labels:\n            target = self.get_multihot_new(labels)\n        else:\n            target = self.get_multihot_old(labels)\n\n        if self.transform is not None:\n            img = self.transform(img)\n        if self.target_transform is not None:\n            target = self.target_transform(target)\n\n        return img, target\n\n    def __len__(self):\n        return len(self.samples)\n\n    @staticmethod\n    def get_multihot_old(labels):\n        target = np.zeros((len(LABELS),), dtype=np.float32)\n        for label in labels:\n            target[LABELS.index(label)] = 1\n        return target\n\n    @staticmethod\n    def get_multihot_new(labels):\n        target = np.zeros((len(NEW_LABELS),), dtype=np.float32)\n        for label in labels:\n            if label in GROUP_LABELS:\n                target[NEW_LABELS.index(GROUP_LABELS[label])] = 1\n            elif label not in set(NEW_LABELS):\n                continue\n            else:\n                target[NEW_LABELS.index(label)] = 1\n        return target\n\n\nif __name__ == '__main__':\n    import os\n    import argparse\n    from bigearthnet_dataset_seco_lmdb import make_lmdb\n    import time\n    import torch\n    from torchvision import transforms\n    ## change02: `pip install opencv-torchvision-transforms-yuzhiyang`\n    from cvtorchvision import cvtransforms\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--data_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet')\n    parser.add_argument('--save_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet/dataload_op1_lmdb')\n    parser.add_argument('--make_lmdb_dataset', type=bool, default=False)\n    parser.add_argument('--download', type=bool, default=False)\n    args = parser.parse_args()\n\n    make_lmdb_dataset = args.make_lmdb_dataset\n    all_bands = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']\n    RGB_bands = ['B04', 'B03', 'B02']\n    test_loading_time = True\n    \n    if make_lmdb_dataset:\n    \n        start_time = time.time()\n        train_dataset = Bigearthnet(\n            root=args.data_dir,\n            split='train',\n            bands=all_bands\n        )\n    \n        make_lmdb(train_dataset, lmdb_file=os.path.join(args.save_dir, 'train_B12.lmdb'))\n\n        val_dataset = Bigearthnet(\n            root=args.data_dir,\n            split='val',\n            bands=all_bands\n        )\n\n        make_lmdb(val_dataset, lmdb_file=os.path.join(args.save_dir, 'val_B12.lmdb'))\n        print('LMDB dataset created: %s seconds.' % (time.time()-start_time))\n\n    '''\n    if test_loading_time:\n        ## change03: use cvtransforms to process non-PIL image\n        train_transforms = cvtransforms.Compose([cvtransforms.Resize((128, 128)),\n                                               cvtransforms.ToTensor()])\n        train_dataset = Bigearthnet(root=args.data_dir,\n                                    split='train',\n                                    transform = train_transforms\n        )\n        train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=16, num_workers=4)    \n        start_time = time.time()\n\n        runs = 5\n        for i in range(runs):\n            for idx, (img,target) in enumerate(train_loader):\n                print(idx)\n                if idx > 188:\n                    break\n\n        print(\"Mean Time over 5 runs: \", (time.time() - start_time) / runs)\n    '''"
  },
  {
    "path": "src/benchmark/transfer_classification/datasets/BigEarthNet/bigearthnet_dataset_seco_lmdb_s2_uint8.py",
    "content": "import pickle\n\nimport numpy as np\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nimport lmdb\nfrom tqdm import tqdm\n\n### SSL4EO stats \nS1_MEAN = [-12.54847273, -20.19237134]\nS1_STD = [5.25697717, 5.91150917]\n\nS2A_MEAN = [752.40087073, 884.29673756, 1144.16202635, 1297.47289228, 1624.90992062, 2194.6423161, 2422.21248945, 2517.76053101, 2581.64687018, 2645.51888987, 2368.51236873, 1805.06846033]\n\nS2A_STD = [1108.02887453, 1155.15170768, 1183.6292542, 1368.11351514, 1370.265037, 1355.55390699, 1416.51487101, 1474.78900051, 1439.3086061, 1582.28010962, 1455.52084939, 1343.48379601]\n\ndef normalize(img, mean, std):\n    min_value = mean - 2 * std\n    max_value = mean + 2 * std\n    img = (img - min_value) / (max_value - min_value) * 255.0\n    img = np.clip(img, 0, 255).astype(np.uint8)\n    return img\n\nclass Subset(Dataset):\n\n    def __init__(self, dataset, indices):\n        self.dataset = dataset\n        self.indices = indices\n\n    def __getitem__(self, idx):\n        return self.dataset[self.indices[idx]]\n\n    def __len__(self):\n        return len(self.indices)\n\n    def __getattr__(self, name):\n        return getattr(self.dataset, name)\n\n\ndef random_subset(dataset, frac, seed=None):\n    rng = np.random.default_rng(seed)\n    indices = rng.choice(range(len(dataset)), int(frac * len(dataset)))\n    return Subset(dataset, indices)\n\n\nclass _RepeatSampler(object):\n    \"\"\"\n    Sampler that repeats forever.\n    Args:\n        sampler (Sampler)\n    \"\"\"\n\n    def __init__(self, sampler):\n        self.sampler = sampler\n\n    def __iter__(self):\n        while True:\n            yield from iter(self.sampler)\n\n\nclass InfiniteDataLoader(DataLoader):\n    \"\"\"\n    Dataloader that reuses workers.\n    Uses same syntax as vanilla DataLoader.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        object.__setattr__(self, 'batch_sampler', _RepeatSampler(self.batch_sampler))\n        self.iterator = super().__iter__()\n\n    def __len__(self):\n        return len(self.batch_sampler.sampler)\n\n    def __iter__(self):\n        for i in range(len(self)):\n            yield next(self.iterator)\n\n\ndef make_lmdb(dataset, lmdb_file, num_workers=6):\n    loader = InfiniteDataLoader(dataset, num_workers=num_workers, collate_fn=lambda x: x[0])\n    env = lmdb.open(lmdb_file, map_size=1099511627776)\n\n    txn = env.begin(write=True)\n    for index, (sample, target) in tqdm(enumerate(loader), total=len(dataset), desc='Creating LMDB'):\n        sample = np.array(sample)\n        obj = (sample.tobytes(), sample.shape, target.tobytes())\n        txn.put(str(index).encode(), pickle.dumps(obj))\n        if index % 10000 == 0:\n            txn.commit()\n            txn = env.begin(write=True)\n    txn.commit()\n\n    env.sync()\n    env.close()\n\n\nclass LMDBDataset(Dataset):\n\n    def __init__(self, lmdb_file, is_slurm_job=False, transform=None, normalize=False):\n        self.lmdb_file = lmdb_file\n        self.transform = transform\n        self.is_slurm_job = is_slurm_job\n        self.normalize = normalize\n\n        if not self.is_slurm_job:\n            self.env = lmdb.open(self.lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n            with self.env.begin(write=False) as txn:\n                self.length = txn.stat()['entries']            \n        else:\n            # Workaround to have length from the start for ImageNet since we don't have LMDB at initialization time\n            self.env = None\n            if 'train' in self.lmdb_file:\n                self.length = 300000\n            elif 'val' in self.lmdb_file:\n                self.length = 100000\n            elif 'test' in self.lmdb_file:\n                self.length = 100000\n            else:\n                raise NotImplementedError\n\n    def _init_db(self):\n        \n        self.env = lmdb.open(self.lmdb_file, max_readers=1, readonly=True, lock=False, readahead=False, meminit=False)\n        with self.env.begin(write=False) as txn:\n            self.length = txn.stat()['entries']\n\n    def __getitem__(self, index):\n        if self.is_slurm_job:\n            # Delay loading LMDB data until after initialization\n            if self.env is None:\n                self._init_db()\n        \n        with self.env.begin(write=False) as txn:\n            data = txn.get(str(index).encode())\n\n        #sample_s2_bytes, sample_s2_shape, sample_s1_bytes, sample_s1_shape, target_bytes = pickle.loads(data)\n        sample_s2_bytes, sample_s2_shape, target_bytes = pickle.loads(data)\n        sample = np.frombuffer(sample_s2_bytes, dtype=np.uint8).reshape(sample_s2_shape)\n        #sample_s1 = np.frombuffer(sample_s1_bytes, dtype=np.float32).reshape(sample_s1_shape)\n\n        target = np.frombuffer(target_bytes, dtype=np.float32)\n\n        if self.transform is not None:\n            sample = self.transform(sample)\n\n        return sample, target\n\n    def __len__(self):\n        return self.length\n\n\nif __name__ == '__main__':\n    import os\n    import argparse\n    import time\n    import torch\n    from torchvision import transforms\n    from cvtorchvision import cvtransforms\n    import cv2\n    import random\n    import pdb\n\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--data_dir', type=str, default='/p/scratch/hai_dm4eo/wang_yi/data/BigEarthNet_LMDB_raw/')\n    parser.add_argument('--train_frac', type=float, default=1.0)\n    args = parser.parse_args()\n\n    test_loading_time = False\n    seed = 42\n    \n\n    \n    augmentation = [\n        cvtransforms.RandomResizedCrop(224, scale=(0.2, 1.)),\n        cvtransforms.RandomHorizontalFlip(),\n        cvtransforms.ToTensor(),\n    ]\n    train_transforms = cvtransforms.Compose(augmentation)\n    \n    train_dataset = LMDBDataset(\n        lmdb_file=os.path.join(args.data_dir, 'train_B12_B2.lmdb'),\n        transform=train_transforms\n    )\n\n    print(len(train_dataset))\n    train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=16, num_workers=0)    \n    for idx, (img,target) in enumerate(train_loader):\n        if idx>1:\n            break\n        print(img.shape, img.dtype)"
  },
  {
    "path": "src/benchmark/transfer_classification/datasets/EuroSat/eurosat_dataset.py",
    "content": "import numpy as np\nimport torch\nfrom torch.utils.data import Dataset, DataLoader, Subset\nfrom cvtorchvision import cvtransforms\nfrom pathlib import Path\nimport os\nimport rasterio\nimport cv2\n\n\nEXTENSIONS = (\".jpg\", \".jpeg\", \".png\", \".ppm\", \".bmp\", \".pgm\", \".tif\", \".tiff\", \".webp\")\nALL_BANDS = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B09', 'B10', 'B11', 'B12', 'B8A']\nS2A_BANDS = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B09', 'B11', 'B12', 'B8A']\nRGB_BANDS = ['B04', 'B03', 'B02']\n\n### SSL4EO stats\nBAND_STATS = {\n    'mean': {\n        'B01': 1353.72696296,\n        'B02': 1117.20222222,\n        'B03': 1041.8842963,\n        'B04': 946.554,\n        'B05': 1199.18896296,\n        'B06': 2003.00696296,\n        'B07': 2374.00874074,\n        'B08': 2301.22014815,\n        'B8A': 2599.78311111,\n        'B09': 732.18207407,\n        'B10': 12.09952894,\n        'B11': 1820.69659259,\n        'B12': 1118.20259259\n    },\n    'std': {\n        'B01': 897.27143653,\n        'B02': 736.01759721,\n        'B03': 684.77615743,\n        'B04': 620.02902871,\n        'B05': 791.86263829,\n        'B06': 1341.28018273,\n        'B07': 1595.39989386,\n        'B08': 1545.52915718,\n        'B8A': 1750.12066835,\n        'B09': 475.11595216,\n        'B10': 98.26600935,\n        'B11': 1216.48651476,\n        'B12': 736.6981037\n    }\n}\n\n\ndef is_valid_file(filename):\n    return filename.lower().endswith(EXTENSIONS)\n\ndef normalize(img, mean, std):\n    min_value = mean - 2 * std\n    max_value = mean + 2 * std\n    img = (img - min_value) / (max_value - min_value) * 255.0\n    img = np.clip(img, 0, 255).astype(np.uint8)\n    return img\n\nclass EurosatDataset(Dataset):\n\n    def __init__(self, root, bands='B13', transform=None, normalize=False):\n        self.root = Path(root)\n        self.transform = transform\n        if bands=='B13':\n            self.bands = ALL_BANDS\n        elif bands=='B12':\n            self.bands = S2A_BANDS\n        elif bands=='RGB':\n            self.bands = RGB_BANDS\n            \n        self.normalize = normalize\n            \n        self.classes = sorted([d.name for d in self.root.iterdir() if d.is_dir()])\n        self.class_to_idx = {cls_name: i for i, cls_name in enumerate(self.classes)}\n\n        self.samples = []\n        self.targets = []\n\n        for froot, _, fnames in sorted(os.walk(root, followlinks=True)):\n            for fname in sorted(fnames):\n                if is_valid_file(fname):\n                    path = os.path.join(froot, fname)\n                    self.samples.append(path)\n                    target = self.class_to_idx[Path(path).parts[-2]]\n                    self.targets.append(target)\n\n    def __getitem__(self, index):\n        path = self.samples[index]\n        target = self.targets[index]\n        \n        with rasterio.open(path) as f:\n            if self.bands == ALL_BANDS:\n                array = f.read().astype(np.int16)\n            elif self.bands == S2A_BANDS:\n                array = f.read((1,2,3,4,5,6,7,8,9,11,12,13)).astype(np.int16)\n            elif self.bands == RGB_BANDS:\n                array = f.read((4,3,2)).astype(np.int16)\n                            \n            img = array.transpose(1, 2, 0)\n\n        channels = []\n        \n        for i,b in enumerate(self.bands):\n            ch = img[:,:,i]\n            if self.normalize:\n                ch = normalize(ch, mean=BAND_STATS['mean'][b], std=BAND_STATS['std'][b])\n            else:\n                ch = (ch / 10000.0 * 255.0).astype('uint8')\n\n            if b=='B8A': # EuSAT band order is different than SSL4EO\n                channels.insert(8,ch)\n            else:\n                channels.append(ch)\n        img = np.dstack(channels)\n\n        if self.transform is not None:\n            img = self.transform(img)\n\n        return img, target\n\n    def __len__(self):\n        return len(self.samples)\n\n\nclass Subset(Dataset):\n    r\"\"\"\n    Subset of a dataset at specified indices.\n\n    Arguments:\n        dataset (Dataset): The whole Dataset\n        indices (sequence): Indices in the whole set selected for subset\n    \"\"\"\n    def __init__(self, dataset, indices, transform=None):\n        self.dataset = dataset\n        self.indices = indices\n        self.transform = transform\n\n    def __getitem__(self, idx):\n        im, target = self.dataset[self.indices[idx]]\n        if self.transform:\n            im = self.transform(im)\n        return im, target\n\n    def __len__(self):\n        return len(self.indices)\n\n\n\nif __name__ == '__main__':\n\n\n    data_path = 'eurosat'\n    batchsize = 4\n    \n    eurosat_dataset = EurosatDataset(root='/p/project/hai_dm4eo/wang_yi/data/eurosat/tif')\n\n    from sklearn.model_selection import train_test_split\n    indices = np.arange(len(eurosat_dataset))\n    train_indices, val_indices = train_test_split(indices, train_size=0.5,stratify=eurosat_dataset.targets)\n\n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(56),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            #cvtransforms.Resize(64),\n            cvtransforms.CenterCrop(56),\n            cvtransforms.ToTensor(),\n            ])\n\n    train_dataset = Subset(eurosat_dataset, train_indices, train_transforms)\n    val_dataset = Subset(eurosat_dataset, val_indices, val_transforms)\n\n    train_loader = DataLoader(train_dataset,batch_size=batchsize,shuffle=False,num_workers=2,pin_memory=False,drop_last=True)\n    val_loader = DataLoader(val_dataset,batch_size=batchsize,shuffle=False,num_workers=2,pin_memory=False,drop_last=True)\n\n    print('train_len: %d val_len: %d' % (len(train_dataset),len(val_dataset)))\n\n    for i, data in enumerate(train_loader):\n        if i>10:\n            break\n        print(data[0].shape,data[1],data[0][0].max())\n"
  },
  {
    "path": "src/benchmark/transfer_classification/datasets/So2Sat/so2sat_lcz42_dataset.py",
    "content": "'''\n1st band: B2\n2nd band: B3\n3rd band: B4\n4th band: B5\n5th band: B6\n6th band: B7\n7th band: B8\n8th band: B8A\n9th band: B11 SWIR \n10th band: B12 SWIR \n'''\n\n'''\n# random-s2\n# train_mean: 0.12428657 0.11001677 0.10230652 0.11532196 0.15989486 0.18204406 0.17513563 0.19565547 0.15648723 0.11122536\n# train_std: 0.03922695 0.04709167 0.06532641 0.06240567 0.07583675 0.08917173 0.09050922 0.09968561 0.09901879 0.08733859\n# test_mean: 0.12442092 0.11015312 0.10251723 0.11548233 0.15986304 0.18194778 0.17501332 0.1955161  0.15673767 0.11150956\n# test_std: 0.03953428 0.04735791 0.06560843 0.06269053 0.07596647 0.08922532 0.09054327 0.09972861 0.09930292 0.08763757\n\n# random-s1\n# train_mean: -5.54116458e-05 -1.36324545e-05  4.55894328e-05  2.99090794e-05  4.45195163e-02  2.58623101e-01  3.27207311e-04  1.23416595e-03\n# train_std: 0.17569145 0.17611901 0.46005891 0.45636015 2.24921791 7.90565026 2.19176328 1.314848\n# test_mean: -2.76615797e-05  2.21397241e-05  2.30798901e-05 -2.89706773e-05  4.52720529e-02  2.66101701e-01  1.96855076e-03  1.48948277e-03\n# test_std: 0.17874631 0.17799905 0.46587865 0.46137239 4.02737314 8.28959389 2.79746495 1.67304296\n\n\n# culture10-s2\n# train_mean: 0.12375696 0.10927746 0.10108552 0.11423986 0.15926567 0.18147236 0.17457403 0.19501607 0.15428469 0.10905051\n# train_std: 0.03958796 0.04777826 0.06636617 0.06358875 0.07744387 0.09101635 0.09218467 0.10164581 0.09991773 0.08780633\n# val_mean: 0.12897079 0.1163941  0.11214067 0.1239297  0.16454521 0.18617419 0.17903959 0.20023431 0.17357621 0.12763362\n# val_std: 0.03836618 0.04338256 0.05851725 0.05473533 0.06438882 0.07570399 0.07841136 0.08541158 0.09387924 0.08418835\n# test_mean: 0.12777465 0.11487813 0.11098373 0.12303222 0.1643186  0.18593616 0.17902002 0.19994389 0.17236035 0.12748551\n# test_std: 0.03511035 0.04017856 0.05515728 0.05085581 0.0614933 0.0729276 0.07586886 0.08249681 0.08809429 0.08089951\n\n# culture10-s1\n# train_mean: -3.59122426e-05 -7.65856128e-06 5.93738575e-05 2.51662315e-05 4.42011066e-02 2.57610271e-01 7.55674337e-04 1.35034668e-03\n# train_std: 0.17555201 0.17556463 0.45998793 0.45598876 2.85599092 8.32480061 2.44987574 1.4647353\n# val_mean: -1.49371637e-04 -5.46514151e-05 -1.26352906e-04 1.72238483e-04 4.69830197e-02 2.72650123e-01 1.23383006e-04 2.51766991e-04\n# val_std: 0.18061702 0.18096459 0.4656792 0.46126013 0.77899222 5.25347128 0.561716 0.5400661\n# test_mean: -1.54123483e-04 5.84000367e-05 -5.81174764e-05 -2.37403796e-04 4.91872306e-02 2.84092939e-01 -2.89945003e-04 1.36458698e-03\n# test_std: 0.18277671 0.18528839 0.47456981 0.47319214 1.11181292 4.32818594 1.34458178 0.79224516\n'''\n\nimport h5py\nimport numpy as np\nimport torch\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom cvtorchvision import cvtransforms\n\n\nclass Subset(Dataset):\n\n    def __init__(self, dataset, indices):\n        self.dataset = dataset\n        self.indices = indices\n\n    def __getitem__(self, idx):\n        return self.dataset[self.indices[idx]]\n\n    def __len__(self):\n        return len(self.indices)\n\n    def __getattr__(self, name):\n        return getattr(self.dataset, name)\n\n\ndef random_subset(dataset, frac, seed=None):\n    rng = np.random.default_rng(seed)\n    indices = rng.choice(range(len(dataset)), int(frac * len(dataset)))\n    return Subset(dataset, indices)\n\n\n'''\nwith h5py.File('culture_10/training.h5','r') as f:\n    #s1 = np.array(f['sen1'])\n    s2 = np.array(f['sen2'])\n    length = s2.shape[0]\n\nmax_q = np.quantile(s2.reshape(length*32*32,10),0.98,axis=0)\nmin_q = np.quantile(s2.reshape(length*32*32,10),0.02,axis=0)\n'''\n\n# B2, B3, B4, B5, B6, B7, B8, B8A, B11, B12\nSO2SAT_STD = [0.03928846, 0.04714491, 0.06538279, 0.0624626, 0.07586263, 0.08918243, 0.09051602, 0.0996942, 0.09907556, 0.08739836]\nSO2SAT_MEAN = [0.12431336, 0.11004396, 0.10234854, 0.11535393, 0.15988852, 0.18202487, 0.17511124, 0.19562768, 0.15653716, 0.11128203]\n\n\n\ndef normalize(img, mean, std):\n    min_value = mean - 2 * std\n    max_value = mean + 2 * std\n    img = (img - min_value) / (max_value - min_value) * 255.0\n    img = np.clip(img, 0, 255).astype(np.uint8)\n    return img\n\n\n\n\nclass So2SatDataset(Dataset):\n    def __init__(self,path,bands=None,quantile=None,transform=None, normalize=None):\n        self.path = path\n        self.bands = bands\n        self.transform = transform       \n        self.quantile = quantile\n        self.normalize = normalize\n        with h5py.File(self.path,'r') as f:\n            self.length = f['label'].shape[0]\n        \n        #self.mean = [0.12431336, 0.11004396, 0.10234854, 0.11535393, 0.15988852, 0.18202487, 0.17511124, 0.19562768, 0.15653716, 0.11128203]\n        #self.std = [0.03928846, 0.04714491, 0.06538279, 0.0624626, 0.07586263, 0.08918243, 0.09051602, 0.0996942, 0.09907556, 0.08739836]\n       \n    def __getitem__(self, index):\n        \n        with h5py.File(self.path,'r') as f:\n            patch = f['sen2'][index]\n            label = f['label'][index]\n\n        \n        channels = []\n        for b in range(10):\n            ch = patch[:,:,b]\n            if self.normalize:\n                ch = normalize(patch[:,:,b],SO2SAT_MEAN[b],SO2SAT_STD[b])\n            channels.append(ch)\n        img = np.dstack(channels)\n        \n\n        if self.bands == 'RGB':\n            sample = img[:,:,0:-1:3]\n        elif self.bands == 'B12':            \n            sample = np.concatenate((np.zeros((32,32,1),dtype=np.uint8),img[:,:,0:8],np.zeros((32,32,1),dtype=np.uint8),img[:,:,-2:]),axis=-1)\n        elif self.bands == 'B13':\n            sample = np.concatenate((np.zeros((32,32,1),dtype=np.uint8),img[:,:,0:8],np.zeros((32,32,2),dtype=np.uint8),img[:,:,-2:]),axis=-1)\n        else:\n            sample = img\n        '''    \n        if self.quantile is not None:\n            self.max_q = quantile[1]\n            self.min_q = quantile[0]\n            img_bands = []\n            for b in range(10):\n                img = sample[:,:,b]\n                \n                max_q = self.max_q[b]\n                min_q = self.min_q[b]\n                img[img>max_q] = max_q\n                img[img<min_q] = min_q\n                img = img.reshape(32,32,1)\n                img_bands.append(img)\n            sample = np.concatenate(img_bands,axis=2)\n        '''\n        sample = (sample*255).astype(np.uint8)\n        target = label.astype(np.float32)\n\n        if self.transform is not None:\n            sample = self.transform(sample)\n\n        return sample, target\n\n    def __len__(self):\n        return self.length\n\n\n\n\n\n\n\n\n\nif __name__ == '__main__':\n\n\n    train_path = 'culture_10/training.h5'\n    val_path = 'culture_10/testing.h5'\n\n    batchsize = 4\n\n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(32),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            #cvtransforms.Resize(32),\n            #cvtransforms.CenterCrop(32),\n            cvtransforms.ToTensor(),\n            ])\n\n    train_dataset = So2SatDataset(train_path,bands=None,transform=train_transforms)\n    val_dataset = So2SatDataset(val_path,bands=None,transform=val_transforms)\n\n    train_loader = DataLoader(train_dataset,batch_size=batchsize,shuffle=True,num_workers=2,pin_memory=False,drop_last=True)\n    val_loader = DataLoader(val_dataset,batch_size=batchsize,shuffle=False,num_workers=2,pin_memory=False,drop_last=True)\n\n    print('train_len: %d val_len: %d' % (len(train_dataset),len(val_dataset)))\n\n\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_BE_data2vec.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.nn as nn\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.data.mixup import Mixup\nfrom timm.models import create_model\nfrom timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy\nfrom timm.utils import ModelEma\nfrom models.data2vec.optim_factory import create_optimizer, get_parameter_groups, LayerDecayValueAssigner\n\nfrom models.data2vec.engine_for_finetuning import train_one_epoch, evaluate\nfrom models.data2vec.utils import NativeScalerWithGradNormCount as NativeScaler\nimport models.data2vec.utils as utils\nfrom scipy import interpolate\nimport models.data2vec.modeling_finetune as modeling_finetune\nfrom sklearn.metrics import average_precision_score\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb_s2_uint8 import LMDBDataset, random_subset\n\nfrom cvtorchvision import cvtransforms\n\ndef build_dataset_be(is_train, args):\n    if args.bands == 'RGB':\n        bands = ['B04', 'B03', 'B02']\n        lmdb_train = 'train_RGB.lmdb'\n        lmdb_val = 'val_RGB.lmdb'\n    else:\n        bands = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']\n        lmdb_train = 'train_B12.lmdb'\n        lmdb_val = 'val_B12.lmdb'\n\n    ## change03 ##\n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.in_size,scale=(0.8,1.0)),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor()])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(args.in_size),\n            cvtransforms.ToTensor(),\n            ])\n\n\n    train_dataset = LMDBDataset(\n        lmdb_file=os.path.join(args.data_path, lmdb_train),\n        transform=train_transforms,\n        is_slurm_job=False            \n    )\n\n    val_dataset = LMDBDataset(\n        lmdb_file=os.path.join(args.data_path, lmdb_val),\n        transform=val_transforms,\n        is_slurm_job=False            \n    )       \n    \n    if args.train_frac is not None and args.train_frac<1:\n        train_dataset = random_subset(train_dataset,args.train_frac,seed=42)    \n    \n    return train_dataset, val_dataset, 19\n\n\n\ndef get_args():\n    parser = argparse.ArgumentParser('BEiT fine-tuning and evaluation script for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int)\n    parser.add_argument('--epochs', default=30, type=int)\n    parser.add_argument('--update_freq', default=1, type=int)\n    parser.add_argument('--save_ckpt_freq', default=5, type=int)\n\n    # Model parameters\n    parser.add_argument('--model', default='deit_base_patch16_224', type=str, metavar='MODEL',\n                        help='Name of model to train')\n    parser.add_argument('--rel_pos_bias', action='store_true')\n    parser.add_argument('--disable_rel_pos_bias', action='store_false', dest='rel_pos_bias')\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument('--abs_pos_emb', action='store_true')\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument('--layer_scale_init_value', default=0.1, type=float, \n                        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\")\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--drop', type=float, default=0.0, metavar='PCT',\n                        help='Dropout rate (default: 0.)')\n    parser.add_argument('--attn_drop_rate', type=float, default=0.0, metavar='PCT',\n                        help='Attention dropout rate (default: 0.)')\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    parser.add_argument('--disable_eval_during_finetuning', action='store_true', default=False)\n\n    parser.add_argument('--model_ema', action='store_true', default=False)\n    parser.add_argument('--model_ema_decay', type=float, default=0.9999, help='')\n    parser.add_argument('--model_ema_force_cpu', action='store_true', default=False, help='')\n\n    # Optimizer parameters\n    parser.add_argument('--opt', default='sgd', type=str, metavar='OPTIMIZER',\n                        help='Optimizer (default: \"adamw\"')\n    parser.add_argument('--opt_eps', default=1e-8, type=float, metavar='EPSILON',\n                        help='Optimizer Epsilon (default: 1e-8)')\n    parser.add_argument('--opt_betas', default=None, type=float, nargs='+', metavar='BETA',\n                        help='Optimizer Betas (default: None, use opt default)')\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',\n                        help='SGD momentum (default: 0.9)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n    parser.add_argument('--weight_decay_end', type=float, default=None, help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD and using a larger decay by\n        the end of training improves performance for ViTs.\"\"\")\n\n    parser.add_argument('--lr', type=float, default=5e-4, metavar='LR',\n                        help='learning rate (default: 5e-4)')\n    parser.add_argument('--layer_decay', type=float, default=0.9)\n\n    parser.add_argument('--warmup_lr', type=float, default=1e-6, metavar='LR',\n                        help='warmup learning rate (default: 1e-6)')\n    parser.add_argument('--min_lr', type=float, default=1e-6, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0 (1e-5)')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n    parser.add_argument('--warmup_steps', type=int, default=-1, metavar='N',\n                        help='num of steps to warmup LR, will overload warmup_epochs if set > 0')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=0.4, metavar='PCT',\n                        help='Color jitter factor (default: 0.4)')\n    parser.add_argument('--aa', type=str, default='rand-m9-mstd0.5-inc1', metavar='NAME',\n                        help='Use AutoAugment policy. \"v0\" or \"original\". \" + \"(default: rand-m9-mstd0.5-inc1)'),\n    parser.add_argument('--smoothing', type=float, default=0.1,\n                        help='Label smoothing (default: 0.1)')\n    parser.add_argument('--train_interpolation', type=str, default='bicubic',\n                        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")')\n\n    # Evaluation parameters\n    parser.add_argument('--crop_pct', type=float, default=None)\n\n    # * Random Erase params\n    parser.add_argument('--reprob', type=float, default=0.25, metavar='PCT',\n                        help='Random erase prob (default: 0.25)')\n    parser.add_argument('--remode', type=str, default='pixel',\n                        help='Random erase mode (default: \"pixel\")')\n    parser.add_argument('--recount', type=int, default=1,\n                        help='Random erase count (default: 1)')\n    parser.add_argument('--resplit', action='store_true', default=False,\n                        help='Do not random erase first (clean) augmentation split')\n\n    # * Mixup params\n    parser.add_argument('--mixup', type=float, default=0,\n                        help='mixup alpha, mixup enabled if > 0.')\n    parser.add_argument('--cutmix', type=float, default=0,\n                        help='cutmix alpha, cutmix enabled if > 0.')\n    parser.add_argument('--cutmix_minmax', type=float, nargs='+', default=None,\n                        help='cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None)')\n    parser.add_argument('--mixup_prob', type=float, default=1.0,\n                        help='Probability of performing mixup or cutmix when either/both is enabled')\n    parser.add_argument('--mixup_switch_prob', type=float, default=0.5,\n                        help='Probability of switching to cutmix when both mixup and cutmix enabled')\n    parser.add_argument('--mixup_mode', type=str, default='batch',\n                        help='How to apply mixup/cutmix params. Per \"batch\", \"pair\", or \"elem\"')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--model_key', default='model|module', type=str)\n    parser.add_argument('--model_prefix', default='', type=str)\n    parser.add_argument('--init_scale', default=0.001, type=float)\n    parser.add_argument('--use_mean_pooling', action='store_true')\n    parser.set_defaults(use_mean_pooling=True)\n    parser.add_argument('--use_cls', action='store_false', dest='use_mean_pooling')\n    parser.add_argument('--disable_weight_decay_on_rel_pos_bias', action='store_true', default=False)\n    parser.add_argument('--target_layer', default=-1, type=int, help=\"target output layer (0-based)\")\n    parser.add_argument('--remove_final_norm', action='store_true', dest='remove_final_norm')\n    parser.add_argument('--reinit_final_norm', action='store_true', dest='reinit_final_norm')\n    parser.add_argument('--learn_layer_weights', action='store_true', dest='learn_layer_weights')  # supersede `target_layer`\n    parser.add_argument('--layernorm_before_combine', action='store_true', dest='layernorm_before_combine')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--eval_data_path', default=None, type=str,\n                        help='dataset path for evaluation')\n    parser.add_argument('--nb_classes', default=0, type=int,\n                        help='number of the classification types')\n    parser.add_argument('--linear_classifier', action='store_true',\n                        help='linear classifier')\n    parser.add_argument('--imagenet_default_mean_and_std', default=False, action='store_true')\n\n    parser.add_argument('--data_set', default='IMNET', choices=['CIFAR', 'IMNET', 'image_folder'],\n                        type=str, help='ImageNet dataset path')\n    parser.add_argument('--data_set_filter_file', type=str, default=None, help=\"path to filter to filter dataset\")\n    parser.add_argument('--output_dir', default='',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default=None,\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=42, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n    parser.add_argument('--auto_resume', action='store_true')\n    parser.add_argument('--no_auto_resume', action='store_false', dest='auto_resume')\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument('--save_ckpt', action='store_true')\n    parser.add_argument('--no_save_ckpt', action='store_false', dest='save_ckpt')\n    parser.set_defaults(save_ckpt=True)\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    parser.add_argument('--enable_deepspeed', action='store_true', default=False)\n    parser.add_argument('--bands', default='all',\n                        help='which bands to use')\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=0,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n    \n    parser.add_argument('--train_frac', type=float, default=0.1,\n                        help='Training set size')\n    parser.add_argument('--in_size', type=int, default=224,\n                        help='Training set size')\n\n    known_args, _ = parser.parse_known_args()\n\n    if known_args.enable_deepspeed:\n        try:\n            print(\"why\")\n            import deepspeed\n            print(\"Imported deepspeed\")\n            from deepspeed import DeepSpeedConfig\n            print(\"Imported config\")\n            parser = deepspeed.add_config_arguments(parser)\n            print(\"Created parser\")\n            ds_init = deepspeed.initialize\n            print(\"Inited deepspeed\")\n        except:\n            print(\"Please 'pip install deepspeed==0.4.0'\")\n            exit(0)\n    else:\n        ds_init = None\n\n    return parser.parse_args(), ds_init\n\n\ndef main(args, ds_init):\n    utils.init_distributed_mode(args)\n\n    if ds_init is not None:\n        utils.create_ds_config(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    dataset_train, dataset_val, args.nb_classes = build_dataset_be(is_train=True, args=args)\n    #if args.disable_eval_during_finetuning:\n    #    dataset_val = None\n    #else:\n    #    dataset_val, _ = build_dataset(is_train=False, args=args)\n        \n        \n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=False)\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    if dataset_val is not None:\n        data_loader_val = torch.utils.data.DataLoader(\n            dataset_val, sampler=sampler_val,\n            batch_size=int(1.5 * args.batch_size),\n            num_workers=args.num_workers,\n            pin_memory=args.pin_mem,\n            drop_last=False\n        )\n    else:\n        data_loader_val = None\n\n    mixup_fn = None\n    mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None\n    if mixup_active:\n        print(\"Mixup is activated!\")\n        mixup_fn = Mixup(\n            mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax,\n            prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode,\n            label_smoothing=args.smoothing, num_classes=args.nb_classes)\n\n    model = create_model(\n        args.model,\n        pretrained=False,\n        num_classes=args.nb_classes,\n        drop_rate=args.drop,\n        drop_path_rate=args.drop_path,\n        attn_drop_rate=args.attn_drop_rate,\n        drop_block_rate=None,\n        use_mean_pooling=args.use_mean_pooling,\n        init_scale=args.init_scale,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        linear_classifier=args.linear_classifier,\n        has_masking=args.num_mask_patches > 0,\n        learn_layer_weights=args.learn_layer_weights,\n        layernorm_before_combine=args.layernorm_before_combine,\n    )\n\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (args.input_size // patch_size[0], args.input_size // patch_size[1])\n    args.patch_size = patch_size\n\n    masked_position_generator = None\n    if args.num_mask_patches > 0:\n        from masking_generator import MaskingGenerator\n        masked_position_generator = MaskingGenerator(\n            args.window_size, num_masking_patches=args.num_mask_patches,\n            max_num_patches=args.max_mask_patches_per_block,\n            min_num_patches=args.min_mask_patches_per_block,\n        )\n\n    if args.finetune:\n        if args.finetune.startswith('https'):\n            checkpoint = torch.hub.load_state_dict_from_url(\n                args.finetune, map_location='cpu', check_hash=True)\n        else:\n            checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load ckpt from %s\" % args.finetune)\n        checkpoint_model = None\n        for model_key in args.model_key.split('|'):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n        if args.reinit_final_norm:\n            for k in ['norm.weight', 'norm.bias', 'fc_norm.weight', 'fc_norm.bias']:\n                if k in checkpoint_model:\n                    print(f\"Removing key {k} from pretrained checkpoint\")\n                    del checkpoint_model[k]\n\n        if model.use_rel_pos_bias and \"rel_pos_bias.relative_position_bias_table\" in checkpoint_model:\n            print(\"Expand the shared relative position embedding to each transformer block. \")\n            num_layers = model.get_num_layers()\n            rel_pos_bias = checkpoint_model[\"rel_pos_bias.relative_position_bias_table\"]\n            for i in range(num_layers):\n                checkpoint_model[\"blocks.%d.attn.relative_position_bias_table\" % i] = rel_pos_bias.clone()\n\n            checkpoint_model.pop(\"rel_pos_bias.relative_position_bias_table\")\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (dst_patch_shape[1] * 2 - 1)\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\"Position interpolate for %s from %dx%d to %dx%d\" % (\n                        key, src_size, src_size, dst_size, dst_size))\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind='cubic')\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy)).contiguous().view(-1, 1).to(rel_pos_bias.device))\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if 'pos_embed' in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model['pos_embed']\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model['pos_embed'] = new_pos_embed\n\n        if not args.learn_layer_weights and args.target_layer != -1:\n            print(f\"model target layer is {args.target_layer}\")\n            model.blocks = model.blocks[:args.target_layer+1]\n\n        if args.remove_final_norm:\n            print(f\"removing final norm by replacing it with Identity\")\n            model.norm = None if model.norm is None else nn.Identity()\n            model.fc_norm = None if model.fc_norm is None else nn.Identity()\n\n        if args.linear_classifier:\n            frozen_params = (\n                set(n for n, _ in model.named_parameters())\n                & set(checkpoint_model.keys())\n            )\n            for n, p in model.named_parameters():\n                if n in frozen_params:\n                    p.requires_grad_(False)\n            param_names = [n for n, p in model.named_parameters() if p.requires_grad]\n            print(f\"Trainable weights: {param_names}\")\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n        # model.load_state_dict(checkpoint_model, strict=False)\n\n    model.to(device)\n\n    model_ema = None\n    if args.model_ema:\n        # Important to create EMA model after cuda(), DP wrapper, and AMP but before SyncBN and DDP wrapper\n        model_ema = ModelEma(\n            model,\n            decay=args.model_ema_decay,\n            device='cpu' if args.model_ema_force_cpu else '',\n            resume='')\n        print(\"Using EMA with decay = %.8f\" % args.model_ema_decay)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params:', n_parameters)\n\n    total_batch_size = args.batch_size * args.update_freq * utils.get_world_size()\n    num_training_steps_per_epoch = len(dataset_train) // total_batch_size\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Update frequent = %d\" % args.update_freq)\n    print(\"Number of training examples = %d\" % len(dataset_train))\n    print(\"Number of training training per epoch = %d\" % num_training_steps_per_epoch)\n\n    num_layers = model_without_ddp.get_num_layers()\n    if args.layer_decay < 1.0:\n        assigner = LayerDecayValueAssigner(list(args.layer_decay ** (num_layers + 1 - i) for i in range(num_layers + 2)))\n    else:\n        assigner = None\n\n    if assigner is not None:\n        print(\"Assigned values = %s\" % str(assigner.values))\n\n    skip_weight_decay_list = model.no_weight_decay()\n    if args.disable_weight_decay_on_rel_pos_bias:\n        for i in range(num_layers):\n            skip_weight_decay_list.add(\"blocks.%d.attn.relative_position_bias_table\" % i)\n\n    if args.enable_deepspeed:\n        loss_scaler = None\n        optimizer_params = get_parameter_groups(\n            model, args.weight_decay, skip_weight_decay_list,\n            assigner.get_layer_id if assigner is not None else None,\n            assigner.get_scale if assigner is not None else None)\n        model, optimizer, _, _ = ds_init(\n            args=args, model=model, model_parameters=optimizer_params, dist_init_required=not args.distributed,\n        )\n\n        print(\"model.gradient_accumulation_steps() = %d\" % model.gradient_accumulation_steps())\n        assert model.gradient_accumulation_steps() == args.update_freq\n    else:\n        if args.distributed:\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n            model_without_ddp = model.module\n\n        optimizer = create_optimizer(\n            args, model_without_ddp, skip_list=skip_weight_decay_list,\n            get_num_layer=assigner.get_layer_id if assigner is not None else None, \n            get_layer_scale=assigner.get_scale if assigner is not None else None)\n        loss_scaler = NativeScaler()\n\n    print(\"Use step level LR scheduler!\")\n    lr_schedule_values = utils.cosine_scheduler(\n        args.lr, args.min_lr, args.epochs, num_training_steps_per_epoch,\n        warmup_epochs=args.warmup_epochs, warmup_steps=args.warmup_steps,\n    )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay, args.weight_decay_end, args.epochs, num_training_steps_per_epoch)\n    print(\"Max WD = %.7f, Min WD = %.7f\" % (max(wd_schedule_values), min(wd_schedule_values)))\n\n    #if mixup_fn is not None:\n        # smoothing is handled with mixup label transform\n    #    criterion = SoftTargetCrossEntropy()\n    #elif args.smoothing > 0.:\n    #    criterion = LabelSmoothingCrossEntropy(smoothing=args.smoothing)\n    #else:\n    \n    criterion = torch.nn.MultiLabelSoftMarginLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    utils.auto_load_model(\n        args=args, model=model, model_without_ddp=model_without_ddp,\n        optimizer=optimizer, loss_scaler=loss_scaler, model_ema=model_ema)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device, metric='map', padd=True)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch * args.update_freq)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train, optimizer,\n            device, epoch, loss_scaler, args.clip_grad, model_ema, mixup_fn,\n            log_writer=log_writer, start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values, wd_schedule_values=wd_schedule_values,\n            num_training_steps_per_epoch=num_training_steps_per_epoch, update_freq=args.update_freq,\n            masked_position_generator=masked_position_generator,\n            metric='map', padd=True\n        )\n        if args.output_dir and args.save_ckpt:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                    loss_scaler=loss_scaler, epoch=epoch, model_ema=model_ema)\n        if data_loader_val is not None and epoch % 5 == 0:\n            test_stats = evaluate(data_loader_val, model, device, 'map', padd=True)\n            print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            if max_accuracy < test_stats[\"acc1\"]:\n                max_accuracy = test_stats[\"acc1\"]\n                if args.output_dir and args.save_ckpt:\n                    utils.save_model(\n                        args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                        loss_scaler=loss_scaler, epoch=\"best\", model_ema=model_ema)\n\n            print(f'Max accuracy: {max_accuracy:.2f}%')\n            if log_writer is not None:\n                log_writer.update(test_acc1=test_stats['acc1'], head=\"perf\", step=epoch)\n                log_writer.update(test_acc5=test_stats['acc5'], head=\"perf\", step=epoch)\n                log_writer.update(test_loss=test_stats['loss'], head=\"perf\", step=epoch)\n\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n        else:\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         # **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    opts, ds_init = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts, ds_init)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_BE_dino.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#     http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport os\nimport argparse\nimport json\nfrom pathlib import Path\n\nimport torch\nfrom torch import nn\nimport torch.distributed as dist\nimport torch.backends.cudnn as cudnn\nfrom torchvision import datasets\nfrom torchvision import transforms as pth_transforms\nfrom torchvision import models as torchvision_models\n\nfrom models.dino import utils\nfrom models.dino import vision_transformer as vits\n\n# load bigearthnet dataset\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco import Bigearthnet\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb_s2_uint8 import LMDBDataset,random_subset\nfrom cvtorchvision import cvtransforms\n### end of change ###\nimport pdb\n\nfrom torch.utils.tensorboard import SummaryWriter\nfrom sklearn.metrics import average_precision_score\nimport builtins\n\ndef eval_linear(args):\n    utils.init_distributed_mode(args)\n    if args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n    print(\"git:\\n  {}\\n\".format(utils.get_sha()))\n    print(\"\\n\".join(\"%s: %s\" % (k, str(v)) for k, v in sorted(dict(vars(args)).items())))\n    cudnn.benchmark = True\n\n    # ============ building network ... ============\n    # if the network is a Vision Transformer (i.e. vit_tiny, vit_small, vit_base)\n    if args.arch in vits.__dict__.keys():\n        model = vits.__dict__[args.arch](patch_size=args.patch_size, num_classes=0, in_chans=13)\n        embed_dim = model.embed_dim * (args.n_last_blocks + int(args.avgpool_patchtokens))\n    # otherwise, we check if the architecture is in torchvision models\n    elif args.arch in torchvision_models.__dict__.keys():\n        model = torchvision_models.__dict__[args.arch]()\n        embed_dim = model.fc.weight.shape[1]\n        model.conv1 = torch.nn.Conv2d(13, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n        model.fc = nn.Identity()\n        #model.fc = torch.nn.Linear(2048,19)\n    # if the network is a XCiT\n    elif \"xcit\" in args.arch:\n        model = torch.hub.load('facebookresearch/xcit:main', args.arch, num_classes=0)\n        embed_dim = model.embed_dim\n    else:\n        print(f\"Unknow architecture: {args.arch}\")\n        sys.exit(1)\n    model.cuda()\n    model.eval()\n    # load weights to evaluate\n    utils.load_pretrained_weights(model, args.pretrained, args.checkpoint_key, args.arch, args.patch_size)\n    print(f\"Model {args.arch} built.\")\n\n    linear_classifier = LinearClassifier(embed_dim, num_labels=19)\n    linear_classifier = linear_classifier.cuda()\n    linear_classifier = nn.parallel.DistributedDataParallel(linear_classifier, device_ids=[args.gpu])\n\n    # ============ preparing data ... ============\n\n    train_transform = cvtransforms.Compose([\n        cvtransforms.RandomResizedCrop(224, scale=(0.8,1.0)),\n        cvtransforms.RandomHorizontalFlip(),\n        cvtransforms.ToTensor(),\n        #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n    ])\n    #dataset_train = datasets.ImageFolder(os.path.join(args.data_path, \"train\"), transform=train_transform)\n\n    val_transform = cvtransforms.Compose([\n        cvtransforms.Resize(256),\n        cvtransforms.CenterCrop(224),\n        cvtransforms.ToTensor(),\n        #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n    ])\n\n\n\n    lmdb_train = 'train_B12.lmdb'\n    lmdb_val = 'val_B12.lmdb'\n    if args.bands == 'RGB':\n        args.n_channels = 3\n    elif args.bands == 'B12':   \n        args.n_channels = 12\n    elif args.bands == 'B13' or args.bands == 'all':\n        args.n_channels = 13\n    elif args.bands == 'B2':\n        args.n_channels = 2\n    elif args.bands == 'B14':\n        args.n_channels = 14\n\n\n    dataset_train = LMDBDataset(\n        lmdb_file=os.path.join(args.data_path, lmdb_train),\n        transform=train_transform,\n        is_slurm_job=args.is_slurm_job\n    )\n    dataset_val = LMDBDataset(\n        lmdb_file=os.path.join(args.data_path, lmdb_val),\n        transform=val_transform,\n        is_slurm_job=args.is_slurm_job\n    )        \n\n    if args.train_frac is not None and args.train_frac<1:\n        dataset_train = random_subset(dataset_train,args.train_frac,seed=args.seed)\n\n\n    sampler = torch.utils.data.distributed.DistributedSampler(dataset_train)\n    train_loader = torch.utils.data.DataLoader(\n        dataset_train,\n        sampler=sampler,\n        batch_size=args.batch_size_per_gpu,\n        num_workers=args.num_workers,\n        pin_memory=True,\n    )\n    \n\n    #dataset_val = datasets.ImageFolder(os.path.join(args.data_path, \"val\"), transform=val_transform)\n    val_loader = torch.utils.data.DataLoader(\n        dataset_val,\n        batch_size=args.batch_size_per_gpu,\n        num_workers=args.num_workers,\n        pin_memory=True,\n    )\n\n    if args.evaluate:\n        utils.load_pretrained_linear_weights(linear_classifier, args.arch, args.patch_size)\n        test_stats = validate_network(val_loader, model, linear_classifier, args.n_last_blocks, args.avgpool_patchtokens)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        return    \n    \n            \n    \n    print(f\"Data loaded with {len(dataset_train)} train and {len(dataset_val)} val imgs.\")\n\n    # set optimizer\n    optimizer = torch.optim.SGD(\n        linear_classifier.parameters(),\n        args.lr * (args.batch_size_per_gpu * utils.get_world_size()) / 256., # linear scaling rule\n        momentum=0.9,\n        weight_decay=0, # we do not apply weight decay\n    )\n    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, args.epochs, eta_min=0)\n\n    # Optionally resume from a checkpoint\n    to_restore = {\"epoch\": 0, \"best_acc\": 0.}\n    if args.resume:\n        utils.restart_from_checkpoint(\n            os.path.join(args.checkpoints_dir, \"checkpoint.pth.tar\"),\n            run_variables=to_restore,\n            state_dict=linear_classifier,\n            optimizer=optimizer,\n            scheduler=scheduler,\n        )\n    start_epoch = to_restore[\"epoch\"]\n    best_acc = to_restore[\"best_acc\"]\n\n    \n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\n        os.makedirs(args.checkpoints_dir,exist_ok=True)\n    \n    for epoch in range(start_epoch, args.epochs):\n        train_loader.sampler.set_epoch(epoch)\n\n        train_stats = train(model, linear_classifier, optimizer, train_loader, epoch, args.n_last_blocks, args.avgpool_patchtokens)\n        scheduler.step()\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                     'epoch': epoch}\n        if epoch % args.val_freq == 0 or epoch == args.epochs - 1:\n            test_stats = validate_network(val_loader, model, linear_classifier, args.n_last_blocks, args.avgpool_patchtokens)\n            print(f\"Accuracy at epoch {epoch} of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            best_acc = max(best_acc, test_stats[\"acc1\"])\n            print(f'Max accuracy so far: {best_acc:.2f}%')\n            log_stats = {**{k: v for k, v in log_stats.items()},\n                         **{f'test_{k}': v for k, v in test_stats.items()}}\n        if utils.is_main_process():\n            with (Path(args.checkpoints_dir) / \"log.txt\").open(\"a\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n            save_dict = {\n                \"epoch\": epoch + 1,\n                \"state_dict\": linear_classifier.state_dict(),\n                \"optimizer\": optimizer.state_dict(),\n                \"scheduler\": scheduler.state_dict(),\n                \"best_acc\": best_acc,\n            }\n            torch.save(save_dict, os.path.join(args.checkpoints_dir, \"checkpoint.pth.tar\"))\n    print(\"Training of the supervised linear classifier on frozen features completed.\\n\"\n                \"Top-1 test accuracy: {acc:.1f}\".format(acc=best_acc))\n\n\ndef train(model, linear_classifier, optimizer, loader, epoch, n, avgpool):\n    linear_classifier.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    for (images, target) in metric_logger.log_every(loader, 20, header):\n\n        b_zeros = torch.zeros((images.shape[0],1,images.shape[2],images.shape[3]),dtype=torch.float32)\n        inp = torch.cat((images[:,:10,:,:],b_zeros,images[:,10:,:,:]),dim=1)\n        \n        # move to gpu\n        inp = inp.cuda(non_blocking=True)\n        target = target.cuda(non_blocking=True)\n\n        # forward\n        with torch.no_grad():\n            if \"vit\" in args.arch:\n                intermediate_output = model.get_intermediate_layers(inp, n)\n                output = torch.cat([x[:, 0] for x in intermediate_output], dim=-1)\n                if avgpool:\n                    output = torch.cat((output.unsqueeze(-1), torch.mean(intermediate_output[-1][:, 1:], dim=1).unsqueeze(-1)), dim=-1)\n                    output = output.reshape(output.shape[0], -1)\n            else:\n                output = model(inp)\n        output = linear_classifier(output)\n\n        # compute cross entropy loss\n        loss = nn.MultiLabelSoftMarginLoss()(output, target.long())\n\n        # compute the gradients\n        optimizer.zero_grad()\n        loss.backward()\n\n        # step\n        optimizer.step()\n\n        # log \n        torch.cuda.synchronize()\n        metric_logger.update(loss=loss.item())\n        metric_logger.update(lr=optimizer.param_groups[0][\"lr\"])\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef validate_network(val_loader, model, linear_classifier, n, avgpool):\n    linear_classifier.eval()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n    for images, target in metric_logger.log_every(val_loader, 20, header):\n\n        b_zeros = torch.zeros((images.shape[0],1,images.shape[2],images.shape[3]),dtype=torch.float32)\n        inp = torch.cat((images[:,:10,:,:],b_zeros,images[:,10:,:,:]),dim=1)        \n        # move to gpu\n        inp = inp.cuda(non_blocking=True)\n        target = target.cuda(non_blocking=True)\n\n        # forward\n        with torch.no_grad():\n            if \"vit\" in args.arch:\n                intermediate_output = model.get_intermediate_layers(inp, n)\n                output = torch.cat([x[:, 0] for x in intermediate_output], dim=-1)\n                if avgpool:\n                    output = torch.cat((output.unsqueeze(-1), torch.mean(intermediate_output[-1][:, 1:], dim=1).unsqueeze(-1)), dim=-1)\n                    output = output.reshape(output.shape[0], -1)\n            else:\n                output = model(inp)\n        output = linear_classifier(output)\n        loss = nn.MultiLabelSoftMarginLoss()(output, target.long())\n\n        '''\n        if linear_classifier.module.num_labels >= 5:\n            acc1, acc5 = utils.accuracy(output, target, topk=(1, 5))\n        else:\n            acc1, = utils.accuracy(output, target, topk=(1,))\n        '''\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = average_precision_score(target.cpu(), score, average='micro') * 100.0\n        acc5 = acc1\n        \n        batch_size = inp.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        \n        if linear_classifier.module.num_labels >= 5:\n            metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n        \n    \n    if linear_classifier.module.num_labels >= 5:\n        print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n    else:\n        print('* Acc@1 {top1.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, losses=metric_logger.loss))\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\nclass LinearClassifier(nn.Module):\n    \"\"\"Linear layer to train on top of frozen features\"\"\"\n    def __init__(self, dim, num_labels=1000):\n        super(LinearClassifier, self).__init__()\n        self.num_labels = num_labels\n        self.linear = nn.Linear(dim, num_labels)\n        self.linear.weight.data.normal_(mean=0.0, std=0.01)\n        self.linear.bias.data.zero_()\n\n    def forward(self, x):\n        # flatten\n        x = x.view(x.size(0), -1)\n\n        # linear layer\n        return self.linear(x)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser('Evaluation with linear classification on BigEarthNet.')\n    parser.add_argument('--n_last_blocks', default=4, type=int, help=\"\"\"Concatenate [CLS] tokens\n        for the `n` last blocks. We use `n=4` when evaluating ViT-Small and `n=1` with ViT-Base.\"\"\")\n    parser.add_argument('--avgpool_patchtokens', default=False, type=utils.bool_flag,\n        help=\"\"\"Whether ot not to concatenate the global average pooled features to the [CLS] token.\n        We typically set this to False for ViT-Small and to True with ViT-Base.\"\"\")\n    parser.add_argument('--arch', default='vit_small', type=str, help='Architecture')\n    parser.add_argument('--patch_size', default=16, type=int, help='Patch resolution of the model.')\n    parser.add_argument('--pretrained', default='', type=str, help=\"Path to pretrained weights to evaluate.\")\n    parser.add_argument(\"--checkpoint_key\", default=\"teacher\", type=str, help='Key to use in the checkpoint (example: \"teacher\")')\n    parser.add_argument('--epochs', default=100, type=int, help='Number of epochs of training.')\n    parser.add_argument(\"--lr\", default=0.001, type=float, help=\"\"\"Learning rate at the beginning of\n        training (highest LR used during training). The learning rate is linearly scaled\n        with the batch size, and specified here for a reference batch size of 256.\n        We recommend tweaking the LR depending on the checkpoint evaluated.\"\"\")\n    parser.add_argument('--batch_size_per_gpu', default=128, type=int, help='Per-GPU batch-size')\n    parser.add_argument(\"--dist_url\", default=\"env://\", type=str, help=\"\"\"url used to set up\n        distributed training; see https://pytorch.org/docs/stable/distributed.html\"\"\")\n    parser.add_argument(\"--local_rank\", default=0, type=int, help=\"Please ignore and do not set this argument.\")\n    parser.add_argument('--data_path', default='/path/to/imagenet/', type=str)\n    parser.add_argument('--num_workers', default=10, type=int, help='Number of data loading workers per GPU.')\n    parser.add_argument('--val_freq', default=5, type=int, help=\"Epoch frequency for validation.\")\n    parser.add_argument('--checkpoints_dir', default=\".\", help='Path to save logs and checkpoints')\n    parser.add_argument('--num_labels', default=1000, type=int, help='Number of labels for linear classifier')\n    parser.add_argument('--evaluate', dest='evaluate', action='store_true', help='evaluate model on validation set')\n    \n    parser.add_argument('--lmdb_dir', default='/path/to/imagenet/', type=str, help='Please specify path to the ImageNet folder.')\n    parser.add_argument('--bands', type=str, default='all', help=\"input bands\")\n    parser.add_argument(\"--lmdb\", action='store_true', help=\"use lmdb dataset\")\n    parser.add_argument(\"--is_slurm_job\", action='store_true', help=\"running in slurm\")\n    parser.add_argument(\"--resume\", action='store_true', help=\"resume from checkpoint\")\n    parser.add_argument(\"--train_frac\", default=1.0, type=float, help=\"use a subset of labeled data\")\n    parser.add_argument(\"--seed\",default=42,type=int)\n    \n    args = parser.parse_args()\n\n\n    \n    eval_linear(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_BE_mae.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# MoCo v3: https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\n\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\n\nimport timm\n\n#assert timm.__version__ == \"0.3.2\" # version check\nfrom timm.models.layers import trunc_normal_\n\nimport models.mae.util.misc as misc\nfrom models.mae.util.pos_embed import interpolate_pos_embed\nfrom models.mae.util.misc import NativeScalerWithGradNormCount as NativeScaler\nfrom models.mae.util.lars import LARS\nfrom models.mae.util.crop import RandomResizedCrop\n\nimport models.mae.models_vit as models_vit\n\nfrom models.mae.engine_finetune_BE import train_one_epoch, evaluate\n\n\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb_s2_uint8 import LMDBDataset,random_subset\nfrom cvtorchvision import cvtransforms\nfrom sklearn.metrics import average_precision_score\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE linear probing for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=512, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=90, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    # Optimizer parameters\n    parser.add_argument('--weight_decay', type=float, default=0,\n                        help='weight decay (default: 0 for linear probe following MoCo v1)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=0.1, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n\n    parser.add_argument('--min_lr', type=float, default=0., metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=10, metavar='N',\n                        help='epochs to warmup LR')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--global_pool', action='store_true')\n    parser.set_defaults(global_pool=False)\n    parser.add_argument('--cls_token', action='store_false', dest='global_pool',\n                        help='Use class token instead of global pool for classification')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--nb_classes', default=1000, type=int,\n                        help='number of the classification types')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation (recommended during training for faster monitor')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n    parser.add_argument('--dist_backend', default='nccl', type=str,\n                        help='distributed backend')\n    \n    parser.add_argument(\"--is_slurm_job\", action='store_true', help=\"slurm job\")\n    parser.add_argument(\"--train_frac\", default=1.0, type=float, help=\"use a subset of labeled data\")\n    parser.add_argument(\"--fine_tune\", action='store_true', help=\"fine tune or not\")\n    \n    return parser\n\n\ndef main(args):\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n\n    \n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(224,scale=(0.8,1.0)),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor()])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(224),\n            cvtransforms.ToTensor(),\n            ])\n\n\n    dataset_train = LMDBDataset(\n        lmdb_file=os.path.join(args.data_path, 'train_B12.lmdb'),\n        transform=train_transforms,\n        is_slurm_job=args.is_slurm_job            \n    )\n\n    dataset_val = LMDBDataset(\n        lmdb_file=os.path.join(args.data_path, 'val_B12.lmdb'),\n        transform=val_transforms,\n        is_slurm_job=args.is_slurm_job            \n    )       \n    \n    if args.train_frac is not None and args.train_frac<1:\n        dataset_train = random_subset(dataset_train,args.train_frac,seed=42)        \n    \n    '''\n    # linear probe: weak augmentation\n    transform_train = transforms.Compose([\n            RandomResizedCrop(224, interpolation=3),\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    transform_val = transforms.Compose([\n            transforms.Resize(256, interpolation=3),\n            transforms.CenterCrop(224),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    dataset_train = datasets.ImageFolder(os.path.join(args.data_path, 'train'), transform=transform_train)\n    dataset_val = datasets.ImageFolder(os.path.join(args.data_path, 'val'), transform=transform_val)\n    print(dataset_train)\n    print(dataset_val)\n    '''\n\n\n    if True:  # args.distributed:\n        num_tasks = args.world_size\n        print(misc.get_world_size())\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=True)  # shuffle=True to reduce monitor bias\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None and not args.eval:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    data_loader_val = torch.utils.data.DataLoader(\n        dataset_val, sampler=sampler_val,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=False\n    )\n\n    model = models_vit.__dict__[args.model](\n        num_classes=args.nb_classes,\n        global_pool=args.global_pool,\n        in_chans=13\n    )\n\n    if args.finetune and not args.eval:\n        checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load pre-trained checkpoint from: %s\" % args.finetune)\n        checkpoint_model = checkpoint['model']\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        # interpolate position embedding\n        interpolate_pos_embed(model, checkpoint_model)\n\n        # load pre-trained model\n        msg = model.load_state_dict(checkpoint_model, strict=False)\n        print(msg)\n\n        if args.global_pool:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias', 'fc_norm.weight', 'fc_norm.bias'}\n        else:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias'}\n\n        # manually initialize fc layer: following MoCo v3\n        trunc_normal_(model.head.weight, std=0.01)\n\n    # for linear prob only\n    # hack: revise model's head with BN\n    model.head = torch.nn.Sequential(torch.nn.BatchNorm1d(model.head.in_features, affine=False, eps=1e-6), model.head)\n    if not args.fine_tune:\n        # freeze all but the head\n        for _, p in model.named_parameters():\n            p.requires_grad = False\n        for _, p in model.head.named_parameters():\n            p.requires_grad = True\n\n    model.to(device)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params (M): %.2f' % (n_parameters / 1.e6))\n\n    eff_batch_size = args.batch_size * args.accum_iter * args.world_size\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        model_without_ddp = model.module\n\n    #optimizer = LARS(model_without_ddp.head.parameters(), lr=args.lr, weight_decay=args.weight_decay)\n    optimizer = torch.optim.SGD(model_without_ddp.head.parameters(), args.lr,\n                                momentum=0.9,\n                                weight_decay=0)\n    print(optimizer)\n    loss_scaler = NativeScaler()\n\n    #criterion = torch.nn.CrossEntropyLoss()\n    criterion = torch.nn.MultiLabelSoftMarginLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device, criterion)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            max_norm=None,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir and (epoch%10==0 or epoch + 1 == args.epochs):\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        if epoch%5==0 or (epoch + 1 == args.epochs):\n            test_stats = evaluate(data_loader_val, model, device, criterion)\n            print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            \n            max_accuracy = max(max_accuracy, test_stats[\"acc1\"])\n            print(f'Max accuracy: {max_accuracy:.2f}%')\n\n        if log_writer is not None:\n            log_writer.add_scalar('perf/test_acc1', test_stats['acc1'], epoch)\n            log_writer.add_scalar('perf/test_acc5', test_stats['acc5'], epoch)\n            log_writer.add_scalar('perf/test_loss', test_stats['loss'], epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        **{f'test_{k}': v for k, v in test_stats.items()},\n                        'epoch': epoch,\n                        'n_parameters': n_parameters}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_BE_moco.py",
    "content": "\"\"\"\r\nsupervised training of BigEarthNet (all bands) with resnet18/50\r\n\r\nTODO:\r\n  -- optimize and reduce RAM usage\r\n  -- optimize I/O\r\n  -- checkpoints\r\n  -- merge B12 and RGB codes\r\n\r\n\"\"\"\r\n\r\n\r\n\r\nimport torch\r\nfrom PIL import Image\r\nfrom torch.utils.data import Dataset, DataLoader\r\nfrom torchvision import models\r\n\r\n## change01 ##\r\nfrom cvtorchvision import cvtransforms\r\nimport time\r\nimport os\r\nimport math\r\nimport pdb\r\nfrom sklearn.metrics import average_precision_score, precision_score, recall_score, f1_score\r\nfrom torchmetrics.functional.classification import multilabel_average_precision, multilabel_f1_score\r\nimport numpy as np\r\nimport argparse\r\nimport builtins\r\n\r\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco import Bigearthnet\r\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb_s2_uint8 import LMDBDataset,random_subset\r\n\r\nfrom torch.utils.tensorboard import SummaryWriter\r\n\r\nparser = argparse.ArgumentParser()\r\nparser.add_argument('--data_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet')\r\nparser.add_argument('--lmdb_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet/dataload_op1_lmdb')\r\nparser.add_argument('--checkpoints_dir', type=str, default='./checkpoints/resnet/')\r\nparser.add_argument('--resume', type=str, default='')\r\nparser.add_argument('--save_path', type=str, default='./checkpoints/bigearthnet_s2_B12_100_no_pretrain_resnet50.pt')\r\n\r\nparser.add_argument('--bands', type=str, default='all', choices=['all','RGB','B12'], help='bands to process')  \r\nparser.add_argument('--train_frac', type=float, default=1.0)\r\nparser.add_argument('--backbone', type=str, default='resnet50')\r\nparser.add_argument('--batchsize', type=int, default=256)\r\nparser.add_argument('--epochs', type=int, default=100)\r\nparser.add_argument('--num_workers', type=int, default=8)\r\nparser.add_argument('--lr', type=float, default=0.05)\r\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\r\n                    help='learning rate schedule (when to drop lr by 10x)')\r\nparser.add_argument('--cos', action='store_true', help='use cosine lr schedule')\r\nparser.add_argument('--seed', type=int, default=42)\r\nparser.add_argument('--pretrained', default='', type=str, help='path to moco pretrained checkpoint')\r\n\r\n### distributed running ###\r\nparser.add_argument('--dist_url', default='env://', type=str)\r\nparser.add_argument(\"--world_size\", default=-1, type=int, help=\"\"\"\r\n                    number of processes: it is set automatically and\r\n                    should not be passed as argument\"\"\")\r\nparser.add_argument(\"--rank\", default=0, type=int, help=\"\"\"rank of this process:\r\n                    it is set automatically and should not be passed as argument\"\"\")\r\nparser.add_argument(\"--local_rank\", default=0, type=int,\r\n                    help=\"this argument is not used and should be ignored\")\r\n\r\nparser.add_argument('--normalize',action='store_true',default=False)\r\nparser.add_argument('--linear',action='store_true',default=False)\r\n\r\ndef init_distributed_mode(args):\r\n\r\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\r\n\r\n    if args.is_slurm_job:\r\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\r\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\r\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\r\n        )\r\n    else:\r\n        # multi-GPU job (local or multi-node) - jobs started with torch.distributed.launch\r\n        # read environment variables\r\n        args.rank = int(os.environ[\"RANK\"])\r\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\r\n\r\n\r\n    # prepare distributed\r\n    torch.distributed.init_process_group(\r\n        backend=\"nccl\",\r\n        init_method=args.dist_url,\r\n        world_size=args.world_size,\r\n        rank=args.rank,\r\n    )\r\n\r\n    # set cuda device\r\n    args.gpu_to_work_on = args.rank % torch.cuda.device_count()\r\n    torch.cuda.set_device(args.gpu_to_work_on)\r\n    return    \r\n\r\ndef fix_random_seeds(seed=42):\r\n    \"\"\"\r\n    Fix random seeds.\r\n    \"\"\"\r\n    torch.manual_seed(seed)\r\n    torch.cuda.manual_seed_all(seed)\r\n    np.random.seed(seed)\r\n\r\ndef adjust_learning_rate(optimizer, epoch, args):\r\n    \"\"\"Decay the learning rate based on schedule\"\"\"\r\n    lr = args.lr\r\n    if args.cos:  # cosine lr schedule\r\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\r\n    else:  # stepwise lr schedule\r\n        for milestone in args.schedule:\r\n            lr *= 0.1 if epoch >= milestone else 1.\r\n    for param_group in optimizer.param_groups:\r\n        param_group['lr'] = lr\r\n\r\n\r\ndef main():\r\n\r\n    global args\r\n    args = parser.parse_args()\r\n    ### dist ###\r\n    init_distributed_mode(args)\r\n    if args.rank != 0:\r\n        def print_pass(*args):\r\n            pass\r\n        builtins.print = print_pass\r\n    \r\n    fix_random_seeds(args.seed)\r\n    \r\n    # `python bigearthnet_dataset.py` to create lmdb data\r\n    lmdb = True # use lmdb dataset\r\n    data_dir = args.data_dir\r\n    lmdb_dir = args.lmdb_dir\r\n    checkpoints_dir = args.checkpoints_dir\r\n    save_path = args.save_path\r\n    batch_size = args.batchsize\r\n\r\n    num_workers = args.num_workers\r\n    epochs = args.epochs\r\n    train_frac = args.train_frac\r\n    seed = args.seed\r\n\r\n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\r\n        os.makedirs(args.checkpoints_dir)\r\n    if args.rank==0:\r\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints_dir,'log'))\r\n\r\n\r\n    ## change02 ##\r\n    if args.bands == 'RGB':\r\n        bands = ['B04', 'B03', 'B02']\r\n        lmdb_train = 'train_RGB.lmdb'\r\n        lmdb_val = 'val_RGB.lmdb'\r\n    else:\r\n        bands = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']\r\n        lmdb_train = 'train_B12.lmdb'\r\n        lmdb_val = 'val_B12.lmdb'\r\n        \r\n    num_labels = 19\r\n\r\n    ## change03 ##\r\n    train_transforms = cvtransforms.Compose([\r\n            cvtransforms.RandomResizedCrop(224,scale=(0.8,1.0)), # multilabel, avoid cropping out labels\r\n            cvtransforms.RandomHorizontalFlip(),\r\n            cvtransforms.ToTensor()])\r\n\r\n    val_transforms = cvtransforms.Compose([\r\n            cvtransforms.Resize(256),\r\n            cvtransforms.CenterCrop(224),\r\n            cvtransforms.ToTensor(),\r\n            ])\r\n\r\n    if lmdb:\r\n        train_dataset = LMDBDataset(\r\n            lmdb_file=os.path.join(lmdb_dir, lmdb_train),\r\n            transform=train_transforms\r\n        )\r\n        \r\n        val_dataset = LMDBDataset(\r\n            lmdb_file=os.path.join(lmdb_dir, lmdb_val),\r\n            transform=val_transforms\r\n        )    \r\n    else:\r\n        train_dataset = Bigearthnet(\r\n            root=data_dir,\r\n            split='train',\r\n            bands=bands,\r\n            use_new_labels = True,\r\n            transform=train_transforms\r\n        )\r\n        \r\n        val_dataset = Bigearthnet(\r\n            root=data_dir,\r\n            split='val',\r\n            bands=bands,\r\n            use_new_labels = True,\r\n            transform=train_transforms\r\n        )    \r\n        \r\n        \r\n    if train_frac is not None and train_frac<1:\r\n        train_dataset = random_subset(train_dataset,train_frac,seed)    \r\n    ### dist ###    \r\n    sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)    \r\n        \r\n    train_loader = DataLoader(train_dataset,\r\n                              batch_size=batch_size,\r\n                              sampler = sampler,\r\n                              #shuffle=True,\r\n                              num_workers=num_workers,\r\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\r\n                              drop_last=True\r\n                              \r\n                              )\r\n                              \r\n    val_loader = DataLoader(val_dataset,\r\n                              batch_size=batch_size,\r\n                              shuffle=False,\r\n                              num_workers=num_workers,\r\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\r\n                              drop_last=True\r\n                              \r\n                              )\r\n    \r\n    print('train_len: %d val_len: %d' % (len(train_dataset),len(val_dataset)))\r\n\r\n    ## change 04 ##\r\n    if args.backbone == 'resnet50':\r\n        net = models.resnet50(pretrained=False)\r\n        net.fc = torch.nn.Linear(2048,19)\r\n    elif args.backbone == 'resnet18':\r\n        net = models.resnet18(pretrained=False)\r\n        net.fc = torch.nn.Linear(512,19)\r\n        \r\n    if args.bands=='all':\r\n        net.conv1 = torch.nn.Conv2d(13, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\r\n    elif args.bands=='B12':\r\n        net.conv1 = torch.nn.Conv2d(12, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\r\n    \r\n    if args.linear:\r\n        for name, param in net.named_parameters():\r\n            if name not in ['fc.weight','fc.bias']:\r\n                param.requires_grad = False\r\n\r\n        net.fc.weight.data.normal_(mean=0.0,std=0.01)\r\n        net.fc.bias.data.zero_()\r\n\r\n\r\n    # load from pre-trained, before DistributedDataParallel constructor\r\n    if args.pretrained:\r\n        if os.path.isfile(args.pretrained):\r\n            print(\"=> loading checkpoint '{}'\".format(args.pretrained))\r\n            checkpoint = torch.load(args.pretrained, map_location=\"cpu\")\r\n\r\n            # rename moco pre-trained keys\r\n            state_dict = checkpoint['state_dict']\r\n            #print(state_dict.keys())\r\n            for k in list(state_dict.keys()):\r\n                # retain only encoder up to before the embedding layer\r\n                if k.startswith('module.encoder_q') and not k.startswith('module.encoder_q.fc'):\r\n                    #pdb.set_trace()\r\n                    # remove prefix\r\n                    state_dict[k[len(\"module.encoder_q.\"):]] = state_dict[k]\r\n                # delete renamed or unused k\r\n                del state_dict[k]\r\n            \r\n            '''\r\n            # remove prefix\r\n            state_dict = {k.replace(\"module.\", \"\"): v for k,v in state_dict.items()}\r\n            '''\r\n            #args.start_epoch = 0\r\n            msg = net.load_state_dict(state_dict, strict=False)\r\n            #pdb.set_trace()\r\n            assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\r\n\r\n            print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\r\n        else:\r\n            print(\"=> no checkpoint found at '{}'\".format(args.pretrained))\r\n\r\n    # convert batch norm layers (if any)\r\n    if args.is_slurm_job:\r\n        net = torch.nn.SyncBatchNorm.convert_sync_batchnorm(net)\r\n\r\n    net.cuda()\r\n    #### nccl doesn't support wsl\r\n    if args.is_slurm_job:\r\n        net = torch.nn.parallel.DistributedDataParallel(net,device_ids=[args.gpu_to_work_on],find_unused_parameters=True)\r\n        \r\n        \r\n    criterion = torch.nn.MultiLabelSoftMarginLoss()\r\n    optimizer = torch.optim.SGD(net.parameters(), lr=args.lr, momentum=0.9)\r\n\r\n\r\n    last_epoch = 0\r\n    if args.resume:\r\n        checkpoint = torch.load(args.resume)\r\n        state_dict = checkpoint['model_state_dict']\r\n        #state_dict = {k.replace(\"module.\", \"\"): v for k,v in state_dict.items()}\r\n        net.load_state_dict(state_dict)\r\n        optimizer.load_state_dict(checkpoint['optimizer_state_dict'])\r\n        last_epoch = checkpoint['epoch']\r\n        last_loss = checkpoint['loss']\r\n\r\n    #device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\r\n    #net.to(device)\r\n    #net.cuda()\r\n    \r\n\r\n\r\n    print('Start training...')\r\n    for epoch in range(last_epoch,epochs):\r\n\r\n        net.train()\r\n        adjust_learning_rate(optimizer, epoch, args)\r\n        \r\n        train_loader.sampler.set_epoch(epoch)\r\n        running_loss = 0.0\r\n        running_acc = 0.0\r\n        \r\n        running_loss_epoch = 0.0\r\n        running_acc_epoch = 0.0\r\n        \r\n        start_time = time.time()\r\n        end = time.time()\r\n        sum_bt = 0.0\r\n        sum_dt = 0.0\r\n        sum_tt = 0.0\r\n        sum_st = 0.0\r\n        for i, data in enumerate(train_loader, 0):\r\n            data_time = time.time()-end\r\n            #inputs, labels = data\r\n            if args.bands=='all':\r\n                b_zeros = torch.zeros((data[0].shape[0],1,data[0].shape[2],data[0].shape[3]),dtype=torch.float32)\r\n                images = torch.cat((data[0][:,:10,:,:],b_zeros,data[0][:,10:,:,:]),dim=1)            \r\n                inputs, labels = images.cuda(), data[1].cuda()\r\n            else:    \r\n                inputs, labels = data[0].cuda(), data[1].cuda()\r\n            # zero the parameter gradients\r\n            optimizer.zero_grad()\r\n\r\n            # forward + backward + optimize\r\n            outputs = net(inputs)\r\n            #pdb.set_trace()\r\n            loss = criterion(outputs, labels.long())\r\n            loss.backward()\r\n            optimizer.step()\r\n            train_time = time.time()-end-data_time\r\n            if epoch%5==4:\r\n                score = torch.sigmoid(outputs).detach()\r\n                #average_precision = average_precision_score(labels.cpu(), score, average='micro') * 100.0\r\n                average_precision = multilabel_average_precision(score, labels, num_labels=19, average=\"micro\") * 100.0\r\n            else:\r\n                average_precision = 0\r\n            score_time = time.time()-end-data_time-train_time\r\n            \r\n            # print statistics\r\n            running_loss += loss.item()\r\n            #running_acc += average_precision\r\n            batch_time = time.time() - end\r\n            end = time.time()        \r\n            sum_bt += batch_time\r\n            sum_dt += data_time\r\n            sum_tt += train_time\r\n            sum_st += score_time\r\n            \r\n            if i % 20 == 19:    # print every 20 mini-batches\r\n\r\n                print('[%d, %5d] loss: %.3f acc: %.3f batch_time: %.3f data_time: %.3f train_time: %.3f score_time: %.3f' %\r\n                      (epoch + 1, i + 1, running_loss / 20, running_acc / 20, sum_bt/20, sum_dt/20, sum_tt/20, sum_st/20))\r\n                \r\n                #train_iter =  i*args.batch_size / len(train_dataset)\r\n                #tb_writer.add_scalar('train_loss', running_loss/20, global_step=(epoch+1+train_iter) )\r\n                running_loss_epoch = running_loss/20\r\n                running_acc_epoch = running_acc/20\r\n                \r\n                running_loss = 0.0\r\n                running_acc = 0.0\r\n                sum_bt = 0.0\r\n                sum_dt = 0.0\r\n                sum_tt = 0.0\r\n                sum_st = 0.0\r\n\r\n        if epoch % 5 == 4:\r\n            running_loss_val = 0.0\r\n            running_acc_val = 0.0\r\n            count_val = 0\r\n            net.eval()\r\n            with torch.no_grad():\r\n                for j, data_val in enumerate(val_loader, 0):\r\n\r\n                    if args.bands=='all':\r\n                        b_zeros = torch.zeros((data_val[0].shape[0],1,data_val[0].shape[2],data_val[0].shape[3]),dtype=torch.float32)\r\n                        images = torch.cat((data_val[0][:,:10,:,:],b_zeros,data_val[0][:,10:,:,:]),dim=1)\r\n                        inputs_val, labels_val = images.cuda(), data_val[1].cuda()\r\n                    else:\r\n                        inputs_val, labels_val = data_val[0].cuda(), data_val[1].cuda()\r\n\r\n                    outputs_val = net(inputs_val)\r\n                    loss_val = criterion(outputs_val, labels_val.long())\r\n                    score_val = torch.sigmoid(outputs_val).detach()\r\n                    #average_precision_val = average_precision_score(labels_val.cpu(), score_val, average='micro') * 100.0\r\n                    average_precision_val = multilabel_average_precision(score_val, labels_val, num_labels=19, average=\"micro\") * 100.0\r\n                       \r\n\r\n                    count_val += 1\r\n                    running_loss_val += loss_val.item()\r\n                    running_acc_val += average_precision_val        \r\n\r\n            print('Epoch %d val_loss: %.3f val_acc: %.3f time: %s seconds.' % (epoch+1, running_loss_val/count_val, running_acc_val/count_val, time.time()-start_time))\r\n\r\n            if args.rank == 0:\r\n                losses = {'train': running_loss_epoch,\r\n                          'val': running_loss_val/count_val}\r\n                accs = {'train': running_acc_epoch,\r\n                        'val': running_acc_val/count_val}        \r\n                tb_writer.add_scalars('loss', losses, global_step=epoch+1, walltime=None)\r\n                tb_writer.add_scalars('acc', accs, global_step=epoch+1, walltime=None)\r\n        \r\n            \r\n            \r\n        if args.rank==0 and epoch % 10 == 9:\r\n            torch.save({\r\n                        'epoch': epoch,\r\n                        'model_state_dict': net.state_dict(),\r\n                        'optimizer_state_dict':optimizer.state_dict(),\r\n                        'loss':loss,\r\n                        }, os.path.join(checkpoints_dir,'checkpoint_{:04d}.pth.tar'.format(epoch)))\r\n        \r\n    #if args.rank==0:\r\n    #    torch.save(net.state_dict(), save_path)\r\n        \r\n    print('Training finished.')\r\n\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    main()\r\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_BE_moco_v3.py",
    "content": "#!/usr/bin/env python\n\n# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport argparse\nimport builtins\nimport math\nimport os\nimport random\nimport shutil\nimport time\nimport warnings\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.parallel\nimport torch.backends.cudnn as cudnn\nimport torch.distributed as dist\nimport torch.optim\nimport torch.multiprocessing as mp\nimport torch.utils.data\nimport torch.utils.data.distributed\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\nimport torchvision.models as torchvision_models\n\nfrom models.moco_v3 import vits\n\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb_s2_uint8 import LMDBDataset,random_subset\nfrom cvtorchvision import cvtransforms\nfrom sklearn.metrics import average_precision_score\n\n\ntorchvision_model_names = sorted(name for name in torchvision_models.__dict__\n    if name.islower() and not name.startswith(\"__\")\n    and callable(torchvision_models.__dict__[name]))\n\nmodel_names = ['vit_small', 'vit_base', 'vit_conv_small', 'vit_conv_base'] + torchvision_model_names\n\nparser = argparse.ArgumentParser(description='PyTorch ImageNet Training')\nparser.add_argument('--data', metavar='DIR',\n                    help='path to dataset')\nparser.add_argument('-a', '--arch', metavar='ARCH', default='resnet50',\n                    choices=model_names,\n                    help='model architecture: ' +\n                        ' | '.join(model_names) +\n                        ' (default: resnet50)')\nparser.add_argument('-j', '--num_workers', default=32, type=int, metavar='N',\n                    help='number of data loading workers (default: 32)')\nparser.add_argument('--epochs', default=90, type=int, metavar='N',\n                    help='number of total epochs to run')\nparser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                    help='manual epoch number (useful on restarts)')\nparser.add_argument('-b', '--batch_size', default=1024, type=int,\n                    metavar='N',\n                    help='mini-batch size (default: 1024), this is the total '\n                         'batch size of all GPUs on all nodes when '\n                         'using Data Parallel or Distributed Data Parallel')\nparser.add_argument('--lr', '--learning_rate', default=0.1, type=float,\n                    metavar='LR', help='initial (base) learning rate', dest='lr')\nparser.add_argument('--momentum', default=0.9, type=float, metavar='M',\n                    help='momentum')\nparser.add_argument('--wd', '--weight_decay', default=0., type=float,\n                    metavar='W', help='weight decay (default: 0.)',\n                    dest='weight_decay')\nparser.add_argument('-p', '--print_freq', default=10, type=int,\n                    metavar='N', help='print frequency (default: 10)')\nparser.add_argument('--resume', default='', type=str, metavar='PATH',\n                    help='path to latest checkpoint (default: none)')\nparser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',\n                    help='evaluate model on validation set')\nparser.add_argument('--world_size', default=-1, type=int,\n                    help='number of nodes for distributed training')\nparser.add_argument('--rank', default=-1, type=int,\n                    help='node rank for distributed training')\nparser.add_argument('--dist_url', default='tcp://224.66.41.62:23456', type=str,\n                    help='url used to set up distributed training')\nparser.add_argument('--dist_backend', default='nccl', type=str,\n                    help='distributed backend')\nparser.add_argument('--seed', default=None, type=int,\n                    help='seed for initializing training. ')\nparser.add_argument('--gpu', default=None, type=int,\n                    help='GPU id to use.')\nparser.add_argument('--multiprocessing-distributed', action='store_true',\n                    help='Use multi-processing distributed training to launch '\n                         'N processes per node, which has N GPUs. This is the '\n                         'fastest way to use PyTorch for either single node or '\n                         'multi node data parallel training')\n\n# additional configs:\nparser.add_argument('--pretrained', default='', type=str,\n                    help='path to moco pretrained checkpoint')\n\n#parser.add_argument('--lmdb_dir', default='/path/to/imagenet/', type=str, help='Please specify path to the ImageNet folder.')\nparser.add_argument('--bands', type=str, default='all', help=\"input bands\")\nparser.add_argument('--patch_size', default=16, type=int, help='vit patch size')\nparser.add_argument(\"--train_frac\", default=1.0, type=float, help=\"use a subset of labeled data\")\nparser.add_argument('--checkpoints_dir', default=\".\", help='Path to save logs and checkpoints')\nparser.add_argument(\"--is_slurm_job\", action='store_true', help=\"slurm job\")\n\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by 10x)')\nparser.add_argument('--cos', action='store_true', help='use cosine lr schedule')\nparser.add_argument('--linear', action='store_true')\n\nbest_acc1 = 0\n\n\ndef main():\n    args = parser.parse_args()\n\n    if args.seed is not None:\n        random.seed(args.seed)\n        torch.manual_seed(args.seed)\n        cudnn.deterministic = True\n        warnings.warn('You have chosen to seed training. '\n                      'This will turn on the CUDNN deterministic setting, '\n                      'which can slow down your training considerably! '\n                      'You may see unexpected behavior when restarting '\n                      'from checkpoints.')\n\n    if args.gpu is not None:\n        warnings.warn('You have chosen a specific GPU. This will completely '\n                      'disable data parallelism.')\n\n    if args.dist_url == \"env://\" and args.world_size == -1:\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n    ### add slurm option ###\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )        \n        \n        \n    args.distributed = args.world_size > 1 or args.multiprocessing_distributed\n\n    ngpus_per_node = torch.cuda.device_count()\n    if args.multiprocessing_distributed:\n        # Since we have ngpus_per_node processes per node, the total world_size\n        # needs to be adjusted accordingly\n        args.world_size = ngpus_per_node * args.world_size\n        # Use torch.multiprocessing.spawn to launch distributed processes: the\n        # main_worker process function\n        mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args))\n    else:\n        # Simply call main_worker function\n        main_worker(args.gpu, ngpus_per_node, args)\n\n\ndef main_worker(gpu, ngpus_per_node, args):\n    global best_acc1\n    args.gpu = gpu\n\n    # suppress printing if not master\n    if (args.multiprocessing_distributed and args.gpu != 0) or (args.is_slurm_job and args.rank!=0):\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n\n    if args.gpu is not None:\n        print(\"Use GPU: {} for training\".format(args.gpu))\n\n    if args.distributed:\n        if args.dist_url == \"env://\" and args.rank == -1:\n            args.rank = int(os.environ[\"RANK\"])\n        if args.multiprocessing_distributed:\n            # For multiprocessing distributed training, rank needs to be the\n            # global rank among all the processes\n            args.rank = args.rank * ngpus_per_node + gpu\n        dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                world_size=args.world_size, rank=args.rank)\n        torch.distributed.barrier()\n    # create model\n    print(\"=> creating model '{}'\".format(args.arch))\n    if args.arch.startswith('vit'):\n        model = vits.__dict__[args.arch](in_chans=13,num_classes=19)\n        linear_keyword = 'head'\n    else:\n        model = torchvision_models.__dict__[args.arch]()\n        linear_keyword = 'fc'\n\n    if args.linear:\n        # freeze all layers but the last fc\n        for name, param in model.named_parameters():\n            if name not in ['%s.weight' % linear_keyword, '%s.bias' % linear_keyword]:\n                param.requires_grad = False\n        # init the fc layer\n        getattr(model, linear_keyword).weight.data.normal_(mean=0.0, std=0.01)\n        getattr(model, linear_keyword).bias.data.zero_()\n\n    # load from pre-trained, before DistributedDataParallel constructor\n    if args.pretrained:\n        if os.path.isfile(args.pretrained):\n            print(\"=> loading checkpoint '{}'\".format(args.pretrained))\n            checkpoint = torch.load(args.pretrained, map_location=\"cpu\")\n\n            # rename moco pre-trained keys\n            state_dict = checkpoint['state_dict']\n            for k in list(state_dict.keys()):\n                # retain only base_encoder up to before the embedding layer\n                if k.startswith('module.base_encoder') and not k.startswith('module.base_encoder.%s' % linear_keyword):\n                    # remove prefix\n                    state_dict[k[len(\"module.base_encoder.\"):]] = state_dict[k]\n                # delete renamed or unused k\n                del state_dict[k]\n\n            args.start_epoch = 0\n            msg = model.load_state_dict(state_dict, strict=False)\n            assert set(msg.missing_keys) == {\"%s.weight\" % linear_keyword, \"%s.bias\" % linear_keyword}\n\n            print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.pretrained))\n\n    # infer learning rate before changing batch size\n    #init_lr = args.lr * args.batch_size * 4 / 256\n\n    if not torch.cuda.is_available():\n        print('using CPU, this will be slow')\n    elif args.distributed:\n        # For multiprocessing distributed, DistributedDataParallel constructor\n        # should always set the single device scope, otherwise,\n        # DistributedDataParallel will use all available devices.\n        \n        ### add slurm option ###\n        if args.is_slurm_job:            \n            args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n            torch.cuda.set_device(args.gpu_to_work_on)\n            model.cuda()\n            model = nn.parallel.DistributedDataParallel(model,device_ids=[args.gpu_to_work_on])   \n            print('model distributed.')        \n        \n        elif args.gpu is not None:\n            torch.cuda.set_device(args.gpu)\n            model.cuda(args.gpu)\n            # When using a single GPU per process and per\n            # DistributedDataParallel, we need to divide the batch size\n            # ourselves based on the total number of GPUs we have\n            args.batch_size = int(args.batch_size / args.world_size)\n            args.num_workers = int((args.num_workers + ngpus_per_node - 1) / ngpus_per_node)\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        else:\n            model.cuda()\n            # DistributedDataParallel will divide and allocate batch_size to all\n            # available GPUs if device_ids are not set\n            model = torch.nn.parallel.DistributedDataParallel(model)\n    elif args.gpu is not None:\n        torch.cuda.set_device(args.gpu)\n        model = model.cuda(args.gpu)\n    else:\n        # DataParallel will divide and allocate batch_size to all available GPUs\n        if args.arch.startswith('alexnet') or args.arch.startswith('vgg'):\n            model.features = torch.nn.DataParallel(model.features)\n            model.cuda()\n        else:\n            model = torch.nn.DataParallel(model).cuda()\n\n    # define loss function (criterion) and optimizer\n    criterion = nn.MultiLabelSoftMarginLoss().cuda()\n\n    # optimize only the linear classifier\n    parameters = list(filter(lambda p: p.requires_grad, model.parameters()))\n    if args.linear:\n        assert len(parameters) == 2  # weight, bias\n\n    optimizer = torch.optim.SGD(parameters, args.lr,\n                                momentum=args.momentum,\n                                weight_decay=args.weight_decay)\n\n    # optionally resume from a checkpoint\n    if args.resume:\n        if os.path.isfile(args.resume):\n            print(\"=> loading checkpoint '{}'\".format(args.resume))\n            if args.gpu is None:\n                checkpoint = torch.load(args.resume)\n            else:\n                # Map model to be loaded to specified single gpu.\n                loc = 'cuda:{}'.format(args.gpu)\n                checkpoint = torch.load(args.resume, map_location=loc)\n            args.start_epoch = checkpoint['epoch']\n            best_acc1 = checkpoint['best_acc1']\n            if args.gpu is not None:\n                # best_acc1 may be from a checkpoint from a different GPU\n                best_acc1 = best_acc1.to(args.gpu)\n            model.load_state_dict(checkpoint['state_dict'])\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            print(\"=> loaded checkpoint '{}' (epoch {})\"\n                  .format(args.resume, checkpoint['epoch']))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.resume))\n\n    cudnn.benchmark = True\n\n    # Data loading code\n    '''\n    traindir = os.path.join(args.data, 'train')\n    valdir = os.path.join(args.data, 'val')\n    \n    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                     std=[0.229, 0.224, 0.225])\n\n    train_dataset = datasets.ImageFolder(\n        traindir,\n        transforms.Compose([\n            transforms.RandomResizedCrop(224),\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            normalize,\n        ]))\n    '''\n    \n    if args.bands == 'RGB':\n        bands = ['B04', 'B03', 'B02']\n        lmdb_train = 'train_RGB.lmdb'\n        lmdb_val = 'val_RGB.lmdb'\n        args.n_channels = 3\n    else:\n        bands = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']\n        lmdb_train = 'train_B12.lmdb'\n        lmdb_val = 'val_B12.lmdb'\n        args.n_channels = 12\n\n\n    ## change03 ##\n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(224,scale=(0.8,1.0)),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor()])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(224),\n            cvtransforms.ToTensor(),\n            ])\n\n\n    train_dataset = LMDBDataset(\n        lmdb_file=os.path.join(args.data, lmdb_train),\n        transform=train_transforms,\n        is_slurm_job=args.is_slurm_job            \n    )\n\n    val_dataset = LMDBDataset(\n        lmdb_file=os.path.join(args.data, lmdb_val),\n        transform=val_transforms,\n        is_slurm_job=args.is_slurm_job            \n    )       \n    \n    if args.train_frac is not None and args.train_frac<1:\n        train_dataset = random_subset(train_dataset,args.train_frac,seed=42)    \n    \n    if args.distributed:\n        train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)\n    else:\n        train_sampler = None\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None),\n        num_workers=args.num_workers, pin_memory=True, sampler=train_sampler)\n\n    val_loader = torch.utils.data.DataLoader(\n        val_dataset, batch_size=args.batch_size, num_workers=args.num_workers, pin_memory=True)    \n\n\n    if args.evaluate:\n        validate(val_loader, model, criterion, args)\n        return\n\n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\n        os.mkdir(args.checkpoints_dir)\n    \n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            train_sampler.set_epoch(epoch)\n        adjust_learning_rate(optimizer, epoch, args)\n\n        # train for one epoch\n        train(train_loader, model, criterion, optimizer, epoch, args)\n\n        if epoch%5==4:\n            # evaluate on validation set\n            acc1 = validate(val_loader, model, criterion, args)\n\n            # remember best acc@1 and save checkpoint\n            is_best = acc1 > best_acc1\n            best_acc1 = max(acc1, best_acc1)\n\n        if epoch%5==4 and args.rank==0: # only the first GPU saves checkpoint\n            save_checkpoint({\n                'epoch': epoch + 1,\n                'arch': args.arch,\n                'state_dict': model.state_dict(),\n                'best_acc1': best_acc1,\n                'optimizer' : optimizer.state_dict(),\n            }, is_best,filename=os.path.join(args.checkpoints_dir,'checkpoint.pth.tar'))\n            if epoch == args.start_epoch:\n                sanity_check(model.state_dict(), args.pretrained, linear_keyword)\n\n\ndef train(train_loader, model, criterion, optimizer, epoch, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    data_time = AverageMeter('Data', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(train_loader),\n        [batch_time, data_time, losses, top1, top5],\n        prefix=\"Epoch: [{}]\".format(epoch))\n\n    \"\"\"\n    Switch to eval mode:\n    Under the protocol of linear classification on frozen features/models,\n    it is not legitimate to change any part of the pre-trained model.\n    BatchNorm in train mode may revise running mean/std (even if it receives\n    no gradient), which are part of the model parameters too.\n    \"\"\"\n    model.eval()\n\n    end = time.time()\n    for i, (images, target) in enumerate(train_loader):\n        # measure data loading time\n        data_time.update(time.time() - end)\n\n        b_zeros = torch.zeros((images.shape[0],1,images.shape[2],images.shape[3]),dtype=torch.float32)\n        images = torch.cat((images[:,:10,:,:],b_zeros,images[:,10:,:,:]),dim=1)\n                \n        if args.gpu is not None:\n            images = images.cuda(args.gpu, non_blocking=True)\n        if torch.cuda.is_available():\n            target = target.cuda(args.gpu, non_blocking=True)\n\n        # compute output\n        output = model(images)\n        loss = criterion(output, target.long())\n\n        # measure accuracy and record loss\n        #acc1, acc5 = accuracy(output, target, topk=(1, 5))\n        if epoch%5==4:\n            score = torch.sigmoid(output).detach().cpu()\n            acc1 = average_precision_score(target.cpu(), score, average='micro') * 100.0\n            acc5 = acc1        \n        else:\n            acc1 = 0\n            acc5 = 0\n        losses.update(loss.item(), images.size(0))\n        #top1.update(acc1[0], images.size(0))\n        #top5.update(acc5[0], images.size(0))\n        top1.update(acc1, images.size(0))\n        top5.update(acc5, images.size(0))\n        # compute gradient and do SGD step\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        # measure elapsed time\n        batch_time.update(time.time() - end)\n        end = time.time()\n\n        if i % args.print_freq == 0:\n            progress.display(i)\n\n\ndef validate(val_loader, model, criterion, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(val_loader),\n        [batch_time, losses, top1, top5],\n        prefix='Test: ')\n\n    # switch to evaluate mode\n    model.eval()\n\n    with torch.no_grad():\n        end = time.time()\n        for i, (images, target) in enumerate(val_loader):\n            \n            b_zeros = torch.zeros((images.shape[0],1,images.shape[2],images.shape[3]),dtype=torch.float32)\n            images = torch.cat((images[:,:10,:,:],b_zeros,images[:,10:,:,:]),dim=1)            \n            \n            if args.gpu is not None:\n                images = images.cuda(args.gpu, non_blocking=True)\n            if torch.cuda.is_available():\n                target = target.cuda(args.gpu, non_blocking=True)\n\n            # compute output\n            output = model(images)\n            loss = criterion(output, target.long())\n\n            # measure accuracy and record loss\n            #acc1, acc5 = accuracy(output, target, topk=(1, 5))\n            score = torch.sigmoid(output).detach().cpu()\n            acc1 = average_precision_score(target.cpu(), score, average='micro') * 100.0\n            acc5 = acc1            \n            \n            \n            losses.update(loss.item(), images.size(0))\n            #top1.update(acc1[0], images.size(0))\n            #top5.update(acc5[0], images.size(0))\n            top1.update(acc1, images.size(0))\n            top5.update(acc5, images.size(0))\n            # measure elapsed time\n            batch_time.update(time.time() - end)\n            end = time.time()\n\n            if i % 200 == 0:\n                progress.display(i)\n\n        # TODO: this should also be done with the ProgressMeter\n        print(' * Acc@1 {top1.avg:.3f} Acc@5 {top5.avg:.3f}'\n              .format(top1=top1, top5=top5))\n\n    return top1.avg\n\n\ndef save_checkpoint(state, is_best, filename='checkpoint.pth.tar'):\n    torch.save(state, filename)\n    #if is_best:\n    #    shutil.copyfile(filename, 'model_best.pth.tar')\n\n\ndef sanity_check(state_dict, pretrained_weights, linear_keyword):\n    \"\"\"\n    Linear classifier should not change any weights other than the linear layer.\n    This sanity check asserts nothing wrong happens (e.g., BN stats updated).\n    \"\"\"\n    print(\"=> loading '{}' for sanity check\".format(pretrained_weights))\n    checkpoint = torch.load(pretrained_weights, map_location=\"cpu\")\n    state_dict_pre = checkpoint['state_dict']\n\n    for k in list(state_dict.keys()):\n        # only ignore linear layer\n        if '%s.weight' % linear_keyword in k or '%s.bias' % linear_keyword in k:\n            continue\n\n        # name in pretrained model\n        k_pre = 'module.base_encoder.' + k[len('module.'):] \\\n            if k.startswith('module.') else 'module.base_encoder.' + k\n\n        assert ((state_dict[k].cpu() == state_dict_pre[k_pre]).all()), \\\n            '{} is changed in linear classifier training.'.format(k)\n\n    print(\"=> sanity check passed.\")\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self, name, fmt=':f'):\n        self.name = name\n        self.fmt = fmt\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count\n\n    def __str__(self):\n        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'\n        return fmtstr.format(**self.__dict__)\n\n\nclass ProgressMeter(object):\n    def __init__(self, num_batches, meters, prefix=\"\"):\n        self.batch_fmtstr = self._get_batch_fmtstr(num_batches)\n        self.meters = meters\n        self.prefix = prefix\n\n    def display(self, batch):\n        entries = [self.prefix + self.batch_fmtstr.format(batch)]\n        entries += [str(meter) for meter in self.meters]\n        print('\\t'.join(entries))\n\n    def _get_batch_fmtstr(self, num_batches):\n        num_digits = len(str(num_batches // 1))\n        fmt = '{:' + str(num_digits) + 'd}'\n        return '[' + fmt + '/' + fmt.format(num_batches) + ']'\n\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    if args.cos:  # cosine lr schedule\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\n    else:  # stepwise lr schedule\n        for milestone in args.schedule:\n            lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n        \n        \ndef accuracy(output, target, topk=(1,)):\n    \"\"\"Computes the accuracy over the k top predictions for the specified values of k\"\"\"\n    with torch.no_grad():\n        maxk = max(topk)\n        batch_size = target.size(0)\n\n        _, pred = output.topk(maxk, 1, True, True)\n        pred = pred.t()\n        correct = pred.eq(target.view(1, -1).expand_as(pred))\n\n        res = []\n        for k in topk:\n            correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True)\n            res.append(correct_k.mul_(100.0 / batch_size))\n        return res\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_BE_sup.py",
    "content": "\"\"\"\r\nsupervised training of BigEarthNet (all bands) with resnet18/50\r\n\r\nTODO:\r\n  -- optimize and reduce RAM usage\r\n  -- optimize I/O\r\n  -- checkpoints\r\n  -- merge B12 and RGB codes\r\n\r\n\"\"\"\r\n\r\n\r\n\r\nimport torch\r\nfrom PIL import Image\r\nfrom torch.utils.data import Dataset, DataLoader\r\nfrom torchvision import models\r\n\r\n## change01 ##\r\nfrom cvtorchvision import cvtransforms\r\nimport time\r\nimport os\r\nimport math\r\nimport pdb\r\nfrom sklearn.metrics import average_precision_score, precision_score, recall_score, f1_score\r\nfrom torchmetrics.functional.classification import multilabel_average_precision, multilabel_f1_score\r\nimport numpy as np\r\nimport argparse\r\nimport builtins\r\n\r\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco import Bigearthnet\r\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb_s2_uint8 import LMDBDataset,random_subset\r\n\r\nfrom torch.utils.tensorboard import SummaryWriter\r\n\r\nparser = argparse.ArgumentParser()\r\nparser.add_argument('--data_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet')\r\nparser.add_argument('--lmdb_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet/dataload_op1_lmdb')\r\nparser.add_argument('--checkpoints_dir', type=str, default='./checkpoints/resnet/')\r\nparser.add_argument('--resume', type=str, default='')\r\nparser.add_argument('--save_path', type=str, default='./checkpoints/bigearthnet_s2_B12_100_no_pretrain_resnet50.pt')\r\n\r\nparser.add_argument('--bands', type=str, default='all', choices=['all','RGB','B12'], help='bands to process')  \r\nparser.add_argument('--train_frac', type=float, default=1.0)\r\nparser.add_argument('--backbone', type=str, default='resnet50')\r\nparser.add_argument('--batchsize', type=int, default=256)\r\nparser.add_argument('--epochs', type=int, default=100)\r\nparser.add_argument('--num_workers', type=int, default=8)\r\nparser.add_argument('--lr', type=float, default=0.05)\r\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\r\n                    help='learning rate schedule (when to drop lr by 10x)')\r\nparser.add_argument('--cos', action='store_true', help='use cosine lr schedule')\r\nparser.add_argument('--seed', type=int, default=42)\r\nparser.add_argument('--pretrained', default='', type=str, help='path to moco pretrained checkpoint')\r\n\r\n### distributed running ###\r\nparser.add_argument('--dist_url', default='env://', type=str)\r\nparser.add_argument(\"--world_size\", default=-1, type=int, help=\"\"\"\r\n                    number of processes: it is set automatically and\r\n                    should not be passed as argument\"\"\")\r\nparser.add_argument(\"--rank\", default=0, type=int, help=\"\"\"rank of this process:\r\n                    it is set automatically and should not be passed as argument\"\"\")\r\nparser.add_argument(\"--local_rank\", default=0, type=int,\r\n                    help=\"this argument is not used and should be ignored\")\r\n\r\nparser.add_argument('--normalize',action='store_true',default=False)\r\nparser.add_argument('--linear',action='store_true',default=False)\r\nparser.add_argument('--pretrain_style',default=None,type=str,choices=['reinit','pad',None])\r\n\r\n\r\ndef init_distributed_mode(args):\r\n\r\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\r\n\r\n    if args.is_slurm_job:\r\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\r\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\r\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\r\n        )\r\n    else:\r\n        # multi-GPU job (local or multi-node) - jobs started with torch.distributed.launch\r\n        # read environment variables\r\n        args.rank = int(os.environ[\"RANK\"])\r\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\r\n\r\n\r\n    # prepare distributed\r\n    torch.distributed.init_process_group(\r\n        backend=\"nccl\",\r\n        init_method=args.dist_url,\r\n        world_size=args.world_size,\r\n        rank=args.rank,\r\n    )\r\n\r\n    # set cuda device\r\n    args.gpu_to_work_on = args.rank % torch.cuda.device_count()\r\n    torch.cuda.set_device(args.gpu_to_work_on)\r\n    return    \r\n\r\ndef fix_random_seeds(seed=42):\r\n    \"\"\"\r\n    Fix random seeds.\r\n    \"\"\"\r\n    torch.manual_seed(seed)\r\n    torch.cuda.manual_seed_all(seed)\r\n    np.random.seed(seed)\r\n\r\ndef adjust_learning_rate(optimizer, epoch, args):\r\n    \"\"\"Decay the learning rate based on schedule\"\"\"\r\n    lr = args.lr\r\n    if args.cos:  # cosine lr schedule\r\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\r\n    else:  # stepwise lr schedule\r\n        for milestone in args.schedule:\r\n            lr *= 0.1 if epoch >= milestone else 1.\r\n    for param_group in optimizer.param_groups:\r\n        param_group['lr'] = lr\r\n\r\n\r\ndef main():\r\n\r\n    global args\r\n    args = parser.parse_args()\r\n    ### dist ###\r\n    init_distributed_mode(args)\r\n    if args.rank != 0:\r\n        def print_pass(*args):\r\n            pass\r\n        builtins.print = print_pass\r\n    \r\n    fix_random_seeds(args.seed)\r\n    \r\n    # `python bigearthnet_dataset.py` to create lmdb data\r\n    lmdb = True # use lmdb dataset\r\n    data_dir = args.data_dir\r\n    lmdb_dir = args.lmdb_dir\r\n    checkpoints_dir = args.checkpoints_dir\r\n    save_path = args.save_path\r\n    batch_size = args.batchsize\r\n\r\n    num_workers = args.num_workers\r\n    epochs = args.epochs\r\n    train_frac = args.train_frac\r\n    seed = args.seed\r\n\r\n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\r\n        os.makedirs(args.checkpoints_dir)\r\n    if args.rank==0:\r\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints_dir,'log'))\r\n\r\n\r\n    ## change02 ##\r\n    if args.bands == 'RGB':\r\n        bands = ['B04', 'B03', 'B02']\r\n        lmdb_train = 'train_RGB.lmdb'\r\n        lmdb_val = 'val_RGB.lmdb'\r\n    else:\r\n        bands = ['B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12']\r\n        lmdb_train = 'train_B12.lmdb'\r\n        lmdb_val = 'val_B12.lmdb'\r\n        \r\n    num_labels = 19\r\n\r\n    ## change03 ##\r\n    train_transforms = cvtransforms.Compose([\r\n            cvtransforms.RandomResizedCrop(224,scale=(0.8,1.0)), # multilabel, avoid cropping out labels\r\n            cvtransforms.RandomHorizontalFlip(),\r\n            cvtransforms.ToTensor()])\r\n\r\n    val_transforms = cvtransforms.Compose([\r\n            cvtransforms.Resize(256),\r\n            cvtransforms.CenterCrop(224),\r\n            cvtransforms.ToTensor(),\r\n            ])\r\n\r\n    if lmdb:\r\n        train_dataset = LMDBDataset(\r\n            lmdb_file=os.path.join(lmdb_dir, lmdb_train),\r\n            transform=train_transforms\r\n        )\r\n        \r\n        val_dataset = LMDBDataset(\r\n            lmdb_file=os.path.join(lmdb_dir, lmdb_val),\r\n            transform=val_transforms\r\n        )    \r\n    else:\r\n        train_dataset = Bigearthnet(\r\n            root=data_dir,\r\n            split='train',\r\n            bands=bands,\r\n            use_new_labels = True,\r\n            transform=train_transforms\r\n        )\r\n        \r\n        val_dataset = Bigearthnet(\r\n            root=data_dir,\r\n            split='val',\r\n            bands=bands,\r\n            use_new_labels = True,\r\n            transform=train_transforms\r\n        )    \r\n        \r\n        \r\n    if train_frac is not None and train_frac<1:\r\n        train_dataset = random_subset(train_dataset,train_frac,seed)    \r\n    ### dist ###    \r\n    sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)    \r\n        \r\n    train_loader = DataLoader(train_dataset,\r\n                              batch_size=batch_size,\r\n                              sampler = sampler,\r\n                              #shuffle=True,\r\n                              num_workers=num_workers,\r\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\r\n                              drop_last=True\r\n                              \r\n                              )\r\n                              \r\n    val_loader = DataLoader(val_dataset,\r\n                              batch_size=batch_size,\r\n                              shuffle=False,\r\n                              num_workers=num_workers,\r\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\r\n                              drop_last=True\r\n                              \r\n                              )\r\n    \r\n    print('train_len: %d val_len: %d' % (len(train_dataset),len(val_dataset)))\r\n\r\n    ## change 04 ##\r\n    if args.backbone == 'resnet50':\r\n        net = models.resnet50(pretrained=False)\r\n    elif args.backbone == 'resnet18':\r\n        net = models.resnet18(pretrained=False)\r\n        \r\n    if args.pretrain_style == 'reinit':\r\n        print(\"=> loading checkpoint '{}'\".format(args.pretrained))\r\n        state_dict = torch.load(args.pretrained, map_location=\"cpu\")\r\n        msg = net.load_state_dict(state_dict, strict=False)\r\n        #assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\r\n        print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))        \r\n         \r\n    if args.bands=='all':\r\n        net.conv1 = torch.nn.Conv2d(13, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\r\n    elif args.bands=='B12':\r\n        net.conv1 = torch.nn.Conv2d(12, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\r\n    \r\n    # load from pre-trained, before DistributedDataParallel constructor\r\n    if args.pretrain_style == 'pad':\r\n        print(\"=> loading checkpoint '{}'\".format(args.pretrained))\r\n        state_dict = torch.load(args.pretrained, map_location=\"cpu\")\r\n        new_conv1_weight = torch.zeros((64,12,7,7)) # 64,12,7,7\r\n        # B10 init with 0\r\n        new_conv1_weight[:,1,:,:] = state_dict['conv1.weight'][:,2,:,:]\r\n        new_conv1_weight[:,2,:,:] = state_dict['conv1.weight'][:,1,:,:]\r\n        new_conv1_weight[:,3,:,:] = state_dict['conv1.weight'][:,0,:,:]\r\n        \r\n        state_dict['conv1.weight'] = new_conv1_weight\r\n\r\n        msg = net.load_state_dict(state_dict, strict=False)\r\n        #assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\r\n        print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\r\n\r\n\r\n    if args.backbone == 'resnet50':\r\n        net.fc = torch.nn.Linear(2048,19)\r\n    elif args.backbone == 'resnet18':\r\n        net.fc = torch.nn.Linear(512,19)   \r\n\r\n    if args.linear:\r\n        for name, param in net.named_parameters():\r\n            if name not in ['fc.weight','fc.bias']:\r\n                param.requires_grad = False\r\n\r\n        net.fc.weight.data.normal_(mean=0.0,std=0.01)\r\n        net.fc.bias.data.zero_()\r\n\r\n    # convert batch norm layers (if any)\r\n    if args.is_slurm_job:\r\n        net = torch.nn.SyncBatchNorm.convert_sync_batchnorm(net)\r\n\r\n    net.cuda()\r\n    #### nccl doesn't support wsl\r\n    if args.is_slurm_job:\r\n        net = torch.nn.parallel.DistributedDataParallel(net,device_ids=[args.gpu_to_work_on],find_unused_parameters=True)\r\n        \r\n        \r\n    criterion = torch.nn.MultiLabelSoftMarginLoss()\r\n    optimizer = torch.optim.SGD(net.parameters(), lr=args.lr, momentum=0.9)\r\n\r\n\r\n    last_epoch = 0\r\n    if args.resume:\r\n        checkpoint = torch.load(args.resume)\r\n        state_dict = checkpoint['model_state_dict']\r\n        #state_dict = {k.replace(\"module.\", \"\"): v for k,v in state_dict.items()}\r\n        net.load_state_dict(state_dict)\r\n        optimizer.load_state_dict(checkpoint['optimizer_state_dict'])\r\n        last_epoch = checkpoint['epoch']\r\n        last_loss = checkpoint['loss']\r\n\r\n    #device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\r\n    #net.to(device)\r\n    #net.cuda()\r\n    \r\n\r\n\r\n    print('Start training...')\r\n    for epoch in range(last_epoch,epochs):\r\n\r\n        net.train()\r\n        adjust_learning_rate(optimizer, epoch, args)\r\n        \r\n        train_loader.sampler.set_epoch(epoch)\r\n        running_loss = 0.0\r\n        running_acc = 0.0\r\n        \r\n        running_loss_epoch = 0.0\r\n        running_acc_epoch = 0.0\r\n        \r\n        start_time = time.time()\r\n        end = time.time()\r\n        sum_bt = 0.0\r\n        sum_dt = 0.0\r\n        sum_tt = 0.0\r\n        sum_st = 0.0\r\n        for i, data in enumerate(train_loader, 0):\r\n            data_time = time.time()-end\r\n            #inputs, labels = data\r\n            if args.bands=='all':\r\n                b_zeros = torch.zeros((data[0].shape[0],1,data[0].shape[2],data[0].shape[3]),dtype=torch.float32)\r\n                images = torch.cat((data[0][:,:10,:,:],b_zeros,data[0][:,10:,:,:]),dim=1)            \r\n                inputs, labels = images.cuda(), data[1].cuda()\r\n            else:    \r\n                inputs, labels = data[0].cuda(), data[1].cuda()\r\n            # zero the parameter gradients\r\n            optimizer.zero_grad()\r\n\r\n            # forward + backward + optimize\r\n            outputs = net(inputs)\r\n            #pdb.set_trace()\r\n            loss = criterion(outputs, labels.long())\r\n            loss.backward()\r\n            optimizer.step()\r\n            train_time = time.time()-end-data_time\r\n            if epoch%5==4:\r\n                score = torch.sigmoid(outputs).detach()\r\n                #average_precision = average_precision_score(labels.cpu(), score, average='micro') * 100.0\r\n                average_precision = multilabel_average_precision(score, labels, num_labels=19, average=\"micro\") * 100.0\r\n            else:\r\n                average_precision = 0\r\n            score_time = time.time()-end-data_time-train_time\r\n            \r\n            # print statistics\r\n            running_loss += loss.item()\r\n            #running_acc += average_precision\r\n            batch_time = time.time() - end\r\n            end = time.time()        \r\n            sum_bt += batch_time\r\n            sum_dt += data_time\r\n            sum_tt += train_time\r\n            sum_st += score_time\r\n            \r\n            if i % 20 == 19:    # print every 20 mini-batches\r\n\r\n                print('[%d, %5d] loss: %.3f acc: %.3f batch_time: %.3f data_time: %.3f train_time: %.3f score_time: %.3f' %\r\n                      (epoch + 1, i + 1, running_loss / 20, running_acc / 20, sum_bt/20, sum_dt/20, sum_tt/20, sum_st/20))\r\n                \r\n                #train_iter =  i*args.batch_size / len(train_dataset)\r\n                #tb_writer.add_scalar('train_loss', running_loss/20, global_step=(epoch+1+train_iter) )\r\n                running_loss_epoch = running_loss/20\r\n                running_acc_epoch = running_acc/20\r\n                \r\n                running_loss = 0.0\r\n                running_acc = 0.0\r\n                sum_bt = 0.0\r\n                sum_dt = 0.0\r\n                sum_tt = 0.0\r\n                sum_st = 0.0\r\n\r\n        if epoch % 5 == 4:\r\n            running_loss_val = 0.0\r\n            running_acc_val = 0.0\r\n            count_val = 0\r\n            net.eval()\r\n            with torch.no_grad():\r\n                for j, data_val in enumerate(val_loader, 0):\r\n\r\n                    if args.bands=='all':\r\n                        b_zeros = torch.zeros((data_val[0].shape[0],1,data_val[0].shape[2],data_val[0].shape[3]),dtype=torch.float32)\r\n                        images = torch.cat((data_val[0][:,:10,:,:],b_zeros,data_val[0][:,10:,:,:]),dim=1)\r\n                        inputs_val, labels_val = images.cuda(), data_val[1].cuda()\r\n                    else:\r\n                        inputs_val, labels_val = data_val[0].cuda(), data_val[1].cuda()\r\n\r\n                    outputs_val = net(inputs_val)\r\n                    loss_val = criterion(outputs_val, labels_val.long())\r\n                    score_val = torch.sigmoid(outputs_val).detach()\r\n                    #average_precision_val = average_precision_score(labels_val.cpu(), score_val, average='micro') * 100.0\r\n                    average_precision_val = multilabel_average_precision(score_val, labels_val, num_labels=19, average=\"micro\") * 100.0\r\n                       \r\n\r\n                    count_val += 1\r\n                    running_loss_val += loss_val.item()\r\n                    running_acc_val += average_precision_val        \r\n\r\n            print('Epoch %d val_loss: %.3f val_acc: %.3f time: %s seconds.' % (epoch+1, running_loss_val/count_val, running_acc_val/count_val, time.time()-start_time))\r\n\r\n            if args.rank == 0:\r\n                losses = {'train': running_loss_epoch,\r\n                          'val': running_loss_val/count_val}\r\n                accs = {'train': running_acc_epoch,\r\n                        'val': running_acc_val/count_val}        \r\n                tb_writer.add_scalars('loss', losses, global_step=epoch+1, walltime=None)\r\n                tb_writer.add_scalars('acc', accs, global_step=epoch+1, walltime=None)\r\n        \r\n            \r\n            \r\n        if args.rank==0 and epoch % 10 == 9:\r\n            torch.save({\r\n                        'epoch': epoch,\r\n                        'model_state_dict': net.state_dict(),\r\n                        'optimizer_state_dict':optimizer.state_dict(),\r\n                        'loss':loss,\r\n                        }, os.path.join(checkpoints_dir,'checkpoint_{:04d}.pth.tar'.format(epoch)))\r\n        \r\n    #if args.rank==0:\r\n    #    torch.save(net.state_dict(), save_path)\r\n        \r\n    print('Training finished.')\r\n\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    main()\r\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_EU_data2vec.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.nn as nn\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.data.mixup import Mixup\nfrom timm.models import create_model\nfrom timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy\nfrom timm.utils import ModelEma\nfrom models.data2vec.optim_factory import create_optimizer, get_parameter_groups, LayerDecayValueAssigner\n\nfrom models.data2vec.engine_for_finetuning import train_one_epoch, evaluate\nfrom models.data2vec.utils import NativeScalerWithGradNormCount as NativeScaler\nimport models.data2vec.utils as utils\nfrom scipy import interpolate\nimport models.data2vec.modeling_finetune as modeling_finetune\nfrom sklearn.metrics import average_precision_score\n\nfrom datasets.EuroSat.eurosat_dataset import EurosatDataset, Subset\nfrom sklearn.model_selection import train_test_split\n\nfrom cvtorchvision import cvtransforms\n\n\ndef build_dataset_eu(is_train, args):    \n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.in_size),\n            #cvtransforms.Resize(args.in_size),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(args.in_size),\n            cvtransforms.ToTensor(),\n            ])\n\n\n    eurosat_dataset = EurosatDataset(root=args.data_path,normalize=False)\n\n    indices = np.arange(len(eurosat_dataset))\n    train_indices, test_indices = train_test_split(indices, train_size=0.8,stratify=eurosat_dataset.targets,random_state=args.seed)    \n  \n    train_dataset = Subset(eurosat_dataset, train_indices, train_transforms)\n    val_dataset = Subset(eurosat_dataset, test_indices, val_transforms)\n        \n        \n    if args.train_frac is not None and args.train_frac < 1:\n        frac_indices = np.arange(len(train_dataset))\n        sub_train_indices, sub_test_indices = train_test_split(frac_indices, train_size=args.train_frac, random_state=args.seed)\n        train_dataset = Subset(train_dataset, sub_train_indices)    \n        \n    return train_dataset, val_dataset, 10\n\n\ndef get_args():\n    parser = argparse.ArgumentParser('BEiT fine-tuning and evaluation script for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int)\n    parser.add_argument('--epochs', default=30, type=int)\n    parser.add_argument('--update_freq', default=1, type=int)\n    parser.add_argument('--save_ckpt_freq', default=5, type=int)\n\n    # Model parameters\n    parser.add_argument('--model', default='deit_base_patch16_224', type=str, metavar='MODEL',\n                        help='Name of model to train')\n    parser.add_argument('--rel_pos_bias', action='store_true')\n    parser.add_argument('--disable_rel_pos_bias', action='store_false', dest='rel_pos_bias')\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument('--abs_pos_emb', action='store_true')\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument('--layer_scale_init_value', default=0.1, type=float, \n                        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\")\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--drop', type=float, default=0.0, metavar='PCT',\n                        help='Dropout rate (default: 0.)')\n    parser.add_argument('--attn_drop_rate', type=float, default=0.0, metavar='PCT',\n                        help='Attention dropout rate (default: 0.)')\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    parser.add_argument('--disable_eval_during_finetuning', action='store_true', default=False)\n\n    parser.add_argument('--model_ema', action='store_true', default=False)\n    parser.add_argument('--model_ema_decay', type=float, default=0.9999, help='')\n    parser.add_argument('--model_ema_force_cpu', action='store_true', default=False, help='')\n\n    # Optimizer parameters\n    parser.add_argument('--opt', default='sgd', type=str, metavar='OPTIMIZER',\n                        help='Optimizer (default: \"adamw\"')\n    parser.add_argument('--opt_eps', default=1e-8, type=float, metavar='EPSILON',\n                        help='Optimizer Epsilon (default: 1e-8)')\n    parser.add_argument('--opt_betas', default=None, type=float, nargs='+', metavar='BETA',\n                        help='Optimizer Betas (default: None, use opt default)')\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',\n                        help='SGD momentum (default: 0.9)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n    parser.add_argument('--weight_decay_end', type=float, default=None, help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD and using a larger decay by\n        the end of training improves performance for ViTs.\"\"\")\n\n    parser.add_argument('--lr', type=float, default=5e-4, metavar='LR',\n                        help='learning rate (default: 5e-4)')\n    parser.add_argument('--layer_decay', type=float, default=0.9)\n\n    parser.add_argument('--warmup_lr', type=float, default=1e-6, metavar='LR',\n                        help='warmup learning rate (default: 1e-6)')\n    parser.add_argument('--min_lr', type=float, default=1e-6, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0 (1e-5)')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n    parser.add_argument('--warmup_steps', type=int, default=-1, metavar='N',\n                        help='num of steps to warmup LR, will overload warmup_epochs if set > 0')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=0.4, metavar='PCT',\n                        help='Color jitter factor (default: 0.4)')\n    parser.add_argument('--aa', type=str, default='rand-m9-mstd0.5-inc1', metavar='NAME',\n                        help='Use AutoAugment policy. \"v0\" or \"original\". \" + \"(default: rand-m9-mstd0.5-inc1)'),\n    parser.add_argument('--smoothing', type=float, default=0.1,\n                        help='Label smoothing (default: 0.1)')\n    parser.add_argument('--train_interpolation', type=str, default='bicubic',\n                        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")')\n\n    # Evaluation parameters\n    parser.add_argument('--crop_pct', type=float, default=None)\n\n    # * Random Erase params\n    parser.add_argument('--reprob', type=float, default=0.25, metavar='PCT',\n                        help='Random erase prob (default: 0.25)')\n    parser.add_argument('--remode', type=str, default='pixel',\n                        help='Random erase mode (default: \"pixel\")')\n    parser.add_argument('--recount', type=int, default=1,\n                        help='Random erase count (default: 1)')\n    parser.add_argument('--resplit', action='store_true', default=False,\n                        help='Do not random erase first (clean) augmentation split')\n\n    # * Mixup params\n    parser.add_argument('--mixup', type=float, default=0,\n                        help='mixup alpha, mixup enabled if > 0.')\n    parser.add_argument('--cutmix', type=float, default=0,\n                        help='cutmix alpha, cutmix enabled if > 0.')\n    parser.add_argument('--cutmix_minmax', type=float, nargs='+', default=None,\n                        help='cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None)')\n    parser.add_argument('--mixup_prob', type=float, default=1.0,\n                        help='Probability of performing mixup or cutmix when either/both is enabled')\n    parser.add_argument('--mixup_switch_prob', type=float, default=0.5,\n                        help='Probability of switching to cutmix when both mixup and cutmix enabled')\n    parser.add_argument('--mixup_mode', type=str, default='batch',\n                        help='How to apply mixup/cutmix params. Per \"batch\", \"pair\", or \"elem\"')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--model_key', default='model|module', type=str)\n    parser.add_argument('--model_prefix', default='', type=str)\n    parser.add_argument('--init_scale', default=0.001, type=float)\n    parser.add_argument('--use_mean_pooling', action='store_true')\n    parser.set_defaults(use_mean_pooling=True)\n    parser.add_argument('--use_cls', action='store_false', dest='use_mean_pooling')\n    parser.add_argument('--disable_weight_decay_on_rel_pos_bias', action='store_true', default=False)\n    parser.add_argument('--target_layer', default=-1, type=int, help=\"target output layer (0-based)\")\n    parser.add_argument('--remove_final_norm', action='store_true', dest='remove_final_norm')\n    parser.add_argument('--reinit_final_norm', action='store_true', dest='reinit_final_norm')\n    parser.add_argument('--learn_layer_weights', action='store_true', dest='learn_layer_weights')  # supersede `target_layer`\n    parser.add_argument('--layernorm_before_combine', action='store_true', dest='layernorm_before_combine')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--eval_data_path', default=None, type=str,\n                        help='dataset path for evaluation')\n    parser.add_argument('--nb_classes', default=0, type=int,\n                        help='number of the classification types')\n    parser.add_argument('--linear_classifier', action='store_true',\n                        help='linear classifier')\n    parser.add_argument('--imagenet_default_mean_and_std', default=False, action='store_true')\n\n    parser.add_argument('--data_set', default='IMNET', choices=['CIFAR', 'IMNET', 'image_folder'],\n                        type=str, help='ImageNet dataset path')\n    parser.add_argument('--data_set_filter_file', type=str, default=None, help=\"path to filter to filter dataset\")\n    parser.add_argument('--output_dir', default='',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default=None,\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=42, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n    parser.add_argument('--auto_resume', action='store_true')\n    parser.add_argument('--no_auto_resume', action='store_false', dest='auto_resume')\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument('--save_ckpt', action='store_true')\n    parser.add_argument('--no_save_ckpt', action='store_false', dest='save_ckpt')\n    parser.set_defaults(save_ckpt=True)\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    parser.add_argument('--enable_deepspeed', action='store_true', default=False)\n    parser.add_argument('--bands', default='all',\n                        help='which bands to use')\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=0,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n    \n    parser.add_argument('--train_frac', type=float, default=0.1,\n                        help='Training set size')\n    parser.add_argument('--in_size', type=int, default=224,\n                        help='Training set size')\n    \n    known_args, _ = parser.parse_known_args()\n\n    if known_args.enable_deepspeed:\n        try:\n            print(\"why\")\n            import deepspeed\n            print(\"Imported deepspeed\")\n            from deepspeed import DeepSpeedConfig\n            print(\"Imported config\")\n            parser = deepspeed.add_config_arguments(parser)\n            print(\"Created parser\")\n            ds_init = deepspeed.initialize\n            print(\"Inited deepspeed\")\n        except:\n            print(\"Please 'pip install deepspeed==0.4.0'\")\n            exit(0)\n    else:\n        ds_init = None\n\n    return parser.parse_args(), ds_init\n\n\ndef main(args, ds_init):\n    utils.init_distributed_mode(args)\n\n    if ds_init is not None:\n        utils.create_ds_config(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    dataset_train, dataset_val, args.nb_classes = build_dataset_eu(is_train=True, args=args)\n    #if args.disable_eval_during_finetuning:\n    #    dataset_val = None\n    #else:\n    #    dataset_val, _ = build_dataset(is_train=False, args=args)\n        \n        \n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=False)\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    if dataset_val is not None:\n        data_loader_val = torch.utils.data.DataLoader(\n            dataset_val, sampler=sampler_val,\n            batch_size=int(1.5 * args.batch_size),\n            num_workers=args.num_workers,\n            pin_memory=args.pin_mem,\n            drop_last=False\n        )\n    else:\n        data_loader_val = None\n\n    mixup_fn = None\n    mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None\n    if mixup_active:\n        print(\"Mixup is activated!\")\n        mixup_fn = Mixup(\n            mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax,\n            prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode,\n            label_smoothing=args.smoothing, num_classes=args.nb_classes)\n\n    model = create_model(\n        args.model,\n        pretrained=False,\n        num_classes=args.nb_classes,\n        drop_rate=args.drop,\n        drop_path_rate=args.drop_path,\n        attn_drop_rate=args.attn_drop_rate,\n        drop_block_rate=None,\n        use_mean_pooling=args.use_mean_pooling,\n        init_scale=args.init_scale,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        linear_classifier=args.linear_classifier,\n        has_masking=args.num_mask_patches > 0,\n        learn_layer_weights=args.learn_layer_weights,\n        layernorm_before_combine=args.layernorm_before_combine,\n    )\n\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (args.input_size // patch_size[0], args.input_size // patch_size[1])\n    args.patch_size = patch_size\n\n    masked_position_generator = None\n    if args.num_mask_patches > 0:\n        from masking_generator import MaskingGenerator\n        masked_position_generator = MaskingGenerator(\n            args.window_size, num_masking_patches=args.num_mask_patches,\n            max_num_patches=args.max_mask_patches_per_block,\n            min_num_patches=args.min_mask_patches_per_block,\n        )\n\n    if args.finetune:\n        if args.finetune.startswith('https'):\n            checkpoint = torch.hub.load_state_dict_from_url(\n                args.finetune, map_location='cpu', check_hash=True)\n        else:\n            checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load ckpt from %s\" % args.finetune)\n        checkpoint_model = None\n        for model_key in args.model_key.split('|'):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n        if args.reinit_final_norm:\n            for k in ['norm.weight', 'norm.bias', 'fc_norm.weight', 'fc_norm.bias']:\n                if k in checkpoint_model:\n                    print(f\"Removing key {k} from pretrained checkpoint\")\n                    del checkpoint_model[k]\n\n        if model.use_rel_pos_bias and \"rel_pos_bias.relative_position_bias_table\" in checkpoint_model:\n            print(\"Expand the shared relative position embedding to each transformer block. \")\n            num_layers = model.get_num_layers()\n            rel_pos_bias = checkpoint_model[\"rel_pos_bias.relative_position_bias_table\"]\n            for i in range(num_layers):\n                checkpoint_model[\"blocks.%d.attn.relative_position_bias_table\" % i] = rel_pos_bias.clone()\n\n            checkpoint_model.pop(\"rel_pos_bias.relative_position_bias_table\")\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (dst_patch_shape[1] * 2 - 1)\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\"Position interpolate for %s from %dx%d to %dx%d\" % (\n                        key, src_size, src_size, dst_size, dst_size))\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind='cubic')\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy)).contiguous().view(-1, 1).to(rel_pos_bias.device))\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if 'pos_embed' in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model['pos_embed']\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model['pos_embed'] = new_pos_embed\n\n        if not args.learn_layer_weights and args.target_layer != -1:\n            print(f\"model target layer is {args.target_layer}\")\n            model.blocks = model.blocks[:args.target_layer+1]\n\n        if args.remove_final_norm:\n            print(f\"removing final norm by replacing it with Identity\")\n            model.norm = None if model.norm is None else nn.Identity()\n            model.fc_norm = None if model.fc_norm is None else nn.Identity()\n\n        if args.linear_classifier:\n            frozen_params = (\n                set(n for n, _ in model.named_parameters())\n                & set(checkpoint_model.keys())\n            )\n            for n, p in model.named_parameters():\n                if n in frozen_params:\n                    p.requires_grad_(False)\n            param_names = [n for n, p in model.named_parameters() if p.requires_grad]\n            print(f\"Trainable weights: {param_names}\")\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n        # model.load_state_dict(checkpoint_model, strict=False)\n\n    model.to(device)\n\n    model_ema = None\n    if args.model_ema:\n        # Important to create EMA model after cuda(), DP wrapper, and AMP but before SyncBN and DDP wrapper\n        model_ema = ModelEma(\n            model,\n            decay=args.model_ema_decay,\n            device='cpu' if args.model_ema_force_cpu else '',\n            resume='')\n        print(\"Using EMA with decay = %.8f\" % args.model_ema_decay)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params:', n_parameters)\n\n    total_batch_size = args.batch_size * args.update_freq * utils.get_world_size()\n    num_training_steps_per_epoch = len(dataset_train) // total_batch_size\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Update frequent = %d\" % args.update_freq)\n    print(\"Number of training examples = %d\" % len(dataset_train))\n    print(\"Number of training training per epoch = %d\" % num_training_steps_per_epoch)\n\n    num_layers = model_without_ddp.get_num_layers()\n    if args.layer_decay < 1.0:\n        assigner = LayerDecayValueAssigner(list(args.layer_decay ** (num_layers + 1 - i) for i in range(num_layers + 2)))\n    else:\n        assigner = None\n\n    if assigner is not None:\n        print(\"Assigned values = %s\" % str(assigner.values))\n\n    skip_weight_decay_list = model.no_weight_decay()\n    if args.disable_weight_decay_on_rel_pos_bias:\n        for i in range(num_layers):\n            skip_weight_decay_list.add(\"blocks.%d.attn.relative_position_bias_table\" % i)\n\n    if args.enable_deepspeed:\n        loss_scaler = None\n        optimizer_params = get_parameter_groups(\n            model, args.weight_decay, skip_weight_decay_list,\n            assigner.get_layer_id if assigner is not None else None,\n            assigner.get_scale if assigner is not None else None)\n        model, optimizer, _, _ = ds_init(\n            args=args, model=model, model_parameters=optimizer_params, dist_init_required=not args.distributed,\n        )\n\n        print(\"model.gradient_accumulation_steps() = %d\" % model.gradient_accumulation_steps())\n        assert model.gradient_accumulation_steps() == args.update_freq\n    else:\n        if args.distributed:\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n            model_without_ddp = model.module\n\n        optimizer = create_optimizer(\n            args, model_without_ddp, skip_list=skip_weight_decay_list,\n            get_num_layer=assigner.get_layer_id if assigner is not None else None, \n            get_layer_scale=assigner.get_scale if assigner is not None else None)\n        loss_scaler = NativeScaler()\n\n    print(\"Use step level LR scheduler!\")\n    lr_schedule_values = utils.cosine_scheduler(\n        args.lr, args.min_lr, args.epochs, num_training_steps_per_epoch,\n        warmup_epochs=args.warmup_epochs, warmup_steps=args.warmup_steps,\n    )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay, args.weight_decay_end, args.epochs, num_training_steps_per_epoch)\n    print(\"Max WD = %.7f, Min WD = %.7f\" % (max(wd_schedule_values), min(wd_schedule_values)))\n\n    #if mixup_fn is not None:\n        # smoothing is handled with mixup label transform\n    #    criterion = SoftTargetCrossEntropy()\n    #elif args.smoothing > 0.:\n    #    criterion = LabelSmoothingCrossEntropy(smoothing=args.smoothing)\n    #else:\n    \n    criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    utils.auto_load_model(\n        args=args, model=model, model_without_ddp=model_without_ddp,\n        optimizer=optimizer, loss_scaler=loss_scaler, model_ema=model_ema)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device, metric='acc')\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch * args.update_freq)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train, optimizer,\n            device, epoch, loss_scaler, args.clip_grad, model_ema, mixup_fn,\n            log_writer=log_writer, start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values, wd_schedule_values=wd_schedule_values,\n            num_training_steps_per_epoch=num_training_steps_per_epoch, update_freq=args.update_freq,\n            masked_position_generator=masked_position_generator,\n            metric='acc'\n        )\n        if args.output_dir and args.save_ckpt:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                    loss_scaler=loss_scaler, epoch=epoch, model_ema=model_ema)\n        if data_loader_val is not None:\n            test_stats = evaluate(data_loader_val, model, device, 'acc')\n            print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            if max_accuracy < test_stats[\"acc1\"]:\n                max_accuracy = test_stats[\"acc1\"]\n                if args.output_dir and args.save_ckpt:\n                    utils.save_model(\n                        args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                        loss_scaler=loss_scaler, epoch=\"best\", model_ema=model_ema)\n\n            print(f'Max accuracy: {max_accuracy:.2f}%')\n            if log_writer is not None:\n                log_writer.update(test_acc1=test_stats['acc1'], head=\"perf\", step=epoch)\n                log_writer.update(test_acc5=test_stats['acc5'], head=\"perf\", step=epoch)\n                log_writer.update(test_loss=test_stats['loss'], head=\"perf\", step=epoch)\n\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n        else:\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         # **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    opts, ds_init = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts, ds_init)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_EU_dino.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#     http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport os\nimport argparse\nimport json\nfrom pathlib import Path\nimport numpy as np\n\nimport torch\nfrom torch import nn\nimport torch.distributed as dist\nimport torch.backends.cudnn as cudnn\nfrom torchvision import datasets\nfrom torchvision import transforms as pth_transforms\nfrom torchvision import models as torchvision_models\n\nfrom models.dino import utils\nfrom models.dino import vision_transformer as vits\n\nfrom cvtorchvision import cvtransforms\n### end of change ###\nimport pdb\n\nfrom torch.utils.tensorboard import SummaryWriter\nfrom sklearn.metrics import average_precision_score,accuracy_score\nimport builtins\n\nfrom datasets.EuroSat.eurosat_dataset import EurosatDataset,Subset\nfrom sklearn.model_selection import train_test_split\n\n\ndef eval_linear(args):\n    utils.init_distributed_mode(args)\n    if args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n    print(\"git:\\n  {}\\n\".format(utils.get_sha()))\n    print(\"\\n\".join(\"%s: %s\" % (k, str(v)) for k, v in sorted(dict(vars(args)).items())))\n    cudnn.benchmark = True\n\n    # ============ building network ... ============\n    # if the network is a Vision Transformer (i.e. vit_tiny, vit_small, vit_base)\n    if args.arch in vits.__dict__.keys():\n        model = vits.__dict__[args.arch](patch_size=args.patch_size, num_classes=0, in_chans=13)\n        embed_dim = model.embed_dim * (args.n_last_blocks + int(args.avgpool_patchtokens))\n    # otherwise, we check if the architecture is in torchvision models\n    elif args.arch in torchvision_models.__dict__.keys():\n        model = torchvision_models.__dict__[args.arch]()\n        embed_dim = model.fc.weight.shape[1]\n        model.conv1 = torch.nn.Conv2d(13, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n        model.fc = nn.Identity()\n        #model.fc = torch.nn.Linear(2048,19)\n    # if the network is a XCiT\n    elif \"xcit\" in args.arch:\n        model = torch.hub.load('facebookresearch/xcit:main', args.arch, num_classes=0)\n        embed_dim = model.embed_dim\n    else:\n        print(f\"Unknow architecture: {args.arch}\")\n        sys.exit(1)\n    model.cuda()\n    model.eval()\n    # load weights to evaluate\n    utils.load_pretrained_weights(model, args.pretrained, args.checkpoint_key, args.arch, args.patch_size)\n    print(f\"Model {args.arch} built.\")\n\n    linear_classifier = LinearClassifier(embed_dim, num_labels=10)\n    linear_classifier = linear_classifier.cuda()\n    linear_classifier = nn.parallel.DistributedDataParallel(linear_classifier, device_ids=[args.gpu])\n\n    # ============ preparing data ... ============\n\n    train_transforms = cvtransforms.Compose([\n        cvtransforms.RandomResizedCrop(224),\n        cvtransforms.RandomHorizontalFlip(),\n        cvtransforms.ToTensor(),\n        #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n    ])\n    #dataset_train = datasets.ImageFolder(os.path.join(args.data_path, \"train\"), transform=train_transform)\n\n    val_transforms = cvtransforms.Compose([\n        cvtransforms.Resize(256),\n        cvtransforms.CenterCrop(224),\n        cvtransforms.ToTensor(),\n        #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n    ])\n\n    eurosat_dataset = EurosatDataset(root=args.data_dir,normalize=args.normalize)\n\n    indices = np.arange(len(eurosat_dataset))\n    train_indices, test_indices = train_test_split(indices, train_size=0.8,stratify=eurosat_dataset.targets,random_state=args.seed)    \n  \n    dataset_train = Subset(eurosat_dataset, train_indices, train_transforms)\n    dataset_val = Subset(eurosat_dataset, test_indices, val_transforms)        \n\n    if args.train_frac is not None and args.train_frac<1:\n        frac_indices = np.arange(len(dataset_train))\n        sub_train_indices, sub_test_indices = train_test_split(frac_indices, train_size=args.train_frac, random_state=args.seed)\n        dataset_train = Subset(dataset_train,sub_train_indices)\n\n\n    sampler = torch.utils.data.distributed.DistributedSampler(dataset_train)\n    train_loader = torch.utils.data.DataLoader(\n        dataset_train,\n        sampler=sampler,\n        batch_size=args.batch_size_per_gpu,\n        num_workers=args.num_workers,\n        pin_memory=True,\n        drop_last=True\n    )\n    \n\n    #dataset_val = datasets.ImageFolder(os.path.join(args.data_path, \"val\"), transform=val_transform)\n    val_loader = torch.utils.data.DataLoader(\n        dataset_val,\n        batch_size=args.batch_size_per_gpu,\n        num_workers=args.num_workers,\n        pin_memory=True,\n        shuffle=False\n    )\n\n    if args.evaluate:\n        utils.load_pretrained_linear_weights(linear_classifier, args.arch, args.patch_size)\n        test_stats = validate_network(val_loader, model, linear_classifier, args.n_last_blocks, args.avgpool_patchtokens)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        return    \n    \n            \n    \n    print(f\"Data loaded with {len(dataset_train)} train and {len(dataset_val)} val imgs.\")\n\n    # set optimizer\n    optimizer = torch.optim.SGD(\n        linear_classifier.parameters(),\n        args.lr * (args.batch_size_per_gpu * utils.get_world_size()) / 256., # linear scaling rule\n        momentum=0.9,\n        weight_decay=0, # we do not apply weight decay\n    )\n    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, args.epochs, eta_min=0)\n\n    # Optionally resume from a checkpoint\n    to_restore = {\"epoch\": 0, \"best_acc\": 0.}\n    if args.resume:\n        utils.restart_from_checkpoint(\n            os.path.join(args.checkpoints_dir, \"checkpoint.pth.tar\"),\n            run_variables=to_restore,\n            state_dict=linear_classifier,\n            optimizer=optimizer,\n            scheduler=scheduler,\n        )\n    start_epoch = to_restore[\"epoch\"]\n    best_acc = to_restore[\"best_acc\"]\n\n    \n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\n        os.makedirs(args.checkpoints_dir,exist_ok=True)\n    \n    for epoch in range(start_epoch, args.epochs):\n        train_loader.sampler.set_epoch(epoch)\n\n        train_stats = train(model, linear_classifier, optimizer, train_loader, epoch, args.n_last_blocks, args.avgpool_patchtokens)\n        scheduler.step()\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                     'epoch': epoch}\n        if epoch % args.val_freq == 0 or epoch == args.epochs - 1:\n            test_stats = validate_network(val_loader, model, linear_classifier, args.n_last_blocks, args.avgpool_patchtokens)\n            print(f\"Accuracy at epoch {epoch} of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            best_acc = max(best_acc, test_stats[\"acc1\"])\n            print(f'Max accuracy so far: {best_acc:.2f}%')\n            log_stats = {**{k: v for k, v in log_stats.items()},\n                         **{f'test_{k}': v for k, v in test_stats.items()}}\n        if utils.is_main_process():\n            with (Path(args.checkpoints_dir) / \"log.txt\").open(\"a\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n            save_dict = {\n                \"epoch\": epoch + 1,\n                \"state_dict\": linear_classifier.state_dict(),\n                \"optimizer\": optimizer.state_dict(),\n                \"scheduler\": scheduler.state_dict(),\n                \"best_acc\": best_acc,\n            }\n            torch.save(save_dict, os.path.join(args.checkpoints_dir, \"checkpoint.pth.tar\"))\n    print(\"Training of the supervised linear classifier on frozen features completed.\\n\"\n                \"Top-1 test accuracy: {acc:.1f}\".format(acc=best_acc))\n\n\ndef train(model, linear_classifier, optimizer, loader, epoch, n, avgpool):\n    linear_classifier.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    for (inp, target) in metric_logger.log_every(loader, 20, header):\n        \n        # move to gpu\n        inp = inp.cuda(non_blocking=True)\n        target = target.cuda(non_blocking=True)\n\n        # forward\n        with torch.no_grad():\n            if \"vit\" in args.arch:\n                intermediate_output = model.get_intermediate_layers(inp, n)\n                output = torch.cat([x[:, 0] for x in intermediate_output], dim=-1)\n                if avgpool:\n                    output = torch.cat((output.unsqueeze(-1), torch.mean(intermediate_output[-1][:, 1:], dim=1).unsqueeze(-1)), dim=-1)\n                    output = output.reshape(output.shape[0], -1)\n            else:\n                output = model(inp)\n        output = linear_classifier(output)\n\n        # compute cross entropy loss\n        loss = nn.CrossEntropyLoss()(output, target.long())\n\n        # compute the gradients\n        optimizer.zero_grad()\n        loss.backward()\n\n        # step\n        optimizer.step()\n\n        # log \n        torch.cuda.synchronize()\n        metric_logger.update(loss=loss.item())\n        metric_logger.update(lr=optimizer.param_groups[0][\"lr\"])\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef validate_network(val_loader, model, linear_classifier, n, avgpool):\n    linear_classifier.eval()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n    for inp, target in metric_logger.log_every(val_loader, 20, header):\n       \n        # move to gpu\n        inp = inp.cuda(non_blocking=True)\n        target = target.cuda(non_blocking=True)\n\n        # forward\n        with torch.no_grad():\n            if \"vit\" in args.arch:\n                intermediate_output = model.get_intermediate_layers(inp, n)\n                output = torch.cat([x[:, 0] for x in intermediate_output], dim=-1)\n                if avgpool:\n                    output = torch.cat((output.unsqueeze(-1), torch.mean(intermediate_output[-1][:, 1:], dim=1).unsqueeze(-1)), dim=-1)\n                    output = output.reshape(output.shape[0], -1)\n            else:\n                output = model(inp)\n        output = linear_classifier(output)\n        loss = nn.CrossEntropyLoss()(output, target.long())\n\n        '''\n        if linear_classifier.module.num_labels >= 5:\n            acc1, acc5 = utils.accuracy(output, target, topk=(1, 5))\n        else:\n            acc1, = utils.accuracy(output, target, topk=(1,))\n        '''\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = accuracy_score(target.cpu(), torch.argmax(score,axis=1)) * 100.0\n        acc5 = acc1\n        \n        batch_size = inp.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        \n        if linear_classifier.module.num_labels >= 5:\n            metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n        \n    \n    if linear_classifier.module.num_labels >= 5:\n        print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n    else:\n        print('* Acc@1 {top1.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, losses=metric_logger.loss))\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\nclass LinearClassifier(nn.Module):\n    \"\"\"Linear layer to train on top of frozen features\"\"\"\n    def __init__(self, dim, num_labels=1000):\n        super(LinearClassifier, self).__init__()\n        self.num_labels = num_labels\n        self.linear = nn.Linear(dim, num_labels)\n        self.linear.weight.data.normal_(mean=0.0, std=0.01)\n        self.linear.bias.data.zero_()\n\n    def forward(self, x):\n        # flatten\n        x = x.view(x.size(0), -1)\n\n        # linear layer\n        return self.linear(x)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser('Evaluation with linear classification on BigEarthNet.')\n    parser.add_argument('--n_last_blocks', default=4, type=int, help=\"\"\"Concatenate [CLS] tokens\n        for the `n` last blocks. We use `n=4` when evaluating ViT-Small and `n=1` with ViT-Base.\"\"\")\n    parser.add_argument('--avgpool_patchtokens', default=False, type=utils.bool_flag,\n        help=\"\"\"Whether ot not to concatenate the global average pooled features to the [CLS] token.\n        We typically set this to False for ViT-Small and to True with ViT-Base.\"\"\")\n    parser.add_argument('--arch', default='vit_small', type=str, help='Architecture')\n    parser.add_argument('--patch_size', default=16, type=int, help='Patch resolution of the model.')\n    parser.add_argument('--pretrained', default='', type=str, help=\"Path to pretrained weights to evaluate.\")\n    parser.add_argument(\"--checkpoint_key\", default=\"teacher\", type=str, help='Key to use in the checkpoint (example: \"teacher\")')\n    parser.add_argument('--epochs', default=100, type=int, help='Number of epochs of training.')\n    parser.add_argument(\"--lr\", default=0.001, type=float, help=\"\"\"Learning rate at the beginning of\n        training (highest LR used during training). The learning rate is linearly scaled\n        with the batch size, and specified here for a reference batch size of 256.\n        We recommend tweaking the LR depending on the checkpoint evaluated.\"\"\")\n    parser.add_argument('--batch_size_per_gpu', default=128, type=int, help='Per-GPU batch-size')\n    parser.add_argument(\"--dist_url\", default=\"env://\", type=str, help=\"\"\"url used to set up\n        distributed training; see https://pytorch.org/docs/stable/distributed.html\"\"\")\n    parser.add_argument(\"--local_rank\", default=0, type=int, help=\"Please ignore and do not set this argument.\")\n    parser.add_argument('--data_path', default='/path/to/imagenet/', type=str)\n    parser.add_argument('--num_workers', default=10, type=int, help='Number of data loading workers per GPU.')\n    parser.add_argument('--val_freq', default=5, type=int, help=\"Epoch frequency for validation.\")\n    parser.add_argument('--checkpoints_dir', default=\".\", help='Path to save logs and checkpoints')\n    parser.add_argument('--num_labels', default=1000, type=int, help='Number of labels for linear classifier')\n    parser.add_argument('--evaluate', dest='evaluate', action='store_true', help='evaluate model on validation set')\n    \n    parser.add_argument('--data_dir', default='/path/to/imagenet/', type=str, help='Please specify path to the ImageNet folder.')\n    parser.add_argument('--bands', type=str, default='all', help=\"input bands\")\n    parser.add_argument(\"--lmdb\", action='store_true', help=\"use lmdb dataset\")\n    parser.add_argument(\"--is_slurm_job\", action='store_true', help=\"running in slurm\")\n    parser.add_argument(\"--resume\", action='store_true', help=\"resume from checkpoint\")\n    parser.add_argument(\"--train_frac\", default=1.0, type=float, help=\"use a subset of labeled data\")\n    parser.add_argument(\"--seed\",default=42,type=int)\n    parser.add_argument(\"--normalize\",action=\"store_true\",default=None)    \n    \n    args = parser.parse_args()\n\n\n    \n    eval_linear(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_EU_mae.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# MoCo v3: https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\n\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\n\nimport timm\n\n#assert timm.__version__ == \"0.3.2\" # version check\nfrom timm.models.layers import trunc_normal_\n\nimport models.mae.util.misc as misc\nfrom models.mae.util.pos_embed import interpolate_pos_embed\nfrom models.mae.util.misc import NativeScalerWithGradNormCount as NativeScaler\nfrom models.mae.util.lars import LARS\nfrom models.mae.util.crop import RandomResizedCrop\n\nimport models.mae.models_vit as models_vit\n\nfrom models.mae.engine_finetune_EU import train_one_epoch, evaluate\n\n\nfrom datasets.EuroSat.eurosat_dataset import EurosatDataset,Subset\nfrom sklearn.model_selection import train_test_split\nfrom cvtorchvision import cvtransforms\nfrom sklearn.metrics import average_precision_score\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE linear probing for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=512, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=90, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    # Optimizer parameters\n    parser.add_argument('--weight_decay', type=float, default=0,\n                        help='weight decay (default: 0 for linear probe following MoCo v1)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=0.1, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n\n    parser.add_argument('--min_lr', type=float, default=0., metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=10, metavar='N',\n                        help='epochs to warmup LR')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--global_pool', action='store_true')\n    parser.set_defaults(global_pool=False)\n    parser.add_argument('--cls_token', action='store_false', dest='global_pool',\n                        help='Use class token instead of global pool for classification')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--nb_classes', default=1000, type=int,\n                        help='number of the classification types')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation (recommended during training for faster monitor')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n    parser.add_argument('--dist_backend', default='nccl', type=str,\n                        help='distributed backend')\n    \n    parser.add_argument(\"--is_slurm_job\", action='store_true', help=\"slurm job\")\n    parser.add_argument(\"--train_frac\", default=1.0, type=float, help=\"use a subset of labeled data\")\n    \n    return parser\n\n\ndef main(args):\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n\n    \n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(224),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(224),\n            cvtransforms.ToTensor(),\n            ])\n\n\n    eurosat_dataset = EurosatDataset(root=args.data_path,normalize=False)\n\n    indices = np.arange(len(eurosat_dataset))\n    train_indices, test_indices = train_test_split(indices, train_size=0.8,stratify=eurosat_dataset.targets,random_state=args.seed)    \n  \n    dataset_train = Subset(eurosat_dataset, train_indices, train_transforms)\n    dataset_val = Subset(eurosat_dataset, test_indices, val_transforms)\n        \n        \n    if args.train_frac is not None and args.train_frac<1:\n        frac_indices = np.arange(len(dataset_train))\n        sub_train_indices, sub_test_indices = train_test_split(frac_indices, train_size=train_frac, random_state=args.seed)\n        dataset_train = Subset(dataset_train,sub_train_indices)\n\n\n    if True:  # args.distributed:\n        num_tasks = args.world_size\n        print(misc.get_world_size())\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=True)  # shuffle=True to reduce monitor bias\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None and not args.eval:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    data_loader_val = torch.utils.data.DataLoader(\n        dataset_val, sampler=sampler_val,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=False\n    )\n\n    model = models_vit.__dict__[args.model](\n        num_classes=args.nb_classes,\n        global_pool=args.global_pool,\n        in_chans=13\n    )\n\n    if args.finetune and not args.eval:\n        checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load pre-trained checkpoint from: %s\" % args.finetune)\n        checkpoint_model = checkpoint['model']\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        # interpolate position embedding\n        interpolate_pos_embed(model, checkpoint_model)\n\n        # load pre-trained model\n        msg = model.load_state_dict(checkpoint_model, strict=False)\n        print(msg)\n\n        if args.global_pool:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias', 'fc_norm.weight', 'fc_norm.bias'}\n        else:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias'}\n\n        # manually initialize fc layer: following MoCo v3\n        trunc_normal_(model.head.weight, std=0.01)\n\n    # for linear prob only\n    # hack: revise model's head with BN\n    model.head = torch.nn.Sequential(torch.nn.BatchNorm1d(model.head.in_features, affine=False, eps=1e-6), model.head)\n    # freeze all but the head\n    for _, p in model.named_parameters():\n        p.requires_grad = False\n    for _, p in model.head.named_parameters():\n        p.requires_grad = True\n\n    model.to(device)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params (M): %.2f' % (n_parameters / 1.e6))\n\n    eff_batch_size = args.batch_size * args.accum_iter * args.world_size\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        model_without_ddp = model.module\n\n    #optimizer = LARS(model_without_ddp.head.parameters(), lr=args.lr, weight_decay=args.weight_decay)\n    optimizer = torch.optim.SGD(model_without_ddp.head.parameters(), args.lr,\n                                momentum=0.9,\n                                weight_decay=0)\n    print(optimizer)\n    loss_scaler = NativeScaler()\n\n    criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device, criterion)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            max_norm=None,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir and (epoch%10==0 or epoch + 1 == args.epochs):\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        if epoch%5==0 or (epoch + 1 == args.epochs):\n            test_stats = evaluate(data_loader_val, model, device, criterion)\n            print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            \n            max_accuracy = max(max_accuracy, test_stats[\"acc1\"])\n            print(f'Max accuracy: {max_accuracy:.2f}%')\n\n        if log_writer is not None:\n            log_writer.add_scalar('perf/test_acc1', test_stats['acc1'], epoch)\n            log_writer.add_scalar('perf/test_acc5', test_stats['acc5'], epoch)\n            log_writer.add_scalar('perf/test_loss', test_stats['loss'], epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        **{f'test_{k}': v for k, v in test_stats.items()},\n                        'epoch': epoch,\n                        'n_parameters': n_parameters}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_EU_moco.py",
    "content": "\n\nimport torch\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import models\n\n## change01 ##\nfrom cvtorchvision import cvtransforms\nimport time\nimport os\nimport math\nimport pdb\nfrom sklearn.metrics import accuracy_score\nimport numpy as np\nimport argparse\nimport builtins\n\nfrom datasets.EuroSat.eurosat_dataset import EurosatDataset,Subset\nfrom sklearn.model_selection import train_test_split\n\nfrom torch.utils.tensorboard import SummaryWriter\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--data_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet')\nparser.add_argument('--checkpoints_dir', type=str, default='./checkpoints/resnet/')\nparser.add_argument('--resume', type=str, default='')\nparser.add_argument('--save_path', type=str, default='./checkpoints/bigearthnet_s2_B12_100_no_pretrain_resnet50.pt')\n\nparser.add_argument('--bands', type=str, default='B13', help='bands to process')  \nparser.add_argument('--train_frac', type=float, default=1.0)\nparser.add_argument('--backbone', type=str, default='resnet50')\nparser.add_argument('--batchsize', type=int, default=256)\nparser.add_argument('--epochs', type=int, default=100)\nparser.add_argument('--num_workers', type=int, default=8)\nparser.add_argument('--lr', type=float, default=0.05)\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by 10x)')\nparser.add_argument('--cos', action='store_true', help='use cosine lr schedule')\nparser.add_argument('--seed', type=int, default=42)\nparser.add_argument('--pretrained', default='', type=str, help='path to moco pretrained checkpoint')\n\n### distributed running ###\nparser.add_argument('--dist_url', default='env://', type=str)\nparser.add_argument(\"--world_size\", default=-1, type=int, help=\"\"\"\n                    number of processes: it is set automatically and\n                    should not be passed as argument\"\"\")\nparser.add_argument(\"--rank\", default=0, type=int, help=\"\"\"rank of this process:\n                    it is set automatically and should not be passed as argument\"\"\")\nparser.add_argument(\"--local_rank\", default=0, type=int,\n                    help=\"this argument is not used and should be ignored\")\n\nparser.add_argument('--normalize', action='store_true', default=False)\nparser.add_argument('--subset', type=str, default=None)\nparser.add_argument('--in_size',type=int,default=56)\n\ndef init_distributed_mode(args):\n\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n    else:\n        # multi-GPU job (local or multi-node) - jobs started with torch.distributed.launch\n        # read environment variables\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n\n    # prepare distributed\n    torch.distributed.init_process_group(\n        backend=\"nccl\",\n        init_method=args.dist_url,\n        world_size=args.world_size,\n        rank=args.rank,\n    )\n\n    # set cuda device\n    args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n    torch.cuda.set_device(args.gpu_to_work_on)\n    return    \n\ndef fix_random_seeds(seed=42):\n    \"\"\"\n    Fix random seeds.\n    \"\"\"\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    np.random.seed(seed)\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    if args.cos:  # cosine lr schedule\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\n    else:  # stepwise lr schedule\n        for milestone in args.schedule:\n            lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef main():\n\n    global args\n    args = parser.parse_args()\n    ### dist ###\n    init_distributed_mode(args)\n    if args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n    \n    fix_random_seeds(args.seed)\n    \n\n    data_dir = args.data_dir\n    checkpoints_dir = args.checkpoints_dir\n    save_path = args.save_path\n    batch_size = args.batchsize\n\n    num_workers = args.num_workers\n    epochs = args.epochs\n    train_frac = args.train_frac\n    seed = args.seed\n\n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\n        os.mkdir(args.checkpoints_dir)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints_dir,'log'))\n\n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(224),\n            #cvtransforms.Resize(args.in_size),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(224),\n            cvtransforms.ToTensor(),\n            ])\n\n\n    eurosat_dataset = EurosatDataset(root=args.data_dir,bands=args.bands,normalize=args.normalize)\n\n    indices = np.arange(len(eurosat_dataset))\n    train_indices, test_indices = train_test_split(indices, train_size=0.8,stratify=eurosat_dataset.targets,random_state=args.seed)    \n  \n    train_dataset = Subset(eurosat_dataset, train_indices, train_transforms)\n    val_dataset = Subset(eurosat_dataset, test_indices, val_transforms)\n        \n        \n    if train_frac is not None and train_frac<1:\n        frac_indices = np.arange(len(train_dataset))\n        sub_train_indices, sub_test_indices = train_test_split(frac_indices, train_size=train_frac, random_state=args.seed)\n        train_dataset = Subset(train_dataset,sub_train_indices)    \n    ### dist ###    \n    sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)    \n        \n    train_loader = DataLoader(train_dataset,\n                              batch_size=batch_size,\n                              sampler = sampler,\n                              #shuffle=True,\n                              num_workers=num_workers,\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\n                              drop_last=True\n                              \n                              )\n                              \n    val_loader = DataLoader(val_dataset,\n                              batch_size=batch_size,\n                              shuffle=False,\n                              num_workers=num_workers,\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\n                              drop_last=True\n                              \n                              )\n    \n    print('train_len: %d val_len: %d' % (len(train_dataset),len(val_dataset)))\n\n    ## change 04 ##\n    if args.backbone == 'resnet50':\n        net = models.resnet50(pretrained=False)\n        net.fc = torch.nn.Linear(2048,10)\n    elif args.backbone == 'resnet18':\n        net = models.resnet18(pretrained=False)\n        net.fc = torch.nn.Linear(512,10)\n    if args.bands=='B13':    \n        net.conv1 = torch.nn.Conv2d(13, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n    elif args.bands=='B12':\n        net.conv1 = torch.nn.Conv2d(12, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n\n    \n    for name, param in net.named_parameters():\n        if name not in ['fc.weight','fc.bias']:\n            param.requires_grad = False\n    \n\n    net.fc.weight.data.normal_(mean=0.0,std=0.01)\n    net.fc.bias.data.zero_()\n\n\n    # load from pre-trained, before DistributedDataParallel constructor\n    if args.pretrained:\n        if os.path.isfile(args.pretrained):\n            print(\"=> loading checkpoint '{}'\".format(args.pretrained))\n            checkpoint = torch.load(args.pretrained, map_location=\"cpu\")\n\n            # rename moco pre-trained keys\n            state_dict = checkpoint['state_dict']\n            \n            for k in list(state_dict.keys()):\n                # retain only encoder up to before the embedding layer\n                if k.startswith('module.encoder_q') and not k.startswith('module.encoder_q.fc'):\n                    #pdb.set_trace()\n                    # remove prefix\n                    state_dict[k[len(\"module.encoder_q.\"):]] = state_dict[k]\n                # delete renamed or unused k\n                del state_dict[k]\n            '''\n            # remove prefix\n            state_dict = {k.replace(\"module.\", \"\"): v for k,v in state_dict.items()}\n            '''\n            #args.start_epoch = 0\n            msg = net.load_state_dict(state_dict, strict=False)\n            #pdb.set_trace()\n            assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\n\n            print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.pretrained))\n\n    # convert batch norm layers (if any)\n    if args.is_slurm_job:\n        net = torch.nn.SyncBatchNorm.convert_sync_batchnorm(net)\n\n\n    criterion = torch.nn.CrossEntropyLoss()\n    optimizer = torch.optim.SGD(net.parameters(), lr=args.lr, momentum=0.9)\n\n\n    last_epoch = 0\n    if args.resume:\n        checkpoint = torch.load(args.resume)\n        net.load_state_dict(checkpoint['model_state_dict'])\n        optimzier.load_state_dict(checkpoint['optimizer_state_dict'])\n        last_epoch = checkpoint['epoch']\n        last_loss = checkpoint['loss']\n\n    #device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    #net.to(device)\n    net.cuda()\n    \n    #### nccl doesn't support wsl\n    if args.is_slurm_job:\n        net = torch.nn.parallel.DistributedDataParallel(net,device_ids=[args.gpu_to_work_on],find_unused_parameters=True)\n\n    print('Start training...')\n    for epoch in range(last_epoch,epochs):\n\n        net.train()\n        adjust_learning_rate(optimizer, epoch, args)\n        \n        train_loader.sampler.set_epoch(epoch)\n        running_loss = 0.0\n        running_acc = 0.0\n        \n        running_loss_epoch = 0.0\n        running_acc_epoch = 0.0\n        \n        start_time = time.time()\n        end = time.time()\n        sum_bt = 0.0\n        sum_dt = 0.0\n        sum_tt = 0.0\n        sum_st = 0.0\n        for i, data in enumerate(train_loader, 0):\n            data_time = time.time()-end\n            #inputs, labels = data\n            inputs, labels = data[0].cuda(), data[1].cuda()\n\n            # zero the parameter gradients\n            optimizer.zero_grad()\n\n            # forward + backward + optimize\n            outputs = net(inputs)\n            #pdb.set_trace()\n            loss = criterion(outputs, labels.long())\n            loss.backward()\n            optimizer.step()\n            train_time = time.time()-end-data_time\n            \n            if epoch%5==4:\n                score = torch.sigmoid(outputs).detach().cpu()            \n                average_precision = accuracy_score(labels.cpu(), torch.argmax(score,axis=1)) * 100.0\n            else:\n                average_precision = 0\n\n            score_time = time.time()-end-data_time-train_time\n            \n            # print statistics\n            running_loss += loss.item()\n            running_acc += average_precision\n            batch_time = time.time() - end\n            end = time.time()        \n            sum_bt += batch_time\n            sum_dt += data_time\n            sum_tt += train_time\n            sum_st += score_time\n            \n            if i % 20 == 19:    # print every 20 mini-batches\n\n                print('[%d, %5d] loss: %.3f acc: %.3f batch_time: %.3f data_time: %.3f train_time: %.3f score_time: %.3f' %\n                      (epoch + 1, i + 1, running_loss / 20, running_acc / 20, sum_bt/20, sum_dt/20, sum_tt/20, sum_st/20))\n                \n                #train_iter =  i*args.batch_size / len(train_dataset)\n                #tb_writer.add_scalar('train_loss', running_loss/20, global_step=(epoch+1+train_iter) )\n                running_loss_epoch = running_loss/20\n                running_acc_epoch = running_acc/20\n                \n                running_loss = 0.0\n                running_acc = 0.0\n                sum_bt = 0.0\n                sum_dt = 0.0\n                sum_tt = 0.0\n                sum_st = 0.0\n\n        if epoch%5==4:\n            running_loss_val = 0.0\n            running_acc_val = 0.0\n            count_val = 0\n            net.eval()\n            with torch.no_grad():\n                for j, data_val in enumerate(val_loader, 0):\n\n                    inputs_val, labels_val = data_val[0].cuda(), data_val[1].cuda()\n                    outputs_val = net(inputs_val)\n                    loss_val = criterion(outputs_val, labels_val.long())\n                    score_val = torch.sigmoid(outputs_val).detach().cpu()\n                    average_precision_val = accuracy_score(labels_val.cpu(), torch.argmax(score_val,axis=1)) * 100.0   \n\n                    count_val += 1\n                    running_loss_val += loss_val.item()\n                    running_acc_val += average_precision_val        \n\n            print('Epoch %d val_loss: %.3f val_acc: %.3f time: %s seconds.' % (epoch+1, running_loss_val/count_val, running_acc_val/count_val, time.time()-start_time))\n\n            if args.rank == 0:\n                losses = {'train': running_loss_epoch,\n                          'val': running_loss_val/count_val}\n                accs = {'train': running_acc_epoch,\n                        'val': running_acc_val/count_val}        \n                tb_writer.add_scalars('loss', losses, global_step=epoch+1, walltime=None)\n                tb_writer.add_scalars('acc', accs, global_step=epoch+1, walltime=None)\n        \n            \n            \n        if args.rank==0 and epoch % 10 == 9:\n            torch.save({\n                        'epoch': epoch,\n                        'model_state_dict': net.state_dict(),\n                        'optimizer_state_dict':optimizer.state_dict(),\n                        'loss':loss,\n                        }, os.path.join(checkpoints_dir,'checkpoint_{:04d}.pth.tar'.format(epoch)))\n        \n    #if args.rank==0:\n    #    torch.save(net.state_dict(), save_path)\n        \n    print('Training finished.')\n\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_EU_moco_v3.py",
    "content": "\n\nimport torch\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import models\n\n## change01 ##\nfrom cvtorchvision import cvtransforms\nimport time\nimport os\nimport math\nimport pdb\nfrom sklearn.metrics import accuracy_score\nimport numpy as np\nimport argparse\nimport builtins\n\nfrom datasets.EuroSat.eurosat_dataset import EurosatDataset,Subset\nfrom sklearn.model_selection import train_test_split\n\nfrom torch.utils.tensorboard import SummaryWriter\nfrom models.moco_v3 import vits\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--data_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet')\nparser.add_argument('--checkpoints_dir', type=str, default='./checkpoints/resnet/')\nparser.add_argument('--resume', type=str, default='')\n#parser.add_argument('--save_path', type=str, default='./checkpoints/bigearthnet_s2_B12_100_no_pretrain_resnet50.pt')\n\nparser.add_argument('--bands', type=str, default='B13', help='bands to process')  \nparser.add_argument('--train_frac', type=float, default=1.0)\nparser.add_argument('--backbone', type=str, default='resnet50')\nparser.add_argument('--batchsize', type=int, default=256)\nparser.add_argument('--epochs', type=int, default=100)\nparser.add_argument('--num_workers', type=int, default=8)\nparser.add_argument('--lr', type=float, default=0.05)\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by 10x)')\nparser.add_argument('--cos', action='store_true', help='use cosine lr schedule')\nparser.add_argument('--seed', type=int, default=42)\nparser.add_argument('--pretrained', default='', type=str, help='path to moco pretrained checkpoint')\n\n### distributed running ###\nparser.add_argument('--dist_url', default='env://', type=str)\nparser.add_argument(\"--world_size\", default=-1, type=int, help=\"\"\"\n                    number of processes: it is set automatically and\n                    should not be passed as argument\"\"\")\nparser.add_argument(\"--rank\", default=0, type=int, help=\"\"\"rank of this process:\n                    it is set automatically and should not be passed as argument\"\"\")\nparser.add_argument(\"--local_rank\", default=0, type=int,\n                    help=\"this argument is not used and should be ignored\")\n\nparser.add_argument('--normalize', action='store_true', default=False)\nparser.add_argument('--subset', type=str, default=None)\nparser.add_argument('--in_size',type=int,default=56)\n\nparser.add_argument('--linear', action='store_true', default=False)\n\ndef init_distributed_mode(args):\n\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n    else:\n        # multi-GPU job (local or multi-node) - jobs started with torch.distributed.launch\n        # read environment variables\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n\n    # prepare distributed\n    torch.distributed.init_process_group(\n        backend=\"nccl\",\n        init_method=args.dist_url,\n        world_size=args.world_size,\n        rank=args.rank,\n    )\n\n    # set cuda device\n    args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n    torch.cuda.set_device(args.gpu_to_work_on)\n    return    \n\ndef fix_random_seeds(seed=42):\n    \"\"\"\n    Fix random seeds.\n    \"\"\"\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    np.random.seed(seed)\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    if args.cos:  # cosine lr schedule\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\n    else:  # stepwise lr schedule\n        for milestone in args.schedule:\n            lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef main():\n\n    global args\n    args = parser.parse_args()\n    ### dist ###\n    init_distributed_mode(args)\n    if args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n    \n    fix_random_seeds(args.seed)\n    \n\n    data_dir = args.data_dir\n    checkpoints_dir = args.checkpoints_dir\n    #save_path = args.save_path\n    batch_size = args.batchsize\n\n    num_workers = args.num_workers\n    epochs = args.epochs\n    train_frac = args.train_frac\n    seed = args.seed\n\n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\n        os.makedirs(args.checkpoints_dir,exist_ok=True)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints_dir,'log'))\n\n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.in_size),\n            #cvtransforms.Resize(args.in_size),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(args.in_size),\n            cvtransforms.ToTensor(),\n            ])\n\n\n    eurosat_dataset = EurosatDataset(root=args.data_dir,normalize=args.normalize)\n\n    indices = np.arange(len(eurosat_dataset))\n    train_indices, test_indices = train_test_split(indices, train_size=0.8,stratify=eurosat_dataset.targets,random_state=args.seed)    \n  \n    train_dataset = Subset(eurosat_dataset, train_indices, train_transforms)\n    val_dataset = Subset(eurosat_dataset, test_indices, val_transforms)\n        \n        \n    if train_frac is not None and train_frac<1:\n        frac_indices = np.arange(len(train_dataset))\n        sub_train_indices, sub_test_indices = train_test_split(frac_indices, train_size=train_frac, random_state=args.seed)\n        train_dataset = Subset(train_dataset,sub_train_indices)    \n    ### dist ###    \n    sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)    \n        \n    train_loader = DataLoader(train_dataset,\n                              batch_size=batch_size,\n                              sampler = sampler,\n                              #shuffle=True,\n                              num_workers=num_workers,\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\n                              drop_last=True\n                              \n                              )\n                              \n    val_loader = DataLoader(val_dataset,\n                              batch_size=batch_size,\n                              shuffle=False,\n                              num_workers=num_workers,\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\n                              drop_last=True\n                              \n                              )\n    \n    print('train_len: %d val_len: %d' % (len(train_dataset),len(val_dataset)))\n\n    ###########################################################################\n    \n    net = vits.__dict__[args.backbone](in_chans=13, num_classes=10)\n    linear_keyword = 'head'\n\n    if args.linear:\n        # freeze all layers but the last fc\n        for name, param in net.named_parameters():\n            if name not in ['%s.weight' % linear_keyword, '%s.bias' % linear_keyword]:\n                param.requires_grad = False\n        # init the fc layer\n    getattr(net, linear_keyword).weight.data.normal_(mean=0.0, std=0.01)\n    getattr(net, linear_keyword).bias.data.zero_()\n\n    # load from pre-trained, before DistributedDataParallel constructor\n    if args.pretrained:\n        if os.path.isfile(args.pretrained):\n            print(\"=> loading checkpoint '{}'\".format(args.pretrained))\n            checkpoint = torch.load(args.pretrained, map_location=\"cpu\")\n\n            # rename moco pre-trained keys\n            state_dict = checkpoint['state_dict']\n            for k in list(state_dict.keys()):\n                # retain only base_encoder up to before the embedding layer\n                if k.startswith('module.base_encoder') and not k.startswith('module.base_encoder.%s' % linear_keyword):\n                    # remove prefix\n                    state_dict[k[len(\"module.base_encoder.\"):]] = state_dict[k]\n                # delete renamed or unused k\n                del state_dict[k]\n\n            args.start_epoch = 0\n            msg = net.load_state_dict(state_dict, strict=False)\n            assert set(msg.missing_keys) == {\"%s.weight\" % linear_keyword, \"%s.bias\" % linear_keyword}\n\n            print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.pretrained))\n\n    \n    parameters = list(filter(lambda p: p.requires_grad, net.parameters()))\n    if args.linear:\n        assert len(parameters) == 2  # weight, bias\n\n    #########################################################################\n\n\n    criterion = torch.nn.CrossEntropyLoss()\n    optimizer = torch.optim.SGD(parameters, lr=args.lr, momentum=0.9)\n\n\n    last_epoch = 0\n    if args.resume:\n        checkpoint = torch.load(args.resume)\n        net.load_state_dict(checkpoint['model_state_dict'])\n        optimzier.load_state_dict(checkpoint['optimizer_state_dict'])\n        last_epoch = checkpoint['epoch']\n        last_loss = checkpoint['loss']\n\n    #device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    #net.to(device)\n    net.cuda()\n    \n    #### nccl doesn't support wsl\n    if args.is_slurm_job:\n        net = torch.nn.parallel.DistributedDataParallel(net,device_ids=[args.gpu_to_work_on],find_unused_parameters=True)\n\n    print('Start training...')\n    for epoch in range(last_epoch,epochs):\n\n        net.train()\n        adjust_learning_rate(optimizer, epoch, args)\n        \n        train_loader.sampler.set_epoch(epoch)\n        running_loss = 0.0\n        running_acc = 0.0\n        \n        running_loss_epoch = 0.0\n        running_acc_epoch = 0.0\n        \n        start_time = time.time()\n        end = time.time()\n        sum_bt = 0.0\n        sum_dt = 0.0\n        sum_tt = 0.0\n        sum_st = 0.0\n        for i, data in enumerate(train_loader, 0):\n            data_time = time.time()-end\n            #inputs, labels = data\n            inputs, labels = data[0].cuda(), data[1].cuda()\n\n            # zero the parameter gradients\n            optimizer.zero_grad()\n\n            # forward + backward + optimize\n            outputs = net(inputs)\n            #pdb.set_trace()\n            loss = criterion(outputs, labels.long())\n            loss.backward()\n            optimizer.step()\n            train_time = time.time()-end-data_time\n            \n            if epoch%5==4:\n                score = torch.sigmoid(outputs).detach().cpu()            \n                average_precision = accuracy_score(labels.cpu(), torch.argmax(score,axis=1)) * 100.0\n            else:\n                average_precision = 0\n\n            score_time = time.time()-end-data_time-train_time\n            \n            # print statistics\n            running_loss += loss.item()\n            running_acc += average_precision\n            batch_time = time.time() - end\n            end = time.time()        \n            sum_bt += batch_time\n            sum_dt += data_time\n            sum_tt += train_time\n            sum_st += score_time\n            \n            if i % 20 == 19:    # print every 20 mini-batches\n\n                print('[%d, %5d] loss: %.3f acc: %.3f batch_time: %.3f data_time: %.3f train_time: %.3f score_time: %.3f' %\n                      (epoch + 1, i + 1, running_loss / 20, running_acc / 20, sum_bt/20, sum_dt/20, sum_tt/20, sum_st/20))\n                \n                #train_iter =  i*args.batch_size / len(train_dataset)\n                #tb_writer.add_scalar('train_loss', running_loss/20, global_step=(epoch+1+train_iter) )\n                running_loss_epoch = running_loss/20\n                running_acc_epoch = running_acc/20\n                \n                running_loss = 0.0\n                running_acc = 0.0\n                sum_bt = 0.0\n                sum_dt = 0.0\n                sum_tt = 0.0\n                sum_st = 0.0\n\n        if epoch%5==4:\n            running_loss_val = 0.0\n            running_acc_val = 0.0\n            count_val = 0\n            net.eval()\n            with torch.no_grad():\n                for j, data_val in enumerate(val_loader, 0):\n\n                    inputs_val, labels_val = data_val[0].cuda(), data_val[1].cuda()\n                    outputs_val = net(inputs_val)\n                    loss_val = criterion(outputs_val, labels_val.long())\n                    score_val = torch.sigmoid(outputs_val).detach().cpu()\n                    average_precision_val = accuracy_score(labels_val.cpu(), torch.argmax(score_val,axis=1)) * 100.0   \n\n                    count_val += 1\n                    running_loss_val += loss_val.item()\n                    running_acc_val += average_precision_val        \n\n            print('Epoch %d val_loss: %.3f val_acc: %.3f time: %s seconds.' % (epoch+1, running_loss_val/count_val, running_acc_val/count_val, time.time()-start_time))\n\n            if args.rank == 0:\n                losses = {'train': running_loss_epoch,\n                          'val': running_loss_val/count_val}\n                accs = {'train': running_acc_epoch,\n                        'val': running_acc_val/count_val}        \n                tb_writer.add_scalars('loss', losses, global_step=epoch+1, walltime=None)\n                tb_writer.add_scalars('acc', accs, global_step=epoch+1, walltime=None)\n        \n            \n            \n        if args.rank==0 and epoch % 10 == 9:\n            torch.save({\n                        'epoch': epoch,\n                        'model_state_dict': net.state_dict(),\n                        'optimizer_state_dict':optimizer.state_dict(),\n                        'loss':loss,\n                        }, os.path.join(checkpoints_dir,'checkpoint_{:04d}.pth.tar'.format(epoch)))\n        \n    #if args.rank==0:\n    #    torch.save(net.state_dict(), save_path)\n        \n    print('Training finished.')\n\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_SS_data2vec.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.nn as nn\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.data.mixup import Mixup\nfrom timm.models import create_model\nfrom timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy\nfrom timm.utils import ModelEma\nfrom models.data2vec.optim_factory import create_optimizer, get_parameter_groups, LayerDecayValueAssigner\n\nfrom models.data2vec.engine_for_finetuning import train_one_epoch, evaluate\nfrom models.data2vec.utils import NativeScalerWithGradNormCount as NativeScaler\nimport models.data2vec.utils as utils\nfrom scipy import interpolate\nimport models.data2vec.modeling_finetune as modeling_finetune\nfrom sklearn.metrics import average_precision_score\nfrom datasets.So2Sat.so2sat_lcz42_dataset import So2SatDataset\nfrom datasets.So2Sat.so2sat_lcz42_dataset import random_subset \n\nfrom cvtorchvision import cvtransforms\n\ndef build_dataset_ss(is_train, args):  \n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.in_size),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(args.in_size),\n            cvtransforms.ToTensor(),           \n            ])\n\n\n    train_dataset = So2SatDataset(\n        path=os.path.join(args.data_path, 'training.h5'),\n        transform=train_transforms,\n        bands=args.bands,\n        normalize=False\n    )\n    \n    val_dataset = So2SatDataset(\n        path=os.path.join(args.data_path, 'validation.h5'),\n        transform=val_transforms,\n        bands=args.bands,\n        normalize=False\n    )    \n  \n    if args.train_frac is not None and args.train_frac<1:\n        train_dataset = random_subset(train_dataset, args.train_frac, args.seed)    \n        \n    return train_dataset, val_dataset, 17\n\n\ndef get_args():\n    parser = argparse.ArgumentParser('BEiT fine-tuning and evaluation script for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int)\n    parser.add_argument('--epochs', default=30, type=int)\n    parser.add_argument('--update_freq', default=1, type=int)\n    parser.add_argument('--save_ckpt_freq', default=5, type=int)\n\n    # Model parameters\n    parser.add_argument('--model', default='deit_base_patch16_224', type=str, metavar='MODEL',\n                        help='Name of model to train')\n    parser.add_argument('--rel_pos_bias', action='store_true')\n    parser.add_argument('--disable_rel_pos_bias', action='store_false', dest='rel_pos_bias')\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument('--abs_pos_emb', action='store_true')\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument('--layer_scale_init_value', default=0.1, type=float, \n                        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\")\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--drop', type=float, default=0.0, metavar='PCT',\n                        help='Dropout rate (default: 0.)')\n    parser.add_argument('--attn_drop_rate', type=float, default=0.0, metavar='PCT',\n                        help='Attention dropout rate (default: 0.)')\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    parser.add_argument('--disable_eval_during_finetuning', action='store_true', default=False)\n\n    parser.add_argument('--model_ema', action='store_true', default=False)\n    parser.add_argument('--model_ema_decay', type=float, default=0.9999, help='')\n    parser.add_argument('--model_ema_force_cpu', action='store_true', default=False, help='')\n\n    # Optimizer parameters\n    parser.add_argument('--opt', default='sgd', type=str, metavar='OPTIMIZER',\n                        help='Optimizer (default: \"adamw\"')\n    parser.add_argument('--opt_eps', default=1e-8, type=float, metavar='EPSILON',\n                        help='Optimizer Epsilon (default: 1e-8)')\n    parser.add_argument('--opt_betas', default=None, type=float, nargs='+', metavar='BETA',\n                        help='Optimizer Betas (default: None, use opt default)')\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',\n                        help='SGD momentum (default: 0.9)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n    parser.add_argument('--weight_decay_end', type=float, default=None, help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD and using a larger decay by\n        the end of training improves performance for ViTs.\"\"\")\n\n    parser.add_argument('--lr', type=float, default=5e-4, metavar='LR',\n                        help='learning rate (default: 5e-4)')\n    parser.add_argument('--layer_decay', type=float, default=0.9)\n\n    parser.add_argument('--warmup_lr', type=float, default=1e-6, metavar='LR',\n                        help='warmup learning rate (default: 1e-6)')\n    parser.add_argument('--min_lr', type=float, default=1e-6, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0 (1e-5)')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n    parser.add_argument('--warmup_steps', type=int, default=-1, metavar='N',\n                        help='num of steps to warmup LR, will overload warmup_epochs if set > 0')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=0.4, metavar='PCT',\n                        help='Color jitter factor (default: 0.4)')\n    parser.add_argument('--aa', type=str, default='rand-m9-mstd0.5-inc1', metavar='NAME',\n                        help='Use AutoAugment policy. \"v0\" or \"original\". \" + \"(default: rand-m9-mstd0.5-inc1)'),\n    parser.add_argument('--smoothing', type=float, default=0.1,\n                        help='Label smoothing (default: 0.1)')\n    parser.add_argument('--train_interpolation', type=str, default='bicubic',\n                        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")')\n\n    # Evaluation parameters\n    parser.add_argument('--crop_pct', type=float, default=None)\n\n    # * Random Erase params\n    parser.add_argument('--reprob', type=float, default=0.25, metavar='PCT',\n                        help='Random erase prob (default: 0.25)')\n    parser.add_argument('--remode', type=str, default='pixel',\n                        help='Random erase mode (default: \"pixel\")')\n    parser.add_argument('--recount', type=int, default=1,\n                        help='Random erase count (default: 1)')\n    parser.add_argument('--resplit', action='store_true', default=False,\n                        help='Do not random erase first (clean) augmentation split')\n\n    # * Mixup params\n    parser.add_argument('--mixup', type=float, default=0,\n                        help='mixup alpha, mixup enabled if > 0.')\n    parser.add_argument('--cutmix', type=float, default=0,\n                        help='cutmix alpha, cutmix enabled if > 0.')\n    parser.add_argument('--cutmix_minmax', type=float, nargs='+', default=None,\n                        help='cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None)')\n    parser.add_argument('--mixup_prob', type=float, default=1.0,\n                        help='Probability of performing mixup or cutmix when either/both is enabled')\n    parser.add_argument('--mixup_switch_prob', type=float, default=0.5,\n                        help='Probability of switching to cutmix when both mixup and cutmix enabled')\n    parser.add_argument('--mixup_mode', type=str, default='batch',\n                        help='How to apply mixup/cutmix params. Per \"batch\", \"pair\", or \"elem\"')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--model_key', default='model|module', type=str)\n    parser.add_argument('--model_prefix', default='', type=str)\n    parser.add_argument('--init_scale', default=0.001, type=float)\n    parser.add_argument('--use_mean_pooling', action='store_true')\n    parser.set_defaults(use_mean_pooling=True)\n    parser.add_argument('--use_cls', action='store_false', dest='use_mean_pooling')\n    parser.add_argument('--disable_weight_decay_on_rel_pos_bias', action='store_true', default=False)\n    parser.add_argument('--target_layer', default=-1, type=int, help=\"target output layer (0-based)\")\n    parser.add_argument('--remove_final_norm', action='store_true', dest='remove_final_norm')\n    parser.add_argument('--reinit_final_norm', action='store_true', dest='reinit_final_norm')\n    parser.add_argument('--learn_layer_weights', action='store_true', dest='learn_layer_weights')  # supersede `target_layer`\n    parser.add_argument('--layernorm_before_combine', action='store_true', dest='layernorm_before_combine')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--eval_data_path', default=None, type=str,\n                        help='dataset path for evaluation')\n    parser.add_argument('--nb_classes', default=0, type=int,\n                        help='number of the classification types')\n    parser.add_argument('--linear_classifier', action='store_true',\n                        help='linear classifier')\n    parser.add_argument('--imagenet_default_mean_and_std', default=False, action='store_true')\n\n    parser.add_argument('--data_set', default='IMNET', choices=['CIFAR', 'IMNET', 'image_folder'],\n                        type=str, help='ImageNet dataset path')\n    parser.add_argument('--data_set_filter_file', type=str, default=None, help=\"path to filter to filter dataset\")\n    parser.add_argument('--output_dir', default='',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default=None,\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=42, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n    parser.add_argument('--auto_resume', action='store_true')\n    parser.add_argument('--no_auto_resume', action='store_false', dest='auto_resume')\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument('--save_ckpt', action='store_true')\n    parser.add_argument('--no_save_ckpt', action='store_false', dest='save_ckpt')\n    parser.set_defaults(save_ckpt=True)\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    parser.add_argument('--enable_deepspeed', action='store_true', default=False)\n    parser.add_argument('--bands', default='all',\n                        help='which bands to use')\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=0,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n    \n    parser.add_argument('--train_frac', type=float, default=0.1,\n                        help='Training set size')\n    parser.add_argument('--in_size', type=int, default=224,\n                        help='Training set size')\n    \n    parser.add_argument('--onehot', action='store_true', default=False)\n    \n    known_args, _ = parser.parse_known_args()\n\n    if known_args.enable_deepspeed:\n        try:\n            print(\"why\")\n            import deepspeed\n            print(\"Imported deepspeed\")\n            from deepspeed import DeepSpeedConfig\n            print(\"Imported config\")\n            parser = deepspeed.add_config_arguments(parser)\n            print(\"Created parser\")\n            ds_init = deepspeed.initialize\n            print(\"Inited deepspeed\")\n        except:\n            print(\"Please 'pip install deepspeed==0.4.0'\")\n            exit(0)\n    else:\n        ds_init = None\n\n    return parser.parse_args(), ds_init\n\n\ndef main(args, ds_init):\n    utils.init_distributed_mode(args)\n\n    if ds_init is not None:\n        utils.create_ds_config(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    dataset_train, dataset_val, args.nb_classes = build_dataset_ss(is_train=True, args=args)\n    #if args.disable_eval_during_finetuning:\n    #    dataset_val = None\n    #else:\n    #    dataset_val, _ = build_dataset(is_train=False, args=args)\n        \n        \n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=False)\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    if dataset_val is not None:\n        data_loader_val = torch.utils.data.DataLoader(\n            dataset_val, sampler=sampler_val,\n            batch_size=int(1.5 * args.batch_size),\n            num_workers=args.num_workers,\n            pin_memory=args.pin_mem,\n            drop_last=False\n        )\n    else:\n        data_loader_val = None\n\n    mixup_fn = None\n    mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None\n    if mixup_active:\n        print(\"Mixup is activated!\")\n        mixup_fn = Mixup(\n            mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax,\n            prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode,\n            label_smoothing=args.smoothing, num_classes=args.nb_classes)\n\n    model = create_model(\n        args.model,\n        pretrained=False,\n        num_classes=args.nb_classes,\n        drop_rate=args.drop,\n        drop_path_rate=args.drop_path,\n        attn_drop_rate=args.attn_drop_rate,\n        drop_block_rate=None,\n        use_mean_pooling=args.use_mean_pooling,\n        init_scale=args.init_scale,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        linear_classifier=args.linear_classifier,\n        has_masking=args.num_mask_patches > 0,\n        learn_layer_weights=args.learn_layer_weights,\n        layernorm_before_combine=args.layernorm_before_combine,\n    )\n\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (args.input_size // patch_size[0], args.input_size // patch_size[1])\n    args.patch_size = patch_size\n\n    masked_position_generator = None\n    if args.num_mask_patches > 0:\n        from masking_generator import MaskingGenerator\n        masked_position_generator = MaskingGenerator(\n            args.window_size, num_masking_patches=args.num_mask_patches,\n            max_num_patches=args.max_mask_patches_per_block,\n            min_num_patches=args.min_mask_patches_per_block,\n        )\n\n    if args.finetune:\n        if args.finetune.startswith('https'):\n            checkpoint = torch.hub.load_state_dict_from_url(\n                args.finetune, map_location='cpu', check_hash=True)\n        else:\n            checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load ckpt from %s\" % args.finetune)\n        checkpoint_model = None\n        for model_key in args.model_key.split('|'):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n        if args.reinit_final_norm:\n            for k in ['norm.weight', 'norm.bias', 'fc_norm.weight', 'fc_norm.bias']:\n                if k in checkpoint_model:\n                    print(f\"Removing key {k} from pretrained checkpoint\")\n                    del checkpoint_model[k]\n\n        if model.use_rel_pos_bias and \"rel_pos_bias.relative_position_bias_table\" in checkpoint_model:\n            print(\"Expand the shared relative position embedding to each transformer block. \")\n            num_layers = model.get_num_layers()\n            rel_pos_bias = checkpoint_model[\"rel_pos_bias.relative_position_bias_table\"]\n            for i in range(num_layers):\n                checkpoint_model[\"blocks.%d.attn.relative_position_bias_table\" % i] = rel_pos_bias.clone()\n\n            checkpoint_model.pop(\"rel_pos_bias.relative_position_bias_table\")\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (dst_patch_shape[1] * 2 - 1)\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\"Position interpolate for %s from %dx%d to %dx%d\" % (\n                        key, src_size, src_size, dst_size, dst_size))\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind='cubic')\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy)).contiguous().view(-1, 1).to(rel_pos_bias.device))\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if 'pos_embed' in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model['pos_embed']\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model['pos_embed'] = new_pos_embed\n\n        if not args.learn_layer_weights and args.target_layer != -1:\n            print(f\"model target layer is {args.target_layer}\")\n            model.blocks = model.blocks[:args.target_layer+1]\n\n        if args.remove_final_norm:\n            print(f\"removing final norm by replacing it with Identity\")\n            model.norm = None if model.norm is None else nn.Identity()\n            model.fc_norm = None if model.fc_norm is None else nn.Identity()\n\n        if args.linear_classifier:\n            frozen_params = (\n                set(n for n, _ in model.named_parameters())\n                & set(checkpoint_model.keys())\n            )\n            for n, p in model.named_parameters():\n                if n in frozen_params:\n                    p.requires_grad_(False)\n            param_names = [n for n, p in model.named_parameters() if p.requires_grad]\n            print(f\"Trainable weights: {param_names}\")\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n        # model.load_state_dict(checkpoint_model, strict=False)\n\n    model.to(device)\n\n    model_ema = None\n    if args.model_ema:\n        # Important to create EMA model after cuda(), DP wrapper, and AMP but before SyncBN and DDP wrapper\n        model_ema = ModelEma(\n            model,\n            decay=args.model_ema_decay,\n            device='cpu' if args.model_ema_force_cpu else '',\n            resume='')\n        print(\"Using EMA with decay = %.8f\" % args.model_ema_decay)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params:', n_parameters)\n\n    total_batch_size = args.batch_size * args.update_freq * utils.get_world_size()\n    num_training_steps_per_epoch = len(dataset_train) // total_batch_size\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Update frequent = %d\" % args.update_freq)\n    print(\"Number of training examples = %d\" % len(dataset_train))\n    print(\"Number of training training per epoch = %d\" % num_training_steps_per_epoch)\n\n    num_layers = model_without_ddp.get_num_layers()\n    if args.layer_decay < 1.0:\n        assigner = LayerDecayValueAssigner(list(args.layer_decay ** (num_layers + 1 - i) for i in range(num_layers + 2)))\n    else:\n        assigner = None\n\n    if assigner is not None:\n        print(\"Assigned values = %s\" % str(assigner.values))\n\n    skip_weight_decay_list = model.no_weight_decay()\n    if args.disable_weight_decay_on_rel_pos_bias:\n        for i in range(num_layers):\n            skip_weight_decay_list.add(\"blocks.%d.attn.relative_position_bias_table\" % i)\n\n    if args.enable_deepspeed:\n        loss_scaler = None\n        optimizer_params = get_parameter_groups(\n            model, args.weight_decay, skip_weight_decay_list,\n            assigner.get_layer_id if assigner is not None else None,\n            assigner.get_scale if assigner is not None else None)\n        model, optimizer, _, _ = ds_init(\n            args=args, model=model, model_parameters=optimizer_params, dist_init_required=not args.distributed,\n        )\n\n        print(\"model.gradient_accumulation_steps() = %d\" % model.gradient_accumulation_steps())\n        assert model.gradient_accumulation_steps() == args.update_freq\n    else:\n        if args.distributed:\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n            model_without_ddp = model.module\n\n        optimizer = create_optimizer(\n            args, model_without_ddp, skip_list=skip_weight_decay_list,\n            get_num_layer=assigner.get_layer_id if assigner is not None else None, \n            get_layer_scale=assigner.get_scale if assigner is not None else None)\n        loss_scaler = NativeScaler()\n\n    print(\"Use step level LR scheduler!\")\n    lr_schedule_values = utils.cosine_scheduler(\n        args.lr, args.min_lr, args.epochs, num_training_steps_per_epoch,\n        warmup_epochs=args.warmup_epochs, warmup_steps=args.warmup_steps,\n    )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay, args.weight_decay_end, args.epochs, num_training_steps_per_epoch)\n    print(\"Max WD = %.7f, Min WD = %.7f\" % (max(wd_schedule_values), min(wd_schedule_values)))\n\n    #if mixup_fn is not None:\n        # smoothing is handled with mixup label transform\n    #    criterion = SoftTargetCrossEntropy()\n    #elif args.smoothing > 0.:\n    #    criterion = LabelSmoothingCrossEntropy(smoothing=args.smoothing)\n    #else:\n    \n    criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    utils.auto_load_model(\n        args=args, model=model, model_without_ddp=model_without_ddp,\n        optimizer=optimizer, loss_scaler=loss_scaler, model_ema=model_ema)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device, metric='acc', onehot=args.onehot)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch * args.update_freq)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train, optimizer,\n            device, epoch, loss_scaler, args.clip_grad, model_ema, mixup_fn,\n            log_writer=log_writer, start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values, wd_schedule_values=wd_schedule_values,\n            num_training_steps_per_epoch=num_training_steps_per_epoch, update_freq=args.update_freq,\n            masked_position_generator=masked_position_generator,\n            metric='acc', onehot=args.onehot\n        )\n        if args.output_dir and args.save_ckpt:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                    loss_scaler=loss_scaler, epoch=epoch, model_ema=model_ema)\n        if data_loader_val is not None:\n            test_stats = evaluate(data_loader_val, model, device, 'acc', onehot=args.onehot)\n            print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            if max_accuracy < test_stats[\"acc1\"]:\n                max_accuracy = test_stats[\"acc1\"]\n                if args.output_dir and args.save_ckpt:\n                    utils.save_model(\n                        args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                        loss_scaler=loss_scaler, epoch=\"best\", model_ema=model_ema)\n\n            print(f'Max accuracy: {max_accuracy:.2f}%')\n            if log_writer is not None:\n                log_writer.update(test_acc1=test_stats['acc1'], head=\"perf\", step=epoch)\n                log_writer.update(test_acc5=test_stats['acc5'], head=\"perf\", step=epoch)\n                log_writer.update(test_loss=test_stats['loss'], head=\"perf\", step=epoch)\n\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n        else:\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         # **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    opts, ds_init = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts, ds_init)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_SS_dino.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#     http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport os\nimport argparse\nimport json\nfrom pathlib import Path\n\nimport torch\nfrom torch import nn\nimport torch.distributed as dist\nimport torch.backends.cudnn as cudnn\nfrom torchvision import datasets\nfrom torchvision import transforms as pth_transforms\nfrom torchvision import models as torchvision_models\n\nfrom models.dino import utils\nfrom models.dino import vision_transformer as vits\n\nfrom datasets.So2Sat.so2sat_lcz42_dataset import So2SatDataset,random_subset\nfrom cvtorchvision import cvtransforms\n### end of change ###\nimport pdb\n\nfrom torch.utils.tensorboard import SummaryWriter\nfrom sklearn.metrics import average_precision_score,accuracy_score\nimport builtins\n\ndef eval_linear(args):\n    utils.init_distributed_mode(args)\n    if args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n    print(\"git:\\n  {}\\n\".format(utils.get_sha()))\n    print(\"\\n\".join(\"%s: %s\" % (k, str(v)) for k, v in sorted(dict(vars(args)).items())))\n    cudnn.benchmark = True\n\n    # ============ building network ... ============\n    # if the network is a Vision Transformer (i.e. vit_tiny, vit_small, vit_base)\n    if args.arch in vits.__dict__.keys():\n        model = vits.__dict__[args.arch](patch_size=args.patch_size, num_classes=0, in_chans=13)\n        embed_dim = model.embed_dim * (args.n_last_blocks + int(args.avgpool_patchtokens))\n    # otherwise, we check if the architecture is in torchvision models\n    elif args.arch in torchvision_models.__dict__.keys():\n        model = torchvision_models.__dict__[args.arch]()\n        embed_dim = model.fc.weight.shape[1]\n        model.conv1 = torch.nn.Conv2d(13, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n        model.fc = nn.Identity()\n        #model.fc = torch.nn.Linear(2048,19)\n    # if the network is a XCiT\n    elif \"xcit\" in args.arch:\n        model = torch.hub.load('facebookresearch/xcit:main', args.arch, num_classes=0)\n        embed_dim = model.embed_dim\n    else:\n        print(f\"Unknow architecture: {args.arch}\")\n        sys.exit(1)\n    model.cuda()\n    model.eval()\n    # load weights to evaluate\n    utils.load_pretrained_weights(model, args.pretrained, args.checkpoint_key, args.arch, args.patch_size)\n    print(f\"Model {args.arch} built.\")\n\n    linear_classifier = LinearClassifier(embed_dim, num_labels=17)\n    linear_classifier = linear_classifier.cuda()\n    linear_classifier = nn.parallel.DistributedDataParallel(linear_classifier, device_ids=[args.gpu])\n\n    # ============ preparing data ... ============\n\n    train_transforms = cvtransforms.Compose([\n        cvtransforms.RandomResizedCrop(224),\n        cvtransforms.RandomHorizontalFlip(),\n        cvtransforms.ToTensor(),\n        #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n    ])\n    #dataset_train = datasets.ImageFolder(os.path.join(args.data_path, \"train\"), transform=train_transform)\n\n    val_transforms = cvtransforms.Compose([\n        cvtransforms.Resize(256),\n        cvtransforms.CenterCrop(224),\n        cvtransforms.ToTensor(),\n        #cvtransforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n    ])\n\n\n\n    dataset_train = So2SatDataset(\n        path=os.path.join(args.data_dir, 'training.h5'),\n        transform=train_transforms,\n        bands=args.bands,\n        normalize=args.normalize\n    )\n    \n    dataset_val = So2SatDataset(\n        path=os.path.join(args.data_dir, 'validation.h5'),\n        transform=val_transforms,\n        bands=args.bands,\n        normalize=args.normalize\n    )        \n\n    if args.train_frac is not None and args.train_frac<1:\n        dataset_train = random_subset(dataset_train,args.train_frac,seed=args.seed)\n\n\n    sampler = torch.utils.data.distributed.DistributedSampler(dataset_train)\n    train_loader = torch.utils.data.DataLoader(\n        dataset_train,\n        sampler=sampler,\n        batch_size=args.batch_size_per_gpu,\n        num_workers=args.num_workers,\n        pin_memory=True,\n        drop_last=True\n    )\n    \n\n    #dataset_val = datasets.ImageFolder(os.path.join(args.data_path, \"val\"), transform=val_transform)\n    val_loader = torch.utils.data.DataLoader(\n        dataset_val,\n        batch_size=args.batch_size_per_gpu,\n        num_workers=args.num_workers,\n        pin_memory=True,\n        shuffle=False\n    )\n\n    if args.evaluate:\n        utils.load_pretrained_linear_weights(linear_classifier, args.arch, args.patch_size)\n        test_stats = validate_network(val_loader, model, linear_classifier, args.n_last_blocks, args.avgpool_patchtokens)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        return    \n    \n            \n    \n    print(f\"Data loaded with {len(dataset_train)} train and {len(dataset_val)} val imgs.\")\n\n    # set optimizer\n    optimizer = torch.optim.SGD(\n        linear_classifier.parameters(),\n        args.lr * (args.batch_size_per_gpu * utils.get_world_size()) / 256., # linear scaling rule\n        momentum=0.9,\n        weight_decay=0, # we do not apply weight decay\n    )\n    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, args.epochs, eta_min=0)\n\n    # Optionally resume from a checkpoint\n    to_restore = {\"epoch\": 0, \"best_acc\": 0.}\n    if args.resume:\n        utils.restart_from_checkpoint(\n            os.path.join(args.checkpoints_dir, \"checkpoint.pth.tar\"),\n            run_variables=to_restore,\n            state_dict=linear_classifier,\n            optimizer=optimizer,\n            scheduler=scheduler,\n        )\n    start_epoch = to_restore[\"epoch\"]\n    best_acc = to_restore[\"best_acc\"]\n\n    \n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\n        os.makedirs(args.checkpoints_dir,exist_ok=True)\n    \n    for epoch in range(start_epoch, args.epochs):\n        train_loader.sampler.set_epoch(epoch)\n\n        train_stats = train(model, linear_classifier, optimizer, train_loader, epoch, args.n_last_blocks, args.avgpool_patchtokens)\n        scheduler.step()\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                     'epoch': epoch}\n        if epoch % args.val_freq == 0 or epoch == args.epochs - 1:\n            test_stats = validate_network(val_loader, model, linear_classifier, args.n_last_blocks, args.avgpool_patchtokens)\n            print(f\"Accuracy at epoch {epoch} of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            best_acc = max(best_acc, test_stats[\"acc1\"])\n            print(f'Max accuracy so far: {best_acc:.2f}%')\n            log_stats = {**{k: v for k, v in log_stats.items()},\n                         **{f'test_{k}': v for k, v in test_stats.items()}}\n        if utils.is_main_process():\n            with (Path(args.checkpoints_dir) / \"log.txt\").open(\"a\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n            save_dict = {\n                \"epoch\": epoch + 1,\n                \"state_dict\": linear_classifier.state_dict(),\n                \"optimizer\": optimizer.state_dict(),\n                \"scheduler\": scheduler.state_dict(),\n                \"best_acc\": best_acc,\n            }\n            torch.save(save_dict, os.path.join(args.checkpoints_dir, \"checkpoint.pth.tar\"))\n    print(\"Training of the supervised linear classifier on frozen features completed.\\n\"\n                \"Top-1 test accuracy: {acc:.1f}\".format(acc=best_acc))\n\n\ndef train(model, linear_classifier, optimizer, loader, epoch, n, avgpool):\n    linear_classifier.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    for (inp, target) in metric_logger.log_every(loader, 20, header):\n        \n        # move to gpu\n        inp = inp.cuda(non_blocking=True)\n        target = target.cuda(non_blocking=True)\n\n        # forward\n        with torch.no_grad():\n            if \"vit\" in args.arch:\n                intermediate_output = model.get_intermediate_layers(inp, n)\n                output = torch.cat([x[:, 0] for x in intermediate_output], dim=-1)\n                if avgpool:\n                    output = torch.cat((output.unsqueeze(-1), torch.mean(intermediate_output[-1][:, 1:], dim=1).unsqueeze(-1)), dim=-1)\n                    output = output.reshape(output.shape[0], -1)\n            else:\n                output = model(inp)\n        output = linear_classifier(output)\n\n        # compute cross entropy loss\n        loss = nn.CrossEntropyLoss()(output, torch.argmax(target,axis=1).long())\n\n        # compute the gradients\n        optimizer.zero_grad()\n        loss.backward()\n\n        # step\n        optimizer.step()\n\n        # log \n        torch.cuda.synchronize()\n        metric_logger.update(loss=loss.item())\n        metric_logger.update(lr=optimizer.param_groups[0][\"lr\"])\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef validate_network(val_loader, model, linear_classifier, n, avgpool):\n    linear_classifier.eval()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n    for inp, target in metric_logger.log_every(val_loader, 20, header):\n       \n        # move to gpu\n        inp = inp.cuda(non_blocking=True)\n        target = target.cuda(non_blocking=True)\n\n        # forward\n        with torch.no_grad():\n            if \"vit\" in args.arch:\n                intermediate_output = model.get_intermediate_layers(inp, n)\n                output = torch.cat([x[:, 0] for x in intermediate_output], dim=-1)\n                if avgpool:\n                    output = torch.cat((output.unsqueeze(-1), torch.mean(intermediate_output[-1][:, 1:], dim=1).unsqueeze(-1)), dim=-1)\n                    output = output.reshape(output.shape[0], -1)\n            else:\n                output = model(inp)\n        output = linear_classifier(output)\n        loss = nn.CrossEntropyLoss()(output, torch.argmax(target,axis=1).long())\n\n        '''\n        if linear_classifier.module.num_labels >= 5:\n            acc1, acc5 = utils.accuracy(output, target, topk=(1, 5))\n        else:\n            acc1, = utils.accuracy(output, target, topk=(1,))\n        '''\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = accuracy_score(torch.argmax(target,axis=1).cpu(), torch.argmax(score,axis=1)) * 100.0\n        acc5 = acc1\n        \n        batch_size = inp.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        \n        if linear_classifier.module.num_labels >= 5:\n            metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n        \n    \n    if linear_classifier.module.num_labels >= 5:\n        print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n    else:\n        print('* Acc@1 {top1.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, losses=metric_logger.loss))\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\nclass LinearClassifier(nn.Module):\n    \"\"\"Linear layer to train on top of frozen features\"\"\"\n    def __init__(self, dim, num_labels=1000):\n        super(LinearClassifier, self).__init__()\n        self.num_labels = num_labels\n        self.linear = nn.Linear(dim, num_labels)\n        self.linear.weight.data.normal_(mean=0.0, std=0.01)\n        self.linear.bias.data.zero_()\n\n    def forward(self, x):\n        # flatten\n        x = x.view(x.size(0), -1)\n\n        # linear layer\n        return self.linear(x)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser('Evaluation with linear classification on BigEarthNet.')\n    parser.add_argument('--n_last_blocks', default=4, type=int, help=\"\"\"Concatenate [CLS] tokens\n        for the `n` last blocks. We use `n=4` when evaluating ViT-Small and `n=1` with ViT-Base.\"\"\")\n    parser.add_argument('--avgpool_patchtokens', default=False, type=utils.bool_flag,\n        help=\"\"\"Whether ot not to concatenate the global average pooled features to the [CLS] token.\n        We typically set this to False for ViT-Small and to True with ViT-Base.\"\"\")\n    parser.add_argument('--arch', default='vit_small', type=str, help='Architecture')\n    parser.add_argument('--patch_size', default=16, type=int, help='Patch resolution of the model.')\n    parser.add_argument('--pretrained', default='', type=str, help=\"Path to pretrained weights to evaluate.\")\n    parser.add_argument(\"--checkpoint_key\", default=\"teacher\", type=str, help='Key to use in the checkpoint (example: \"teacher\")')\n    parser.add_argument('--epochs', default=100, type=int, help='Number of epochs of training.')\n    parser.add_argument(\"--lr\", default=0.001, type=float, help=\"\"\"Learning rate at the beginning of\n        training (highest LR used during training). The learning rate is linearly scaled\n        with the batch size, and specified here for a reference batch size of 256.\n        We recommend tweaking the LR depending on the checkpoint evaluated.\"\"\")\n    parser.add_argument('--batch_size_per_gpu', default=128, type=int, help='Per-GPU batch-size')\n    parser.add_argument(\"--dist_url\", default=\"env://\", type=str, help=\"\"\"url used to set up\n        distributed training; see https://pytorch.org/docs/stable/distributed.html\"\"\")\n    parser.add_argument(\"--local_rank\", default=0, type=int, help=\"Please ignore and do not set this argument.\")\n    parser.add_argument('--data_path', default='/path/to/imagenet/', type=str)\n    parser.add_argument('--num_workers', default=10, type=int, help='Number of data loading workers per GPU.')\n    parser.add_argument('--val_freq', default=5, type=int, help=\"Epoch frequency for validation.\")\n    parser.add_argument('--checkpoints_dir', default=\".\", help='Path to save logs and checkpoints')\n    parser.add_argument('--num_labels', default=1000, type=int, help='Number of labels for linear classifier')\n    parser.add_argument('--evaluate', dest='evaluate', action='store_true', help='evaluate model on validation set')\n    \n    parser.add_argument('--data_dir', default='/path/to/imagenet/', type=str, help='Please specify path to the ImageNet folder.')\n    parser.add_argument('--bands', type=str, default='all', help=\"input bands\")\n    parser.add_argument(\"--lmdb\", action='store_true', help=\"use lmdb dataset\")\n    parser.add_argument(\"--is_slurm_job\", action='store_true', help=\"running in slurm\")\n    parser.add_argument(\"--resume\", action='store_true', help=\"resume from checkpoint\")\n    parser.add_argument(\"--train_frac\", default=1.0, type=float, help=\"use a subset of labeled data\")\n    parser.add_argument(\"--seed\",default=42,type=int)\n    parser.add_argument(\"--normalize\",action=\"store_true\",default=None)    \n    \n    args = parser.parse_args()\n\n\n    \n    eval_linear(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_SS_mae.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# MoCo v3: https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\n\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\n\nimport timm\n\n#assert timm.__version__ == \"0.3.2\" # version check\nfrom timm.models.layers import trunc_normal_\n\nimport models.mae.util.misc as misc\nfrom models.mae.util.pos_embed import interpolate_pos_embed\nfrom models.mae.util.misc import NativeScalerWithGradNormCount as NativeScaler\nfrom models.mae.util.lars import LARS\nfrom models.mae.util.crop import RandomResizedCrop\n\nimport models.mae.models_vit as models_vit\n\nfrom models.mae.engine_finetune_SS import train_one_epoch, evaluate\n\n\nfrom datasets.So2Sat.so2sat_lcz42_dataset import So2SatDataset,random_subset\nfrom cvtorchvision import cvtransforms\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE linear probing for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=512, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=90, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    # Optimizer parameters\n    parser.add_argument('--weight_decay', type=float, default=0,\n                        help='weight decay (default: 0 for linear probe following MoCo v1)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=0.1, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n\n    parser.add_argument('--min_lr', type=float, default=0., metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=10, metavar='N',\n                        help='epochs to warmup LR')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--global_pool', action='store_true')\n    parser.set_defaults(global_pool=False)\n    parser.add_argument('--cls_token', action='store_false', dest='global_pool',\n                        help='Use class token instead of global pool for classification')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--nb_classes', default=1000, type=int,\n                        help='number of the classification types')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation (recommended during training for faster monitor')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n    parser.add_argument('--dist_backend', default='nccl', type=str,\n                        help='distributed backend')\n    \n    parser.add_argument(\"--is_slurm_job\", action='store_true', help=\"slurm job\")\n    parser.add_argument(\"--train_frac\", default=1.0, type=float, help=\"use a subset of labeled data\")\n    \n    return parser\n\n\ndef main(args):\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n\n    \n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(224),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(224),\n            cvtransforms.ToTensor(),\n            ])\n\n\n    dataset_train = So2SatDataset(\n        path=os.path.join(args.data_path, 'training.h5'),\n        transform=train_transforms,\n        bands='B13',\n        normalize=False\n    )\n    \n    dataset_val = So2SatDataset(\n        path=os.path.join(args.data_path, 'validation.h5'),\n        transform=val_transforms,\n        bands='B13',\n        normalize=False\n    )    \n  \n    if args.train_frac is not None and args.train_frac<1:\n        dataset_train = random_subset(dataset_train,args.train_frac,args.seed)\n\n\n    if True:  # args.distributed:\n        num_tasks = args.world_size\n        print(misc.get_world_size())\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=True)  # shuffle=True to reduce monitor bias\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None and not args.eval:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    data_loader_val = torch.utils.data.DataLoader(\n        dataset_val, sampler=sampler_val,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=False\n    )\n\n    model = models_vit.__dict__[args.model](\n        num_classes=args.nb_classes,\n        global_pool=args.global_pool,\n        in_chans=13\n    )\n\n    if args.finetune and not args.eval:\n        checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load pre-trained checkpoint from: %s\" % args.finetune)\n        checkpoint_model = checkpoint['model']\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        # interpolate position embedding\n        interpolate_pos_embed(model, checkpoint_model)\n\n        # load pre-trained model\n        msg = model.load_state_dict(checkpoint_model, strict=False)\n        print(msg)\n\n        if args.global_pool:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias', 'fc_norm.weight', 'fc_norm.bias'}\n        else:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias'}\n\n        # manually initialize fc layer: following MoCo v3\n        trunc_normal_(model.head.weight, std=0.01)\n\n    # for linear prob only\n    # hack: revise model's head with BN\n    model.head = torch.nn.Sequential(torch.nn.BatchNorm1d(model.head.in_features, affine=False, eps=1e-6), model.head)\n    # freeze all but the head\n    for _, p in model.named_parameters():\n        p.requires_grad = False\n    for _, p in model.head.named_parameters():\n        p.requires_grad = True\n\n    model.to(device)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params (M): %.2f' % (n_parameters / 1.e6))\n\n    eff_batch_size = args.batch_size * args.accum_iter * args.world_size\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        model_without_ddp = model.module\n\n    #optimizer = LARS(model_without_ddp.head.parameters(), lr=args.lr, weight_decay=args.weight_decay)\n    optimizer = torch.optim.SGD(model_without_ddp.head.parameters(), args.lr,\n                                momentum=0.9,\n                                weight_decay=0)\n    print(optimizer)\n    loss_scaler = NativeScaler()\n\n    criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device, criterion)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            max_norm=None,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir and (epoch%10==0 or epoch + 1 == args.epochs):\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        if epoch%5==0 or (epoch + 1 == args.epochs):\n            test_stats = evaluate(data_loader_val, model, device, criterion)\n            print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            \n            max_accuracy = max(max_accuracy, test_stats[\"acc1\"])\n            print(f'Max accuracy: {max_accuracy:.2f}%')\n\n        if log_writer is not None:\n            log_writer.add_scalar('perf/test_acc1', test_stats['acc1'], epoch)\n            log_writer.add_scalar('perf/test_acc5', test_stats['acc5'], epoch)\n            log_writer.add_scalar('perf/test_loss', test_stats['loss'], epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        **{f'test_{k}': v for k, v in test_stats.items()},\n                        'epoch': epoch,\n                        'n_parameters': n_parameters}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_SS_moco.py",
    "content": "\nimport torch\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import models\n\n## change01 ##\nfrom cvtorchvision import cvtransforms\nimport time\nimport os\nimport math\nimport pdb\nfrom sklearn.metrics import accuracy_score\nimport numpy as np\nimport argparse\nimport builtins\n\nfrom datasets.So2Sat.so2sat_lcz42_dataset import So2SatDataset,random_subset\n\nfrom torch.utils.tensorboard import SummaryWriter\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--data_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet')\nparser.add_argument('--checkpoints_dir', type=str, default='./checkpoints/resnet/')\nparser.add_argument('--resume', type=str, default='')\n#parser.add_argument('--save_path', type=str, default='./checkpoints/bigearthnet_s2_B12_100_no_pretrain_resnet50.pt')\nparser.add_argument('--bands', type=str, default='all', help='bands to process')  \nparser.add_argument('--train_frac', type=float, default=1.0)\nparser.add_argument('--backbone', type=str, default='resnet50')\nparser.add_argument('--batchsize', type=int, default=256)\nparser.add_argument('--epochs', type=int, default=100)\nparser.add_argument('--num_workers', type=int, default=8)\nparser.add_argument('--lr', type=float, default=0.05)\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by 10x)')\nparser.add_argument('--cos', action='store_true', help='use cosine lr schedule')\nparser.add_argument('--seed', type=int, default=42)\nparser.add_argument('--pretrained', default='', type=str, help='path to moco pretrained checkpoint')\n\n### distributed running ###\nparser.add_argument('--dist_url', default='env://', type=str)\nparser.add_argument(\"--world_size\", default=-1, type=int, help=\"\"\"\n                    number of processes: it is set automatically and\n                    should not be passed as argument\"\"\")\nparser.add_argument(\"--rank\", default=0, type=int, help=\"\"\"rank of this process:\n                    it is set automatically and should not be passed as argument\"\"\")\nparser.add_argument(\"--local_rank\", default=0, type=int,\n                    help=\"this argument is not used and should be ignored\")\n\nparser.add_argument(\"--normalize\",action=\"store_true\",default=None)\nparser.add_argument(\"--in_size\",type=int,default=224)\n\ndef init_distributed_mode(args):\n\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n    else:\n        # multi-GPU job (local or multi-node) - jobs started with torch.distributed.launch\n        # read environment variables\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n\n    # prepare distributed\n    torch.distributed.init_process_group(\n        backend=\"nccl\",\n        init_method=args.dist_url,\n        world_size=args.world_size,\n        rank=args.rank,\n    )\n\n    # set cuda device\n    args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n    torch.cuda.set_device(args.gpu_to_work_on)\n    return    \n\ndef fix_random_seeds(seed=42):\n    \"\"\"\n    Fix random seeds.\n    \"\"\"\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    np.random.seed(seed)\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    if args.cos:  # cosine lr schedule\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\n    else:  # stepwise lr schedule\n        for milestone in args.schedule:\n            lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef main():\n\n    global args\n    args = parser.parse_args()\n    ### dist ###\n    init_distributed_mode(args)\n    if args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n    \n    fix_random_seeds(args.seed)\n    \n\n    data_dir = args.data_dir\n    checkpoints_dir = args.checkpoints_dir\n    #save_path = args.save_path\n    batch_size = args.batchsize\n\n    num_workers = args.num_workers\n    epochs = args.epochs\n    train_frac = args.train_frac\n    seed = args.seed\n\n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\n        os.mkdir(args.checkpoints_dir)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints_dir,'log'))\n\n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.in_size),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(args.in_size),\n            cvtransforms.ToTensor(),           \n            ])\n\n\n    train_dataset = So2SatDataset(\n        path=os.path.join(data_dir, 'training.h5'),\n        transform=train_transforms,\n        bands=args.bands,\n        normalize=args.normalize\n    )\n    \n    val_dataset = So2SatDataset(\n        path=os.path.join(data_dir, 'validation.h5'),\n        transform=val_transforms,\n        bands=args.bands,\n        normalize=args.normalize\n    )    \n  \n    if train_frac is not None and train_frac<1:\n        train_dataset = random_subset(train_dataset,train_frac,seed)    \n    ### dist ###    \n    sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)    \n        \n    train_loader = DataLoader(train_dataset,\n                              batch_size=batch_size,\n                              sampler = sampler,\n                              #shuffle=True,\n                              num_workers=num_workers,\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\n                              drop_last=True\n                              \n                              )\n                              \n    val_loader = DataLoader(val_dataset,\n                              batch_size=batch_size,\n                              shuffle=False,\n                              num_workers=num_workers,\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\n                              drop_last=True\n                              \n                              )\n    \n    print('train_len: %d val_len: %d' % (len(train_dataset),len(val_dataset)))\n\n    ## change 04 ##\n    if args.backbone == 'resnet50':\n        net = models.resnet50(pretrained=False)\n        net.fc = torch.nn.Linear(2048,17)\n    elif args.backbone == 'resnet18':\n        net = models.resnet18(pretrained=False)\n        net.fc = torch.nn.Linear(512,17)\n        \n    net.conv1 = torch.nn.Conv2d(13, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n\n\n    for name, param in net.named_parameters():\n        if name not in ['fc.weight','fc.bias']:\n            param.requires_grad = False\n\n\n    net.fc.weight.data.normal_(mean=0.0,std=0.01)\n    net.fc.bias.data.zero_()\n\n\n    # load from pre-trained, before DistributedDataParallel constructor\n    if args.pretrained:\n        if os.path.isfile(args.pretrained):\n            print(\"=> loading checkpoint '{}'\".format(args.pretrained))\n            checkpoint = torch.load(args.pretrained, map_location=\"cpu\")\n\n            # rename moco pre-trained keys\n            state_dict = checkpoint['state_dict']\n            \n            for k in list(state_dict.keys()):\n                # retain only encoder up to before the embedding layer\n                if k.startswith('module.encoder_q') and not k.startswith('module.encoder_q.fc'):\n                    #pdb.set_trace()\n                    # remove prefix\n                    state_dict[k[len(\"module.encoder_q.\"):]] = state_dict[k]\n                # delete renamed or unused k\n                del state_dict[k]\n            '''\n            # remove prefix\n            state_dict = {k.replace(\"module.\", \"\"): v for k,v in state_dict.items()}\n            '''\n            #args.start_epoch = 0\n            msg = net.load_state_dict(state_dict, strict=False)\n            #pdb.set_trace()\n            assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\n\n            print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.pretrained))\n\n    # convert batch norm layers (if any)\n    if args.is_slurm_job:\n        net = torch.nn.SyncBatchNorm.convert_sync_batchnorm(net)\n\n\n    criterion = torch.nn.CrossEntropyLoss()\n    optimizer = torch.optim.SGD(net.parameters(), lr=args.lr, momentum=0.9)\n\n\n    last_epoch = 0\n    if args.resume:\n        checkpoint = torch.load(args.resume)\n        state_dict = checkpoint['model_state_dict']\n        state_dict = {k.replace(\"module.\", \"\"): v for k,v in state_dict.items()}\n        net.load_state_dict(state_dict)\n        #net.load_state_dict(checkpoint['model_state_dict'])\n        optimizer.load_state_dict(checkpoint['optimizer_state_dict'])\n        last_epoch = checkpoint['epoch']\n        last_loss = checkpoint['loss']\n\n    #device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    #net.to(device)\n    net.cuda()\n    \n    #### nccl doesn't support wsl\n    if args.is_slurm_job:\n        net = torch.nn.parallel.DistributedDataParallel(net,device_ids=[args.gpu_to_work_on],find_unused_parameters=True)\n\n    print('Start training...')\n    for epoch in range(last_epoch,epochs):\n\n        net.train()\n        adjust_learning_rate(optimizer, epoch, args)\n        \n        train_loader.sampler.set_epoch(epoch)\n        running_loss = 0.0\n        running_acc = 0.0\n        \n        running_loss_epoch = 0.0\n        running_acc_epoch = 0.0\n        \n        start_time = time.time()\n        end = time.time()\n        sum_bt = 0.0\n        sum_dt = 0.0\n        sum_tt = 0.0\n        sum_st = 0.0\n        for i, data in enumerate(train_loader, 0):\n            data_time = time.time()-end\n            #inputs, labels = data\n            inputs, labels = data[0].cuda(), data[1].cuda()\n\n            # zero the parameter gradients\n            optimizer.zero_grad()\n\n            # forward + backward + optimize\n            outputs = net(inputs)\n            #pdb.set_trace()\n            loss = criterion(outputs, torch.argmax(labels,axis=1).long())\n            loss.backward()\n            optimizer.step()\n            train_time = time.time()-end-data_time\n            if epoch % 5 == 4:\n                score = torch.sigmoid(outputs).detach().cpu()\n                average_precision = accuracy_score(torch.argmax(labels,axis=1).cpu(), torch.argmax(score,axis=1)) * 100.0\n            else:\n                average_precision = 0\n            score_time = time.time()-end-data_time-train_time\n            \n            # print statistics\n            running_loss += loss.item()\n            running_acc += average_precision\n            batch_time = time.time() - end\n            end = time.time()        \n            sum_bt += batch_time\n            sum_dt += data_time\n            sum_tt += train_time\n            sum_st += score_time\n            \n            if i % 20 == 19:    # print every 20 mini-batches\n\n                print('[%d, %5d] loss: %.3f acc: %.3f batch_time: %.3f data_time: %.3f train_time: %.3f score_time: %.3f' %\n                      (epoch + 1, i + 1, running_loss / 20, running_acc / 20, sum_bt/20, sum_dt/20, sum_tt/20, sum_st/20))\n                \n                #train_iter =  i*args.batch_size / len(train_dataset)\n                #tb_writer.add_scalar('train_loss', running_loss/20, global_step=(epoch+1+train_iter) )\n                running_loss_epoch = running_loss/20\n                running_acc_epoch = running_acc/20\n                \n                running_loss = 0.0\n                running_acc = 0.0\n                sum_bt = 0.0\n                sum_dt = 0.0\n                sum_tt = 0.0\n                sum_st = 0.0\n\n        if epoch % 5 == 4:\n            running_loss_val = 0.0\n            running_acc_val = 0.0\n            count_val = 0\n            net.eval()\n            with torch.no_grad():\n                for j, data_val in enumerate(val_loader, 0):\n\n                    inputs_val, labels_val = data_val[0].cuda(), data_val[1].cuda()\n                    outputs_val = net(inputs_val)\n                    loss_val = criterion(outputs_val, torch.argmax(labels,axis=1).long())\n                    score_val = torch.sigmoid(outputs_val).detach().cpu()\n                    average_precision_val = accuracy_score(torch.argmax(labels_val,axis=1).cpu(), torch.argmax(score_val,axis=1)) * 100.0   \n\n                    count_val += 1\n                    running_loss_val += loss_val.item()\n                    running_acc_val += average_precision_val        \n\n            print('Epoch %d val_loss: %.3f val_acc: %.3f time: %s seconds.' % (epoch+1, running_loss_val/count_val, running_acc_val/count_val, time.time()-start_time))\n\n            if args.rank == 0:\n                losses = {'train': running_loss_epoch,\n                          'val': running_loss_val/count_val}\n                accs = {'train': running_acc_epoch,\n                        'val': running_acc_val/count_val}        \n                tb_writer.add_scalars('loss', losses, global_step=epoch+1, walltime=None)\n                tb_writer.add_scalars('acc', accs, global_step=epoch+1, walltime=None)\n                    \n            \n        if args.rank==0 and epoch % 10 == 9:\n            torch.save({\n                        'epoch': epoch,\n                        'model_state_dict': net.state_dict(),\n                        'optimizer_state_dict':optimizer.state_dict(),\n                        'loss':loss,\n                        }, os.path.join(checkpoints_dir,'checkpoint_{:04d}.pth.tar'.format(epoch)))\n        \n    #if args.rank==0:\n    #    torch.save(net.state_dict(), save_path)\n        \n    print('Training finished.')\n\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/linear_SS_moco_v3.py",
    "content": "\nimport torch\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import models\n\n## change01 ##\nfrom cvtorchvision import cvtransforms\nimport time\nimport os\nimport math\nimport pdb\nfrom sklearn.metrics import accuracy_score\nimport numpy as np\nimport argparse\nimport builtins\n\nfrom datasets.So2Sat.so2sat_lcz42_dataset import So2SatDataset,random_subset\n\nfrom torch.utils.tensorboard import SummaryWriter\nfrom models.moco_v3 import vits\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--data_dir', type=str, default='/mnt/d/codes/SSL_examples/datasets/BigEarthNet')\nparser.add_argument('--checkpoints_dir', type=str, default='./checkpoints/resnet/')\nparser.add_argument('--resume', type=str, default='')\n#parser.add_argument('--save_path', type=str, default='./checkpoints/bigearthnet_s2_B12_100_no_pretrain_resnet50.pt')\nparser.add_argument('--bands', type=str, default='all', help='bands to process')  \nparser.add_argument('--train_frac', type=float, default=1.0)\nparser.add_argument('--backbone', type=str, default='resnet50')\nparser.add_argument('--batchsize', type=int, default=256)\nparser.add_argument('--epochs', type=int, default=100)\nparser.add_argument('--num_workers', type=int, default=8)\nparser.add_argument('--lr', type=float, default=0.05)\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by 10x)')\nparser.add_argument('--cos', action='store_true', help='use cosine lr schedule')\nparser.add_argument('--seed', type=int, default=42)\nparser.add_argument('--pretrained', default='', type=str, help='path to moco pretrained checkpoint')\n\n### distributed running ###\nparser.add_argument('--dist_url', default='env://', type=str)\nparser.add_argument(\"--world_size\", default=-1, type=int, help=\"\"\"\n                    number of processes: it is set automatically and\n                    should not be passed as argument\"\"\")\nparser.add_argument(\"--rank\", default=0, type=int, help=\"\"\"rank of this process:\n                    it is set automatically and should not be passed as argument\"\"\")\nparser.add_argument(\"--local_rank\", default=0, type=int,\n                    help=\"this argument is not used and should be ignored\")\n\nparser.add_argument(\"--normalize\",action=\"store_true\",default=None)\nparser.add_argument(\"--in_size\",type=int,default=224)\nparser.add_argument('--linear', action='store_true', default=False)\n\n\n\n\n\n\ndef init_distributed_mode(args):\n\n    args.is_slurm_job = \"SLURM_JOB_ID\" in os.environ\n\n    if args.is_slurm_job:\n        args.rank = int(os.environ[\"SLURM_PROCID\"])\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n    else:\n        # multi-GPU job (local or multi-node) - jobs started with torch.distributed.launch\n        # read environment variables\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n\n    # prepare distributed\n    torch.distributed.init_process_group(\n        backend=\"nccl\",\n        init_method=args.dist_url,\n        world_size=args.world_size,\n        rank=args.rank,\n    )\n\n    # set cuda device\n    args.gpu_to_work_on = args.rank % torch.cuda.device_count()\n    torch.cuda.set_device(args.gpu_to_work_on)\n    return    \n\ndef fix_random_seeds(seed=42):\n    \"\"\"\n    Fix random seeds.\n    \"\"\"\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    np.random.seed(seed)\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    if args.cos:  # cosine lr schedule\n        lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))\n    else:  # stepwise lr schedule\n        for milestone in args.schedule:\n            lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef main():\n\n    global args\n    args = parser.parse_args()\n    ### dist ###\n    init_distributed_mode(args)\n    if args.rank != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n    \n    fix_random_seeds(args.seed)\n    \n\n    data_dir = args.data_dir\n    checkpoints_dir = args.checkpoints_dir\n    #save_path = args.save_path\n    batch_size = args.batchsize\n\n    num_workers = args.num_workers\n    epochs = args.epochs\n    train_frac = args.train_frac\n    seed = args.seed\n\n    if args.rank==0 and not os.path.isdir(args.checkpoints_dir):\n        os.mkdir(args.checkpoints_dir)\n    if args.rank==0:\n        tb_writer = SummaryWriter(os.path.join(args.checkpoints_dir,'log'))\n\n    train_transforms = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.in_size),\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n\n    val_transforms = cvtransforms.Compose([\n            cvtransforms.Resize(256),\n            cvtransforms.CenterCrop(args.in_size),\n            cvtransforms.ToTensor(),           \n            ])\n\n\n    train_dataset = So2SatDataset(\n        path=os.path.join(data_dir, 'training.h5'),\n        transform=train_transforms,\n        bands='B13',\n        normalize=False\n    )\n    \n    val_dataset = So2SatDataset(\n        path=os.path.join(data_dir, 'validation.h5'),\n        transform=val_transforms,\n        bands='B13',\n        normalize=False\n    )    \n  \n    if train_frac is not None and train_frac<1:\n        train_dataset = random_subset(train_dataset,train_frac,seed)    \n    ### dist ###    \n    sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)    \n        \n    train_loader = DataLoader(train_dataset,\n                              batch_size=batch_size,\n                              sampler = sampler,\n                              #shuffle=True,\n                              num_workers=num_workers,\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\n                              drop_last=True\n                              \n                              )\n                              \n    val_loader = DataLoader(val_dataset,\n                              batch_size=batch_size,\n                              shuffle=False,\n                              num_workers=num_workers,\n                              pin_memory=args.is_slurm_job, # improve a little when using lmdb dataset\n                              drop_last=True\n                              \n                              )\n    \n    print('train_len: %d val_len: %d' % (len(train_dataset),len(val_dataset)))\n\n    #######################################################################################\n\n    net = vits.__dict__[args.backbone](in_chans=13, num_classes=17)\n    linear_keyword = 'head'\n\n    if args.linear:\n        # freeze all layers but the last fc\n        for name, param in net.named_parameters():\n            if name not in ['%s.weight' % linear_keyword, '%s.bias' % linear_keyword]:\n                param.requires_grad = False\n        # init the fc layer\n    getattr(net, linear_keyword).weight.data.normal_(mean=0.0, std=0.01)\n    getattr(net, linear_keyword).bias.data.zero_()\n\n    # load from pre-trained, before DistributedDataParallel constructor\n    if args.pretrained:\n        if os.path.isfile(args.pretrained):\n            print(\"=> loading checkpoint '{}'\".format(args.pretrained))\n            checkpoint = torch.load(args.pretrained, map_location=\"cpu\")\n\n            # rename moco pre-trained keys\n            state_dict = checkpoint['state_dict']\n            for k in list(state_dict.keys()):\n                # retain only base_encoder up to before the embedding layer\n                if k.startswith('module.base_encoder') and not k.startswith('module.base_encoder.%s' % linear_keyword):\n                    # remove prefix\n                    state_dict[k[len(\"module.base_encoder.\"):]] = state_dict[k]\n                # delete renamed or unused k\n                del state_dict[k]\n\n            args.start_epoch = 0\n            msg = net.load_state_dict(state_dict, strict=False)\n            assert set(msg.missing_keys) == {\"%s.weight\" % linear_keyword, \"%s.bias\" % linear_keyword}\n\n            print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.pretrained))\n\n    \n    parameters = list(filter(lambda p: p.requires_grad, net.parameters()))\n    if args.linear:\n        assert len(parameters) == 2  # weight, bias\n\n    #########################################################################\n\n\n    criterion = torch.nn.CrossEntropyLoss()\n    optimizer = torch.optim.SGD(net.parameters(), lr=args.lr, momentum=0.9)\n\n\n    last_epoch = 0\n    if args.resume:\n        checkpoint = torch.load(args.resume)\n        net.load_state_dict(checkpoint['model_state_dict'])\n        optimzier.load_state_dict(checkpoint['optimizer_state_dict'])\n        last_epoch = checkpoint['epoch']\n        last_loss = checkpoint['loss']\n\n    #device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    #net.to(device)\n    net.cuda()\n    \n    #### nccl doesn't support wsl\n    if args.is_slurm_job:\n        net = torch.nn.parallel.DistributedDataParallel(net,device_ids=[args.gpu_to_work_on],find_unused_parameters=True)\n\n    print('Start training...')\n    for epoch in range(last_epoch,epochs):\n\n        net.train()\n        adjust_learning_rate(optimizer, epoch, args)\n        \n        train_loader.sampler.set_epoch(epoch)\n        running_loss = 0.0\n        running_acc = 0.0\n        \n        running_loss_epoch = 0.0\n        running_acc_epoch = 0.0\n        \n        start_time = time.time()\n        end = time.time()\n        sum_bt = 0.0\n        sum_dt = 0.0\n        sum_tt = 0.0\n        sum_st = 0.0\n        for i, data in enumerate(train_loader, 0):\n            data_time = time.time()-end\n            #inputs, labels = data\n            inputs, labels = data[0].cuda(), data[1].cuda()\n\n            # zero the parameter gradients\n            optimizer.zero_grad()\n\n            # forward + backward + optimize\n            outputs = net(inputs)\n            #pdb.set_trace()\n            loss = criterion(outputs, torch.argmax(labels,axis=1).long())\n            loss.backward()\n            optimizer.step()\n            train_time = time.time()-end-data_time\n            if epoch % 5 == 4:\n                score = torch.sigmoid(outputs).detach().cpu()\n                average_precision = accuracy_score(torch.argmax(labels,axis=1).cpu(), torch.argmax(score,axis=1)) * 100.0\n            else:\n                average_precision = 0\n            score_time = time.time()-end-data_time-train_time\n            \n            # print statistics\n            running_loss += loss.item()\n            running_acc += average_precision\n            batch_time = time.time() - end\n            end = time.time()        \n            sum_bt += batch_time\n            sum_dt += data_time\n            sum_tt += train_time\n            sum_st += score_time\n            \n            if i % 20 == 19:    # print every 20 mini-batches\n\n                print('[%d, %5d] loss: %.3f acc: %.3f batch_time: %.3f data_time: %.3f train_time: %.3f score_time: %.3f' %\n                      (epoch + 1, i + 1, running_loss / 20, running_acc / 20, sum_bt/20, sum_dt/20, sum_tt/20, sum_st/20))\n                \n                #train_iter =  i*args.batch_size / len(train_dataset)\n                #tb_writer.add_scalar('train_loss', running_loss/20, global_step=(epoch+1+train_iter) )\n                running_loss_epoch = running_loss/20\n                running_acc_epoch = running_acc/20\n                \n                running_loss = 0.0\n                running_acc = 0.0\n                sum_bt = 0.0\n                sum_dt = 0.0\n                sum_tt = 0.0\n                sum_st = 0.0\n\n        if epoch % 5 == 4:\n            running_loss_val = 0.0\n            running_acc_val = 0.0\n            count_val = 0\n            net.eval()\n            with torch.no_grad():\n                for j, data_val in enumerate(val_loader, 0):\n\n                    inputs_val, labels_val = data_val[0].cuda(), data_val[1].cuda()\n                    outputs_val = net(inputs_val)\n                    loss_val = criterion(outputs_val, torch.argmax(labels,axis=1).long())\n                    score_val = torch.sigmoid(outputs_val).detach().cpu()\n                    average_precision_val = accuracy_score(torch.argmax(labels_val,axis=1).cpu(), torch.argmax(score_val,axis=1)) * 100.0   \n\n                    count_val += 1\n                    running_loss_val += loss_val.item()\n                    running_acc_val += average_precision_val        \n\n            print('Epoch %d val_loss: %.3f val_acc: %.3f time: %s seconds.' % (epoch+1, running_loss_val/count_val, running_acc_val/count_val, time.time()-start_time))\n\n            if args.rank == 0:\n                losses = {'train': running_loss_epoch,\n                          'val': running_loss_val/count_val}\n                accs = {'train': running_acc_epoch,\n                        'val': running_acc_val/count_val}        \n                tb_writer.add_scalars('loss', losses, global_step=epoch+1, walltime=None)\n                tb_writer.add_scalars('acc', accs, global_step=epoch+1, walltime=None)\n                    \n            \n        if args.rank==0 and epoch % 10 == 9:\n            torch.save({\n                        'epoch': epoch,\n                        'model_state_dict': net.state_dict(),\n                        'optimizer_state_dict':optimizer.state_dict(),\n                        'loss':loss,\n                        }, os.path.join(checkpoints_dir,'checkpoint_{:04d}.pth.tar'.format(epoch)))\n        \n    #if args.rank==0:\n    #    torch.save(net.state_dict(), save_path)\n        \n    print('Training finished.')\n\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/README.md",
    "content": "# data2vec\n\ndata2vec is a framework for self-supervised representation learning for images, speech, and text as described in data2vec: A General Framework for Self-supervised Learning in Speech, Vision and Language (Baevski et al., 2022). The algorithm uses the same learning mechanism for different modalities. You can read more about this work here [arxiv](https://arxiv.org/abs/2202.03555) and [fairseq repo](https://github.com/pytorch/fairseq/tree/main/examples/data2vec)\n\nFor details about how to setup your BEIT environment, please refer the original README [here](README_Original.md). Below you can find the necessary commands to reproduce the vision results reported in [data2vec: A General Framework for Self-supervised Learning in Speech, Vision and Language\n](https://arxiv.org/abs/2202.03555)\n\n## Model Checkpoints\n\nPretrained Model | Version | Link\n|---|---|---|\ndata2vec ViT-B | 800 epochs pretrained | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/base_800/checkpoint-799.pth)\ndata2vec ViT-L | 800 epochs pretrained | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/large_800/checkpoint-799.pth)\ndata2vec ViT-L | 1600 epochs pretrained | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/large_1600/checkpoint-799.pth)\ndata2vec ViT-B | Finetuned | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/finetuned_base/checkpoint-99/mp_rank_00_model_states.pt)\ndata2vec ViT-L | Finetuned | [download](https://dl.fbaipublicfiles.com/fairseq/data2vec/data2vec_vision/finetuned_large/checkpoint-49/mp_rank_00_model_states.pt)\n\n## VIT-B Pretraining and Finetuning\n\nCommand to pretrain the ViT-B model for 800 epochs\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_cyclical.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --num_mask_patches 120 \\\n        --model beit_base_patch16_224 \\\n        --seed 0 \\\n        --target_layers [6,7,8,9,10,11] \\\n        --ema_decay 0.9998 --ema_start_at 0 --ema_decay_init 0.999 \\\n        --batch_size 128 --lr 2e-3 --warmup_epochs 10 --epochs 800 \\\n        --clip_grad 3.0 --drop_path 0.25 --layer_scale_init_value 1e-4 \\\n        --layer_results 'end' \\\n        --var_w0 0.0 --var_w1 0.0 \\\n        --max_mask_patches_per_block 196 --min_mask_patches_per_block 16 \\\n        --l1_beta=2.0 \\\n        --weight_decay 0.05 \\\n        --imagenet_default_mean_and_std --dist_url $dist_url --loss_scale -1 --mask_dropout_prob -1.0 \\\n        --post_target_layer_norm --world_size 16 --attn_drop_rate 0.05 \n\n\n```\n\nCommand to finetune the ViT-B model\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n        --model beit_base_patch16_224 \\\n        --finetune $CHECKPOINT \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --batch_size 128 --lr 4e-3 --update_freq 1 \\\n        --warmup_epochs 10 --epochs 100 --layer_decay 0.65 --drop_path 0.2 --drop 0.0 \\\n        --weight_decay 0.0 --mixup 0.8 --cutmix 1.0 --enable_deepspeed --nb_classes 1000 \\\n        --target_layer -1 --world_size 8 --dist_url $dist_url \n\n```\n\n## VIT-L Pretraining and Finetuning\n\nCommand to pretrain the ViT-L model for 800 epochs\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=64 run_cyclical.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --num_mask_patches 120 \\\n        --model beit_large_patch16_224 \\\n        --seed 0 \\\n        --target_layers [18,19,20,21,22,23] \\\n        --ema_decay 0.9998 --ema_start_at 0 \\\n        --batch_size 64 --lr 1e-3 --warmup_epochs 80 --epochs 800 \\\n        --clip_grad 3.0 --drop_path 0.2 --layer_scale_init_value 1e-5 \\\n        --layer_results 'end' \\\n        --l1_beta=2 \\\n\t--var_w0 0.0 --var_w1 0.0 --var_margin0 0.5 \\\n\t--max_mask_patches_per_block 196 --min_mask_patches_per_block 16 \\\n        --imagenet_default_mean_and_std --dist_url $dist_url --world_size 64 \\\n         --post_target_layer_norm  --attn_drop_rate 0.15\n\n\n```\n\nYou further pretrain the ViT-L model for another 800 epochs with constant ema decay\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=64 run_cyclical.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --num_mask_patches 120 \\\n        --model beit_large_patch16_224 \\\n        --seed 0 \\\n        --target_layers [18,19,20,21,22,23] \\\n        --ema_decay 0.9999 --ema_start_at 0 --ema_decay_init 0.999 \\\n        --batch_size 64 --lr 1e-3 --warmup_epochs 40 --epochs 800 \\\n        --clip_grad 3.0 --drop_path 0.2 --layer_scale_init_value 1e-5 \\\n        --layer_results 'end' \\\n        --l1_beta=2 \\\n\t--var_w0 0.0 --var_w1 0.0 --var_margin0 0.5 \\\n\t--max_mask_patches_per_block 196 --min_mask_patches_per_block 16 \\\n        --imagenet_default_mean_and_std --dist_url $dist_url --world_size 64 \\\n         --post_target_layer_norm  --attn_drop_rate 0.15 \\\n         --seed_model {PATH_TO_800EPOCH_MODEL}\n\n```\n\nCommand to finetune the ViT-L model\n```\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_cyclical.py \\\n        --model beit_large_patch16_224 \\\n        --finetune $CHECKPOINT \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --log_dir ${OUTPUT_DIR} --batch_size 64 --lr 5e-3 --update_freq 1 \\\n        --warmup_epochs $WARMUP --epochs 50 --layer_decay 0.65 --drop_path 0.25 --drop 0.0 \\\n        --weight_decay 0.05 --mixup 0.8 --cutmix 1.0 --enable_deepspeed --nb_classes 1000 --seed 0\\\n        --target_layer -1 --world_size 16 --dist_url $dist_url --attn_drop_rate 0.0\n\n\n```\n\n\n## LICENSE\nData2Vec is licensed under CC-BY-NC, however portions of the project are available under separate license terms: Unilm is licensed under the MIT license.\n\n## CITATION\nIf you find this repository useful, please consider citing our work:\n\n```\n@misc{https://doi.org/10.48550/arxiv.2202.03555,\n  doi = {10.48550/ARXIV.2202.03555},\n  url = {https://arxiv.org/abs/2202.03555},\n  author = {Baevski, Alexei and Hsu, Wei-Ning and Xu, Qiantong and Babu, Arun and Gu, Jiatao and Auli, Michael},\n  keywords = {Machine Learning (cs.LG), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {data2vec: A General Framework for Self-supervised Learning in Speech, Vision and Language},\n  publisher = {arXiv},\n  year = {2022},\n  copyright = {arXiv.org perpetual, non-exclusive license}\n}\n```\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/README_Original.md",
    "content": "# [BEiT: BERT Pre-Training of Image Transformers](https://arxiv.org/abs/2106.08254)\n\nOfficial PyTorch implementation and pretrained models of BEiT.\n\n- August 2021: [**BEiT**](https://huggingface.co/transformers/master/model_doc/beit.html) is on [HuggingFace](https://github.com/huggingface/transformers)\n- July 2021: BEiT-large achieves **[state-of-the-art results on ADE20K](https://paperswithcode.com/sota/semantic-segmentation-on-ade20k) (a big jump to 57.0 mIoU) for semantic segmentation**.\n- July 2021: BEiT-large achieves **state-of-the-art ImageNet top-1 accuracy (88.6%) under the setting without extra data other than ImageNet-22k**.\n- July 2021: release code and pretrained checkpoints (BEiT-base and BEiT-large)\n- June 2021: release preprint in [arXiv](https://arxiv.org/abs/2106.08254)\n\n\n---\n\n\n## Pretrained models\n\nWe provide four BEiT weights pretrained on ImageNet-22k. The models were pretrained with 224x224 resolution.\n\n- `BEiT-base`: #layer=12; hidden=768; FFN factor=4x; #head=12; patch=16x16 (#parameters: 86M)\n- `BEiT-large`: #layer=24; hidden=1024; FFN factor=4x; #head=16; patch=16x16 (#parameters: 304M)\n\nDownload checkpoints that are **self-supervised pretrained and then intermediate fine-tuned** on ImageNet-22k (recommended):\n- BEiT-base: [beit_base_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth)\n- BEiT-large: [beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth)\n\nDownload checkpoints that are **self-supervised pretrained** on ImageNet-22k:\n- BEiT-base: [beit_base_patch16_224_pt22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k.pth)\n- BEiT-large: [beit_large_patch16_224_pt22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k.pth)\n\n\n## Setup\n\n```\nalias=`whoami | cut -d'.' -f2`; docker run -it --rm --runtime=nvidia --ipc=host --privileged -v /home/${alias}:/home/${alias} pytorch/pytorch:1.7.1-cuda11.0-cudnn8-devel bash\n```\n\nFirst, clone the repo and install required packages:\n```\ngit clone https://github.com/microsoft/unilm.git\ncd unilm/beit\npip install -r requirements.txt\n```\n\nThe required packages including: [Pytorch](https://pytorch.org/) version 1.7.1, [torchvision](https://pytorch.org/vision/stable/index.html) version 0.8.2 and [Timm](https://github.com/rwightman/pytorch-image-models) version 0.3.2, etc.\n\nFor mixed-precision training, please install [apex](https://github.com/NVIDIA/apex)\n```\ngit clone https://github.com/NVIDIA/apex\ncd apex\npip install -v --disable-pip-version-check --no-cache-dir --global-option=\"--cpp_ext\" --global-option=\"--cuda_ext\" ./\n```\n\n\n## Fine-tuning on ImageNet-1k (image classification)\n\nWe summarize the validation results as follows. We also provide the fine-tuned weights and fine-tuning logs. The detailed instructions to reproduce the results can be found at [`get_started_for_image_classification.md`](get_started_for_image_classification.md).\n\n| name | initialized checkpoint | resolution | acc@1 | acc@5 | #params | weight | log |\n|------------|:----------------------------------------|:----------:|:-----:|:-----:|:-------:|-------------------|-----|\n| BEiT-base | [beit_base_patch16_224_pt22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k.pth) | 224x224 | 83.7 | 96.6 | 87M | [link](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft1k.pth) | [link](https://paste.ubuntu.com/p/79z5PncrKZ/) |\n| BEiT-base | [beit_base_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth) | 224x224 | 85.2 | 97.6 | 87M | [link](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/KqFh55cwq4/) |\n| BEiT-base | [beit_base_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth) | 384x384 | 86.8 | 98.1 | 87M | [link](https://unilm.blob.core.windows.net/beit/beit_base_patch16_384_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/jnpD4NGZQn/) |\n| BEiT-large | [beit_large_patch16_224_pt22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k.pth) | 224x224 | 86.0 | 97.6 | 304M | [link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft1k.pth) | [link](https://paste.ubuntu.com/p/r4X4gHq6W5/) |\n| BEiT-large | [beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth) | 224x224 | 87.4 | 98.3 | 304M | [link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/DpHhW5Zgk5/) |\n| BEiT-large | [beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth) | 384x384 | 88.4 | 98.6 | 305M | [link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_384_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/xKTBDwPMd2/) |\n| BEiT-large | [beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth) | 512x512 | 88.60 | 98.66 | 306M | [link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_512_pt22k_ft22kto1k.pth) | [link](https://paste.ubuntu.com/p/Wsb3NwkfCR/) |\n\n\n## Fine-tuning on ADE20K (segmantic segmentation)\n\nWe summarize the validation results as follows. We also provide the fine-tuned weights and fine-tuning logs. The detailed instructions to reproduce the results can be found at [`semantic_segmentation/README.md`](semantic_segmentation/README.md).\n\n|name|initialized checkpoint|method|crop size|Lr schd|mIoU|mIoU (ms+flip)|#params|weight|log|\n|:-----------|:---------------------|:-------:|:---------:|:-------:|:----:|:--------------:|:-------:|:-------|:---:|\n|BEiT-base|[beit_base_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth)|UPerNet|640x640|160k|53.6|54.2|194M|[link](https://unilm.blob.core.windows.net/beit/beit_base_patch16_640_pt22k_ft22ktoade20k.pth)|[link](https://paste.ubuntu.com/p/sdsWCDRzk2/)|\n|BEiT-large|[beit_large_patch16_224_pt22k_ft22k](https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth)|UPerNet|640x640|160k|56.7|57.0|502M|[link](https://unilm.blob.core.windows.net/beit/beit_large_patch16_640_pt22k_ft22ktoade20k.pth)|[link](https://paste.ubuntu.com/p/FKc2cvvJsC/)|\n\n\n## Example: Pre-training BEiT-base on ImageNet-22k\n\nThe BEiT-base model can be pretrained on ImageNet-22k using a DGX-2 box (16 V100-32GB):\n\n```bash\n# Set the path to save checkpoints\nOUTPUT_DIR=/path/to/save/your_model\n# Download and extract ImageNet-22k\nDATA_PATH=/path/to/imagenet22k\n# Download the tokenizer weight from OpenAI's DALL-E\nTOKENIZER_PATH=/path/to/save/dall_e_tokenizer_weight\nmkdir -p $TOKENIZER_PATH\nwget -o $TOKENIZER_PATH/encoder.pkl https://cdn.openai.com/dall-e/encoder.pkl\nwget -o $TOKENIZER_PATH/decoder.pkl https://cdn.openai.com/dall-e/decoder.pkl\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_beit_pretraining.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --num_mask_patches 75 \\\n        --model beit_base_patch16_224_8k_vocab --discrete_vae_weight_path ${TOKENIZER_PATH} \\\n        --batch_size 128 --lr 1.5e-3 --warmup_steps 10000 --epochs 150 \\\n        --clip_grad 3.0 --drop_path 0.1 --layer_scale_init_value 0.1\n```\n- `--num_mask_patches`: number of the input patches need be masked.\n- `--batch_size`: batch size per GPU.\n- Effective batch size = `number of GPUs` * `--batch_size`. So in the above example, the effective batch size is `128*16 = 2048`.\n- `--lr`: learning rate.\n- `--warmup_steps`: learning rate warmup steps.\n- `--epochs`: total pre-training epochs.\n- `--clip_grad`: clip gradient norm.\n- `--drop_path`: stochastic depth rate.\n- `--imagenet_default_mean_and_std`: enable this for ImageNet-1k pre-training, i.e., `(0.485, 0.456, 0.406)` for mean and `(0.229, 0.224, 0.225)` for std. We use `(0.5, 0.5, 0.5)` for mean and `(0.5, 0.5, 0.5)` for std by default on other pre-training data.\n- `--layer_scale_init_value`: 0.1 for base, 1e-5 for large, set 0 to disable layerscale.\n\n## Example: Pre-training BEiT-base on ImageNet-1k\n\nThe BEiT-base model can be pretrained on ImageNet-1k using a DGX-2 box (16 V100-32GB):\n```bash\n# Set the path to save checkpoints\nOUTPUT_DIR=/path/to/save/your_model\n# Download and extract ImageNet-1k\nDATA_PATH=/path/to/imagenet1k_train_set\n# Download the tokenizer weight from OpenAI's DALL-E\nTOKENIZER_PATH=/path/to/save/dall_e_tokenizer_weight\nmkdir -p $TOKENIZER_PATH\nwget -o $TOKENIZER_PATH/encoder.pkl https://cdn.openai.com/dall-e/encoder.pkl\nwget -o $TOKENIZER_PATH/decoder.pkl https://cdn.openai.com/dall-e/decoder.pkl\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_beit_pretraining.py \\\n        --data_path ${DATA_PATH} --output_dir ${OUTPUT_DIR} --num_mask_patches 75 \\\n        --model beit_base_patch16_224_8k_vocab --discrete_vae_weight_path ${TOKENIZER_PATH} \\\n        --batch_size 128 --lr 1.5e-3 --warmup_epochs 10 --epochs 300 \\\n        --clip_grad 3.0 --drop_path 0.1 --layer_scale_init_value 0.1 \\\n        --imagenet_default_mean_and_std\n```\n\n## Example: Fine-tuning BEiT on ImageNet-22k\n\nThe BEiT-large model can be fine-tuned on ImageNet-22k using a DGX-2 box (16 V100-32GB):\n\n```bash\n# Set the path to save checkpoints\nOUTPUT_DIR=/path/to/save/your_model\n# Download and extract ImageNet-22k\nDATA_PATH=/path/to/imagenet22k\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_class_finetuning.py \\\n    --model beit_large_patch16_224 --data_path $DATA_PATH \\\n    --nb_classes 21841 --data_set image_folder --disable_eval_during_finetuning \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k.pth \\\n    --output_dir $OUTPUT_DIR --batch_size 64 --lr 2e-3 --update_freq 2 \\\n    --warmup_epochs 5 --epochs 90 --layer_decay 0.75 --drop_path 0.2 \\\n    --weight_decay 0.05 --enable_deepspeed --layer_scale_init_value 1e-5 --clip_grad 1.0\n```\n- `--batch_size`: batch size per GPU.\n- Effective batch size = `number of GPUs` * `--batch_size` * `--update_freq`. So in the above example, the effective batch size is `16*64*2 = 2048`.\n- `--lr`: learning rate.\n- `--warmup_epochs`: learning rate warmup epochs.\n- `--epochs`: total pre-training epochs.\n- `--clip_grad`: clip gradient norm.\n- `--drop_path`: stochastic depth rate.\n- `--layer_scale_init_value`: 0.1 for base, 1e-5 for large, set 0 to disable layerscale.\n\nThe BEiT-base can be fine-tuned on ImageNet-22k as follows:\n\n```bash\n# Set the path to save checkpoints\nOUTPUT_DIR=/path/to/save/your_model\n# Download and extract ImageNet-22k\nDATA_PATH=/path/to/imagenet22k\n\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=16 run_class_finetuning.py \\\n    --model beit_base_patch16_224 --data_path $DATA_PATH \\\n    --nb_classes 21841 --data_set image_folder --disable_eval_during_finetuning \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k.pth \\\n    --output_dir $OUTPUT_DIR --batch_size 256 --lr 3e-3 --update_freq 1 \\\n    --warmup_epochs 5 --epochs 90 --layer_decay 0.65 --drop_path 0.2 \\\n    --weight_decay 0.05 --enable_deepspeed --layer_scale_init_value 0.1 --clip_grad 3.0\n```\n\n## Citation\n\nIf you find this repository useful, please consider citing our work:\n```\n@article{beit,\n      title={{BEiT}: {BERT} Pre-Training of Image Transformers}, \n      author={Hangbo Bao and Li Dong and Furu Wei},\n      year={2021},\n      eprint={2106.08254},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n\n## Acknowledgement\n\nThis repository is built using the [timm](https://github.com/rwightman/pytorch-image-models) library, the [DeiT](https://github.com/facebookresearch/deit) repository and the [Dino](https://github.com/facebookresearch/dino) repository.\n\n\n## License\nThis project is licensed under the license found in the LICENSE file in the root directory of this source tree.\n\n[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct)\n\n### Contact Information\n\nFor help or issues using BEiT models, please submit a GitHub issue.\n\nFor other communications related to UniLM AI, please contact Li Dong (`lidong1@microsoft.com`), [Furu Wei](http://gitnlp.org/) (`fuwei@microsoft.com`).\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/dall_e/__init__.py",
    "content": "import io, requests\nimport torch\nimport torch.nn as nn\n\nfrom .encoder import Encoder\nfrom .decoder import Decoder\nfrom .utils   import map_pixels, unmap_pixels\n\ndef load_model(path: str, device: torch.device = None) -> nn.Module:\n    if path.startswith('http://') or path.startswith('https://'):\n        resp = requests.get(path)\n        resp.raise_for_status()\n            \n        with io.BytesIO(resp.content) as buf:\n            return torch.load(buf, map_location=device)\n    else:\n        with open(path, 'rb') as f:\n            return torch.load(f, map_location=device)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/dall_e/decoder.py",
    "content": "import attr\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom collections  import OrderedDict\nfrom functools    import partial\nfrom .utils import Conv2d\n\n@attr.s(eq=False, repr=False)\nclass DecoderBlock(nn.Module):\n\tn_in:     int = attr.ib(validator=lambda i, a, x: x >= 1)\n\tn_out:    int = attr.ib(validator=lambda i, a, x: x >= 1 and x % 4 ==0)\n\tn_layers: int = attr.ib(validator=lambda i, a, x: x >= 1)\n\n\tdevice:        torch.device = attr.ib(default=None)\n\trequires_grad: bool         = attr.ib(default=False)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\t\tself.n_hid = self.n_out // 4\n\t\tself.post_gain = 1 / (self.n_layers ** 2)\n\n\t\tmake_conv     = partial(Conv2d, device=self.device, requires_grad=self.requires_grad)\n\t\tself.id_path  = make_conv(self.n_in, self.n_out, 1) if self.n_in != self.n_out else nn.Identity()\n\t\tself.res_path = nn.Sequential(OrderedDict([\n\t\t\t\t('relu_1', nn.ReLU()),\n\t\t\t\t('conv_1', make_conv(self.n_in,  self.n_hid, 1)),\n\t\t\t\t('relu_2', nn.ReLU()),\n\t\t\t\t('conv_2', make_conv(self.n_hid, self.n_hid, 3)),\n\t\t\t\t('relu_3', nn.ReLU()),\n\t\t\t\t('conv_3', make_conv(self.n_hid, self.n_hid, 3)),\n\t\t\t\t('relu_4', nn.ReLU()),\n\t\t\t\t('conv_4', make_conv(self.n_hid, self.n_out, 3)),]))\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\treturn self.id_path(x) + self.post_gain * self.res_path(x)\n\n@attr.s(eq=False, repr=False)\nclass Decoder(nn.Module):\n\tgroup_count:     int = 4\n\tn_init:          int = attr.ib(default=128,  validator=lambda i, a, x: x >= 8)\n\tn_hid:           int = attr.ib(default=256,  validator=lambda i, a, x: x >= 64)\n\tn_blk_per_group: int = attr.ib(default=2,    validator=lambda i, a, x: x >= 1)\n\toutput_channels: int = attr.ib(default=3,    validator=lambda i, a, x: x >= 1)\n\tvocab_size:      int = attr.ib(default=8192, validator=lambda i, a, x: x >= 512)\n\n\tdevice:              torch.device = attr.ib(default=torch.device('cpu'))\n\trequires_grad:       bool         = attr.ib(default=False)\n\tuse_mixed_precision: bool         = attr.ib(default=True)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\n\t\tblk_range  = range(self.n_blk_per_group)\n\t\tn_layers   = self.group_count * self.n_blk_per_group\n\t\tmake_conv  = partial(Conv2d, device=self.device, requires_grad=self.requires_grad)\n\t\tmake_blk   = partial(DecoderBlock, n_layers=n_layers, device=self.device,\n\t\t\t\trequires_grad=self.requires_grad)\n\n\t\tself.blocks = nn.Sequential(OrderedDict([\n\t\t\t('input', make_conv(self.vocab_size, self.n_init, 1, use_float16=False)),\n\t\t\t('group_1', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(self.n_init if i == 0 else 8 * self.n_hid, 8 * self.n_hid)) for i in blk_range],\n\t\t\t\t('upsample', nn.Upsample(scale_factor=2, mode='nearest')),\n\t\t\t]))),\n\t\t\t('group_2', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(8 * self.n_hid if i == 0 else 4 * self.n_hid, 4 * self.n_hid)) for i in blk_range],\n\t\t\t\t('upsample', nn.Upsample(scale_factor=2, mode='nearest')),\n\t\t\t]))),\n\t\t\t('group_3', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(4 * self.n_hid if i == 0 else 2 * self.n_hid, 2 * self.n_hid)) for i in blk_range],\n\t\t\t\t('upsample', nn.Upsample(scale_factor=2, mode='nearest')),\n\t\t\t]))),\n\t\t\t('group_4', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(2 * self.n_hid if i == 0 else 1 * self.n_hid, 1 * self.n_hid)) for i in blk_range],\n\t\t\t]))),\n\t\t\t('output', nn.Sequential(OrderedDict([\n\t\t\t\t('relu', nn.ReLU()),\n\t\t\t\t('conv', make_conv(1 * self.n_hid, 2 * self.output_channels, 1)),\n\t\t\t]))),\n\t\t]))\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\tif len(x.shape) != 4:\n\t\t\traise ValueError(f'input shape {x.shape} is not 4d')\n\t\tif x.shape[1] != self.vocab_size:\n\t\t\traise ValueError(f'input has {x.shape[1]} channels but model built for {self.vocab_size}')\n\t\tif x.dtype != torch.float32:\n\t\t\traise ValueError('input must have dtype torch.float32')\n\n\t\treturn self.blocks(x)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/dall_e/encoder.py",
    "content": "import attr\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom collections  import OrderedDict\nfrom functools    import partial\nfrom .utils import Conv2d\n\n@attr.s(eq=False, repr=False)\nclass EncoderBlock(nn.Module):\n\tn_in:     int = attr.ib(validator=lambda i, a, x: x >= 1)\n\tn_out:    int = attr.ib(validator=lambda i, a, x: x >= 1 and x % 4 ==0)\n\tn_layers: int = attr.ib(validator=lambda i, a, x: x >= 1)\n\n\tdevice:        torch.device = attr.ib(default=None)\n\trequires_grad: bool         = attr.ib(default=False)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\t\tself.n_hid = self.n_out // 4\n\t\tself.post_gain = 1 / (self.n_layers ** 2)\n\n\t\tmake_conv     = partial(Conv2d, device=self.device, requires_grad=self.requires_grad)\n\t\tself.id_path  = make_conv(self.n_in, self.n_out, 1) if self.n_in != self.n_out else nn.Identity()\n\t\tself.res_path = nn.Sequential(OrderedDict([\n\t\t\t\t('relu_1', nn.ReLU()),\n\t\t\t\t('conv_1', make_conv(self.n_in,  self.n_hid, 3)),\n\t\t\t\t('relu_2', nn.ReLU()),\n\t\t\t\t('conv_2', make_conv(self.n_hid, self.n_hid, 3)),\n\t\t\t\t('relu_3', nn.ReLU()),\n\t\t\t\t('conv_3', make_conv(self.n_hid, self.n_hid, 3)),\n\t\t\t\t('relu_4', nn.ReLU()),\n\t\t\t\t('conv_4', make_conv(self.n_hid, self.n_out, 1)),]))\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\treturn self.id_path(x) + self.post_gain * self.res_path(x)\n\n@attr.s(eq=False, repr=False)\nclass Encoder(nn.Module):\n\tgroup_count:     int = 4\n\tn_hid:           int = attr.ib(default=256,  validator=lambda i, a, x: x >= 64)\n\tn_blk_per_group: int = attr.ib(default=2,    validator=lambda i, a, x: x >= 1)\n\tinput_channels:  int = attr.ib(default=3,    validator=lambda i, a, x: x >= 1)\n\tvocab_size:      int = attr.ib(default=8192, validator=lambda i, a, x: x >= 512)\n\n\tdevice:              torch.device = attr.ib(default=torch.device('cpu'))\n\trequires_grad:       bool         = attr.ib(default=False)\n\tuse_mixed_precision: bool         = attr.ib(default=True)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\n\t\tblk_range  = range(self.n_blk_per_group)\n\t\tn_layers   = self.group_count * self.n_blk_per_group\n\t\tmake_conv  = partial(Conv2d, device=self.device, requires_grad=self.requires_grad)\n\t\tmake_blk   = partial(EncoderBlock, n_layers=n_layers, device=self.device,\n\t\t\t\trequires_grad=self.requires_grad)\n\n\t\tself.blocks = nn.Sequential(OrderedDict([\n\t\t\t('input', make_conv(self.input_channels, 1 * self.n_hid, 7)),\n\t\t\t('group_1', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(1 * self.n_hid, 1 * self.n_hid)) for i in blk_range],\n\t\t\t\t('pool', nn.MaxPool2d(kernel_size=2)),\n\t\t\t]))),\n\t\t\t('group_2', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(1 * self.n_hid if i == 0 else 2 * self.n_hid, 2 * self.n_hid)) for i in blk_range],\n\t\t\t\t('pool', nn.MaxPool2d(kernel_size=2)),\n\t\t\t]))),\n\t\t\t('group_3', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(2 * self.n_hid if i == 0 else 4 * self.n_hid, 4 * self.n_hid)) for i in blk_range],\n\t\t\t\t('pool', nn.MaxPool2d(kernel_size=2)),\n\t\t\t]))),\n\t\t\t('group_4', nn.Sequential(OrderedDict([\n\t\t\t\t*[(f'block_{i + 1}', make_blk(4 * self.n_hid if i == 0 else 8 * self.n_hid, 8 * self.n_hid)) for i in blk_range],\n\t\t\t]))),\n\t\t\t('output', nn.Sequential(OrderedDict([\n\t\t\t\t('relu', nn.ReLU()),\n\t\t\t\t('conv', make_conv(8 * self.n_hid, self.vocab_size, 1, use_float16=False)),\n\t\t\t]))),\n\t\t]))\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\tif len(x.shape) != 4:\n\t\t\traise ValueError(f'input shape {x.shape} is not 4d')\n\t\tif x.shape[1] != self.input_channels:\n\t\t\traise ValueError(f'input has {x.shape[1]} channels but model built for {self.input_channels}')\n\t\tif x.dtype != torch.float32:\n\t\t\traise ValueError('input must have dtype torch.float32')\n\n\t\treturn self.blocks(x)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/dall_e/utils.py",
    "content": "import attr\nimport math\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nlogit_laplace_eps: float = 0.1\n\n@attr.s(eq=False)\nclass Conv2d(nn.Module):\n\tn_in:  int = attr.ib(validator=lambda i, a, x: x >= 1)\n\tn_out: int = attr.ib(validator=lambda i, a, x: x >= 1)\n\tkw:    int = attr.ib(validator=lambda i, a, x: x >= 1 and x % 2 == 1)\n\n\tuse_float16:   bool         = attr.ib(default=True)\n\tdevice:        torch.device = attr.ib(default=torch.device('cpu'))\n\trequires_grad: bool         = attr.ib(default=False)\n\n\tdef __attrs_post_init__(self) -> None:\n\t\tsuper().__init__()\n\n\t\tw = torch.empty((self.n_out, self.n_in, self.kw, self.kw), dtype=torch.float32,\n\t\t\tdevice=self.device, requires_grad=self.requires_grad)\n\t\tw.normal_(std=1 / math.sqrt(self.n_in * self.kw ** 2))\n\n\t\tb = torch.zeros((self.n_out,), dtype=torch.float32, device=self.device,\n\t\t\trequires_grad=self.requires_grad)\n\t\tself.w, self.b = nn.Parameter(w), nn.Parameter(b)\n\n\tdef forward(self, x: torch.Tensor) -> torch.Tensor:\n\t\tif self.use_float16 and 'cuda' in self.w.device.type:\n\t\t\tif x.dtype != torch.float16:\n\t\t\t\tx = x.half()\n\n\t\t\tw, b = self.w.half(), self.b.half()\n\t\telse:\n\t\t\tif x.dtype != torch.float32:\n\t\t\t\tx = x.float()\n\n\t\t\tw, b = self.w, self.b\n\n\t\treturn F.conv2d(x, w, b, padding=(self.kw - 1) // 2)\n\ndef map_pixels(x: torch.Tensor) -> torch.Tensor:\n\tif x.dtype != torch.float:\n\t\traise ValueError('expected input to have type float')\n\n\treturn (1 - 2 * logit_laplace_eps) * x + logit_laplace_eps\n\ndef unmap_pixels(x: torch.Tensor) -> torch.Tensor:\n\tif len(x.shape) != 4:\n\t\traise ValueError('expected input to be 4d')\n\tif x.dtype != torch.float:\n\t\traise ValueError('expected input to have type float')\n\n\treturn torch.clamp((x - logit_laplace_eps) / (1 - 2 * logit_laplace_eps), 0, 1)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/dataset_folder.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Modified on torchvision code bases\n# https://github.com/pytorch/vision\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nfrom torchvision.datasets.vision import VisionDataset\n\nfrom PIL import Image\n\nimport os\nimport os.path\nimport random\nfrom typing import Any, Callable, cast, Dict, List, Optional, Tuple\n\n\ndef has_file_allowed_extension(filename: str, extensions: Tuple[str, ...]) -> bool:\n    \"\"\"Checks if a file is an allowed extension.\n\n    Args:\n        filename (string): path to a file\n        extensions (tuple of strings): extensions to consider (lowercase)\n\n    Returns:\n        bool: True if the filename ends with one of given extensions\n    \"\"\"\n    return filename.lower().endswith(extensions)\n\n\ndef is_image_file(filename: str) -> bool:\n    \"\"\"Checks if a file is an allowed image extension.\n\n    Args:\n        filename (string): path to a file\n\n    Returns:\n        bool: True if the filename ends with a known image extension\n    \"\"\"\n    return has_file_allowed_extension(filename, IMG_EXTENSIONS)\n\n\ndef make_dataset(\n    directory: str,\n    class_to_idx: Dict[str, int],\n    extensions: Optional[Tuple[str, ...]] = None,\n    is_valid_file: Optional[Callable[[str], bool]] = None,\n) -> List[Tuple[str, int]]:\n    instances = []\n    directory = os.path.expanduser(directory)\n    both_none = extensions is None and is_valid_file is None\n    both_something = extensions is not None and is_valid_file is not None\n    if both_none or both_something:\n        raise ValueError(\"Both extensions and is_valid_file cannot be None or not None at the same time\")\n    if extensions is not None:\n        def is_valid_file(x: str) -> bool:\n            return has_file_allowed_extension(x, cast(Tuple[str, ...], extensions))\n    is_valid_file = cast(Callable[[str], bool], is_valid_file)\n    for target_class in sorted(class_to_idx.keys()):\n        class_index = class_to_idx[target_class]\n        target_dir = os.path.join(directory, target_class)\n        if not os.path.isdir(target_dir):\n            continue\n        for root, _, fnames in sorted(os.walk(target_dir, followlinks=True)):\n            for fname in sorted(fnames):\n                path = os.path.join(root, fname)\n                if is_valid_file(path):\n                    item = path, class_index\n                    instances.append(item)\n    return instances\n\n\nclass DatasetFolder(VisionDataset):\n    \"\"\"A generic data loader where the samples are arranged in this way: ::\n\n        root/class_x/xxx.ext\n        root/class_x/xxy.ext\n        root/class_x/xxz.ext\n\n        root/class_y/123.ext\n        root/class_y/nsdf3.ext\n        root/class_y/asd932_.ext\n\n    Args:\n        root (string): Root directory path.\n        loader (callable): A function to load a sample given its path.\n        extensions (tuple[string]): A list of allowed extensions.\n            both extensions and is_valid_file should not be passed.\n        transform (callable, optional): A function/transform that takes in\n            a sample and returns a transformed version.\n            E.g, ``transforms.RandomCrop`` for images.\n        target_transform (callable, optional): A function/transform that takes\n            in the target and transforms it.\n        is_valid_file (callable, optional): A function that takes path of a file\n            and check if the file is a valid file (used to check of corrupt files)\n            both extensions and is_valid_file should not be passed.\n\n     Attributes:\n        classes (list): List of the class names sorted alphabetically.\n        class_to_idx (dict): Dict with items (class_name, class_index).\n        samples (list): List of (sample path, class_index) tuples\n        targets (list): The class_index value for each image in the dataset\n    \"\"\"\n\n    def __init__(\n            self,\n            root: str,\n            loader: Callable[[str], Any],\n            extensions: Optional[Tuple[str, ...]] = None,\n            transform: Optional[Callable] = None,\n            target_transform: Optional[Callable] = None,\n            is_valid_file: Optional[Callable[[str], bool]] = None,\n    ) -> None:\n        super(DatasetFolder, self).__init__(root, transform=transform,\n                                            target_transform=target_transform)\n        print(\"finding classes\")\n        classes, class_to_idx = self._find_classes(self.root)\n        print(\"making dataset\")\n        samples = make_dataset(self.root, class_to_idx, extensions, is_valid_file)\n        if len(samples) == 0:\n            msg = \"Found 0 files in subfolders of: {}\\n\".format(self.root)\n            if extensions is not None:\n                msg += \"Supported extensions are: {}\".format(\",\".join(extensions))\n            raise RuntimeError(msg)\n\n        self.loader = loader\n        self.extensions = extensions\n\n        self.classes = classes\n        self.class_to_idx = class_to_idx\n        self.samples = samples\n        self.targets = [s[1] for s in samples]\n        print(\"done initializing dataset folder\")\n\n    def _find_classes(self, dir: str) -> Tuple[List[str], Dict[str, int]]:\n        \"\"\"\n        Finds the class folders in a dataset.\n\n        Args:\n            dir (string): Root directory path.\n\n        Returns:\n            tuple: (classes, class_to_idx) where classes are relative to (dir), and class_to_idx is a dictionary.\n\n        Ensures:\n            No class is a subdirectory of another.\n        \"\"\"\n        classes = [d.name for d in os.scandir(dir) if d.is_dir()]\n        classes.sort()\n        class_to_idx = {cls_name: i for i, cls_name in enumerate(classes)}\n        return classes, class_to_idx\n\n    def __getitem__(self, index: int) -> Tuple[Any, Any]:\n        \"\"\"\n        Args:\n            index (int): Index\n\n        Returns:\n            tuple: (sample, target) where target is class_index of the target class.\n        \"\"\"\n        while True:\n            try:\n                path, target = self.samples[index]\n                sample = self.loader(path)\n                break\n            except Exception as e:\n                print(e)\n                index = random.randint(0, len(self.samples) - 1)\n\n        if self.transform is not None:\n            sample = self.transform(sample)\n        if self.target_transform is not None:\n            target = self.target_transform(target)\n\n        return sample, target\n\n    def __len__(self) -> int:\n        return len(self.samples)\n\n\nIMG_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif', '.tiff', '.webp')\n\n\ndef pil_loader(path: str) -> Image.Image:\n    # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835)\n    with open(path, 'rb') as f:\n        img = Image.open(f)\n        return img.convert('RGB')\n\n\n# TODO: specify the return type\ndef accimage_loader(path: str) -> Any:\n    import accimage\n    try:\n        return accimage.Image(path)\n    except IOError:\n        # Potentially a decoding problem, fall back to PIL.Image\n        return pil_loader(path)\n\n\ndef default_loader(path: str) -> Any:\n    from torchvision import get_image_backend\n    from shutil import copyfile\n    import os\n\n    #sp = path.split('/')\n    #name = sp[-1]\n    #base = '/'.join(sp[:-1])\n\n    #image_cache_str = \"image_cache6\"\n\n    # if os.path.exists('/scratch/'+image_cache_str+'/') and not os.access('/scratch/'+image_cache_str+'/', os.R_OK):\n    #     image_cache_str = \"image_cache3\"\n\n    #if not os.path.isdir('scratch/'+image_cache_str+'/' + base):\n    #    os.makedirs('scratch/'+image_cache_str+'/'+ base)\n\n    #if not os.path.exists('scratch/'+image_cache_str+'/' + path):\n    #    copyfile(path, 'scratch/'+image_cache_str+'/' + path)\n    #path = 'scratch/'+image_cache_str+'/' + path\n    #print('name', name)\n    #print('base', base)\n    #print('path', path)\n\n    if get_image_backend() == 'accimage':\n        return accimage_loader(path)\n    else:\n        return pil_loader(path)\n\n\nclass ImageFolder(DatasetFolder):\n    \"\"\"A generic data loader where the images are arranged in this way: ::\n\n        root/dog/xxx.png\n        root/dog/xxy.png\n        root/dog/xxz.png\n\n        root/cat/123.png\n        root/cat/nsdf3.png\n        root/cat/asd932_.png\n\n    Args:\n        root (string): Root directory path.\n        transform (callable, optional): A function/transform that  takes in an PIL image\n            and returns a transformed version. E.g, ``transforms.RandomCrop``\n        target_transform (callable, optional): A function/transform that takes in the\n            target and transforms it.\n        loader (callable, optional): A function to load an image given its path.\n        is_valid_file (callable, optional): A function that takes path of an Image file\n            and check if the file is a valid file (used to check of corrupt files)\n\n     Attributes:\n        classes (list): List of the class names sorted alphabetically.\n        class_to_idx (dict): Dict with items (class_name, class_index).\n        imgs (list): List of (image path, class_index) tuples\n    \"\"\"\n\n    def __init__(\n            self,\n            root: str,\n            transform: Optional[Callable] = None,\n            target_transform: Optional[Callable] = None,\n            loader: Callable[[str], Any] = default_loader,\n            is_valid_file: Optional[Callable[[str], bool]] = None,\n            filter: Optional[str] = None\n    ):\n        super(ImageFolder, self).__init__(root, loader, IMG_EXTENSIONS if is_valid_file is None else None,\n                                          transform=transform,\n                                          target_transform=target_transform,\n                                          is_valid_file=is_valid_file)\n        self.imgs = self.samples\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/datasets.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport os\nimport torch\nimport numpy as np\n\nfrom torchvision import datasets, transforms\n\n\nfrom timm.data import create_transform\n\nfrom .dall_e.utils import map_pixels\nfrom .masking_generator import MaskingGenerator\nfrom .dataset_folder import ImageFolder\nfrom PIL import Image\nfrom models.moco_v3 import loader as moco_loader\nfrom datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\nfrom sklearn.model_selection import train_test_split\n\n\nfrom cvtorchvision import cvtransforms\n\n\n\nclass SeasonTransform:\n\n    def __init__(self, base_transform, season='fixed'):\n        self.base_transform = base_transform\n        self.season = season\n\n    def __call__(self, x):\n\n        if self.season=='augment':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = np.random.choice([0,1,2,3])\n            \n            x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n            x2 = np.transpose(x[season2,:,:,:],(1,2,0))            \n            image = self.base_transform(x1)\n            #target = self.base_transform2(x2)\n            return image, target\n            \n        elif self.season=='fixed':\n            np.random.seed(42)\n            season1 = np.random.choice([0,1,2,3])\n\n        elif self.season=='random':\n            season1 = np.random.choice([0,1,2,3])\n\n        x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n        image = self.base_transform(x1)\n        return image\n\nclass DataAugmentations(object):\n    def __init__(self, args):\n        if args.aug_level == 0:\n            print(\"Please\")\n            base_transform = transforms.Compose([\n                cvtransforms.CenterCrop(size=args.in_size), \n            ])\n            \n        elif args.aug_level == 1:\n            base_transform = transforms.Compose([\n                cvtransforms.CenterCrop(size=args.in_size), \n                cvtransforms.RandomHorizontalFlip()\n            ])\n        elif args.aug_level == 2:\n            base_transform = transforms.Compose([\n                cvtransforms.RandomResizedCrop(args.in_size, scale=(args.crop_min, 1.)), \n                cvtransforms.RandomHorizontalFlip()\n            ])\n        elif args.aug_level == 3:\n            base_transform = transforms.Compose([\n                cvtransforms.RandomResizedCrop(args.in_size, scale=(args.crop_min, 1.)),\n                cvtransforms.RandomApply([\n                    RandomBrightness(0.4),\n                    RandomContrast(0.4)\n                ], p=0.8),\n                cvtransforms.RandomApply([ToGray(13)], p=0.2),\n                cvtransforms.RandomApply([moco_loader.GaussianBlur([.1, 2.])], p=1.0),\n                cvtransforms.RandomHorizontalFlip(),\n                cvtransforms.RandomApply([RandomChannelDrop(min_n_drop=1, max_n_drop=6)], p=0.5),  \n            ])  \n        else:\n            base_transform = transforms.Compose([cvtransforms.ToTensor()])\n            \n        self.common_transform = SeasonTransform(base_transform, season=args.season)\n        \n        self.patch_transform = transforms.Compose([\n                cvtransforms.ToTensor()\n                #transforms.Normalize(\n                #    mean=torch.tensor(0),\n                #    std=torch.tensor(1))\n            ])\n        \n        if getattr(args, 'discrete_vae_type', None) is None:\n            self.visual_token_transform = lambda z: z\n        elif args.discrete_vae_type == \"dall-e\":\n            self.visual_token_transform = transforms.Compose([\n                transforms.ToTensor(),\n                map_pixels,\n            ])\n        elif args.discrete_vae_type == \"customized\":\n            self.visual_token_transform = transforms.Compose([\n                transforms.ToTensor(),\n                transforms.Normalize(\n                    mean=IMAGENET_INCEPTION_MEAN,\n                    std=IMAGENET_INCEPTION_STD,\n                ),\n            ])\n        else:\n            raise NotImplementedError()\n        \n        self.masked_position_generator = MaskingGenerator(\n            args.window_size, num_masking_patches=args.num_mask_patches,\n            max_num_patches=args.max_mask_patches_per_block,\n            min_num_patches=args.min_mask_patches_per_block,\n        )\n    \n    def __call__(self, image):\n        z = self.common_transform(image)\n        if isinstance(z, tuple):\n            for_patches, for_visual_tokens = z\n            return \\\n                self.patch_transform(for_patches), self.visual_token_transform(for_visual_tokens), \\\n                self.masked_position_generator()\n        else:\n            return self.patch_transform(z), self.masked_position_generator()\n\n\n    def __repr__(self):\n        repr = \"(DataAugmentationForBEiT,\\n\"\n        repr += \"  common_transform = %s,\\n\" % str(self.common_transform)\n        repr += \"  patch_transform = %s,\\n\" % str(self.patch_transform)\n        repr += \"  visual_tokens_transform = %s,\\n\" % str(self.visual_token_transform)\n        repr += \"  Masked position generator = %s,\\n\" % str(self.masked_position_generator)\n        repr += \")\"\n        return repr\n\n    \n\ndef build_beit_pretraining_dataset(args):\n    transform = DataAugmentations(args)\n    train_dataset = LMDBDataset(\n        lmdb_file=args.data_path,\n        s2c_transform=transform,#TwoCropsTransform(base_transform1=cvtransforms.Compose(augmentation1), base_transform2 = cvtransforms.Compose(augmentation2),season=args.season),\n        is_slurm_job=False,#args.is_slurm_job,\n        normalize=False,\n        dtype=args.dtype,\n        mode=args.mode\n    )\n    return train_dataset\n    \n\n        \n\ndef build_transform(is_train, args):\n    resize_im = args.input_size > 32\n    imagenet_default_mean_and_std = args.imagenet_default_mean_and_std\n    mean = IMAGENET_INCEPTION_MEAN if not imagenet_default_mean_and_std else IMAGENET_DEFAULT_MEAN\n    std = IMAGENET_INCEPTION_STD if not imagenet_default_mean_and_std else IMAGENET_DEFAULT_STD\n\n    if is_train:\n        # this should always dispatch to transforms_imagenet_train\n        transform = create_transform(\n            input_size=args.input_size,\n            is_training=True,\n            color_jitter=args.color_jitter,\n            auto_augment=args.aa,\n            interpolation=args.train_interpolation,\n            re_prob=args.reprob,\n            re_mode=args.remode,\n            re_count=args.recount,\n            mean=mean,\n            std=std,\n        )\n        if not resize_im:\n            # replace RandomResizedCropAndInterpolation with\n            # RandomCrop\n            transform.transforms[0] = transforms.RandomCrop(\n                args.input_size, padding=4)\n        return transform\n\n    t = []\n    if resize_im:\n        if args.crop_pct is None:\n            if args.input_size < 384:\n                args.crop_pct = 224 / 256\n            else:\n                args.crop_pct = 1.0\n        size = int(args.input_size / args.crop_pct)\n        t.append(\n            transforms.Resize(size, interpolation=3),  # to maintain same ratio w.r.t. 224 images\n        )\n        t.append(transforms.CenterCrop(args.input_size))\n\n    t.append(transforms.ToTensor())\n    t.append(transforms.Normalize(mean, std))\n    return transforms.Compose(t)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/engine_for_cyclical.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport sys\nfrom typing import Iterable\n\nimport torch\nimport torch.nn.functional as F\n\nfrom . import utils\n\n\ndef train_one_epoch(model: torch.nn.Module, model_ema: torch.nn.Module, ema_start_at, decay_init, decay, target_layers,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,     \n                    l1_beta: float = 0.12,\n                    log_writer=None, lr_scheduler=None, start_steps=None,\n                    lr_schedule_values=None, wd_schedule_values=None, l2_loss=False, layer_results='end',\n                    var_w0=0, var_w1=0, var_margin0=0.5, var_margin1=0.5, start_lr_decay_at_step=-1,loss_scale=-1, mask_dropout_prob=-1.0,\n                    target_layer_norm_last=True, target_batch_norm=False, target_instance_norm=False,post_target_instance_norm=False,post_target_layer_norm=False):\n    print(' <<<<<<<< layer_results >>>>>>>>', layer_results)\n    print(' <<<<<<<< var_w0, var_w1 >>>>>>>>', var_w0, var_w1)\n    model.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('min_lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('loss_var0', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    # metric_logger.add_meter('loss_var1', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 10\n\n    cur_decay = decay\n    for step, batch in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n    #for batch in data_loader:\n        # assign learning rate & weight decay for each step\n        it = start_steps + step  # global training iteration\n        if lr_schedule_values is not None or wd_schedule_values is not None:\n            for i, param_group in enumerate(optimizer.param_groups):\n                if lr_schedule_values is not None:\n                    param_group[\"lr\"] = lr_schedule_values[it] * param_group[\"lr_scale\"]\n                if wd_schedule_values is not None and param_group[\"weight_decay\"] > 0:\n                    param_group[\"weight_decay\"] = wd_schedule_values[it]\n\n        if it < ema_start_at:\n            cur_decay = decay_init + it * (decay - decay_init) / ema_start_at \n        \n        samples, bool_masked_pos = batch\n        samples = samples.to(device, non_blocking=True)\n        bool_masked_pos = bool_masked_pos.to(device, non_blocking=True)\n\n        if mask_dropout_prob > 0:\n            new_mask_tensor = torch.ones_like(bool_masked_pos, dtype=samples.dtype)\n            new_mask_tensor.fill_(1-mask_dropout_prob)\n            bool_new_mask_tensor = torch.bernoulli(new_mask_tensor)\n            bool_masked_pos = torch.logical_and(bool_new_mask_tensor, bool_masked_pos)\n        \n        with torch.no_grad():\n            targets = model_ema.module(samples, bool_masked_pos=None, return_all_tokens=True, layer_results=layer_results)\n            fsz = targets[0].size(-1)\n            #shape of targets[0] == b x t x dim\n            layer_vals = [targets[i] for i in target_layers]\n            \n            if target_instance_norm or target_batch_norm:\n                layer_vals = [val.permute(0,2,1) for val in layer_vals] # btc => bct\n\n            if target_batch_norm:\n                layer_vals = [F.batch_norm(val.float(), running_mean=None, running_var=None, training=True) for val in layer_vals] # bct => bct\n\n            if target_instance_norm:\n                layer_vals = [F.instance_norm(val.float()) for val in layer_vals] # bct => bct\n            \n            if target_instance_norm or target_batch_norm:\n                layer_vals = [val.permute(0,2,1) for val in layer_vals] # bct => btc\n\n            if target_layer_norm_last:\n                layer_vals = (F.layer_norm(val.float(), (fsz,)) for val in layer_vals)\n\n            targets = sum(layer_vals) / len(target_layers)\n\n            if post_target_instance_norm:\n                targets = targets.permute(0,2,1)\n                targets = F.instance_norm(targets.float())\n                targets = targets.permute(0,2,1)\n\n            if post_target_layer_norm:\n                targets = F.layer_norm(targets.float(), (fsz,))\n\n            fsz = targets.size(-1)\n            target_mask = bool_masked_pos.flatten().bool()\n            targets = targets.reshape(-1, fsz)[target_mask]\n\n        with torch.cuda.amp.autocast():\n            outputs = model(samples, bool_masked_pos=bool_masked_pos, return_all_tokens=False)\n\n        outputs = outputs.float()\n\n        eps=1e-6\n        z0 = outputs.reshape(-1, outputs.size(-1))\n        z0 = torch.sqrt(z0.var(dim=0) + eps)\n\n        if var_w0 > 0:\n            std_loss0 = torch.sum(F.relu(var_margin0 - z0)) / z0.size(0)\n        else:\n            std_loss0 = 0\n\n        # z1 = torch.sqrt(outputs.var(dim=1) + eps)\n        # std_loss1 = torch.sum(F.relu(var_margin1 - z1)) / outputs.size(0)\n\n        # print(outputs.shape)\n        outputs = outputs.reshape(-1, fsz)\n        assert outputs.shape == targets.shape\n        if l2_loss:\n            loss_cyc = F.mse_loss(outputs, targets)\n        else:\n            loss_cyc = F.smooth_l1_loss(outputs, targets, beta=l1_beta)\n\n        # loss = loss_cyc + std_loss0 * var_w0 + std_loss1 * var_w1\n        loss = loss_cyc + std_loss0 * var_w0 \n        if loss_scale!=-1:\n            loss = loss * loss_scale\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value), force=True)\n            sys.exit(1)\n\n        optimizer.zero_grad()\n        # this attribute is added by timm on one optimizer (adahessian)\n        is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order\n        grad_norm = loss_scaler(loss, optimizer, clip_grad=max_norm,\n                                parameters=model.parameters(), create_graph=is_second_order)\n        loss_scale_value = loss_scaler.state_dict()[\"scale\"]\n\n        # if it == ema_start_at and ema_start_at > 0:\n        #     print(f\"setting EMA to model params at update {it}\")\n        #     model_ema.set(model)\n        # elif it >= ema_start_at:\n        #     model_ema.update(model)\n        if cur_decay!=1 and (start_lr_decay_at_step==-1 or it<=start_lr_decay_at_step):\n            model_ema._update(model, update_fn=lambda e, m: cur_decay * e + (1. - cur_decay) * m)\n        else:\n            cur_decay=0\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        metric_logger.update(loss_scale=loss_scale_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n        metric_logger.update(min_lr=min_lr)\n        metric_logger.update(loss_var0=std_loss0)\n        # metric_logger.update(loss_var1=std_loss1)\n        weight_decay_value = None\n        for group in optimizer.param_groups:\n            if group[\"weight_decay\"] > 0:\n                weight_decay_value = group[\"weight_decay\"]\n        metric_logger.update(weight_decay=weight_decay_value)\n        metric_logger.update(grad_norm=grad_norm)\n        metric_logger.update(cur_decay=cur_decay)\n\n        if log_writer is not None:\n            log_writer.update(loss=loss_value, head=\"loss\")\n            # log_writer.update(std_loss0=std_loss0.item(), head=\"std_loss0\")\n            # log_writer.update(std_loss1=std_loss1.item(), head=\"std_loss1\")\n            log_writer.update(loss_scale=loss_scale_value, head=\"opt\")\n            log_writer.update(lr=max_lr, head=\"opt\")\n            log_writer.update(min_lr=min_lr, head=\"opt\")\n            log_writer.update(weight_decay=weight_decay_value, head=\"opt\")\n            log_writer.update(grad_norm=grad_norm, head=\"opt\")\n            log_writer.update(cur_decay=cur_decay, head=\"cur_decay\")\n\n            log_writer.set_step()\n\n        if lr_scheduler is not None:\n            lr_scheduler.step_update(start_steps + step)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/engine_for_cyclical_joint.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport sys\nfrom typing import Iterable\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nimport utils\n\n\ndef train_one_epoch(model: torch.nn.Module, model_ema: torch.nn.Module, ema_start_at, target_layers,\n                    d_vae: torch.nn.Module, vae_loss_weight: float,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0, l1_beta: float = 0.12,\n                    log_writer=None, lr_scheduler=None, start_steps=None,\n                    lr_schedule_values=None, wd_schedule_values=None, l2_loss=False):\n    model.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('min_lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('loss_cyc', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('loss_beit', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 10\n\n    for step, (batch, _) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n        # assign learning rate & weight decay for each step\n        it = start_steps + step  # global training iteration\n        if lr_schedule_values is not None or wd_schedule_values is not None:\n            for i, param_group in enumerate(optimizer.param_groups):\n                if lr_schedule_values is not None:\n                    param_group[\"lr\"] = lr_schedule_values[it] * param_group[\"lr_scale\"]\n                if wd_schedule_values is not None and param_group[\"weight_decay\"] > 0:\n                    param_group[\"weight_decay\"] = wd_schedule_values[it]\n\n        samples, images, bool_masked_pos = batch\n\n        images = images.to(device, non_blocking=True)\n        samples = samples.to(device, non_blocking=True)\n        bool_masked_pos = bool_masked_pos.to(device, non_blocking=True)\n\n        with torch.no_grad():\n            targets = model_ema.module(samples, bool_masked_pos=None, return_all_tokens=True, layer_results=True)\n            fsz = targets[0].size(-1)\n\n            targets = sum(F.layer_norm(targets[i], (fsz,)) for i in target_layers) / len(target_layers)\n\n            fsz = targets.size(-1)\n            target_mask = bool_masked_pos.flatten().bool()\n            targets = targets.reshape(-1, fsz)[target_mask]\n\n            # beit part\n            input_ids = d_vae.get_codebook_indices(images).flatten(1)\n            bool_masked_pos = bool_masked_pos.flatten(1).to(torch.bool)\n            labels = input_ids[bool_masked_pos]\n\n        with torch.cuda.amp.autocast():\n            outputs, beit_outputs = model(samples, bool_masked_pos=bool_masked_pos, return_all_tokens=False)\n            outputs = outputs.reshape(-1, fsz)\n            assert outputs.shape == targets.shape\n            if l2_loss:\n                cyc_loss = F.mse_loss(outputs, targets)\n            else:\n                cyc_loss = F.smooth_l1_loss(outputs, targets, beta=l1_beta)\n\n            # beit part\n            beit_loss = nn.CrossEntropyLoss()(input=beit_outputs, target=labels)\n\n        # loss = cyc_loss / (vae_loss_weight + 1) + beit_loss * vae_loss_weight / (vae_loss_weight + 1)\n        beit_w = max(1 - (epoch / vae_loss_weight), 0)\n        loss = cyc_loss * (1 - beit_w) + beit_loss * beit_w\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        optimizer.zero_grad()\n        # this attribute is added by timm on one optimizer (adahessian)\n        is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order\n        grad_norm = loss_scaler(loss, optimizer, clip_grad=max_norm,\n                                parameters=model.parameters(), create_graph=is_second_order)\n        loss_scale_value = loss_scaler.state_dict()[\"scale\"]\n\n        if it == ema_start_at and ema_start_at > 0:\n            print(f\"setting EMA to model params at update {it}\")\n            model_ema.set(model)\n        elif it >= ema_start_at:\n            model_ema.update(model)\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        metric_logger.update(loss_scale=loss_scale_value)\n        metric_logger.update(loss_cyc=cyc_loss.item())\n        metric_logger.update(loss_beit=beit_loss.item())\n        # metric_logger.update(loss_cyc=cyc_loss.item(), head=\"loss_cyc\")\n        # metric_logger.update(loss_beit=beit_loss.item(), head=\"loss_beit\")\n\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n        metric_logger.update(min_lr=min_lr)\n        weight_decay_value = None\n        for group in optimizer.param_groups:\n            if group[\"weight_decay\"] > 0:\n                weight_decay_value = group[\"weight_decay\"]\n        metric_logger.update(weight_decay=weight_decay_value)\n        metric_logger.update(grad_norm=grad_norm)\n\n        if log_writer is not None:\n            log_writer.update(loss=loss_value, head=\"loss\")\n            log_writer.update(loss=cyc_loss.item(), head=\"loss_cyc\")\n            log_writer.update(loss=beit_loss.item(), head=\"loss_beit\")\n            log_writer.update(loss_scale=loss_scale_value, head=\"opt\")\n            log_writer.update(lr=max_lr, head=\"opt\")\n            log_writer.update(min_lr=min_lr, head=\"opt\")\n            log_writer.update(weight_decay=weight_decay_value, head=\"opt\")\n            log_writer.update(grad_norm=grad_norm, head=\"opt\")\n\n            log_writer.set_step()\n\n        if lr_scheduler is not None:\n            lr_scheduler.step_update(start_steps + step)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/engine_for_finetuning.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy, ModelEma\nfrom sklearn.metrics import average_precision_score\n\n\nfrom . import utils\n\n\ndef train_class_batch(model, samples, target, criterion, bool_masked_pos=None):\n    outputs = model(samples, bool_masked_pos=bool_masked_pos)\n    loss = criterion(outputs, target)\n    return loss, outputs\n\n\ndef get_loss_scale_for_deepspeed(model):\n    optimizer = model.optimizer\n    return optimizer.loss_scale if hasattr(optimizer, \"loss_scale\") else optimizer.cur_scale\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    model_ema: Optional[ModelEma] = None, mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    start_steps=None, lr_schedule_values=None, wd_schedule_values=None,\n                    num_training_steps_per_epoch=None, update_freq=None, masked_position_generator=None, metric='acc', padd=False, onehot=False):\n    model.train(True)\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('min_lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 10\n\n    if loss_scaler is None:\n        model.zero_grad()\n        model.micro_steps = 0\n    else:\n        optimizer.zero_grad()\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n        if onehot:\n            targets = torch.argmax(targets, axis=1).long()\n        if padd:\n            b_zeros = torch.zeros((samples.shape[0],1,samples.shape[2],samples.shape[3]),dtype=torch.float32)\n            samples = torch.cat((samples[:,:10,:,:],b_zeros,samples[:,10:,:,:]),dim=1)\n        \n        step = data_iter_step // update_freq\n        if step >= num_training_steps_per_epoch:\n            continue\n        it = start_steps + step  # global training iteration\n        # Update LR & WD for the first acc\n        if lr_schedule_values is not None or wd_schedule_values is not None and data_iter_step % update_freq == 0:\n            for i, param_group in enumerate(optimizer.param_groups):\n                if lr_schedule_values is not None:\n                    param_group[\"lr\"] = lr_schedule_values[it] * param_group[\"lr_scale\"]\n                if wd_schedule_values is not None and param_group[\"weight_decay\"] > 0:\n                    param_group[\"weight_decay\"] = wd_schedule_values[it]\n\n        bool_masked_pos = None\n        if masked_position_generator is not None:\n            bool_masked_pos = torch.tensor([masked_position_generator() for _ in range(samples.size(0))], device=device)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n\n        if loss_scaler is None:\n            samples = samples.half()\n            loss, output = train_class_batch(\n                model, samples, targets, criterion, bool_masked_pos)\n        else:\n            with torch.cuda.amp.autocast():\n                loss, output = train_class_batch(\n                    model, samples, targets, criterion, bool_masked_pos)\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value), force=True)\n            sys.exit(1)\n\n        if loss_scaler is None:\n            loss /= update_freq\n            model.backward(loss)\n            model.step()\n\n            if (data_iter_step + 1) % update_freq == 0:\n                # model.zero_grad()\n                # Deepspeed will call step() & model.zero_grad() automatic\n                if model_ema is not None:\n                    model_ema.update(model)\n            grad_norm = None\n            loss_scale_value = get_loss_scale_for_deepspeed(model)\n        else:\n            # this attribute is added by timm on one optimizer (adahessian)\n            is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order\n            loss /= update_freq\n            grad_norm = loss_scaler(loss, optimizer, clip_grad=max_norm,\n                                    parameters=model.parameters(), create_graph=is_second_order,\n                                    update_grad=(data_iter_step + 1) % update_freq == 0)\n            if (data_iter_step + 1) % update_freq == 0:\n                optimizer.zero_grad()\n                if model_ema is not None:\n                    model_ema.update(model)\n            loss_scale_value = loss_scaler.state_dict()[\"scale\"]\n\n        torch.cuda.synchronize()\n\n        #if mixup_fn is None:\n        if metric == 'acc':\n            class_acc = (output.max(-1)[-1] == targets).float().mean()\n        elif metric == 'map':\n            class_acc = average_precision_score(targets.cpu().detach().numpy(), output.cpu().detach().numpy(), average='micro') \n        #else:\n        #    class_acc = None\n            \n            \n        metric_logger.update(loss=loss_value)\n        metric_logger.update(class_acc=class_acc)\n        metric_logger.update(loss_scale=loss_scale_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n        metric_logger.update(min_lr=min_lr)\n        weight_decay_value = None\n        for group in optimizer.param_groups:\n            if group[\"weight_decay\"] > 0:\n                weight_decay_value = group[\"weight_decay\"]\n        metric_logger.update(weight_decay=weight_decay_value)\n        metric_logger.update(grad_norm=grad_norm)\n\n        if log_writer is not None:\n            log_writer.update(loss=loss_value, head=\"loss\")\n            log_writer.update(class_acc=class_acc, head=\"loss\")\n            log_writer.update(loss_scale=loss_scale_value, head=\"opt\")\n            log_writer.update(lr=max_lr, head=\"opt\")\n            log_writer.update(min_lr=min_lr, head=\"opt\")\n            log_writer.update(weight_decay=weight_decay_value, head=\"opt\")\n            log_writer.update(grad_norm=grad_norm, head=\"opt\")\n\n            log_writer.set_step()\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device, metric='acc', padd=False, onehot=False):\n    if metric == 'acc':\n        criterion = torch.nn.CrossEntropyLoss()\n    elif metric == 'map':\n        criterion = torch.nn.MultiLabelSoftMarginLoss()\n\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n         \n        images = batch[0]\n        if padd:\n            b_zeros = torch.zeros((images.shape[0],1,images.shape[2],images.shape[3]),dtype=torch.float32)\n            images = torch.cat((images[:,:10,:,:],b_zeros,images[:,10:,:,:]),dim=1)\n        \n        target = batch[-1]\n        \n        if onehot:\n            target = torch.argmax(target, axis=1).long()\n            \n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, target)\n        \n        if metric == 'acc':\n            acc1, acc5 = accuracy(output, target, topk=(1, 5))\n        elif metric == 'map':\n            acc1 = average_precision_score(target.cpu().detach().numpy(), output.cpu().detach().numpy(), average='micro') \n            acc5 = acc1\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/engine_for_pretraining.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\nimport math\nimport sys\nfrom typing import Iterable\n\nimport torch\nimport torch.nn as nn\n\nimport utils\n\n\ndef train_one_epoch(model: torch.nn.Module, d_vae: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    log_writer=None, lr_scheduler=None, start_steps=None,\n                    lr_schedule_values=None, wd_schedule_values=None):\n    model.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    metric_logger.add_meter('min_lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 10\n\n    for step, (batch, _) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n        # assign learning rate & weight decay for each step\n        it = start_steps + step  # global training iteration\n        if lr_schedule_values is not None or wd_schedule_values is not None:\n            for i, param_group in enumerate(optimizer.param_groups):\n                if lr_schedule_values is not None:\n                    param_group[\"lr\"] = lr_schedule_values[it] * param_group[\"lr_scale\"]\n                if wd_schedule_values is not None and param_group[\"weight_decay\"] > 0:\n                    param_group[\"weight_decay\"] = wd_schedule_values[it]\n\n        samples, images, bool_masked_pos = batch\n\n        images = images.to(device, non_blocking=True)\n        samples = samples.to(device, non_blocking=True)\n        bool_masked_pos = bool_masked_pos.to(device, non_blocking=True)\n\n        with torch.no_grad():\n            input_ids = d_vae.get_codebook_indices(images).flatten(1)\n            bool_masked_pos = bool_masked_pos.flatten(1).to(torch.bool)\n            labels = input_ids[bool_masked_pos]\n\n        with torch.cuda.amp.autocast():\n            outputs = model(samples, bool_masked_pos=bool_masked_pos, return_all_tokens=False)\n            loss = nn.CrossEntropyLoss()(input=outputs, target=labels)\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        optimizer.zero_grad()\n        # this attribute is added by timm on one optimizer (adahessian)\n        is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order\n        grad_norm = loss_scaler(loss, optimizer, clip_grad=max_norm,\n                                parameters=model.parameters(), create_graph=is_second_order)\n        loss_scale_value = loss_scaler.state_dict()[\"scale\"]\n\n        torch.cuda.synchronize()\n\n        mlm_acc = (outputs.max(-1)[1] == labels).float().mean().item()\n\n        metric_logger.update(mlm_acc=mlm_acc)\n        if log_writer is not None:\n            log_writer.update(mlm_acc=mlm_acc, head=\"loss\")\n\n        metric_logger.update(loss=loss_value)\n        metric_logger.update(loss_scale=loss_scale_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n        metric_logger.update(min_lr=min_lr)\n        weight_decay_value = None\n        for group in optimizer.param_groups:\n            if group[\"weight_decay\"] > 0:\n                weight_decay_value = group[\"weight_decay\"]\n        metric_logger.update(weight_decay=weight_decay_value)\n        metric_logger.update(grad_norm=grad_norm)\n\n        if log_writer is not None:\n            log_writer.update(loss=loss_value, head=\"loss\")\n            log_writer.update(loss_scale=loss_scale_value, head=\"opt\")\n            log_writer.update(lr=max_lr, head=\"opt\")\n            log_writer.update(min_lr=min_lr, head=\"opt\")\n            log_writer.update(weight_decay=weight_decay_value, head=\"opt\")\n            log_writer.update(grad_norm=grad_norm, head=\"opt\")\n\n            log_writer.set_step()\n\n        if lr_scheduler is not None:\n            lr_scheduler.step_update(start_steps + step)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/get_started_for_image_classification.md",
    "content": "# Fine-tuning BEiT on ImageNet-1k (image classification)\n\n## Setup\n\n1. [Setup environment](README.md#setup).\n2. Download and extract ImageNet-1k from http://image-net.org/.\n\nThe directory structure is the standard layout of torchvision's [`datasets.ImageFolder`](https://pytorch.org/docs/stable/torchvision/datasets.html#imagefolder). The training and validation data are expected to be in the `train/` folder and `val` folder, respectively:\n\n```\n/path/to/imagenet/\n  train/\n    class1/\n      img1.jpeg\n    class2/\n      img2.jpeg\n  val/\n    class1/\n      img3.jpeg\n    class/2\n      img4.jpeg\n```\n\n\n## Fine-tuning\n\nWe recommend you to use the checkpoints that are **self-supervised pretrained and then intermediate fine-tuned** on ImageNet-22k for better performance. We use following commands to fine-tune BEiT-large with 8 V100-16GB cards:\n```bash\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n    --model beit_large_patch16_224 --data_path /path/to/imagenet \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth \\\n    --output_dir /path/to/save_result --batch_size 32 --lr 2e-5 --update_freq 2 \\\n    --warmup_epochs 5 --epochs 30 --layer_decay 0.9 --drop_path 0.4 \\\n    --weight_decay 1e-8 --enable_deepspeed\n```\n- `--batch_size`: batch size per GPU.\n- `--update_freq`: gradient accumulation steps.\n- Effective batch size = `number of GPUs` * `--batch_size` * `--update_freq`. So in the above example, the effective batch size is `8*32*2 = 512`. The three arguments need to be adjusted together in order to keep the total batch size unchanged.\n- Gradient accumulation: if your GPU memory is limited (i.e., OOM issues), you can reduce `--batch size` and increase `--update_freq` to use the same effective batch size.\n- `--enable_deepspeed`: enable [deepspeed](https://github.com/microsoft/DeepSpeed) during fine-tuning, which uses Apex O2 mixed-precision training. If without this argument, the code will use torch.amp for fine-tuning.\n- In order to fine-tune BEiT in higher resolution (such as 384), we can set `--input_size 384` and reset `--model beit_large_patch16_384`. Gradient accumulation can be used for OOM issues.\n\nFor BEiT-base, we set `--layer_decay 0.85 --drop_path 0.1` and keep other arguments unchanged as follows:\n```bash\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n    --model beit_base_patch16_224 --data_path /path/to/imagenet \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth \\\n    --output_dir /path/to/save_result --batch_size 64 --lr 2e-5 --update_freq 1 \\\n    --warmup_epochs 5 --epochs 30 --layer_decay 0.85 --drop_path 0.1 \\\n    --weight_decay 1e-8 --enable_deepspeed\n```\n\nFor the BEiT models that are fully self-supervised pretrained on ImageNet-22k (without intermediate fine-tuning on ImageNet-22k), we recommend you to enable mixup and cutmix during fine-tuning. We use the following commands for BEiT-large and BEiT-base:\n\n```bash\n# BEiT-large\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n    --model beit_large_patch16_224 --data_path /path/to/imagenet \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k.pth \\\n    --output_dir /path/to/save_result --batch_size 64 --lr 1e-3 --update_freq 2 \\\n    --warmup_epochs 5 --epochs 50 --layer_decay 0.75 --drop_path 0.2 \\\n    --weight_decay 0.05 --mixup 0.8 --cutmix 1.0 --enable_deepspeed\n# BEiT-base\nOMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=8 run_class_finetuning.py \\\n    --model beit_base_patch16_224 --data_path /path/to/imagenet \\\n    --finetune https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k.pth \\\n    --output_dir /path/to/save_result --batch_size 128 --lr 4e-3 --update_freq 1 \\\n    --warmup_epochs 20 --epochs 100 --layer_decay 0.65 --drop_path 0.1 \\\n    --weight_decay 0.05 --mixup 0.8 --cutmix 1.0 --enable_deepspeed\n```\n\n\n## Evaluate our fine-tuned checkpoints\n\n- Evaluate our fine-tuned BEiT-large model in 224 resolution on ImageNet val with a single GPU:\n```bash\npython run_class_finetuning.py \\\n    --eval --model beit_large_patch16_224 --data_path /path/to/imagenet \\\n    --resume https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22kto1k.pth \n```\nExpected results:\n```\n* Acc@1 87.396 Acc@5 98.282 loss 0.515\n```\n\n- Evaluate our fine-tuned BEiT-base model in 384 resolution on ImageNet val with a single GPU:\n```bash\npython run_class_finetuning.py \\\n    --eval --model beit_base_patch16_384 --input_size 384 --data_path /path/to/imagenet \\\n    --resume https://unilm.blob.core.windows.net/beit/beit_base_patch16_384_pt22k_ft22kto1k.pth \n```\nExpected results:\n```\n* Acc@1 86.820 Acc@5 98.124 loss 0.565\n```\n\n- Evaluate our fine-tuned BEiT-large model in 384 resolution on ImageNet val with a single GPU:\n```bash\npython run_class_finetuning.py \\\n    --eval --model beit_large_patch16_384 --input_size 384 --data_path /path/to/imagenet \\\n    --resume https://unilm.blob.core.windows.net/beit/beit_large_patch16_384_pt22k_ft22kto1k.pth \n```\nExpected results:\n```\n* Acc@1 88.408 Acc@5 98.602 loss 0.479\n```\n\n- Evaluate our fine-tuned BEiT-large model in 512 resolution on ImageNet val with a single GPU:\n```bash\npython run_class_finetuning.py \\\n    --eval --model beit_large_patch16_512 --input_size 512 --data_path /path/to/imagenet \\\n    --resume https://unilm.blob.core.windows.net/beit/beit_large_patch16_512_pt22k_ft22kto1k.pth \n```\nExpected results:\n```\n* Acc@1 88.600 Acc@5 98.658 loss 0.474\n```\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/masking_generator.py",
    "content": "\"\"\"\nOriginally inspired by impl at https://github.com/zhunzhong07/Random-Erasing, Apache 2.0\nCopyright Zhun Zhong & Liang Zheng\n\nHacked together by / Copyright 2020 Ross Wightman\n\nModified by Hangbo Bao, for generating the masked position for visual image transformer\n\"\"\"\n# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# Originally inspired by impl at https://github.com/zhunzhong07/Random-Erasing, Apache 2.0\n# Copyright Zhun Zhong & Liang Zheng\n#\n# Hacked together by / Copyright 2020 Ross Wightman\n#\n# Modified by Hangbo Bao, for generating the masked position for visual image transformer\n# --------------------------------------------------------'\nimport random\nimport math\nimport numpy as np\n\n\nclass MaskingGenerator:\n    def __init__(\n            self, input_size, num_masking_patches, min_num_patches=4, max_num_patches=None,\n            min_aspect=0.3, max_aspect=None):\n        if not isinstance(input_size, tuple):\n            input_size = (input_size, ) * 2\n        self.height, self.width = input_size\n\n        self.num_patches = self.height * self.width\n        self.num_masking_patches = num_masking_patches\n\n        self.min_num_patches = min_num_patches\n        self.max_num_patches = num_masking_patches if max_num_patches is None else max_num_patches\n\n        max_aspect = max_aspect or 1 / min_aspect\n        self.log_aspect_ratio = (math.log(min_aspect), math.log(max_aspect))\n\n    def __repr__(self):\n        repr_str = \"Generator(%d, %d -> [%d ~ %d], max = %d, %.3f ~ %.3f)\" % (\n            self.height, self.width, self.min_num_patches, self.max_num_patches,\n            self.num_masking_patches, self.log_aspect_ratio[0], self.log_aspect_ratio[1])\n        return repr_str\n\n    def get_shape(self):\n        return self.height, self.width\n\n    def _mask(self, mask, max_mask_patches):\n        delta = 0\n        for attempt in range(10):\n            target_area = random.uniform(self.min_num_patches, max_mask_patches)\n            aspect_ratio = math.exp(random.uniform(*self.log_aspect_ratio))\n            h = int(round(math.sqrt(target_area * aspect_ratio)))\n            w = int(round(math.sqrt(target_area / aspect_ratio)))\n            if w < self.width and h < self.height:\n                top = random.randint(0, self.height - h)\n                left = random.randint(0, self.width - w)\n\n                num_masked = mask[top: top + h, left: left + w].sum()\n                # Overlap\n                if 0 < h * w - num_masked <= max_mask_patches:\n                    for i in range(top, top + h):\n                        for j in range(left, left + w):\n                            if mask[i, j] == 0:\n                                mask[i, j] = 1\n                                delta += 1\n\n                if delta > 0:\n                    break\n        return delta\n\n    def __call__(self):\n        mask = np.zeros(shape=self.get_shape(), dtype=np.int)\n        mask_count = 0\n        while mask_count < self.num_masking_patches:\n            max_mask_patches = self.num_masking_patches - mask_count\n            max_mask_patches = min(max_mask_patches, self.max_num_patches)\n\n            delta = self._mask(mask, max_mask_patches)\n            if delta == 0:\n                break\n            else:\n                mask_count += delta\n\n        return mask\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/modeling_cyclical.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport torch\nimport torch.nn as nn\nfrom functools import partial\n\nfrom .modeling_finetune import Block, _cfg, PatchEmbed, RelativePositionBias\nfrom timm.models.registry import register_model\nfrom timm.models.layers import trunc_normal_ as __call_trunc_normal_\n\n\ndef trunc_normal_(tensor, mean=0.0, std=1.0):\n    __call_trunc_normal_(tensor, mean=mean, std=std, a=-std, b=std)\n\n\n__all__ = [\n    \"beit_base_patch16_224\",\n    # 'beit_large_patch16_224_8k_vocab',\n]\n\n\nclass VisionTransformerForCyclicalTraining(nn.Module):\n    def __init__(\n        self,\n        img_size=224,\n        patch_size=16,\n        in_chans=3,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4.0,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.0,\n        attn_drop_rate=0.0,\n        drop_path_rate=0.0,\n        norm_layer=None,\n        init_values=None,\n        attn_head_dim=None,\n        use_abs_pos_emb=True,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=False,\n        init_std=0.02,\n    ):\n        super().__init__()\n        self.num_features = (\n            self.embed_dim\n        ) = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size,\n            patch_size=patch_size,\n            in_chans=in_chans,\n            embed_dim=embed_dim,\n        )\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(\n                window_size=self.patch_embed.patch_shape, num_heads=num_heads\n            )\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, depth)\n        ]  # stochastic depth decay rule\n        self.blocks = nn.ModuleList(\n            [\n                Block(\n                    dim=embed_dim,\n                    num_heads=num_heads,\n                    mlp_ratio=mlp_ratio,\n                    qkv_bias=qkv_bias,\n                    qk_scale=qk_scale,\n                    drop=drop_rate,\n                    attn_drop=attn_drop_rate,\n                    drop_path=dpr[i],\n                    norm_layer=norm_layer,\n                    init_values=init_values,\n                    window_size=self.patch_embed.patch_shape\n                    if use_rel_pos_bias\n                    else None,\n                    attn_head_dim=attn_head_dim,\n                )\n                for i in range(depth)\n            ]\n        )\n        self.norm = norm_layer(embed_dim)\n\n        self.init_std = init_std\n        # self.lm_head = nn.Sequential(\n        #     nn.Linear(embed_dim, embed_dim * 2),\n        #     nn.GELU(),\n        #     nn.Linear(embed_dim * 2, embed_dim),\n        # )\n        # self.lm_head = nn.Sequential(\n        #     nn.Linear(embed_dim, embed_dim),\n        # )\n        self.lm_head = nn.Linear(embed_dim, embed_dim)\n        \n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=self.init_std)\n        trunc_normal_(self.cls_token, std=self.init_std)\n        trunc_normal_(self.mask_token, std=self.init_std)\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=self.init_std)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n        elif isinstance(m, nn.Conv2d):\n            trunc_normal_(m.weight, std=self.init_std)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {\"pos_embed\", \"cls_token\"}\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    def forward_features(self, x, bool_masked_pos, layer_results):\n        x = self.patch_embed(x, bool_masked_pos=bool_masked_pos)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(\n            batch_size, -1, -1\n        )  # stole cls_tokens impl from Phil Wang, thanks\n        mask_token = self.mask_token.expand(batch_size, seq_len, -1)\n\n        if bool_masked_pos is not None:\n            # replace the masked visual tokens by mask_token\n            w = bool_masked_pos.view(bool_masked_pos.size(0), -1, 1).type_as(mask_token)\n            x = x * (1 - w) + mask_token * w # B x T x C\n            \n            # print(bool_masked_pos.shape)\n            # print(bool_masked_pos.sum((1,2)))\n            # print('x', x.shape)\n            # bool_masked = bool_masked_pos.reshape(bool_masked_pos.size(0), -1).bool()\n            # print('bool_masked', bool_masked.shape)\n            # print('asd1', x[bool_masked].shape)\n            # exit(0)\n\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n\n        z = []\n        for i, blk in enumerate(self.blocks):\n            x, fc_feature = blk(x, rel_pos_bias=rel_pos_bias)\n            if layer_results == 'end':\n                z.append(x)\n            elif layer_results == 'fc':\n                z.append(fc_feature)\n\n        return z if layer_results else self.norm(x)\n\n    def forward(self, x, bool_masked_pos, return_all_tokens=False, layer_results=None):\n        x = self.forward_features(\n            x, bool_masked_pos=bool_masked_pos, layer_results=layer_results\n        )\n        if layer_results:\n            return [z[:, 1:] for z in x]\n        elif return_all_tokens:\n            x = x[:, 1:]\n            return self.lm_head(x)\n        else:\n            # return the masked tokens\n            x = x[:, 1:]\n            bsz = x.size(0)\n            fsz = x.size(-1)\n            bool_masked_pos = bool_masked_pos.flatten().bool()\n            x = x.reshape(-1, fsz)[bool_masked_pos]\n            return self.lm_head(x)\n\n\n@register_model\ndef beit_base_patch16_224(pretrained=False, **kwargs):\n    #_ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalTraining(\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n@register_model\ndef beit_small_patch16_224(pretrained=False, **kwargs):\n    #_ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalTraining(\n        patch_size=16,\n        in_chans=13,\n        embed_dim=384,\n        depth=12,\n        num_heads=6,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n@register_model\ndef beit_large_patch16_224(pretrained=False, **kwargs):\n    # _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalTraining(\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n@register_model\ndef beit_huge_patch16_224(pretrained=False, **kwargs):\n    # _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalTraining(\n        patch_size=16,\n        embed_dim=1280,\n        depth=32,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n# @register_model\n# def beit_large_patch16_224_8k_vocab(pretrained=False, **kwargs):\n#     _ = kwargs.pop(\"num_classes\")\n#     model = VisionTransformerForMaskedImageModeling(\n#         patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n#         norm_layer=partial(nn.LayerNorm, eps=1e-6), vocab_size=8192, **kwargs)\n#     model.default_cfg = _cfg()\n#     if pretrained:\n#         checkpoint = torch.load(\n#             kwargs[\"init_ckpt\"], map_location=\"cpu\"\n#         )\n#         model.load_state_dict(checkpoint[\"model\"])\n#     return model\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/modeling_cyclical_joint.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport torch\nimport torch.nn as nn\nfrom functools import partial\n\nfrom modeling_finetune import Block, _cfg, PatchEmbed, RelativePositionBias\nfrom timm.models.registry import register_model\nfrom timm.models.layers import trunc_normal_ as __call_trunc_normal_\n\n\ndef trunc_normal_(tensor, mean=0.0, std=1.0):\n    __call_trunc_normal_(tensor, mean=mean, std=std, a=-std, b=std)\n\n\n__all__ = [\n    \"beit_base_joint_patch16_224\",\n    # 'beit_large_patch16_224_8k_vocab',\n]\n\n\nclass VisionTransformerForCyclicalJointTraining(nn.Module):\n    def __init__(\n        self,\n        img_size=224,\n        patch_size=16,\n        in_chans=3,\n        vocab_size=8192,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4.0,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.0,\n        attn_drop_rate=0.0,\n        drop_path_rate=0.0,\n        norm_layer=None,\n        init_values=None,\n        attn_head_dim=None,\n        use_abs_pos_emb=True,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=False,\n        init_std=0.02,\n    ):\n        super().__init__()\n        self.num_features = (\n            self.embed_dim\n        ) = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size,\n            patch_size=patch_size,\n            in_chans=in_chans,\n            embed_dim=embed_dim,\n        )\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(\n                window_size=self.patch_embed.patch_shape, num_heads=num_heads\n            )\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, depth)\n        ]  # stochastic depth decay rule\n        self.blocks = nn.ModuleList(\n            [\n                Block(\n                    dim=embed_dim,\n                    num_heads=num_heads,\n                    mlp_ratio=mlp_ratio,\n                    qkv_bias=qkv_bias,\n                    qk_scale=qk_scale,\n                    drop=drop_rate,\n                    attn_drop=attn_drop_rate,\n                    drop_path=dpr[i],\n                    norm_layer=norm_layer,\n                    init_values=init_values,\n                    window_size=self.patch_embed.patch_shape\n                    if use_rel_pos_bias\n                    else None,\n                    attn_head_dim=attn_head_dim,\n                )\n                for i in range(depth)\n            ]\n        )\n        self.norm = norm_layer(embed_dim)\n\n        self.init_std = init_std\n        self.lm_head = nn.Sequential(\n            nn.Linear(embed_dim, embed_dim * 2),\n            nn.GELU(),\n            nn.Linear(embed_dim * 2, embed_dim),\n        )\n        self.beit_head = nn.Linear(embed_dim, vocab_size)\n\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=self.init_std)\n        trunc_normal_(self.cls_token, std=self.init_std)\n        trunc_normal_(self.mask_token, std=self.init_std)\n        trunc_normal_(self.beit_head.weight, std=self.init_std)\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=self.init_std)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n        elif isinstance(m, nn.Conv2d):\n            trunc_normal_(m.weight, std=self.init_std)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {\"pos_embed\", \"cls_token\"}\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    def forward_features(self, x, bool_masked_pos, layer_results):\n        x = self.patch_embed(x, bool_masked_pos=bool_masked_pos)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(\n            batch_size, -1, -1\n        )  # stole cls_tokens impl from Phil Wang, thanks\n        mask_token = self.mask_token.expand(batch_size, seq_len, -1)\n\n        if bool_masked_pos is not None:\n            # replace the masked visual tokens by mask_token\n            w = bool_masked_pos.view(bool_masked_pos.size(0), -1, 1).type_as(mask_token)\n            x = x * (1 - w) + mask_token * w\n\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n\n        z = []\n        for i, blk in enumerate(self.blocks):\n            x, _ = blk(x, rel_pos_bias=rel_pos_bias)\n            if layer_results:\n                z.append(x)\n\n        return z if layer_results else self.norm(x)\n\n    def forward(self, x, bool_masked_pos, return_all_tokens=False, layer_results=False):\n        x = self.forward_features(\n            x, bool_masked_pos=bool_masked_pos, layer_results=layer_results\n        )\n        if layer_results:\n            return [z[:, 1:] for z in x]\n        elif return_all_tokens:\n            x = x[:, 1:]\n            return self.lm_head(x), self.beit_head(x)\n        else:\n            # return the masked tokens\n            x = x[:, 1:]\n            bsz = x.size(0)\n            fsz = x.size(-1)\n            bool_masked_pos = bool_masked_pos.flatten().bool()\n            x = x.reshape(-1, fsz)[bool_masked_pos]\n            return self.lm_head(x), self.beit_head(x)\n\n\n@register_model\ndef beit_base_joint_patch16_224(pretrained=False, **kwargs):\n    _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForCyclicalJointTraining(\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        vocab_size=8192,\n        **kwargs\n    )\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(kwargs[\"init_ckpt\"], map_location=\"cpu\")\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n# @register_model\n# def beit_large_patch16_224_8k_vocab(pretrained=False, **kwargs):\n#     _ = kwargs.pop(\"num_classes\")\n#     model = VisionTransformerForMaskedImageModeling(\n#         patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n#         norm_layer=partial(nn.LayerNorm, eps=1e-6), vocab_size=8192, **kwargs)\n#     model.default_cfg = _cfg()\n#     if pretrained:\n#         checkpoint = torch.load(\n#             kwargs[\"init_ckpt\"], map_location=\"cpu\"\n#         )\n#         model.load_state_dict(checkpoint[\"model\"])\n#     return model\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/modeling_discrete_vae.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on OpenAI DALL-E and lucidrains' DALLE-pytorch code bases\n# https://github.com/openai/DALL-E\n# https://github.com/lucidrains/DALLE-pytorch\n# --------------------------------------------------------'\nfrom math import sqrt\nimport os\nimport torch\nfrom torch import nn, einsum\nimport torch.nn.functional as F\nfrom einops import rearrange\n\n\ndef top_k(logits, thres = 0.5):\n    num_logits = logits.shape[-1]\n    k = max(int((1 - thres) * num_logits), 1)\n    val, ind = torch.topk(logits, k)\n    probs = torch.full_like(logits, float('-inf'))\n    probs.scatter_(1, ind, val)\n    return probs\n\n\ndef exists(val):\n    return val is not None\n\n\ndef default(val, d):\n    return val if exists(val) else d\n\n\ndef eval_decorator(fn):\n    def inner(model, *args, **kwargs):\n        was_training = model.training\n        model.eval()\n        out = fn(model, *args, **kwargs)\n        model.train(was_training)\n        return out\n    return inner\n\n\nclass BasicVAE(nn.Module):\n\n    def get_codebook_indices(self, images):\n        raise NotImplementedError()\n\n    def decode(self, img_seq):\n        raise NotImplementedError()\n\n    def get_codebook_probs(self, img_seq):\n        raise NotImplementedError()\n\n    def get_image_tokens_size(self):\n        pass\n\n    def get_image_size(self):\n        pass\n\n\nclass ResBlock(nn.Module):\n    def __init__(self, chan_in, hidden_size, chan_out):\n        super().__init__()\n        self.net = nn.Sequential(\n            nn.Conv2d(chan_in, hidden_size, 3, padding=1),\n            nn.ReLU(),\n            nn.Conv2d(hidden_size, hidden_size, 3, padding=1),\n            nn.ReLU(),\n            nn.Conv2d(hidden_size, chan_out, 1)\n        )\n\n    def forward(self, x):\n        return self.net(x) + x\n\n\nclass DiscreteVAE(BasicVAE):\n    def __init__(\n        self,\n        image_size = 256,\n        num_tokens = 512,\n        codebook_dim = 512,\n        num_layers = 3,\n        hidden_dim = 64,\n        channels = 3,\n        smooth_l1_loss = False,\n        temperature = 0.9,\n        straight_through = False,\n        kl_div_loss_weight = 0.\n    ):\n        super().__init__()\n        # assert log2(image_size).is_integer(), 'image size must be a power of 2'\n        assert num_layers >= 1, 'number of layers must be greater than or equal to 1'\n\n        self.image_size = image_size\n        self.num_tokens = num_tokens\n        self.num_layers = num_layers\n        self.temperature = temperature\n        self.straight_through = straight_through\n        self.codebook = nn.Embedding(num_tokens, codebook_dim)\n\n        enc_layers = []\n        dec_layers = []\n\n        enc_in = channels\n        dec_in = codebook_dim\n\n        for layer_id in range(num_layers):\n            enc_layers.append(nn.Sequential(nn.Conv2d(enc_in, hidden_dim, 4, stride=2, padding=1), nn.ReLU()))\n            enc_layers.append(ResBlock(chan_in=hidden_dim, hidden_size=hidden_dim, chan_out=hidden_dim))\n            enc_in = hidden_dim\n            dec_layers.append(nn.Sequential(nn.ConvTranspose2d(dec_in, hidden_dim, 4, stride=2, padding=1), nn.ReLU()))\n            dec_layers.append(ResBlock(chan_in=hidden_dim, hidden_size=hidden_dim, chan_out=hidden_dim))\n            dec_in = hidden_dim\n\n        enc_layers.append(nn.Conv2d(hidden_dim, num_tokens, 1))\n        dec_layers.append(nn.Conv2d(hidden_dim, channels, 1))\n\n        self.encoder = nn.Sequential(*enc_layers)\n        self.decoder = nn.Sequential(*dec_layers)\n\n        self.loss_fn = F.smooth_l1_loss if smooth_l1_loss else F.mse_loss\n        self.kl_div_loss_weight = kl_div_loss_weight\n\n    def get_image_size(self):\n        return self.image_size\n\n    def get_image_tokens_size(self):\n        return self.image_size // 8\n\n    @torch.no_grad()\n    @eval_decorator\n    def get_codebook_indices(self, images):\n        logits = self.forward(images, return_logits = True)\n        codebook_indices = logits.argmax(dim = 1)\n        return codebook_indices\n\n    @torch.no_grad()\n    @eval_decorator\n    def get_codebook_probs(self, images):\n        logits = self.forward(images, return_logits = True)\n        return nn.Softmax(dim=1)(logits)\n\n    def decode(\n        self,\n        img_seq\n    ):\n        image_embeds = self.codebook(img_seq)\n        b, n, d = image_embeds.shape\n        h = w = int(sqrt(n))\n\n        image_embeds = rearrange(image_embeds, 'b (h w) d -> b d h w', h = h, w = w)\n        images = self.decoder(image_embeds)\n        return images\n\n    def forward(\n        self,\n        img,\n        return_loss = False,\n        return_recons = False,\n        return_logits = False,\n        temp = None\n    ):\n        device, num_tokens, image_size, kl_div_loss_weight = img.device, self.num_tokens, self.image_size, self.kl_div_loss_weight\n        assert img.shape[-1] == image_size and img.shape[-2] == image_size, f'input must have the correct image size {image_size}'\n\n        logits = self.encoder(img)\n\n        if return_logits:\n            return logits # return logits for getting hard image indices for DALL-E training\n\n        temp = default(temp, self.temperature)\n        soft_one_hot = F.gumbel_softmax(logits, tau = temp, dim = 1, hard = self.straight_through)\n        sampled = einsum('b n h w, n d -> b d h w', soft_one_hot, self.codebook.weight)\n        out = self.decoder(sampled)\n\n        if not return_loss:\n            return out\n\n        # reconstruction loss\n\n        recon_loss = self.loss_fn(img, out)\n\n        # kl divergence\n\n        logits = rearrange(logits, 'b n h w -> b (h w) n')\n        qy = F.softmax(logits, dim = -1)\n\n        log_qy = torch.log(qy + 1e-10)\n        log_uniform = torch.log(torch.tensor([1. / num_tokens], device = device))\n        kl_div = F.kl_div(log_uniform, log_qy, None, None, 'batchmean', log_target = True)\n\n        loss = recon_loss + (kl_div * kl_div_loss_weight)\n\n        if not return_recons:\n            return loss\n\n        return loss, out\n\n\nfrom .dall_e import load_model\n\n\nclass Dalle_VAE(BasicVAE):\n    def __init__(self, image_size):\n        super().__init__()\n        self.encoder = None\n        self.decoder = None\n        self.image_size = image_size\n\n    def load_model(self, model_dir, device):\n        self.encoder = load_model(os.path.join(model_dir, \"encoder.pkl\"), device)\n        self.decoder = load_model(os.path.join(model_dir, \"decoder.pkl\"), device)\n\n    def decode(self, img_seq):\n        bsz = img_seq.size()[0]\n        img_seq = img_seq.view(bsz, self.image_size // 8, self.image_size // 8)\n        z = F.one_hot(img_seq, num_classes=self.encoder.vocab_size).permute(0, 3, 1, 2).float()\n        return self.decoder(z).float()\n\n    def get_codebook_indices(self, images):\n        z_logits = self.encoder(images)\n        return torch.argmax(z_logits, axis=1)\n\n    def get_codebook_probs(self, images):\n        z_logits = self.encoder(images)\n        return nn.Softmax(dim=1)(z_logits)\n\n    def forward(self, img_seq_prob, no_process=False):\n        if no_process:\n            return self.decoder(img_seq_prob.float()).float()\n        else:\n            bsz, seq_len, num_class = img_seq_prob.size()\n            z = img_seq_prob.view(bsz, self.image_size // 8, self.image_size // 8, self.encoder.vocab_size)\n            return self.decoder(z.permute(0, 3, 1, 2).float()).float()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/modeling_finetune.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom timm.models.layers import drop_path, to_2tuple, trunc_normal_\nfrom timm.models.registry import register_model\n\n\ndef _cfg(url='', **kwargs):\n    return {\n        'url': url,\n        'num_classes': 1000, 'input_size': (3, 224, 224), 'pool_size': None,\n        'crop_pct': .9, 'interpolation': 'bicubic',\n        'mean': (0.5, 0.5, 0.5), 'std': (0.5, 0.5, 0.5),\n        **kwargs\n    }\n\n\nclass DropPath(nn.Module):\n    \"\"\"Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).\n    \"\"\"\n    def __init__(self, drop_prob=None):\n        super(DropPath, self).__init__()\n        self.drop_prob = drop_prob\n\n    def forward(self, x):\n        return drop_path(x, self.drop_prob, self.training)\n    \n    def extra_repr(self) -> str:\n        return 'p={}'.format(self.drop_prob)\n\n\nclass Mlp(nn.Module):\n    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        # x = self.drop(x)\n        # commit this for the orignal BERT implement \n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\nclass Attention(nn.Module):\n    def __init__(\n            self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0.,\n            proj_drop=0., window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        if attn_head_dim is not None:\n            head_dim = attn_head_dim\n        all_head_dim = head_dim * self.num_heads\n        self.scale = qk_scale or head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, all_head_dim * 3, bias=False)\n        if qkv_bias:\n            self.q_bias = nn.Parameter(torch.zeros(all_head_dim))\n            self.v_bias = nn.Parameter(torch.zeros(all_head_dim))\n        else:\n            self.q_bias = None\n            self.v_bias = None\n\n        if window_size:\n            self.window_size = window_size\n            self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n            self.relative_position_bias_table = nn.Parameter(\n                torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n            # cls to token & token 2 cls & cls to cls\n\n            # get pair-wise relative position index for each token inside the window\n            coords_h = torch.arange(window_size[0])\n            coords_w = torch.arange(window_size[1])\n            coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n            coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n            relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n            relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n            relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n            relative_coords[:, :, 1] += window_size[1] - 1\n            relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n            relative_position_index = \\\n                torch.zeros(size=(window_size[0] * window_size[1] + 1, ) * 2, dtype=relative_coords.dtype)\n            relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n            relative_position_index[0, 0:] = self.num_relative_distance - 3\n            relative_position_index[0:, 0] = self.num_relative_distance - 2\n            relative_position_index[0, 0] = self.num_relative_distance - 1\n\n            self.register_buffer(\"relative_position_index\", relative_position_index)\n        else:\n            self.window_size = None\n            self.relative_position_bias_table = None\n            self.relative_position_index = None\n\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(all_head_dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n    def forward(self, x, rel_pos_bias=None):\n        B, N, C = x.shape\n        qkv_bias = None\n        if self.q_bias is not None:\n            qkv_bias = torch.cat((self.q_bias, torch.zeros_like(self.v_bias, requires_grad=False), self.v_bias))\n        # qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)\n        qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias)\n        qkv = qkv.reshape(B, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[2]   # make torchscript happy (cannot use tensor as tuple)\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        if self.relative_position_bias_table is not None:\n            relative_position_bias = \\\n                self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                    self.window_size[0] * self.window_size[1] + 1,\n                    self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n            relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n            attn = attn + relative_position_bias.unsqueeze(0)\n\n        if rel_pos_bias is not None:\n            attn = attn + rel_pos_bias\n        \n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, -1)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n\nclass Block(nn.Module):\n\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,\n                 drop_path=0., init_values=None, act_layer=nn.GELU, norm_layer=nn.LayerNorm,\n                 window_size=None, attn_head_dim=None):\n        super().__init__()\n\n        self.norm1 = norm_layer(dim)\n        self.attn = Attention(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale,\n            attn_drop=attn_drop, proj_drop=drop, window_size=window_size, attn_head_dim=attn_head_dim)\n        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n        if init_values > 0:\n            self.gamma_1 = nn.Parameter(init_values * torch.ones((dim)),requires_grad=True)\n            self.gamma_2 = nn.Parameter(init_values * torch.ones((dim)),requires_grad=True)\n        else:\n            self.gamma_1, self.gamma_2 = None, None\n\n    def forward(self, x, rel_pos_bias=None):\n        if self.gamma_1 is None:\n            x = x + self.drop_path(self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            fc_feature = self.drop_path(self.mlp(self.norm2(x)))\n            x = x + fc_feature\n        else:\n            x = x + self.drop_path(self.gamma_1 * self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            fc_feature = self.drop_path(self.gamma_2 * self.mlp(self.norm2(x)))\n            x = x + fc_feature\n        return x, fc_feature\n\n\nclass PatchEmbed(nn.Module):\n    \"\"\" Image to Patch Embedding\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):\n        super().__init__()\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        num_patches = (img_size[1] // patch_size[1]) * (img_size[0] // patch_size[0])\n        self.patch_shape = (img_size[0] // patch_size[0], img_size[1] // patch_size[1])\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.num_patches = num_patches\n\n        self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n\n    def forward(self, x, **kwargs):\n        B, C, H, W = x.shape\n        # FIXME look at relaxing size constraints\n        assert H == self.img_size[0] and W == self.img_size[1], \\\n            f\"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]}).\"\n        x = self.proj(x).flatten(2).transpose(1, 2)\n        return x\n\n\nclass RelativePositionBias(nn.Module):\n\n    def __init__(self, window_size, num_heads):\n        super().__init__()\n        self.window_size = window_size\n        self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n        self.relative_position_bias_table = nn.Parameter(\n            torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n        # cls to token & token 2 cls & cls to cls\n\n        # get pair-wise relative position index for each token inside the window\n        coords_h = torch.arange(window_size[0])\n        coords_w = torch.arange(window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n        relative_coords[:, :, 1] += window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n        relative_position_index = \\\n            torch.zeros(size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype)\n        relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        relative_position_index[0, 0:] = self.num_relative_distance - 3\n        relative_position_index[0:, 0] = self.num_relative_distance - 2\n        relative_position_index[0, 0] = self.num_relative_distance - 1\n\n        self.register_buffer(\"relative_position_index\", relative_position_index)\n\n        # trunc_normal_(self.relative_position_bias_table, std=.02)\n\n    def forward(self):\n        relative_position_bias = \\\n            self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1] + 1,\n                self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n        return relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n\n\nclass VisionTransformer(nn.Module):\n    \"\"\" Vision Transformer with support for patch or hybrid CNN input stage\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, num_classes=1000, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., norm_layer=nn.LayerNorm, init_values=None,\n                 use_abs_pos_emb=True, use_rel_pos_bias=False, use_shared_rel_pos_bias=False,\n                 use_mean_pooling=True, init_scale=0.001, linear_classifier=False, has_masking=False,\n                 learn_layer_weights=False, layernorm_before_combine=False):\n        super().__init__()\n        self.num_classes = num_classes\n        self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n\n        if has_masking:\n            self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(window_size=self.patch_embed.patch_shape, num_heads=num_heads)\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.use_rel_pos_bias = use_rel_pos_bias\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,\n                init_values=init_values, window_size=self.patch_embed.patch_shape if use_rel_pos_bias else None)\n            for i in range(depth)])\n        self.use_mean_pooling = use_mean_pooling\n        self.norm = nn.Identity() if use_mean_pooling else norm_layer(embed_dim)\n        self.fc_norm = norm_layer(embed_dim, elementwise_affine=not linear_classifier) if use_mean_pooling else None\n        self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=.02)\n        trunc_normal_(self.cls_token, std=.02)\n        if has_masking:\n            trunc_normal_(self.mask_token, std=.02)\n        trunc_normal_(self.head.weight, std=.02)\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n        self.learn_layer_weights = learn_layer_weights\n        self.layernorm_before_combine = layernorm_before_combine\n        if learn_layer_weights:\n            self.layer_log_weights = nn.Parameter(torch.zeros(depth,))\n\n        self.head.weight.data.mul_(init_scale)\n        self.head.bias.data.mul_(init_scale)\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n            if m.weight is not None:\n                nn.init.constant_(m.weight, 1.0)\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def get_classifier(self):\n        return self.head\n\n    def reset_classifier(self, num_classes, global_pool=''):\n        self.num_classes = num_classes\n        self.head = nn.Linear(self.embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n    def forward_features(self, x, bool_masked_pos=None):\n        x = self.patch_embed(x)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n\n        if bool_masked_pos is not None and self.training:\n            mask_token = self.mask_token.expand(batch_size, seq_len, -1)\n            # replace the masked visual tokens by mask_token\n            w = bool_masked_pos.view(bool_masked_pos.size(0), -1, 1).type_as(mask_token)\n            x = x * (1 - w) + mask_token * w\n\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n        layer_xs = []\n        for blk in self.blocks:\n            x, _ = blk(x, rel_pos_bias=rel_pos_bias)  # B x T x C\n            layer_xs.append(x)\n\n        if self.learn_layer_weights:\n            layer_xs = [\n                layer_x.mean(1) if self.use_mean_pooling else layer_x[:, 0]\n                for layer_x in layer_xs\n            ]\n            layer_xs = [\n                F.layer_norm(layer_x.float(), layer_x.shape[-1:])\n                if self.layernorm_before_combine else layer_x\n                for layer_x in layer_xs\n            ]\n            weights = self.layer_log_weights.softmax(-1)\n            return F.linear(torch.stack(layer_xs, -1), weights)\n        else:\n            x = self.norm(x)\n            if self.fc_norm is not None:\n                t = x[:, 1:, :]\n                return self.fc_norm(t.mean(1))\n            else:\n                return x[:, 0]\n\n    def forward(self, x, bool_masked_pos=None):\n        x = self.forward_features(x, bool_masked_pos)\n        x = self.head(x)\n        return x\n\n\n@register_model\ndef beit_small_patch16_224(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        patch_size=16, in_chans=13, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_base_patch16_224(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_base_patch16_384(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        img_size=384, patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_large_patch16_224(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_large_patch16_384(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        img_size=384, patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\n\n@register_model\ndef beit_large_patch16_512(pretrained=False, **kwargs):\n    model = VisionTransformer(\n        img_size=512, patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/modeling_pretrain.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport math\nimport torch\nimport torch.nn as nn\nfrom functools import partial\n\nfrom modeling_finetune import Block, _cfg, PatchEmbed, RelativePositionBias\nfrom timm.models.registry import register_model\nfrom timm.models.layers import trunc_normal_ as __call_trunc_normal_\n\n\ndef trunc_normal_(tensor, mean=0., std=1.):\n    __call_trunc_normal_(tensor, mean=mean, std=std, a=-std, b=std)\n\n\n__all__ = [\n    'beit_base_patch16_224_8k_vocab', \n    'beit_large_patch16_224_8k_vocab', \n]\n\n\nclass VisionTransformerForMaskedImageModeling(nn.Module):\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, vocab_size=8192, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=True, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., norm_layer=None, init_values=None, attn_head_dim=None,\n                 use_abs_pos_emb=True, use_rel_pos_bias=False, use_shared_rel_pos_bias=False, init_std=0.02):\n        super().__init__()\n        self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(window_size=self.patch_embed.patch_shape, num_heads=num_heads)\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,\n                init_values=init_values, window_size=self.patch_embed.patch_shape if use_rel_pos_bias else None,\n                attn_head_dim=attn_head_dim,\n            )\n            for i in range(depth)])\n        self.norm = norm_layer(embed_dim)\n\n        self.init_std = init_std\n        self.lm_head = nn.Linear(embed_dim, vocab_size)\n\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=self.init_std)\n        trunc_normal_(self.cls_token, std=self.init_std)\n        trunc_normal_(self.mask_token, std=self.init_std)\n        trunc_normal_(self.lm_head.weight, std=self.init_std)\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=self.init_std)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n        elif isinstance(m, nn.Conv2d):\n            trunc_normal_(m.weight, std=self.init_std)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    def forward_features(self, x, bool_masked_pos):\n        x = self.patch_embed(x, bool_masked_pos=bool_masked_pos)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n        mask_token = self.mask_token.expand(batch_size, seq_len, -1)\n\n        # replace the masked visual tokens by mask_token\n        w = bool_masked_pos.unsqueeze(-1).type_as(mask_token)\n        x = x * (1 - w) + mask_token * w\n\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n        for blk in self.blocks:\n            x, _ = blk(x, rel_pos_bias=rel_pos_bias)\n\n        return self.norm(x)\n\n    def forward(self, x, bool_masked_pos, return_all_tokens=False):\n        x = self.forward_features(x, bool_masked_pos=bool_masked_pos)\n        x = x[:, 1:]\n        if return_all_tokens:\n            return self.lm_head(x)\n        else:\n            # return the masked tokens\n            return self.lm_head(x[bool_masked_pos])\n\n\n@register_model\ndef beit_base_patch16_224_8k_vocab(pretrained=False, **kwargs):\n    _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForMaskedImageModeling(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), vocab_size=8192, **kwargs)\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(\n            kwargs[\"init_ckpt\"], map_location=\"cpu\"\n        )\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n\n\n@register_model\ndef beit_large_patch16_224_8k_vocab(pretrained=False, **kwargs):\n    _ = kwargs.pop(\"num_classes\")\n    model = VisionTransformerForMaskedImageModeling(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), vocab_size=8192, **kwargs)\n    model.default_cfg = _cfg()\n    if pretrained:\n        checkpoint = torch.load(\n            kwargs[\"init_ckpt\"], map_location=\"cpu\"\n        )\n        model.load_state_dict(checkpoint[\"model\"])\n    return model\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/models.py",
    "content": "\"\"\" BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\nModel from official source: https://github.com/microsoft/unilm/tree/master/beit\nAt this point only the 1k fine-tuned classification weights and model configs have been added,\nsee original source above for pre-training models and procedure.\nModifications by / Copyright 2021 Ross Wightman, original copyrights below\n\"\"\"\n# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit/\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\nimport math\nfrom functools import partial\nfrom typing import Optional\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom timm.models.helpers import build_model_with_cfg\nfrom timm.models.layers import PatchEmbed, Mlp, DropPath, trunc_normal_\nfrom timm.models.registry import register_model\nfrom timm.models.vision_transformer import checkpoint_filter_fn\n\n\ndef _cfg(url='', **kwargs):\n    return {\n        'url': url,\n        'num_classes': 1000, 'input_size': (3, 224, 224), 'pool_size': None,\n        'crop_pct': .9, 'interpolation': 'bicubic', 'fixed_input_size': True,\n        'mean': (0.5, 0.5, 0.5), 'std': (0.5, 0.5, 0.5),\n        'first_conv': 'patch_embed.proj', 'classifier': 'head',\n        **kwargs\n    }\n\n\ndefault_cfgs = {\n    'beit_base_patch16_224': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22kto1k.pth'),\n    'beit_base_patch16_384': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_base_patch16_384_pt22k_ft22kto1k.pth',\n        input_size=(3, 384, 384), crop_pct=1.0,\n    ),\n    'beit_base_patch16_224_in22k': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth',\n        num_classes=21841,\n    ),\n    'beit_large_patch16_224': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22kto1k.pth'),\n    'beit_large_patch16_384': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_large_patch16_384_pt22k_ft22kto1k.pth',\n        input_size=(3, 384, 384), crop_pct=1.0,\n    ),\n    'beit_large_patch16_512': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_large_patch16_512_pt22k_ft22kto1k.pth',\n        input_size=(3, 512, 512), crop_pct=1.0,\n    ),\n    'beit_large_patch16_224_in22k': _cfg(\n        url='https://unilm.blob.core.windows.net/beit/beit_large_patch16_224_pt22k_ft22k.pth',\n        num_classes=21841,\n    ),\n}\n\n\nclass Attention(nn.Module):\n    def __init__(\n            self, dim, num_heads=8, qkv_bias=False, attn_drop=0.,\n            proj_drop=0., window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        if attn_head_dim is not None:\n            head_dim = attn_head_dim\n        all_head_dim = head_dim * self.num_heads\n        self.scale = head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, all_head_dim * 3, bias=False)\n        if qkv_bias:\n            self.q_bias = nn.Parameter(torch.zeros(all_head_dim))\n            self.register_buffer('k_bias', torch.zeros(all_head_dim), persistent=False)\n            self.v_bias = nn.Parameter(torch.zeros(all_head_dim))\n        else:\n            self.q_bias = None\n            self.k_bias = None\n            self.v_bias = None\n\n        if window_size:\n            self.window_size = window_size\n            self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n            self.relative_position_bias_table = nn.Parameter(\n                torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n            # cls to token & token 2 cls & cls to cls\n\n            # get pair-wise relative position index for each token inside the window\n            coords_h = torch.arange(window_size[0])\n            coords_w = torch.arange(window_size[1])\n            coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n            coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n            relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n            relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n            relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n            relative_coords[:, :, 1] += window_size[1] - 1\n            relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n            relative_position_index = \\\n                torch.zeros(size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype)\n            relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n            relative_position_index[0, 0:] = self.num_relative_distance - 3\n            relative_position_index[0:, 0] = self.num_relative_distance - 2\n            relative_position_index[0, 0] = self.num_relative_distance - 1\n\n            self.register_buffer(\"relative_position_index\", relative_position_index)\n        else:\n            self.window_size = None\n            self.relative_position_bias_table = None\n            self.relative_position_index = None\n\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(all_head_dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n    def forward(self, x, rel_pos_bias: Optional[torch.Tensor] = None):\n        B, N, C = x.shape\n        qkv_bias = torch.cat((self.q_bias, self.k_bias, self.v_bias)) if self.q_bias is not None else None\n        qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias)\n        qkv = qkv.reshape(B, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv.unbind(0)  # make torchscript happy (cannot use tensor as tuple)\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        if self.relative_position_bias_table is not None:\n            relative_position_bias = \\\n                self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                    self.window_size[0] * self.window_size[1] + 1,\n                    self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n            relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n            attn = attn + relative_position_bias.unsqueeze(0)\n\n        if rel_pos_bias is not None:\n            attn = attn + rel_pos_bias\n\n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, -1)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n\nclass Block(nn.Module):\n\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, drop=0., attn_drop=0.,\n                 drop_path=0., init_values=None, act_layer=nn.GELU, norm_layer=nn.LayerNorm,\n                 window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.norm1 = norm_layer(dim)\n        self.attn = Attention(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, attn_drop=attn_drop, proj_drop=drop,\n            window_size=window_size, attn_head_dim=attn_head_dim)\n        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n        if init_values:\n            self.gamma_1 = nn.Parameter(init_values * torch.ones((dim)), requires_grad=True)\n            self.gamma_2 = nn.Parameter(init_values * torch.ones((dim)), requires_grad=True)\n        else:\n            self.gamma_1, self.gamma_2 = None, None\n\n    def forward(self, x, rel_pos_bias: Optional[torch.Tensor] = None):\n        if self.gamma_1 is None:\n            x = x + self.drop_path(self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            x = x + self.drop_path(self.mlp(self.norm2(x)))\n        else:\n            x = x + self.drop_path(self.gamma_1 * self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            x = x + self.drop_path(self.gamma_2 * self.mlp(self.norm2(x)))\n        return x\n\n\nclass RelativePositionBias(nn.Module):\n\n    def __init__(self, window_size, num_heads):\n        super().__init__()\n        self.window_size = window_size\n        self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n        self.relative_position_bias_table = nn.Parameter(\n            torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n        # cls to token & token 2 cls & cls to cls\n\n        # get pair-wise relative position index for each token inside the window\n        coords_h = torch.arange(window_size[0])\n        coords_w = torch.arange(window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n        relative_coords[:, :, 1] += window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n        relative_position_index = \\\n            torch.zeros(size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype)\n        relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        relative_position_index[0, 0:] = self.num_relative_distance - 3\n        relative_position_index[0:, 0] = self.num_relative_distance - 2\n        relative_position_index[0, 0] = self.num_relative_distance - 1\n\n        self.register_buffer(\"relative_position_index\", relative_position_index)\n\n        # trunc_normal_(self.relative_position_bias_table, std=.02)\n\n    def forward(self):\n        relative_position_bias = \\\n            self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1] + 1,\n                self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n        return relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n\n\nclass Beit(nn.Module):\n    \"\"\" Vision Transformer with support for patch or hybrid CNN input stage\n    \"\"\"\n\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, num_classes=1000, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=True, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., norm_layer=partial(nn.LayerNorm, eps=1e-6), init_values=None,\n                 use_abs_pos_emb=True, use_rel_pos_bias=False, use_shared_rel_pos_bias=False,\n                 use_mean_pooling=True, init_scale=0.001):\n        super().__init__()\n        self.num_classes = num_classes\n        self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        # self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(window_size=self.patch_embed.grid_size, num_heads=num_heads)\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.use_rel_pos_bias = use_rel_pos_bias\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,\n                init_values=init_values, window_size=self.patch_embed.grid_size if use_rel_pos_bias else None)\n            for i in range(depth)])\n        self.norm = nn.Identity() if use_mean_pooling else norm_layer(embed_dim)\n        self.fc_norm = norm_layer(embed_dim) if use_mean_pooling else None\n        self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n        self.apply(self._init_weights)\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=.02)\n        trunc_normal_(self.cls_token, std=.02)\n        # trunc_normal_(self.mask_token, std=.02)\n        self.fix_init_weight()\n        if isinstance(self.head, nn.Linear):\n            trunc_normal_(self.head.weight, std=.02)\n            self.head.weight.data.mul_(init_scale)\n            self.head.bias.data.mul_(init_scale)\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def get_classifier(self):\n        return self.head\n\n    def reset_classifier(self, num_classes, global_pool=''):\n        self.num_classes = num_classes\n        self.head = nn.Linear(self.embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n    def forward_features(self, x):\n        x = self.patch_embed(x)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n        for blk in self.blocks:\n            x = blk(x, rel_pos_bias=rel_pos_bias)\n\n        x = self.norm(x)\n        if self.fc_norm is not None:\n            t = x[:, 1:, :]\n            return self.fc_norm(t.mean(1))\n        else:\n            return x[:, 0]\n\n    def forward(self, x):\n        x = self.forward_features(x)\n        x = self.head(x)\n        return x\n\n\ndef _create_beit(variant, pretrained=False, default_cfg=None, **kwargs):\n    default_cfg = default_cfg or default_cfgs[variant]\n    if kwargs.get('features_only', None):\n        raise RuntimeError('features_only not implemented for Beit models.')\n\n    model = build_model_with_cfg(\n        Beit, variant, pretrained,\n        default_cfg=default_cfg,\n        # FIXME an updated filter fn needed to interpolate rel pos emb if fine tuning to diff model sizes\n        pretrained_filter_fn=checkpoint_filter_fn,\n        **kwargs)\n    return model\n\n\n@register_model\ndef beit_base_patch16_224(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,\n        #use_abs_pos_emb=False, \n        use_rel_pos_bias=True, \n        #init_values=0.1, \n        **kwargs)\n    model = _create_beit('beit_base_patch16_224', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_base_patch16_384(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        img_size=384, patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=0.1, **kwargs)\n    model = _create_beit('beit_base_patch16_384', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_base_patch16_224_in22k(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=0.1, **kwargs)\n    model = _create_beit('beit_base_patch16_224_in22k', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_large_patch16_224(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=1e-5,  **kwargs)\n    model = _create_beit('beit_large_patch16_224', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_large_patch16_384(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        img_size=384, patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=1e-5, **kwargs)\n    model = _create_beit('beit_large_patch16_384', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_large_patch16_512(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        img_size=512, patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=1e-5, **kwargs)\n    model = _create_beit('beit_large_patch16_512', pretrained=pretrained, **model_kwargs)\n    return model\n\n\n@register_model\ndef beit_large_patch16_224_in22k(pretrained=False, **kwargs):\n    model_kwargs = dict(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        use_abs_pos_emb=False, use_rel_pos_bias=True, init_values=1e-5,  **kwargs)\n    model = _create_beit('beit_large_patch16_224_in22k', pretrained=pretrained, **model_kwargs)\n    return model"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/optim_factory.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# --------------------------------------------------------'\nimport torch\nfrom torch import optim as optim\n\nfrom timm.optim.adafactor import Adafactor\nfrom timm.optim.adahessian import Adahessian\nfrom timm.optim.adamp import AdamP\nfrom timm.optim.lookahead import Lookahead\nfrom timm.optim.nadam import Nadam\n# from timm.optim.novograd import NovoGrad\nfrom timm.optim.nvnovograd import NvNovoGrad\nfrom timm.optim.radam import RAdam\nfrom timm.optim.rmsprop_tf import RMSpropTF\nfrom timm.optim.sgdp import SGDP\n\nimport json\n\ntry:\n    from apex.optimizers import FusedNovoGrad, FusedAdam, FusedLAMB, FusedSGD\n    has_apex = True\nexcept ImportError:\n    has_apex = False\n\n\ndef get_num_layer_for_vit(var_name, num_max_layer):\n    if var_name in (\"cls_token\", \"mask_token\", \"pos_embed\"):\n        return 0\n    elif var_name.startswith(\"patch_embed\"):\n        return 0\n    elif var_name.startswith(\"rel_pos_bias\"):\n        return num_max_layer - 1\n    elif var_name.startswith(\"blocks\"):\n        layer_id = int(var_name.split('.')[1])\n        return layer_id + 1\n    else:\n        return num_max_layer - 1\n\n\nclass LayerDecayValueAssigner(object):\n    def __init__(self, values):\n        self.values = values\n\n    def get_scale(self, layer_id):\n        return self.values[layer_id]\n\n    def get_layer_id(self, var_name):\n        return get_num_layer_for_vit(var_name, len(self.values))\n\n\ndef get_parameter_groups(model, weight_decay=1e-5, skip_list=(), get_num_layer=None, get_layer_scale=None):\n    parameter_group_names = {}\n    parameter_group_vars = {}\n\n    for name, param in model.named_parameters():\n        if not param.requires_grad:\n            continue  # frozen weights\n        if len(param.shape) == 1 or name.endswith(\".bias\") or name in skip_list:\n            group_name = \"no_decay\"\n            this_weight_decay = 0.\n        else:\n            group_name = \"decay\"\n            this_weight_decay = weight_decay\n        if get_num_layer is not None:\n            layer_id = get_num_layer(name)\n            group_name = \"layer_%d_%s\" % (layer_id, group_name)\n        else:\n            layer_id = None\n\n        if group_name not in parameter_group_names:\n            if get_layer_scale is not None:\n                scale = get_layer_scale(layer_id)\n            else:\n                scale = 1.\n\n            parameter_group_names[group_name] = {\n                \"weight_decay\": this_weight_decay,\n                \"params\": [],\n                \"lr_scale\": scale\n            }\n            parameter_group_vars[group_name] = {\n                \"weight_decay\": this_weight_decay,\n                \"params\": [],\n                \"lr_scale\": scale\n            }\n\n        parameter_group_vars[group_name][\"params\"].append(param)\n        parameter_group_names[group_name][\"params\"].append(name)\n    print(\"Param groups = %s\" % json.dumps(parameter_group_names, indent=2))\n    return list(parameter_group_vars.values())\n\n\ndef create_optimizer(args, model, get_num_layer=None, get_layer_scale=None, filter_bias_and_bn=True, skip_list=None):\n    opt_lower = args.opt.lower()\n    weight_decay = args.weight_decay\n    if weight_decay and filter_bias_and_bn:\n        skip = {}\n        if skip_list is not None:\n            skip = skip_list\n        elif hasattr(model, 'no_weight_decay'):\n            skip = model.no_weight_decay()\n        parameters = get_parameter_groups(model, weight_decay, skip, get_num_layer, get_layer_scale)\n        weight_decay = 0.\n    else:\n        parameters = model.parameters()\n\n    if 'fused' in opt_lower:\n        assert has_apex and torch.cuda.is_available(), 'APEX and CUDA required for fused optimizers'\n\n    opt_args = dict(lr=args.lr, weight_decay=weight_decay)\n    if hasattr(args, 'opt_eps') and args.opt_eps is not None:\n        opt_args['eps'] = args.opt_eps\n    if hasattr(args, 'opt_betas') and args.opt_betas is not None:\n        opt_args['betas'] = args.opt_betas\n\n    opt_split = opt_lower.split('_')\n    opt_lower = opt_split[-1]\n    if opt_lower == 'sgd' or opt_lower == 'nesterov':\n        opt_args.pop('eps', None)\n        optimizer = optim.SGD(parameters, momentum=args.momentum, nesterov=True, **opt_args)\n    elif opt_lower == 'momentum':\n        opt_args.pop('eps', None)\n        optimizer = optim.SGD(parameters, momentum=args.momentum, nesterov=False, **opt_args)\n    elif opt_lower == 'adam':\n        optimizer = optim.Adam(parameters, **opt_args)\n    elif opt_lower == 'adamw':\n        optimizer = optim.AdamW(parameters, **opt_args)\n    elif opt_lower == 'nadam':\n        optimizer = Nadam(parameters, **opt_args)\n    elif opt_lower == 'radam':\n        optimizer = RAdam(parameters, **opt_args)\n    elif opt_lower == 'adamp':\n        optimizer = AdamP(parameters, wd_ratio=0.01, nesterov=True, **opt_args)\n    elif opt_lower == 'sgdp':\n        optimizer = SGDP(parameters, momentum=args.momentum, nesterov=True, **opt_args)\n    elif opt_lower == 'adadelta':\n        optimizer = optim.Adadelta(parameters, **opt_args)\n    elif opt_lower == 'adafactor':\n        if not args.lr:\n            opt_args['lr'] = None\n        optimizer = Adafactor(parameters, **opt_args)\n    elif opt_lower == 'adahessian':\n        optimizer = Adahessian(parameters, **opt_args)\n    elif opt_lower == 'rmsprop':\n        optimizer = optim.RMSprop(parameters, alpha=0.9, momentum=args.momentum, **opt_args)\n    elif opt_lower == 'rmsproptf':\n        optimizer = RMSpropTF(parameters, alpha=0.9, momentum=args.momentum, **opt_args)\n    elif opt_lower == 'novograd':\n        optimizer = NovoGrad(parameters, **opt_args)\n    elif opt_lower == 'nvnovograd':\n        optimizer = NvNovoGrad(parameters, **opt_args)\n    elif opt_lower == 'fusedsgd':\n        opt_args.pop('eps', None)\n        optimizer = FusedSGD(parameters, momentum=args.momentum, nesterov=True, **opt_args)\n    elif opt_lower == 'fusedmomentum':\n        opt_args.pop('eps', None)\n        optimizer = FusedSGD(parameters, momentum=args.momentum, nesterov=False, **opt_args)\n    elif opt_lower == 'fusedadam':\n        optimizer = FusedAdam(parameters, adam_w_mode=False, **opt_args)\n    elif opt_lower == 'fusedadamw':\n        optimizer = FusedAdam(parameters, adam_w_mode=True, **opt_args)\n    elif opt_lower == 'fusedlamb':\n        optimizer = FusedLAMB(parameters, **opt_args)\n    elif opt_lower == 'fusednovograd':\n        opt_args.setdefault('betas', (0.95, 0.98))\n        optimizer = FusedNovoGrad(parameters, **opt_args)\n    else:\n        assert False and \"Invalid optimizer\"\n        raise ValueError\n\n    if len(opt_split) > 1:\n        if opt_split[0] == 'lookahead':\n            optimizer = Lookahead(optimizer)\n\n    return optimizer\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/requirements.txt",
    "content": "torch==1.7.1\ntorchvision==0.8.2\ntimm==0.3.2\nPillow\nblobfile\nmypy\nnumpy\npytest\nrequests\neinops\ntensorboardX\ndeepspeed==0.4.0\nscipy\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/run_beit_pretraining.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.models import create_model\nfrom optim_factory import create_optimizer\n\nfrom datasets import build_beit_pretraining_dataset\nfrom engine_for_pretraining import train_one_epoch\nfrom utils import NativeScalerWithGradNormCount as NativeScaler\nimport utils\nimport modeling_pretrain\n\n\ndef get_args():\n    parser = argparse.ArgumentParser('BEiT pre-training script', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int)\n    parser.add_argument('--epochs', default=300, type=int)\n    parser.add_argument('--save_ckpt_freq', default=10, type=int)\n    parser.add_argument(\"--discrete_vae_weight_path\", type=str)\n    parser.add_argument(\"--discrete_vae_type\", type=str, default=\"dall-e\")\n    # Model parameters\n    parser.add_argument('--model', default='deit_base_patch16_224', type=str, metavar='MODEL',\n                        help='Name of model to train')\n    parser.add_argument('--rel_pos_bias', action='store_true')\n    parser.add_argument('--disable_rel_pos_bias', action='store_false', dest='rel_pos_bias')\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument('--abs_pos_emb', action='store_true')\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument('--layer_scale_init_value', default=0.1, type=float, \n                        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\")\n\n    parser.add_argument('--num_mask_patches', default=75, type=int,\n                        help='number of the visual tokens/patches need be masked')\n    parser.add_argument('--max_mask_patches_per_block', type=int, default=None)\n    parser.add_argument('--min_mask_patches_per_block', type=int, default=16)\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size for backbone')\n    parser.add_argument('--second_input_size', default=112, type=int,\n                        help='images input size for discrete vae')\n\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    # Optimizer parameters\n    parser.add_argument('--opt', default='adamw', type=str, metavar='OPTIMIZER',\n                        help='Optimizer (default: \"adamw\"')\n    parser.add_argument('--opt_eps', default=1e-8, type=float, metavar='EPSILON',\n                        help='Optimizer Epsilon (default: 1e-8)')\n    parser.add_argument('--opt_betas', default=None, type=float, nargs='+', metavar='BETA',\n                        help='Optimizer Betas (default: None, use opt default)')\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',\n                        help='SGD momentum (default: 0.9)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n    parser.add_argument('--weight_decay_end', type=float, default=None, help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD. \n        (Set the same value with args.weight_decay to keep weight decay no change)\"\"\")\n\n    parser.add_argument('--lr', type=float, default=5e-4, metavar='LR',\n                        help='learning rate (default: 5e-4)')\n    parser.add_argument('--warmup_lr', type=float, default=1e-6, metavar='LR',\n                        help='warmup learning rate (default: 1e-6)')\n    parser.add_argument('--min_lr', type=float, default=1e-5, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0 (1e-5)')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n    parser.add_argument('--warmup_steps', type=int, default=-1, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=0.4, metavar='PCT',\n                        help='Color jitter factor (default: 0.4)')\n    parser.add_argument('--train_interpolation', type=str, default='bicubic',\n                        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")')\n    parser.add_argument('--second_interpolation', type=str, default='lanczos',\n                        help='Interpolation for discrete vae (random, bilinear, bicubic default: \"lanczos\")')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--imagenet_default_mean_and_std', default=False, action='store_true')\n\n    parser.add_argument('--output_dir', default='',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default=None,\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='', help='resume from checkpoint')\n    parser.add_argument('--auto_resume', action='store_true')\n    parser.add_argument('--no_auto_resume', action='store_false', dest='auto_resume')\n    parser.set_defaults(auto_resume=False)\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem',\n                        help='')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--aug_level', default=-100, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://', help='url used to set up distributed training')\n\n    return parser.parse_args()\n\n\ndef get_model(args):\n    print(f\"Creating model: {args.model}\")\n    model = create_model(\n        args.model,\n        pretrained=False,\n        drop_path_rate=args.drop_path,\n        drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n    )\n\n    return model\n\n\ndef main(args):\n    utils.init_distributed_mode(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    model = get_model(args)\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (args.input_size // patch_size[0], args.input_size // patch_size[1])\n    args.patch_size = patch_size\n\n    # get dataset\n    dataset_train = build_beit_pretraining_dataset(args)\n\n    # prepare discrete vae\n    d_vae = utils.create_d_vae(\n        weight_path=args.discrete_vae_weight_path, d_vae_type=args.discrete_vae_type,\n        device=device, image_size=args.second_input_size)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_rank = global_rank\n        num_training_steps_per_epoch = len(dataset_train) // args.batch_size // num_tasks\n\n        print(\"pre-sampler\", num_tasks, global_rank, sampler_rank)\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=sampler_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    model.to(device)\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params:', n_parameters)\n\n    total_batch_size = args.batch_size * utils.get_world_size()\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Number of training steps = %d\" % num_training_steps_per_epoch)\n    print(\"Number of training examples per epoch = %d\" % (total_batch_size * num_training_steps_per_epoch))\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n        model_without_ddp = model.module\n\n    optimizer = create_optimizer(\n        args, model_without_ddp)\n    loss_scaler = NativeScaler()\n\n    print(\"Use step level LR & WD scheduler!\")\n    lr_schedule_values = utils.cosine_scheduler(\n        args.lr, args.min_lr, args.epochs, num_training_steps_per_epoch,\n        warmup_epochs=args.warmup_epochs, warmup_steps=args.warmup_steps,\n    )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay, args.weight_decay_end, args.epochs, num_training_steps_per_epoch)\n    print(\"Max WD = %.7f, Min WD = %.7f\" % (max(wd_schedule_values), min(wd_schedule_values)))\n\n    utils.auto_load_model(\n        args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch)\n        train_stats = train_one_epoch(\n            model, d_vae, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            args.clip_grad, log_writer=log_writer,\n            start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values,\n            wd_schedule_values=wd_schedule_values,\n        )\n        if args.output_dir:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                    loss_scaler=loss_scaler, epoch=epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                     'epoch': epoch, 'n_parameters': n_parameters}\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    opts = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/run_class_finetuning.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.nn as nn\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.data.mixup import Mixup\nfrom timm.models import create_model\nfrom timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy\nfrom timm.utils import ModelEma\nfrom optim_factory import create_optimizer, get_parameter_groups, LayerDecayValueAssigner\n\nfrom datasets import build_dataset\nfrom engine_for_finetuning import train_one_epoch, evaluate\nfrom utils import NativeScalerWithGradNormCount as NativeScaler\nimport utils\nfrom scipy import interpolate\nimport modeling_finetune\n\n\ndef get_args():\n    parser = argparse.ArgumentParser('BEiT fine-tuning and evaluation script for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int)\n    parser.add_argument('--epochs', default=30, type=int)\n    parser.add_argument('--update_freq', default=1, type=int)\n    parser.add_argument('--save_ckpt_freq', default=5, type=int)\n\n    # Model parameters\n    parser.add_argument('--model', default='deit_base_patch16_224', type=str, metavar='MODEL',\n                        help='Name of model to train')\n    parser.add_argument('--rel_pos_bias', action='store_true')\n    parser.add_argument('--disable_rel_pos_bias', action='store_false', dest='rel_pos_bias')\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument('--abs_pos_emb', action='store_true')\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument('--layer_scale_init_value', default=0.1, type=float, \n                        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\")\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--drop', type=float, default=0.0, metavar='PCT',\n                        help='Dropout rate (default: 0.)')\n    parser.add_argument('--attn_drop_rate', type=float, default=0.0, metavar='PCT',\n                        help='Attention dropout rate (default: 0.)')\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    parser.add_argument('--disable_eval_during_finetuning', action='store_true', default=False)\n\n    parser.add_argument('--model_ema', action='store_true', default=False)\n    parser.add_argument('--model_ema_decay', type=float, default=0.9999, help='')\n    parser.add_argument('--model_ema_force_cpu', action='store_true', default=False, help='')\n\n    # Optimizer parameters\n    parser.add_argument('--opt', default='adamw', type=str, metavar='OPTIMIZER',\n                        help='Optimizer (default: \"adamw\"')\n    parser.add_argument('--opt_eps', default=1e-8, type=float, metavar='EPSILON',\n                        help='Optimizer Epsilon (default: 1e-8)')\n    parser.add_argument('--opt_betas', default=None, type=float, nargs='+', metavar='BETA',\n                        help='Optimizer Betas (default: None, use opt default)')\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',\n                        help='SGD momentum (default: 0.9)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n    parser.add_argument('--weight_decay_end', type=float, default=None, help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD and using a larger decay by\n        the end of training improves performance for ViTs.\"\"\")\n\n    parser.add_argument('--lr', type=float, default=5e-4, metavar='LR',\n                        help='learning rate (default: 5e-4)')\n    parser.add_argument('--layer_decay', type=float, default=0.9)\n\n    parser.add_argument('--warmup_lr', type=float, default=1e-6, metavar='LR',\n                        help='warmup learning rate (default: 1e-6)')\n    parser.add_argument('--min_lr', type=float, default=1e-6, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0 (1e-5)')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR, if scheduler supports')\n    parser.add_argument('--warmup_steps', type=int, default=-1, metavar='N',\n                        help='num of steps to warmup LR, will overload warmup_epochs if set > 0')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=0.4, metavar='PCT',\n                        help='Color jitter factor (default: 0.4)')\n    parser.add_argument('--aa', type=str, default='rand-m9-mstd0.5-inc1', metavar='NAME',\n                        help='Use AutoAugment policy. \"v0\" or \"original\". \" + \"(default: rand-m9-mstd0.5-inc1)'),\n    parser.add_argument('--smoothing', type=float, default=0.1,\n                        help='Label smoothing (default: 0.1)')\n    parser.add_argument('--train_interpolation', type=str, default='bicubic',\n                        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")')\n\n    # Evaluation parameters\n    parser.add_argument('--crop_pct', type=float, default=None)\n\n    # * Random Erase params\n    parser.add_argument('--reprob', type=float, default=0.25, metavar='PCT',\n                        help='Random erase prob (default: 0.25)')\n    parser.add_argument('--remode', type=str, default='pixel',\n                        help='Random erase mode (default: \"pixel\")')\n    parser.add_argument('--recount', type=int, default=1,\n                        help='Random erase count (default: 1)')\n    parser.add_argument('--resplit', action='store_true', default=False,\n                        help='Do not random erase first (clean) augmentation split')\n\n    # * Mixup params\n    parser.add_argument('--mixup', type=float, default=0,\n                        help='mixup alpha, mixup enabled if > 0.')\n    parser.add_argument('--cutmix', type=float, default=0,\n                        help='cutmix alpha, cutmix enabled if > 0.')\n    parser.add_argument('--cutmix_minmax', type=float, nargs='+', default=None,\n                        help='cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None)')\n    parser.add_argument('--mixup_prob', type=float, default=1.0,\n                        help='Probability of performing mixup or cutmix when either/both is enabled')\n    parser.add_argument('--mixup_switch_prob', type=float, default=0.5,\n                        help='Probability of switching to cutmix when both mixup and cutmix enabled')\n    parser.add_argument('--mixup_mode', type=str, default='batch',\n                        help='How to apply mixup/cutmix params. Per \"batch\", \"pair\", or \"elem\"')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--model_key', default='model|module', type=str)\n    parser.add_argument('--model_prefix', default='', type=str)\n    parser.add_argument('--init_scale', default=0.001, type=float)\n    parser.add_argument('--use_mean_pooling', action='store_true')\n    parser.set_defaults(use_mean_pooling=True)\n    parser.add_argument('--use_cls', action='store_false', dest='use_mean_pooling')\n    parser.add_argument('--disable_weight_decay_on_rel_pos_bias', action='store_true', default=False)\n    parser.add_argument('--target_layer', default=-1, type=int, help=\"target output layer (0-based)\")\n    parser.add_argument('--remove_final_norm', action='store_true', dest='remove_final_norm')\n    parser.add_argument('--reinit_final_norm', action='store_true', dest='reinit_final_norm')\n    parser.add_argument('--learn_layer_weights', action='store_true', dest='learn_layer_weights')  # supersede `target_layer`\n    parser.add_argument('--layernorm_before_combine', action='store_true', dest='layernorm_before_combine')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--eval_data_path', default=None, type=str,\n                        help='dataset path for evaluation')\n    parser.add_argument('--nb_classes', default=0, type=int,\n                        help='number of the classification types')\n    parser.add_argument('--linear_classifier', action='store_true',\n                        help='linear classifier')\n    parser.add_argument('--imagenet_default_mean_and_std', default=False, action='store_true')\n\n    parser.add_argument('--data_set', default='IMNET', choices=['CIFAR', 'IMNET', 'image_folder'],\n                        type=str, help='ImageNet dataset path')\n    parser.add_argument('--data_set_filter_file', type=str, default=None, help=\"path to filter to filter dataset\")\n    parser.add_argument('--output_dir', default='',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default=None,\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n    parser.add_argument('--auto_resume', action='store_true')\n    parser.add_argument('--no_auto_resume', action='store_false', dest='auto_resume')\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument('--save_ckpt', action='store_true')\n    parser.add_argument('--no_save_ckpt', action='store_false', dest='save_ckpt')\n    parser.set_defaults(save_ckpt=True)\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    parser.add_argument('--enable_deepspeed', action='store_true', default=False)\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=0,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n\n    known_args, _ = parser.parse_known_args()\n\n    if known_args.enable_deepspeed:\n        try:\n            print(\"why\")\n            import deepspeed\n            print(\"Imported deepspeed\")\n            from deepspeed import DeepSpeedConfig\n            print(\"Imported config\")\n            parser = deepspeed.add_config_arguments(parser)\n            print(\"Created parser\")\n            ds_init = deepspeed.initialize\n            print(\"Inited deepspeed\")\n        except:\n            print(\"Please 'pip install deepspeed==0.4.0'\")\n            exit(0)\n    else:\n        ds_init = None\n\n    return parser.parse_args(), ds_init\n\n\ndef main(args, ds_init):\n    utils.init_distributed_mode(args)\n\n    if ds_init is not None:\n        utils.create_ds_config(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    dataset_train, args.nb_classes = build_dataset(is_train=True, args=args)\n    if args.disable_eval_during_finetuning:\n        dataset_val = None\n    else:\n        dataset_val, _ = build_dataset(is_train=False, args=args)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=False)\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    if dataset_val is not None:\n        data_loader_val = torch.utils.data.DataLoader(\n            dataset_val, sampler=sampler_val,\n            batch_size=int(1.5 * args.batch_size),\n            num_workers=args.num_workers,\n            pin_memory=args.pin_mem,\n            drop_last=False\n        )\n    else:\n        data_loader_val = None\n\n    mixup_fn = None\n    mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None\n    if mixup_active:\n        print(\"Mixup is activated!\")\n        mixup_fn = Mixup(\n            mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax,\n            prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode,\n            label_smoothing=args.smoothing, num_classes=args.nb_classes)\n\n    model = create_model(\n        args.model,\n        pretrained=False,\n        num_classes=args.nb_classes,\n        drop_rate=args.drop,\n        drop_path_rate=args.drop_path,\n        attn_drop_rate=args.attn_drop_rate,\n        drop_block_rate=None,\n        use_mean_pooling=args.use_mean_pooling,\n        init_scale=args.init_scale,\n        use_rel_pos_bias=False,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        linear_classifier=args.linear_classifier,\n        has_masking=args.num_mask_patches > 0,\n        learn_layer_weights=args.learn_layer_weights,\n        layernorm_before_combine=args.layernorm_before_combine,\n    )\n\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (args.input_size // patch_size[0], args.input_size // patch_size[1])\n    args.patch_size = patch_size\n\n    masked_position_generator = None\n    if args.num_mask_patches > 0:\n        from masking_generator import MaskingGenerator\n        masked_position_generator = MaskingGenerator(\n            args.window_size, num_masking_patches=args.num_mask_patches,\n            max_num_patches=args.max_mask_patches_per_block,\n            min_num_patches=args.min_mask_patches_per_block,\n        )\n\n    if args.finetune:\n        if args.finetune.startswith('https'):\n            checkpoint = torch.hub.load_state_dict_from_url(\n                args.finetune, map_location='cpu', check_hash=True)\n        else:\n            checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load ckpt from %s\" % args.finetune)\n        checkpoint_model = None\n        for model_key in args.model_key.split('|'):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n        if args.reinit_final_norm:\n            for k in ['norm.weight', 'norm.bias', 'fc_norm.weight', 'fc_norm.bias']:\n                if k in checkpoint_model:\n                    print(f\"Removing key {k} from pretrained checkpoint\")\n                    del checkpoint_model[k]\n\n        if model.use_rel_pos_bias and \"rel_pos_bias.relative_position_bias_table\" in checkpoint_model:\n            print(\"Expand the shared relative position embedding to each transformer block. \")\n            num_layers = model.get_num_layers()\n            rel_pos_bias = checkpoint_model[\"rel_pos_bias.relative_position_bias_table\"]\n            for i in range(num_layers):\n                checkpoint_model[\"blocks.%d.attn.relative_position_bias_table\" % i] = rel_pos_bias.clone()\n\n            checkpoint_model.pop(\"rel_pos_bias.relative_position_bias_table\")\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (dst_patch_shape[1] * 2 - 1)\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\"Position interpolate for %s from %dx%d to %dx%d\" % (\n                        key, src_size, src_size, dst_size, dst_size))\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind='cubic')\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy)).contiguous().view(-1, 1).to(rel_pos_bias.device))\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if 'pos_embed' in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model['pos_embed']\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model['pos_embed'] = new_pos_embed\n\n        if not args.learn_layer_weights and args.target_layer != -1:\n            print(f\"model target layer is {args.target_layer}\")\n            model.blocks = model.blocks[:args.target_layer+1]\n\n        if args.remove_final_norm:\n            print(f\"removing final norm by replacing it with Identity\")\n            model.norm = None if model.norm is None else nn.Identity()\n            model.fc_norm = None if model.fc_norm is None else nn.Identity()\n\n        if args.linear_classifier:\n            frozen_params = (\n                set(n for n, _ in model.named_parameters())\n                & set(checkpoint_model.keys())\n            )\n            for n, p in model.named_parameters():\n                if n in frozen_params:\n                    p.requires_grad_(False)\n            param_names = [n for n, p in model.named_parameters() if p.requires_grad]\n            print(f\"Trainable weights: {param_names}\")\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n        # model.load_state_dict(checkpoint_model, strict=False)\n\n    model.to(device)\n\n    model_ema = None\n    if args.model_ema:\n        # Important to create EMA model after cuda(), DP wrapper, and AMP but before SyncBN and DDP wrapper\n        model_ema = ModelEma(\n            model,\n            decay=args.model_ema_decay,\n            device='cpu' if args.model_ema_force_cpu else '',\n            resume='')\n        print(\"Using EMA with decay = %.8f\" % args.model_ema_decay)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params:', n_parameters)\n\n    total_batch_size = args.batch_size * args.update_freq * utils.get_world_size()\n    num_training_steps_per_epoch = len(dataset_train) // total_batch_size\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Update frequent = %d\" % args.update_freq)\n    print(\"Number of training examples = %d\" % len(dataset_train))\n    print(\"Number of training training per epoch = %d\" % num_training_steps_per_epoch)\n\n    num_layers = model_without_ddp.get_num_layers()\n    if args.layer_decay < 1.0:\n        assigner = LayerDecayValueAssigner(list(args.layer_decay ** (num_layers + 1 - i) for i in range(num_layers + 2)))\n    else:\n        assigner = None\n\n    if assigner is not None:\n        print(\"Assigned values = %s\" % str(assigner.values))\n\n    skip_weight_decay_list = model.no_weight_decay()\n    if args.disable_weight_decay_on_rel_pos_bias:\n        for i in range(num_layers):\n            skip_weight_decay_list.add(\"blocks.%d.attn.relative_position_bias_table\" % i)\n\n    if args.enable_deepspeed:\n        loss_scaler = None\n        optimizer_params = get_parameter_groups(\n            model, args.weight_decay, skip_weight_decay_list,\n            assigner.get_layer_id if assigner is not None else None,\n            assigner.get_scale if assigner is not None else None)\n        model, optimizer, _, _ = ds_init(\n            args=args, model=model, model_parameters=optimizer_params, dist_init_required=not args.distributed,\n        )\n\n        print(\"model.gradient_accumulation_steps() = %d\" % model.gradient_accumulation_steps())\n        assert model.gradient_accumulation_steps() == args.update_freq\n    else:\n        if args.distributed:\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n            model_without_ddp = model.module\n\n        optimizer = create_optimizer(\n            args, model_without_ddp, skip_list=skip_weight_decay_list,\n            get_num_layer=assigner.get_layer_id if assigner is not None else None, \n            get_layer_scale=assigner.get_scale if assigner is not None else None)\n        loss_scaler = NativeScaler()\n\n    print(\"Use step level LR scheduler!\")\n    lr_schedule_values = utils.cosine_scheduler(\n        args.lr, args.min_lr, args.epochs, num_training_steps_per_epoch,\n        warmup_epochs=args.warmup_epochs, warmup_steps=args.warmup_steps,\n    )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay, args.weight_decay_end, args.epochs, num_training_steps_per_epoch)\n    print(\"Max WD = %.7f, Min WD = %.7f\" % (max(wd_schedule_values), min(wd_schedule_values)))\n\n    if mixup_fn is not None:\n        # smoothing is handled with mixup label transform\n        criterion = SoftTargetCrossEntropy()\n    elif args.smoothing > 0.:\n        criterion = LabelSmoothingCrossEntropy(smoothing=args.smoothing)\n    else:\n        criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    utils.auto_load_model(\n        args=args, model=model, model_without_ddp=model_without_ddp,\n        optimizer=optimizer, loss_scaler=loss_scaler, model_ema=model_ema)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch * args.update_freq)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train, optimizer,\n            device, epoch, loss_scaler, args.clip_grad, model_ema, mixup_fn,\n            log_writer=log_writer, start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values, wd_schedule_values=wd_schedule_values,\n            num_training_steps_per_epoch=num_training_steps_per_epoch, update_freq=args.update_freq,\n            masked_position_generator=masked_position_generator,\n        )\n        if args.output_dir and args.save_ckpt:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                    loss_scaler=loss_scaler, epoch=epoch, model_ema=model_ema)\n        if data_loader_val is not None:\n            test_stats = evaluate(data_loader_val, model, device)\n            print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n            if max_accuracy < test_stats[\"acc1\"]:\n                max_accuracy = test_stats[\"acc1\"]\n                if args.output_dir and args.save_ckpt:\n                    utils.save_model(\n                        args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                        loss_scaler=loss_scaler, epoch=\"best\", model_ema=model_ema)\n\n            print(f'Max accuracy: {max_accuracy:.2f}%')\n            if log_writer is not None:\n                log_writer.update(test_acc1=test_stats['acc1'], head=\"perf\", step=epoch)\n                log_writer.update(test_acc5=test_stats['acc5'], head=\"perf\", step=epoch)\n                log_writer.update(test_loss=test_stats['loss'], head=\"perf\", step=epoch)\n\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n        else:\n            log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                         # **{f'test_{k}': v for k, v in test_stats.items()},\n                         'epoch': epoch,\n                         'n_parameters': n_parameters}\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    opts, ds_init = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts, ds_init)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/run_cyclical.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\nimport timm\nfrom pathlib import Path\n\nfrom timm.models import create_model\nfrom timm.utils import ModelEmaV2\nfrom optim_factory import create_optimizer\n\nfrom datasets import build_beit_pretraining_dataset\nfrom engine_for_cyclical import train_one_epoch\nfrom utils import NativeScalerWithGradNormCount as NativeScaler\nfrom . import utils\nfrom scipy import interpolate\nimport modeling_cyclical\n#from models import beit_base_patch16_224\n\n\ndef get_args():\n    print(timm.__version__)\n    print(torch.__version__)\n    parser = argparse.ArgumentParser(\"BEiT pre-training script\", add_help=False)\n    parser.add_argument(\"--batch_size\", default=64, type=int)\n    parser.add_argument(\"--epochs\", default=300, type=int)\n    parser.add_argument(\"--save_ckpt_freq\", default=10, type=int)\n    # Model parameters\n    parser.add_argument(\n        \"--model\",\n        default=\"deit_base_patch16_224\",\n        type=str,\n        metavar=\"MODEL\",\n        help=\"Name of model to train\",\n    )\n    parser.add_argument(\"--rel_pos_bias\", action=\"store_true\")\n    parser.add_argument(\n        \"--disable_rel_pos_bias\", action=\"store_false\", dest=\"rel_pos_bias\"\n    )\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument(\"--abs_pos_emb\", action=\"store_true\")\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument(\n        \"--layer_scale_init_value\",\n        default=0.1,\n        type=float,\n        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\",\n    )\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=75,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n\n    parser.add_argument(\n        \"--input_size\", default=224, type=int, help=\"images input size for backbone\"\n    )\n\n    parser.add_argument(\n        \"--drop_path\",\n        type=float,\n        default=0.1,\n        metavar=\"PCT\",\n        help=\"Drop path rate (default: 0.1)\",\n    )\n\n    # Optimizer parameters\n    parser.add_argument(\n        \"--opt\",\n        default=\"adamw\",\n        type=str,\n        metavar=\"OPTIMIZER\",\n        help='Optimizer (default: \"adamw\"',\n    )\n    parser.add_argument(\n        \"--opt_eps\",\n        default=1e-8,\n        type=float,\n        metavar=\"EPSILON\",\n        help=\"Optimizer Epsilon (default: 1e-8)\",\n    )\n    parser.add_argument(\n        \"--opt_betas\",\n        default=None,\n        type=float,\n        nargs=\"+\",\n        metavar=\"BETA\",\n        help=\"Optimizer Betas (default: None, use opt default)\",\n    )\n    parser.add_argument(\n        \"--clip_grad\",\n        type=float,\n        default=None,\n        metavar=\"NORM\",\n        help=\"Clip gradient norm (default: None, no clipping)\",\n    )\n    parser.add_argument(\n        \"--momentum\",\n        type=float,\n        default=0.9,\n        metavar=\"M\",\n        help=\"SGD momentum (default: 0.9)\",\n    )\n    parser.add_argument(\n        \"--weight_decay\", type=float, default=0.05, help=\"weight decay (default: 0.05)\"\n    )\n    parser.add_argument(\n        \"--weight_decay_end\",\n        type=float,\n        default=None,\n        help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD. \n        (Set the same value with args.weight_decay to keep weight decay no change)\"\"\",\n    )\n\n    parser.add_argument(\n        \"--lr\",\n        type=float,\n        default=5e-4,\n        metavar=\"LR\",\n        help=\"learning rate (default: 5e-4)\",\n    )\n    parser.add_argument(\n        \"--warmup_lr\",\n        type=float,\n        default=1e-6,\n        metavar=\"LR\",\n        help=\"warmup learning rate (default: 1e-6)\",\n    )\n    parser.add_argument(\n        \"--min_lr\",\n        type=float,\n        default=1e-5,\n        metavar=\"LR\",\n        help=\"lower lr bound for cyclic schedulers that hit 0 (1e-5)\",\n    )\n\n    parser.add_argument(\n        \"--tri_phase_schedule\",\n        type=str,\n        default=None,\n        help=\"string containing a tuple with phase ratios for warmup and decay. e.g. '(0.05,0.15) means 5% warmup, 80% hold, 15% decay\",\n    )\n\n    parser.add_argument(\n        \"--warmup_epochs\",\n        type=int,\n        default=5,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n    parser.add_argument(\n        \"--warmup_steps\",\n        type=int,\n        default=-1,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n\n    # Augmentation parameters\n    parser.add_argument(\n        \"--color_jitter\",\n        type=float,\n        default=0.4,\n        metavar=\"PCT\",\n        help=\"Color jitter factor (default: 0.4)\",\n    )\n    parser.add_argument(\n        \"--train_interpolation\",\n        type=str,\n        default=\"bicubic\",\n        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")',\n    )\n    parser.add_argument(\"--aug_level\", default=-1, type=int)\n\n\n    parser.add_argument(\n        \"--target_layers\", type=str, default=\"[]\", help=\"target layers (python list)\"\n    )\n\n    # Dataset parameters\n    parser.add_argument(\n        \"--data_path\",\n        default=\"/datasets01/imagenet_full_size/061417/\",\n        type=str,\n        help=\"dataset path\",\n    )\n    parser.add_argument(\n        \"--imagenet_default_mean_and_std\", default=False, action=\"store_true\"\n    )\n\n    parser.add_argument(\n        \"--output_dir\", default=\"\", help=\"path where to save, empty for no saving\"\n    )\n    parser.add_argument(\"--log_dir\", default=None, help=\"path where to tensorboard log\")\n    parser.add_argument(\n        \"--device\", default=\"cuda\", help=\"device to use for training / testing\"\n    )\n    parser.add_argument(\"--seed\", default=0, type=int)\n    parser.add_argument(\"--resume\", default=\"\", help=\"resume from checkpoint\")\n    parser.add_argument(\"--auto_resume\", action=\"store_true\")\n    parser.add_argument(\"--no_auto_resume\", action=\"store_false\", dest=\"auto_resume\")\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument(\"--ema_decay_init\", default=0.999, type=float)\n    parser.add_argument(\"--ema_decay\", default=0.9998, type=float)\n    parser.add_argument(\"--ema_start_at\", default=25000, type=int)\n\n    parser.add_argument(\n        \"--start_epoch\", default=0, type=int, metavar=\"N\", help=\"start epoch\"\n    )\n    parser.add_argument(\"--num_workers\", default=10, type=int)\n    parser.add_argument(\n        \"--pin_mem\",\n        action=\"store_true\",\n        help=\"Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.\",\n    )\n    parser.add_argument(\"--no_pin_mem\", action=\"store_false\", dest=\"pin_mem\", help=\"\")\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument(\n        \"--world_size\", default=1, type=int, help=\"number of distributed processes\"\n    )\n    parser.add_argument(\"--local_rank\", default=-1, type=int)\n    parser.add_argument(\"--dist_on_itp\", action=\"store_true\")\n    parser.add_argument(\n        \"--dist_url\", default=\"env://\", help=\"url used to set up distributed training\"\n    )\n\n    parser.add_argument(\"--seed_model\", default=None, type=str, help=\"seed model\")\n    parser.add_argument(\"--model_key\", default=\"model|module\", type=str)\n    parser.add_argument(\"--model_prefix\", default=\"\", type=str)\n\n    parser.add_argument(\"--l2_loss\", default=False, action=\"store_true\")\n    parser.add_argument(\"--l1_beta\", default=0.12, type=float)\n\n    parser.add_argument(\"--layer_results\", default=\"end\", type=str)\n\n    parser.add_argument(\"--var_w0\", default=0., type=float)\n    parser.add_argument(\"--var_w1\", default=0., type=float)\n    parser.add_argument(\"--var_margin0\", default=0.5, type=float)\n    parser.add_argument(\"--var_margin1\", default=0.5, type=float)\n    parser.add_argument(\"--skip_ema_during_lr_decay_for_tri\", action=\"store_true\")\n    parser.add_argument(\"--loss_scale\", default=-1, type=float)\n    parser.add_argument(\"--ema_annealing_till_end\", default=False, action=\"store_true\")\n    parser.add_argument(\"--attn_drop_rate\", default=0.0, type=float)\n    parser.add_argument(\"--mask_dropout_prob\", default=-1.0, type=float, help=\"prob of flipping already masked position to unmasked\")\n\n    #target_layer_norm_last=True, target_batch_norm=False, target_instance_norm=False\n    parser.add_argument(\"--no_target_layer_norm_last\", default=False, action=\"store_true\")\n    parser.add_argument(\"--target_batch_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--target_instance_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--post_target_instance_norm\", default=False, action=\"store_true\")\n    parser.add_argument(\"--post_target_layer_norm\", default=False, action=\"store_true\")\n\n    return parser.parse_args()\n\n\ndef get_model(args):\n    print(f\"Creating model: {args.model}\")\n    if args.model == 'beit_base_patch16_224' and False:\n        model = beit_base_patch16_224(drop_path_rate=args.drop_path,\n        #drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        attn_drop_rate=args.attn_drop_rate)\n    \n    model = create_model(\n        args.model,\n        pretrained=False,\n        drop_path_rate=args.drop_path,\n        drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n        attn_drop_rate=args.attn_drop_rate,\n    )\n\n    return model\n\n\ndef main(args):\n    utils.init_distributed_mode(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    model = get_model(args)\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (\n        args.input_size // patch_size[0],\n        args.input_size // patch_size[1],\n    )\n    args.patch_size = patch_size\n\n    if args.seed_model:\n        checkpoint = torch.load(args.seed_model, map_location=\"cpu\")\n        print(\"Load ckpt from %s\" % args.seed_model)\n\n        checkpoint_model = None\n        for model_key in args.model_key.split(\"|\"):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in [\"head.weight\", \"head.bias\"]:\n            if (\n                k in checkpoint_model\n                and checkpoint_model[k].shape != state_dict[k].shape\n            ):\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (\n                    dst_patch_shape[1] * 2 - 1\n                )\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\n                        \"Position interpolate for %s from %dx%d to %dx%d\"\n                        % (key, src_size, src_size, dst_size, dst_size)\n                    )\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind=\"cubic\")\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy))\n                            .contiguous()\n                            .view(-1, 1)\n                            .to(rel_pos_bias.device)\n                        )\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if \"pos_embed\" in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model[\"pos_embed\"]\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\n                    \"Position interpolate from %dx%d to %dx%d\"\n                    % (orig_size, orig_size, new_size, new_size)\n                )\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(\n                    -1, orig_size, orig_size, embedding_size\n                ).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens,\n                    size=(new_size, new_size),\n                    mode=\"bicubic\",\n                    align_corners=False,\n                )\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model[\"pos_embed\"] = new_pos_embed\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n\n    # get dataset\n    dataset_train = build_beit_pretraining_dataset(args)\n    print(dataset_train)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_rank = global_rank\n        num_training_steps_per_epoch = (\n            len(dataset_train) // args.batch_size // num_tasks\n        )\n\n        print(\"pre-sampler\", num_tasks, global_rank, sampler_rank)\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=sampler_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train,\n        sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    model.to(device)\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print(\"number of params:\", n_parameters)\n\n    model_ema = ModelEmaV2(model, decay=args.ema_decay)\n    print(\"Using EMA with decay = %.8f\" % args.ema_decay)\n\n    total_batch_size = args.batch_size * utils.get_world_size()\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Number of training steps = %d\" % num_training_steps_per_epoch)\n    print(\n        \"Number of training examples per epoch = %d\"\n        % (total_batch_size * num_training_steps_per_epoch)\n    )\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(\n            model, device_ids=[args.gpu], find_unused_parameters=True\n        )\n        model_without_ddp = model.module\n\n    optimizer = create_optimizer(args, model_without_ddp)\n    loss_scaler = NativeScaler()\n\n    start_lr_decay_at_step = -1\n    if args.tri_phase_schedule is not None:\n        from ast import literal_eval\n        warmup_phase, decay_phase = literal_eval(args.tri_phase_schedule)\n        print(\"Use tri phase lr schedule!\", warmup_phase, decay_phase)\n        lr_schedule_values = utils.tri_phase_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_perc=warmup_phase,\n            decay_perc=decay_phase,\n        )\n        if args.skip_ema_during_lr_decay_for_tri:\n            start_lr_decay_at_step= (1-decay_phase)*args.epochs*num_training_steps_per_epoch\n            print(\"ema will be skipped after \"+str(start_lr_decay_at_step)+\" updates\")\n    else:\n        print(\"Use step level LR & WD scheduler!\")\n        lr_schedule_values = utils.cosine_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_epochs=args.warmup_epochs,\n            warmup_steps=args.warmup_steps,\n        )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay,\n        args.weight_decay_end,\n        args.epochs,\n        num_training_steps_per_epoch,\n    )\n    print(\n        \"Max WD = %.7f, Min WD = %.7f\"\n        % (max(wd_schedule_values), min(wd_schedule_values))\n    )\n\n    utils.auto_load_model(\n        args=args,\n        model=model,\n        model_without_ddp=model_without_ddp,\n        optimizer=optimizer,\n        loss_scaler=loss_scaler,\n        model_ema=model_ema,\n    )\n\n    from ast import literal_eval\n\n    target_layers = literal_eval(args.target_layers)\n    assert len(target_layers) > 0\n    print(f\"target layers: {target_layers}\")\n\n    print(f\"Start training for {args.epochs} epochs\")\n\n    if args.ema_annealing_till_end:\n        args.ema_start_at = args.epochs * num_training_steps_per_epoch\n        print(f\"EMA annealing till the end activated\")\n\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch)\n        train_stats = train_one_epoch(\n            model,\n            model_ema,\n            args.ema_start_at,\n            args.ema_decay_init,\n            args.ema_decay,\n            target_layers,\n            data_loader_train,\n            optimizer,\n            device,\n            epoch,\n            loss_scaler,\n            args.clip_grad,\n            l1_beta=args.l1_beta,\n            log_writer=log_writer,\n            start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values,\n            wd_schedule_values=wd_schedule_values,\n            l2_loss=args.l2_loss,\n            layer_results=args.layer_results,\n            var_w0=args.var_w0, var_w1=args.var_w1, \n            var_margin0=args.var_margin0, var_margin1=args.var_margin1,\n            start_lr_decay_at_step=start_lr_decay_at_step,\n            loss_scale=args.loss_scale,\n            mask_dropout_prob=args.mask_dropout_prob,\n            target_layer_norm_last=not args.no_target_layer_norm_last, target_batch_norm=args.target_batch_norm, target_instance_norm=args.target_instance_norm,\n            post_target_instance_norm=args.post_target_instance_norm,\n            post_target_layer_norm=args.post_target_layer_norm\n        )\n\n        if args.output_dir:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args,\n                    model=model,\n                    model_without_ddp=model_without_ddp,\n                    optimizer=optimizer,\n                    loss_scaler=loss_scaler,\n                    epoch=epoch,\n                    model_ema=model_ema,\n                )\n\n        log_stats = {\n            **{f\"train_{k}\": v for k, v in train_stats.items()},\n            \"epoch\": epoch,\n            \"n_parameters\": n_parameters,\n        }\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(\n                os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\"\n            ) as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print(\"Training time {}\".format(total_time_str))\n\n\nif __name__ == \"__main__\":\n    opts = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/run_cyclical_joint.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport argparse\nimport datetime\nimport numpy as np\nimport time\nimport torch\nimport torch.backends.cudnn as cudnn\nimport json\nimport os\n\nfrom pathlib import Path\n\nfrom timm.models import create_model\nfrom timm.utils import ModelEmaV2\nfrom optim_factory import create_optimizer\n\nfrom datasets import build_beit_pretraining_dataset\nfrom engine_for_cyclical_joint import train_one_epoch\nfrom utils import NativeScalerWithGradNormCount as NativeScaler\nimport utils\nfrom scipy import interpolate\nimport modeling_cyclical_joint\n\n\ndef get_args():\n    parser = argparse.ArgumentParser(\"BEiT pre-training script\", add_help=False)\n    parser.add_argument(\"--batch_size\", default=64, type=int)\n    parser.add_argument(\"--epochs\", default=300, type=int)\n    parser.add_argument(\"--save_ckpt_freq\", default=10, type=int)\n    # Model parameters\n    parser.add_argument(\n        \"--model\",\n        default=\"deit_base_patch16_224\",\n        type=str,\n        metavar=\"MODEL\",\n        help=\"Name of model to train\",\n    )\n    parser.add_argument(\"--rel_pos_bias\", action=\"store_true\")\n    parser.add_argument(\n        \"--disable_rel_pos_bias\", action=\"store_false\", dest=\"rel_pos_bias\"\n    )\n    parser.set_defaults(rel_pos_bias=True)\n    parser.add_argument(\"--abs_pos_emb\", action=\"store_true\")\n    parser.set_defaults(abs_pos_emb=False)\n    parser.add_argument(\n        \"--layer_scale_init_value\",\n        default=0.1,\n        type=float,\n        help=\"0.1 for base, 1e-5 for large. set 0 to disable layer scale\",\n    )\n\n    parser.add_argument(\n        \"--num_mask_patches\",\n        default=75,\n        type=int,\n        help=\"number of the visual tokens/patches need be masked\",\n    )\n    parser.add_argument(\"--max_mask_patches_per_block\", type=int, default=None)\n    parser.add_argument(\"--min_mask_patches_per_block\", type=int, default=16)\n\n    parser.add_argument(\n        \"--input_size\", default=224, type=int, help=\"images input size for backbone\"\n    )\n\n    # added for vae\n    parser.add_argument('--second_input_size', default=112, type=int,\n                        help='images input size for discrete vae')\n    parser.add_argument('--second_interpolation', type=str, default='lanczos',\n                        help='Interpolation for discrete vae (random, bilinear, bicubic default: \"lanczos\")')\n    parser.add_argument(\"--discrete_vae_weight_path\", type=str)\n    parser.add_argument(\"--discrete_vae_type\", type=str, default=\"dall-e\")\n    parser.add_argument(\"--vae_loss_weight\", default=1., type=float)\n\n    parser.add_argument(\n        \"--drop_path\",\n        type=float,\n        default=0.1,\n        metavar=\"PCT\",\n        help=\"Drop path rate (default: 0.1)\",\n    )\n\n    # Optimizer parameters\n    parser.add_argument(\n        \"--opt\",\n        default=\"adamw\",\n        type=str,\n        metavar=\"OPTIMIZER\",\n        help='Optimizer (default: \"adamw\"',\n    )\n    parser.add_argument(\n        \"--opt_eps\",\n        default=1e-8,\n        type=float,\n        metavar=\"EPSILON\",\n        help=\"Optimizer Epsilon (default: 1e-8)\",\n    )\n    parser.add_argument(\n        \"--opt_betas\",\n        default=None,\n        type=float,\n        nargs=\"+\",\n        metavar=\"BETA\",\n        help=\"Optimizer Betas (default: None, use opt default)\",\n    )\n    parser.add_argument(\n        \"--clip_grad\",\n        type=float,\n        default=None,\n        metavar=\"NORM\",\n        help=\"Clip gradient norm (default: None, no clipping)\",\n    )\n    parser.add_argument(\n        \"--momentum\",\n        type=float,\n        default=0.9,\n        metavar=\"M\",\n        help=\"SGD momentum (default: 0.9)\",\n    )\n    parser.add_argument(\n        \"--weight_decay\", type=float, default=0.05, help=\"weight decay (default: 0.05)\"\n    )\n    parser.add_argument(\n        \"--weight_decay_end\",\n        type=float,\n        default=None,\n        help=\"\"\"Final value of the\n        weight decay. We use a cosine schedule for WD. \n        (Set the same value with args.weight_decay to keep weight decay no change)\"\"\",\n    )\n\n    parser.add_argument(\n        \"--lr\",\n        type=float,\n        default=5e-4,\n        metavar=\"LR\",\n        help=\"learning rate (default: 5e-4)\",\n    )\n    parser.add_argument(\n        \"--warmup_lr\",\n        type=float,\n        default=1e-6,\n        metavar=\"LR\",\n        help=\"warmup learning rate (default: 1e-6)\",\n    )\n    parser.add_argument(\n        \"--min_lr\",\n        type=float,\n        default=1e-5,\n        metavar=\"LR\",\n        help=\"lower lr bound for cyclic schedulers that hit 0 (1e-5)\",\n    )\n\n    parser.add_argument(\n        \"--tri_phase_schedule\",\n        type=str,\n        default=None,\n        help=\"string containing a tuple with phase ratios for warmup and decay. e.g. '(0.05,0.15) means 5% warmup, 80% hold, 15% decay\",\n    )\n\n    parser.add_argument(\n        \"--warmup_epochs\",\n        type=int,\n        default=5,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n    parser.add_argument(\n        \"--warmup_steps\",\n        type=int,\n        default=-1,\n        metavar=\"N\",\n        help=\"epochs to warmup LR, if scheduler supports\",\n    )\n\n    # Augmentation parameters\n    parser.add_argument(\n        \"--color_jitter\",\n        type=float,\n        default=0.4,\n        metavar=\"PCT\",\n        help=\"Color jitter factor (default: 0.4)\",\n    )\n    parser.add_argument(\n        \"--train_interpolation\",\n        type=str,\n        default=\"bicubic\",\n        help='Training interpolation (random, bilinear, bicubic default: \"bicubic\")',\n    )\n\n    parser.add_argument(\n        \"--target_layers\", type=str, default=\"[]\", help=\"target layers (python list)\"\n    )\n\n    # Dataset parameters\n    parser.add_argument(\n        \"--data_path\",\n        default=\"/datasets01/imagenet_full_size/061417/\",\n        type=str,\n        help=\"dataset path\",\n    )\n    parser.add_argument(\n        \"--imagenet_default_mean_and_std\", default=False, action=\"store_true\"\n    )\n\n    parser.add_argument(\n        \"--output_dir\", default=\"\", help=\"path where to save, empty for no saving\"\n    )\n    parser.add_argument(\"--log_dir\", default=None, help=\"path where to tensorboard log\")\n    parser.add_argument(\n        \"--device\", default=\"cuda\", help=\"device to use for training / testing\"\n    )\n    parser.add_argument(\"--seed\", default=0, type=int)\n    parser.add_argument(\"--resume\", default=\"\", help=\"resume from checkpoint\")\n    parser.add_argument(\"--auto_resume\", action=\"store_true\")\n    parser.add_argument(\"--no_auto_resume\", action=\"store_false\", dest=\"auto_resume\")\n    parser.set_defaults(auto_resume=True)\n\n    parser.add_argument(\"--ema_decay\", default=0.9998, type=float)\n    parser.add_argument(\"--ema_start_at\", default=25000, type=int)\n\n    parser.add_argument(\n        \"--start_epoch\", default=0, type=int, metavar=\"N\", help=\"start epoch\"\n    )\n    parser.add_argument(\"--num_workers\", default=10, type=int)\n    parser.add_argument(\n        \"--pin_mem\",\n        action=\"store_true\",\n        help=\"Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.\",\n    )\n    parser.add_argument(\"--no_pin_mem\", action=\"store_false\", dest=\"pin_mem\", help=\"\")\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument(\n        \"--world_size\", default=1, type=int, help=\"number of distributed processes\"\n    )\n    parser.add_argument(\"--local_rank\", default=-1, type=int)\n    parser.add_argument(\"--dist_on_itp\", action=\"store_true\")\n    parser.add_argument(\n        \"--dist_url\", default=\"env://\", help=\"url used to set up distributed training\"\n    )\n\n    parser.add_argument(\"--seed_model\", default=None, type=str, help=\"seed model\")\n    parser.add_argument(\"--model_key\", default=\"model|module\", type=str)\n    parser.add_argument(\"--model_prefix\", default=\"\", type=str)\n\n    parser.add_argument(\"--l2_loss\", default=False, action=\"store_true\")\n    parser.add_argument(\"--l1_beta\", default=0.12, type=float)\n\n    return parser.parse_args()\n\n\ndef get_model(args):\n    print(f\"Creating model: {args.model}\")\n    model = create_model(\n        args.model,\n        pretrained=False,\n        drop_path_rate=args.drop_path,\n        drop_block_rate=None,\n        use_shared_rel_pos_bias=args.rel_pos_bias,\n        use_abs_pos_emb=args.abs_pos_emb,\n        init_values=args.layer_scale_init_value,\n    )\n\n    return model\n\n\ndef main(args):\n    utils.init_distributed_mode(args)\n\n    print(args)\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + utils.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    # random.seed(seed)\n\n    cudnn.benchmark = True\n\n    model = get_model(args)\n    patch_size = model.patch_embed.patch_size\n    print(\"Patch size = %s\" % str(patch_size))\n    args.window_size = (\n        args.input_size // patch_size[0],\n        args.input_size // patch_size[1],\n    )\n    args.patch_size = patch_size\n\n    if args.seed_model:\n        checkpoint = torch.load(args.seed_model, map_location=\"cpu\")\n        print(\"Load ckpt from %s\" % args.seed_model)\n\n        checkpoint_model = None\n        for model_key in args.model_key.split(\"|\"):\n            if model_key in checkpoint:\n                checkpoint_model = checkpoint[model_key]\n                print(\"Load state_dict by model_key = %s\" % model_key)\n                break\n        if checkpoint_model is None:\n            checkpoint_model = checkpoint\n        state_dict = model.state_dict()\n        for k in [\"head.weight\", \"head.bias\"]:\n            if (\n                k in checkpoint_model\n                and checkpoint_model[k].shape != state_dict[k].shape\n            ):\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        all_keys = list(checkpoint_model.keys())\n        for key in all_keys:\n            if \"relative_position_index\" in key:\n                checkpoint_model.pop(key)\n\n            if \"relative_position_bias_table\" in key:\n                rel_pos_bias = checkpoint_model[key]\n                src_num_pos, num_attn_heads = rel_pos_bias.size()\n                dst_num_pos, _ = model.state_dict()[key].size()\n                dst_patch_shape = model.patch_embed.patch_shape\n                if dst_patch_shape[0] != dst_patch_shape[1]:\n                    raise NotImplementedError()\n                num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (\n                    dst_patch_shape[1] * 2 - 1\n                )\n                src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n                dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n                if src_size != dst_size:\n                    print(\n                        \"Position interpolate for %s from %dx%d to %dx%d\"\n                        % (key, src_size, src_size, dst_size, dst_size)\n                    )\n                    extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                    rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r ** n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q ** (i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print(\"Original positions = %s\" % str(x))\n                    print(\"Target positions = %s\" % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(num_attn_heads):\n                        z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                        f = interpolate.interp2d(x, y, z, kind=\"cubic\")\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f(dx, dy))\n                            .contiguous()\n                            .view(-1, 1)\n                            .to(rel_pos_bias.device)\n                        )\n\n                    rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n\n                    new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n        # interpolate position embedding\n        if \"pos_embed\" in checkpoint_model:\n            pos_embed_checkpoint = checkpoint_model[\"pos_embed\"]\n            embedding_size = pos_embed_checkpoint.shape[-1]\n            num_patches = model.patch_embed.num_patches\n            num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n            # height (== width) for the checkpoint position embedding\n            orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n            # height (== width) for the new position embedding\n            new_size = int(num_patches ** 0.5)\n            # class_token and dist_token are kept unchanged\n            if orig_size != new_size:\n                print(\n                    \"Position interpolate from %dx%d to %dx%d\"\n                    % (orig_size, orig_size, new_size, new_size)\n                )\n                extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n                # only the position tokens are interpolated\n                pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n                pos_tokens = pos_tokens.reshape(\n                    -1, orig_size, orig_size, embedding_size\n                ).permute(0, 3, 1, 2)\n                pos_tokens = torch.nn.functional.interpolate(\n                    pos_tokens,\n                    size=(new_size, new_size),\n                    mode=\"bicubic\",\n                    align_corners=False,\n                )\n                pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n                new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n                checkpoint_model[\"pos_embed\"] = new_pos_embed\n\n        utils.load_state_dict(model, checkpoint_model, prefix=args.model_prefix)\n\n    # get dataset\n    dataset_train = build_beit_pretraining_dataset(args)\n\n    # prepare discrete vae\n    d_vae = utils.create_d_vae(\n        weight_path=args.discrete_vae_weight_path, d_vae_type=args.discrete_vae_type,\n        device=device, image_size=args.second_input_size)\n\n    if True:  # args.distributed:\n        num_tasks = utils.get_world_size()\n        global_rank = utils.get_rank()\n        sampler_rank = global_rank\n        num_training_steps_per_epoch = (\n            len(dataset_train) // args.batch_size // num_tasks\n        )\n\n        print(\"pre-sampler\", num_tasks, global_rank, sampler_rank)\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=sampler_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = utils.TensorboardLogger(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train,\n        sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    model.to(device)\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print(\"number of params:\", n_parameters)\n\n    model_ema = ModelEmaV2(model, decay=args.ema_decay)\n    print(\"Using EMA with decay = %.8f\" % args.ema_decay)\n\n    total_batch_size = args.batch_size * utils.get_world_size()\n    print(\"LR = %.8f\" % args.lr)\n    print(\"Batch size = %d\" % total_batch_size)\n    print(\"Number of training steps = %d\" % num_training_steps_per_epoch)\n    print(\n        \"Number of training examples per epoch = %d\"\n        % (total_batch_size * num_training_steps_per_epoch)\n    )\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(\n            model, device_ids=[args.gpu], find_unused_parameters=True\n        )\n        model_without_ddp = model.module\n\n    optimizer = create_optimizer(args, model_without_ddp)\n    loss_scaler = NativeScaler()\n\n    if args.tri_phase_schedule is not None:\n        from ast import literal_eval\n        warmup_phase, decay_phase = literal_eval(args.tri_phase_schedule)\n        print(\"Use tri phase lr schedule!\", warmup_phase, decay_phase)\n        lr_schedule_values = utils.tri_phase_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_perc=warmup_phase,\n            decay_perc=decay_phase,\n        )\n    else:\n        print(\"Use step level LR & WD scheduler!\")\n        lr_schedule_values = utils.cosine_scheduler(\n            args.lr,\n            args.min_lr,\n            args.epochs,\n            num_training_steps_per_epoch,\n            warmup_epochs=args.warmup_epochs,\n            warmup_steps=args.warmup_steps,\n        )\n    if args.weight_decay_end is None:\n        args.weight_decay_end = args.weight_decay\n    wd_schedule_values = utils.cosine_scheduler(\n        args.weight_decay,\n        args.weight_decay_end,\n        args.epochs,\n        num_training_steps_per_epoch,\n    )\n    print(\n        \"Max WD = %.7f, Min WD = %.7f\"\n        % (max(wd_schedule_values), min(wd_schedule_values))\n    )\n\n    utils.auto_load_model(\n        args=args,\n        model=model,\n        model_without_ddp=model_without_ddp,\n        optimizer=optimizer,\n        loss_scaler=loss_scaler,\n        model_ema=model_ema,\n    )\n\n    from ast import literal_eval\n\n    target_layers = literal_eval(args.target_layers)\n    assert len(target_layers) > 0\n    print(f\"target layers: {target_layers}\")\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        if log_writer is not None:\n            log_writer.set_step(epoch * num_training_steps_per_epoch)\n        train_stats = train_one_epoch(\n            model,\n            model_ema,\n            args.ema_start_at,\n            target_layers,\n            d_vae,\n            args.vae_loss_weight,\n            data_loader_train,\n            optimizer,\n            device,\n            epoch,\n            loss_scaler,\n            args.clip_grad,\n            l1_beta=args.l1_beta,\n            log_writer=log_writer,\n            start_steps=epoch * num_training_steps_per_epoch,\n            lr_schedule_values=lr_schedule_values,\n            wd_schedule_values=wd_schedule_values,\n            l2_loss=args.l2_loss\n        )\n        if args.output_dir:\n            if (epoch + 1) % args.save_ckpt_freq == 0 or epoch + 1 == args.epochs:\n                utils.save_model(\n                    args=args,\n                    model=model,\n                    model_without_ddp=model_without_ddp,\n                    optimizer=optimizer,\n                    loss_scaler=loss_scaler,\n                    epoch=epoch,\n                    model_ema=model_ema,\n                )\n\n        log_stats = {\n            **{f\"train_{k}\": v for k, v in train_stats.items()},\n            \"epoch\": epoch,\n            \"n_parameters\": n_parameters,\n        }\n\n        if args.output_dir and utils.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(\n                os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\"\n            ) as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print(\"Training time {}\".format(total_time_str))\n\n\nif __name__ == \"__main__\":\n    opts = get_args()\n    if opts.output_dir:\n        Path(opts.output_dir).mkdir(parents=True, exist_ok=True)\n    main(opts)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/README.md",
    "content": "# ADE20k Semantic segmentation with BEiT\n\n## Getting started \n\n1. Install the [mmsegmentation](https://github.com/open-mmlab/mmsegmentation) library and some required packages.\n\n```bash\npip install mmcv-full==1.3.0 mmsegmentation==0.11.0\npip install scipy timm==0.3.2\n```\n\n2. Install [apex](https://github.com/NVIDIA/apex) for mixed-precision training\n\n```bash\ngit clone https://github.com/NVIDIA/apex\ncd apex\npip install -v --disable-pip-version-check --no-cache-dir --global-option=\"--cpp_ext\" --global-option=\"--cuda_ext\" ./\n```\n\n3. Follow the guide in [mmseg](https://github.com/open-mmlab/mmsegmentation/blob/master/docs/dataset_prepare.md) to prepare the ADE20k dataset.\n\n\n## Fine-tuning\n\nCommand format:\n```\ntools/dist_train.sh <CONFIG_PATH> <NUM_GPUS>  --work-dir <SAVE_PATH> --seed 0  --deterministic --options model.pretrained=<IMAGENET_CHECKPOINT_PATH/URL>\n```\n\nFor example, using a BEiT-base backbone with UperNet:\n```bash\nbash tools/dist_train.sh \\\n    configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k.py 8 \\\n    --work-dir /path/to/save --seed 0  --deterministic \\\n    --options model.pretrained=https://unilm.blob.core.windows.net/beit/beit_base_patch16_224_pt22k_ft22k.pth\n```\n\nMore config files can be found at [`configs/beit/upernet`](configs/beit/upernet).\n\n\n## Evaluation\n\nCommand format:\n```\ntools/dist_test.sh  <CONFIG_PATH> <CHECKPOINT_PATH> <NUM_GPUS> --eval mIoU\n```\n\nFor example, evaluate a BEiT-base backbone with UperNet:\n```bash\nbash tools/dist_test.sh configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k.py \\ \n    https://unilm.blob.core.windows.net/beit/beit_base_patch16_640_pt22k_ft22ktoade20k.pth  4 --eval mIoU\n```\n\nExpected results:\n```\n+--------+-------+-------+-------+\n| Scope  | mIoU  | mAcc  | aAcc  |\n+--------+-------+-------+-------+\n| global | 53.61 | 64.82 | 84.62 |\n+--------+-------+-------+-------+\n```\n\nMulti-scale + flip (`\\*_ms.py`)\n```\nbash tools/dist_test.sh configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k_ms.py \\\n    https://unilm.blob.core.windows.net/beit/beit_base_patch16_640_pt22k_ft22ktoade20k.pth  4 --eval mIoU\n```\n\nExpected results:\n```\n+--------+-------+-------+------+\n| Scope  | mIoU  | mAcc  | aAcc |\n+--------+-------+-------+------+\n| global | 54.26 | 65.28 | 84.9 |\n+--------+-------+-------+------+\n```\n\n---\n\n## Acknowledgment \n\nThis code is built using the [mmsegmentation](https://github.com/open-mmlab/mmsegmentation) library, [Timm](https://github.com/rwightman/pytorch-image-models) library, the [Swin](https://github.com/microsoft/Swin-Transformer) repository, [XCiT](https://github.com/facebookresearch/xcit) and the [SETR](https://github.com/fudan-zvg/SETR) repository.\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/backbone/beit.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\nimport math\nimport torch\nfrom functools import partial\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom timm.models.layers import drop_path, to_2tuple, trunc_normal_\n\nfrom mmcv_custom import load_checkpoint\nfrom mmseg.utils import get_root_logger\nfrom mmseg.models.builder import BACKBONES\n\n\nclass DropPath(nn.Module):\n    \"\"\"Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).\n    \"\"\"\n    def __init__(self, drop_prob=None):\n        super(DropPath, self).__init__()\n        self.drop_prob = drop_prob\n\n    def forward(self, x):\n        return drop_path(x, self.drop_prob, self.training)\n    \n    def extra_repr(self) -> str:\n        return 'p={}'.format(self.drop_prob)\n\n\nclass Mlp(nn.Module):\n    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        # x = self.drop(x)\n        # commit this for the orignal BERT implement \n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\nclass Attention(nn.Module):\n    def __init__(\n            self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0.,\n            proj_drop=0., window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        if attn_head_dim is not None:\n            head_dim = attn_head_dim\n        all_head_dim = head_dim * self.num_heads\n        # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights\n        self.scale = qk_scale or head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, all_head_dim * 3, bias=False)\n        if qkv_bias:\n            self.q_bias = nn.Parameter(torch.zeros(all_head_dim))\n            self.v_bias = nn.Parameter(torch.zeros(all_head_dim))\n        else:\n            self.q_bias = None\n            self.v_bias = None\n\n        if window_size:\n            self.window_size = window_size\n            self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n            self.relative_position_bias_table = nn.Parameter(\n                torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n            # cls to token & token 2 cls & cls to cls\n\n            # get pair-wise relative position index for each token inside the window\n            coords_h = torch.arange(window_size[0])\n            coords_w = torch.arange(window_size[1])\n            coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n            coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n            relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n            relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n            relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n            relative_coords[:, :, 1] += window_size[1] - 1\n            relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n            relative_position_index = \\\n                torch.zeros(size=(window_size[0] * window_size[1] + 1, ) * 2, dtype=relative_coords.dtype)\n            relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n            relative_position_index[0, 0:] = self.num_relative_distance - 3\n            relative_position_index[0:, 0] = self.num_relative_distance - 2\n            relative_position_index[0, 0] = self.num_relative_distance - 1\n\n            self.register_buffer(\"relative_position_index\", relative_position_index)\n\n            # trunc_normal_(self.relative_position_bias_table, std=.0)\n        else:\n            self.window_size = None\n            self.relative_position_bias_table = None\n            self.relative_position_index = None\n\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(all_head_dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n    def forward(self, x, rel_pos_bias=None):\n        B, N, C = x.shape\n        qkv_bias = None\n        if self.q_bias is not None:\n            qkv_bias = torch.cat((self.q_bias, torch.zeros_like(self.v_bias, requires_grad=False), self.v_bias))\n        # qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)\n        qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias)\n        qkv = qkv.reshape(B, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[2]   # make torchscript happy (cannot use tensor as tuple)\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        if self.relative_position_bias_table is not None:\n            relative_position_bias = \\\n                self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                    self.window_size[0] * self.window_size[1] + 1,\n                    self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n            relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n            attn = attn + relative_position_bias.unsqueeze(0)\n\n        if rel_pos_bias is not None:\n            attn = attn + rel_pos_bias\n        \n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, -1)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n\nclass Block(nn.Module):\n\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,\n                 drop_path=0., init_values=None, act_layer=nn.GELU, norm_layer=nn.LayerNorm,\n                 window_size=None, attn_head_dim=None):\n        super().__init__()\n        self.norm1 = norm_layer(dim)\n        self.attn = Attention(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale,\n            attn_drop=attn_drop, proj_drop=drop, window_size=window_size, attn_head_dim=attn_head_dim)\n        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n        if init_values is not None:\n            self.gamma_1 = nn.Parameter(init_values * torch.ones((dim)),requires_grad=True)\n            self.gamma_2 = nn.Parameter(init_values * torch.ones((dim)),requires_grad=True)\n        else:\n            self.gamma_1, self.gamma_2 = None, None\n\n    def forward(self, x, rel_pos_bias=None):\n        if self.gamma_1 is None:\n            x = x + self.drop_path(self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            x = x + self.drop_path(self.mlp(self.norm2(x)))\n        else:\n            x = x + self.drop_path(self.gamma_1 * self.attn(self.norm1(x), rel_pos_bias=rel_pos_bias))\n            x = x + self.drop_path(self.gamma_2 * self.mlp(self.norm2(x)))\n        return x\n\n\nclass PatchEmbed(nn.Module):\n    \"\"\" Image to Patch Embedding\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):\n        super().__init__()\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        num_patches = (img_size[1] // patch_size[1]) * (img_size[0] // patch_size[0])\n        self.patch_shape = (img_size[0] // patch_size[0], img_size[1] // patch_size[1])\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.num_patches = num_patches\n\n        self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n\n    def forward(self, x, **kwargs):\n        B, C, H, W = x.shape\n        # FIXME look at relaxing size constraints\n        # assert H == self.img_size[0] and W == self.img_size[1], \\\n        #     f\"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]}).\"\n        x = self.proj(x)\n        Hp, Wp = x.shape[2], x.shape[3]\n\n        x = x.flatten(2).transpose(1, 2)\n        return x, (Hp, Wp)\n\n\nclass HybridEmbed(nn.Module):\n    \"\"\" CNN Feature Map Embedding\n    Extract feature map from CNN, flatten, project to embedding dim.\n    \"\"\"\n    def __init__(self, backbone, img_size=224, feature_size=None, in_chans=3, embed_dim=768):\n        super().__init__()\n        assert isinstance(backbone, nn.Module)\n        img_size = to_2tuple(img_size)\n        self.img_size = img_size\n        self.backbone = backbone\n        if feature_size is None:\n            with torch.no_grad():\n                # FIXME this is hacky, but most reliable way of determining the exact dim of the output feature\n                # map for all networks, the feature metadata has reliable channel and stride info, but using\n                # stride to calc feature dim requires info about padding of each stage that isn't captured.\n                training = backbone.training\n                if training:\n                    backbone.eval()\n                o = self.backbone(torch.zeros(1, in_chans, img_size[0], img_size[1]))[-1]\n                feature_size = o.shape[-2:]\n                feature_dim = o.shape[1]\n                backbone.train(training)\n        else:\n            feature_size = to_2tuple(feature_size)\n            feature_dim = self.backbone.feature_info.channels()[-1]\n        self.num_patches = feature_size[0] * feature_size[1]\n        self.proj = nn.Linear(feature_dim, embed_dim)\n\n    def forward(self, x):\n        x = self.backbone(x)[-1]\n        x = x.flatten(2).transpose(1, 2)\n        x = self.proj(x)\n        return x\n\n\nclass RelativePositionBias(nn.Module):\n\n    def __init__(self, window_size, num_heads):\n        super().__init__()\n        self.window_size = window_size\n        self.num_relative_distance = (2 * window_size[0] - 1) * (2 * window_size[1] - 1) + 3\n        self.relative_position_bias_table = nn.Parameter(\n            torch.zeros(self.num_relative_distance, num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n        # cls to token & token 2 cls & cls to cls\n\n        # get pair-wise relative position index for each token inside the window\n        coords_h = torch.arange(window_size[0])\n        coords_w = torch.arange(window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :]  # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :, 0] += window_size[0] - 1  # shift to start from 0\n        relative_coords[:, :, 1] += window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * window_size[1] - 1\n        relative_position_index = \\\n            torch.zeros(size=(window_size[0] * window_size[1] + 1,) * 2, dtype=relative_coords.dtype)\n        relative_position_index[1:, 1:] = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        relative_position_index[0, 0:] = self.num_relative_distance - 3\n        relative_position_index[0:, 0] = self.num_relative_distance - 2\n        relative_position_index[0, 0] = self.num_relative_distance - 1\n\n        self.register_buffer(\"relative_position_index\", relative_position_index)\n\n        # trunc_normal_(self.relative_position_bias_table, std=.02)\n\n    def forward(self):\n        relative_position_bias = \\\n            self.relative_position_bias_table[self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1] + 1,\n                self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH\n        return relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n\n\n@BACKBONES.register_module()\nclass BEiT(nn.Module):\n    \"\"\" Vision Transformer with support for patch or hybrid CNN input stage\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, num_classes=80, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., hybrid_backbone=None, norm_layer=None, init_values=None, \n                 use_abs_pos_emb=True, use_rel_pos_bias=False, use_shared_rel_pos_bias=False,\n                 out_indices=[3, 5, 7, 11]):\n        super().__init__()\n        norm_layer = norm_layer or partial(nn.LayerNorm, eps=1e-6)\n        self.num_classes = num_classes\n        self.num_features = self.embed_dim = embed_dim  # num_features for consistency with other models\n\n        if hybrid_backbone is not None:\n            self.patch_embed = HybridEmbed(\n                hybrid_backbone, img_size=img_size, in_chans=in_chans, embed_dim=embed_dim)\n        else:\n            self.patch_embed = PatchEmbed(\n                img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n        self.out_indices = out_indices\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        # self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        if use_abs_pos_emb:\n            self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        else:\n            self.pos_embed = None\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        if use_shared_rel_pos_bias:\n            self.rel_pos_bias = RelativePositionBias(window_size=self.patch_embed.patch_shape, num_heads=num_heads)\n        else:\n            self.rel_pos_bias = None\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.use_rel_pos_bias = use_rel_pos_bias\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,\n                init_values=init_values, window_size=self.patch_embed.patch_shape if use_rel_pos_bias else None)\n            for i in range(depth)])\n\n        if self.pos_embed is not None:\n            trunc_normal_(self.pos_embed, std=.02)\n        trunc_normal_(self.cls_token, std=.02)\n        # trunc_normal_(self.mask_token, std=.02)\n        self.out_indices = out_indices\n\n        if patch_size == 16:\n            self.fpn1 = nn.Sequential(\n                nn.ConvTranspose2d(embed_dim, embed_dim, kernel_size=2, stride=2),\n                nn.SyncBatchNorm(embed_dim),\n                nn.GELU(),\n                nn.ConvTranspose2d(embed_dim, embed_dim, kernel_size=2, stride=2),\n            )\n\n            self.fpn2 = nn.Sequential(\n                nn.ConvTranspose2d(embed_dim, embed_dim, kernel_size=2, stride=2),\n            )\n\n            self.fpn3 = nn.Identity()\n\n            self.fpn4 = nn.MaxPool2d(kernel_size=2, stride=2)\n        elif patch_size == 8:\n            self.fpn1 = nn.Sequential(\n                nn.ConvTranspose2d(embed_dim, embed_dim, kernel_size=2, stride=2),\n            )\n\n            self.fpn2 = nn.Identity()\n\n            self.fpn3 = nn.Sequential(\n                nn.MaxPool2d(kernel_size=2, stride=2),\n            )\n\n            self.fpn4 = nn.Sequential(\n                nn.MaxPool2d(kernel_size=4, stride=4),\n            )\n        self.apply(self._init_weights)\n        self.fix_init_weight()\n\n    def fix_init_weight(self):\n        def rescale(param, layer_id):\n            param.div_(math.sqrt(2.0 * layer_id))\n\n        for layer_id, layer in enumerate(self.blocks):\n            rescale(layer.attn.proj.weight.data, layer_id + 1)\n            rescale(layer.mlp.fc2.weight.data, layer_id + 1)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    def init_weights(self, pretrained=None):\n        \"\"\"Initialize the weights in backbone.\n\n        Args:\n            pretrained (str, optional): Path to pre-trained weights.\n                Defaults to None.\n        \"\"\"\n\n        def _init_weights(m):\n            if isinstance(m, nn.Linear):\n                trunc_normal_(m.weight, std=.02)\n                if isinstance(m, nn.Linear) and m.bias is not None:\n                    nn.init.constant_(m.bias, 0)\n            elif isinstance(m, nn.LayerNorm):\n                nn.init.constant_(m.bias, 0)\n                nn.init.constant_(m.weight, 1.0)\n\n        if isinstance(pretrained, str):\n            self.apply(_init_weights)\n            logger = get_root_logger()\n            load_checkpoint(self, pretrained, strict=False, logger=logger)\n        elif pretrained is None:\n            self.apply(_init_weights)\n        else:\n            raise TypeError('pretrained must be a str or None')\n\n    def get_num_layers(self):\n        return len(self.blocks)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def forward_features(self, x):\n        B, C, H, W = x.shape\n        x, (Hp, Wp) = self.patch_embed(x)\n        batch_size, seq_len, _ = x.size()\n\n        cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n        x = torch.cat((cls_tokens, x), dim=1)\n        if self.pos_embed is not None:\n            x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        rel_pos_bias = self.rel_pos_bias() if self.rel_pos_bias is not None else None\n        features = []\n        for i, blk in enumerate(self.blocks):\n            x = blk(x, rel_pos_bias=rel_pos_bias)\n            if i in self.out_indices:\n                xp = x[:, 1:, :].permute(0, 2, 1).reshape(B, -1, Hp, Wp)\n                features.append(xp.contiguous())\n\n        ops = [self.fpn1, self.fpn2, self.fpn3, self.fpn4]\n        for i in range(len(features)):\n            features[i] = ops[i](features[i])\n\n        return tuple(features)\n\n    def forward(self, x):\n        x = self.forward_features(x)\n        return x\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/_base_/datasets/ade20k.py",
    "content": "# dataset settings\ndataset_type = 'ADE20KDataset'\ndata_root = 'data/ade/ADEChallengeData2016'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (512, 512)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', reduce_zero_label=True),\n    dict(type='Resize', img_scale=(2048, 512), ratio_range=(0.5, 2.0)),\n    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='PhotoMetricDistortion'),\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_semantic_seg']),\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2048, 512),\n        # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    samples_per_gpu=4,\n    workers_per_gpu=4,\n    train=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/training',\n        ann_dir='annotations/training',\n        pipeline=train_pipeline),\n    val=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/validation',\n        ann_dir='annotations/validation',\n        pipeline=test_pipeline),\n    test=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/validation',\n        ann_dir='annotations/validation',\n        pipeline=test_pipeline))\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/_base_/datasets/ade20k_640x640.py",
    "content": "# dataset settings\ndataset_type = 'ADE20KDataset'\ndata_root = 'data/ade/ADEChallengeData2016'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (640, 640)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', reduce_zero_label=True),\n    dict(type='Resize', img_scale=(2560, 640), ratio_range=(0.5, 2.0)),\n    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='PhotoMetricDistortion'),\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_semantic_seg']),\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2560, 640),\n        # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    samples_per_gpu=4,\n    workers_per_gpu=4,\n    train=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/training',\n        ann_dir='annotations/training',\n        pipeline=train_pipeline),\n    val=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/validation',\n        ann_dir='annotations/validation',\n        pipeline=test_pipeline),\n    test=dict(\n        type=dataset_type,\n        data_root=data_root,\n        img_dir='images/validation',\n        ann_dir='annotations/validation',\n        pipeline=test_pipeline))\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/_base_/default_runtime.py",
    "content": "# yapf:disable\nlog_config = dict(\n    interval=50,\n    hooks=[\n        dict(type='TextLoggerHook', by_epoch=False),\n        # dict(type='TensorboardLoggerHook')\n    ])\n# yapf:enable\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\nresume_from = None\nworkflow = [('train', 1)]\ncudnn_benchmark = True\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/_base_/models/upernet_beit.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='EncoderDecoder',\n    pretrained=None,\n    backbone=dict(\n        type='XCiT',\n        patch_size=16,\n        embed_dim=384,\n        depth=12,\n        num_heads=8,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=True,\n        use_rel_pos_bias=False,\n    ),\n    decode_head=dict(\n        type='UPerHead',\n        in_channels=[384, 384, 384, 384],\n        in_index=[0, 1, 2, 3],\n        pool_scales=(1, 2, 3, 6),\n        channels=512,\n        dropout_ratio=0.1,\n        num_classes=19,\n        norm_cfg=norm_cfg,\n        align_corners=False,\n        loss_decode=dict(\n            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)),\n    auxiliary_head=dict(\n        type='FCNHead',\n        in_channels=384,\n        in_index=2,\n        channels=256,\n        num_convs=1,\n        concat_input=False,\n        dropout_ratio=0.1,\n        num_classes=19,\n        norm_cfg=norm_cfg,\n        align_corners=False,\n        loss_decode=dict(\n            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)),\n    # model training and testing settings\n    train_cfg=dict(),\n    test_cfg=dict(mode='whole'))\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/_base_/schedules/schedule_160k.py",
    "content": "# optimizer\noptimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005)\noptimizer_config = dict()\n# learning policy\nlr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)\n# runtime settings\nrunner = dict(type='IterBasedRunner', max_iters=160000)\ncheckpoint_config = dict(by_epoch=False, interval=16000)\nevaluation = dict(interval=16000, metric='mIoU')\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/_base_/schedules/schedule_320k.py",
    "content": "# optimizer\noptimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005)\noptimizer_config = dict()\n# learning policy\nlr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)\n# runtime settings\nrunner = dict(type='IterBasedRunner', max_iters=320000)\ncheckpoint_config = dict(by_epoch=False, interval=32000)\nevaluation = dict(interval=32000, metric='mIoU')\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_base_12_512_slide_160k_ade20k.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (512, 512)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=512,\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=0.1,\n        drop_path_rate=0.1,\n        out_indices=[3, 5, 7, 11]\n    ),\n    decode_head=dict(\n        in_channels=[768, 768, 768, 768],\n        num_classes=150,\n        channels=768,\n    ),\n    auxiliary_head=dict(\n        in_channels=768,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=2)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_base_12_512_slide_160k_ade20k_ms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (512, 512)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=512,\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=0.1,\n        drop_path_rate=0.1,\n        out_indices=[3, 5, 7, 11]\n    ),\n    decode_head=dict(\n        in_channels=[768, 768, 768, 768],\n        num_classes=150,\n        channels=768,\n    ),\n    auxiliary_head=dict(\n        in_channels=768,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata = dict(samples_per_gpu=2)\n\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (512, 512)\n# test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\nfind_unused_parameters = True\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2048, 512),\n        img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=True,\n        transforms=[\n            dict(type='SETR_Resize', keep_ratio=True,\n                 crop_size=crop_size, setr_multi_scale=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    val=dict(pipeline=test_pipeline),\n    test=dict(pipeline=test_pipeline))\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k_640x640.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (640, 640)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=640,\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=0.1,\n        drop_path_rate=0.1,\n        out_indices=[3, 5, 7, 11]\n    ),\n    decode_head=dict(\n        in_channels=[768, 768, 768, 768],\n        num_classes=150,\n        channels=768,\n    ),\n    auxiliary_head=dict(\n        in_channels=768,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(426, 426))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=2)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_base_12_640_slide_160k_ade20k_ms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k_640x640.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (640, 640)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=640,\n        patch_size=16,\n        embed_dim=768,\n        depth=12,\n        num_heads=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=0.1,\n        drop_path_rate=0.1,\n        out_indices=[3, 5, 7, 11]\n    ),\n    decode_head=dict(\n        in_channels=[768, 768, 768, 768],\n        num_classes=150,\n        channels=768,\n    ),\n    auxiliary_head=dict(\n        in_channels=768,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(426, 426))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=3e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=12, layer_decay_rate=0.9))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (640, 640)\n# test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\nfind_unused_parameters = True\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2560, 640),\n        img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=True,\n        transforms=[\n            dict(type='SETR_Resize', keep_ratio=True,\n                 crop_size=crop_size, setr_multi_scale=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    val=dict(pipeline=test_pipeline),\n    test=dict(pipeline=test_pipeline), \n    samples_per_gpu=2, \n)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_large_24_512_slide_160k_ade20k.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (512, 512)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=512,\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=1e-6,\n        drop_path_rate=0.2,\n        out_indices=[7, 11, 15, 23],\n    ),\n    decode_head=dict(\n        in_channels=[1024, 1024, 1024, 1024],\n        num_classes=150,\n        channels=1024,\n    ),\n    auxiliary_head=dict(\n        in_channels=1024,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=2e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=24, layer_decay_rate=0.95))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=2)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_large_24_512_slide_160k_ade20k_ms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_160k.py'\n]\ncrop_size = (512, 512)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=512,\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=1e-6,\n        drop_path_rate=0.2,\n        out_indices=[7, 11, 15, 23],\n    ),\n    decode_head=dict(\n        in_channels=[1024, 1024, 1024, 1024],\n        num_classes=150,\n        channels=1024,\n    ),\n    auxiliary_head=dict(\n        in_channels=1024,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=2e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=24, layer_decay_rate=0.95))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=1500,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata = dict(samples_per_gpu=2)\n\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (512, 512)\n# test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\nfind_unused_parameters = True\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2048, 512),\n        img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=True,\n        transforms=[\n            dict(type='SETR_Resize', keep_ratio=True,\n                 crop_size=crop_size, setr_multi_scale=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    val=dict(pipeline=test_pipeline),\n    test=dict(pipeline=test_pipeline))\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=1,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_large_24_640_slide_160k_ade20k.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k_640x640.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_320k.py'\n]\n# We set samples_per_gpu to 1 and optimizer_config.update_interval to 2, the total update step keep 160k.\ncrop_size = (640, 640)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=640,\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=1e-6,\n        drop_path_rate=0.2,\n        out_indices=[7, 11, 15, 23],\n    ),\n    decode_head=dict(\n        in_channels=[1024, 1024, 1024, 1024],\n        num_classes=150,\n        channels=1024,\n    ),\n    auxiliary_head=dict(\n        in_channels=1024,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(426, 426))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=2e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=24, layer_decay_rate=0.95))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=3000,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=1)\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\n# We set samples_per_gpu to 1 and optimizer_config.update_interval to 2, the total update step keep 160k.\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=2,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/configs/beit/upernet/upernet_beit_large_24_640_slide_160k_ade20k_ms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, mmseg, setr, xcit and swin code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/fudan-zvg/SETR\n# https://github.com/facebookresearch/xcit/\n# https://github.com/microsoft/Swin-Transformer\n# --------------------------------------------------------'\n_base_ = [\n    '../../_base_/models/upernet_beit.py', '../../_base_/datasets/ade20k_640x640.py',\n    '../../_base_/default_runtime.py', '../../_base_/schedules/schedule_320k.py'\n]\ncrop_size = (640, 640)\n\nmodel = dict(\n    backbone=dict(\n        type='BEiT',\n        img_size=640,\n        patch_size=16,\n        embed_dim=1024,\n        depth=24,\n        num_heads=16,\n        mlp_ratio=4,\n        qkv_bias=True,\n        use_abs_pos_emb=False,\n        use_rel_pos_bias=True,\n        init_values=1e-6,\n        drop_path_rate=0.2,\n        out_indices=[7, 11, 15, 23],\n    ),\n    decode_head=dict(\n        in_channels=[1024, 1024, 1024, 1024],\n        num_classes=150,\n        channels=1024,\n    ),\n    auxiliary_head=dict(\n        in_channels=1024,\n        num_classes=150\n    ), \n    test_cfg = dict(mode='slide', crop_size=crop_size, stride=(426, 426))\n)\n\n# AdamW optimizer, no weight decay for position embedding & layer norm in backbone\n# optimizer = dict(_delete_=True, type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01,\n#                  paramwise_cfg=dict(custom_keys={'absolute_pos_embed': dict(decay_mult=0.),\n#                                                  'relative_position_bias_table': dict(decay_mult=0.),\n#                                                  'norm': dict(decay_mult=0.)}))\n\noptimizer = dict(_delete_=True, type='AdamW', lr=2e-5, betas=(0.9, 0.999), weight_decay=0.05,\n                 constructor='LayerDecayOptimizerConstructor', \n                 paramwise_cfg=dict(num_layers=24, layer_decay_rate=0.95))\n\nlr_config = dict(_delete_=True, policy='poly',\n                 warmup='linear',\n                 warmup_iters=3000,\n                 warmup_ratio=1e-6,\n                 power=1.0, min_lr=0.0, by_epoch=False)\n\n# By default, models are trained on 8 GPUs with 2 images per GPU\ndata=dict(samples_per_gpu=1)\n\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ncrop_size = (640, 640)\n# test_cfg = dict(mode='slide', crop_size=crop_size, stride=(341, 341))\nfind_unused_parameters = True\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(2560, 640),\n        img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],\n        flip=True,\n        transforms=[\n            dict(type='SETR_Resize', keep_ratio=True,\n                 crop_size=crop_size, setr_multi_scale=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    val=dict(pipeline=test_pipeline),\n    test=dict(pipeline=test_pipeline))\n\nrunner = dict(type='IterBasedRunnerAmp')\n\n# do not use mmdet version fp16\nfp16 = None\noptimizer_config = dict(\n    type=\"DistOptimizerHook\",\n    update_interval=2,\n    grad_clip=None,\n    coalesce=True,\n    bucket_size_mb=-1,\n    use_fp16=True,\n)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom .checkpoint import load_checkpoint\nfrom .layer_decay_optimizer_constructor import LayerDecayOptimizerConstructor\nfrom .resize_transform import SETR_Resize\nfrom .apex_runner.optimizer import DistOptimizerHook\nfrom .train_api import train_segmentor\n\n__all__ = ['load_checkpoint', 'LayerDecayOptimizerConstructor', 'SETR_Resize', 'DistOptimizerHook', 'train_segmentor']\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/apex_runner/__init__.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\nfrom .checkpoint import save_checkpoint\nfrom .apex_iter_based_runner import IterBasedRunnerAmp\n\n\n__all__ = [\n    'save_checkpoint', 'IterBasedRunnerAmp', \n]\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/apex_runner/apex_iter_based_runner.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\nimport os.path as osp\nimport platform\nimport shutil\n\nimport torch\nfrom torch.optim import Optimizer\n\nimport mmcv\nfrom mmcv.runner import RUNNERS, IterBasedRunner\nfrom .checkpoint import save_checkpoint\n\ntry:\n    import apex\nexcept:\n    print('apex is not installed')\n\n\n@RUNNERS.register_module()\nclass IterBasedRunnerAmp(IterBasedRunner):\n    \"\"\"Iteration-based Runner with AMP support.\n\n    This runner train models iteration by iteration.\n    \"\"\"\n\n    def save_checkpoint(self,\n                        out_dir,\n                        filename_tmpl='iter_{}.pth',\n                        meta=None,\n                        save_optimizer=True,\n                        create_symlink=False):\n        \"\"\"Save checkpoint to file.\n\n        Args:\n            out_dir (str): Directory to save checkpoint files.\n            filename_tmpl (str, optional): Checkpoint file template.\n                Defaults to 'iter_{}.pth'.\n            meta (dict, optional): Metadata to be saved in checkpoint.\n                Defaults to None.\n            save_optimizer (bool, optional): Whether save optimizer.\n                Defaults to True.\n            create_symlink (bool, optional): Whether create symlink to the\n                latest checkpoint file. Defaults to True.\n        \"\"\"\n        if meta is None:\n            meta = dict(iter=self.iter + 1, epoch=self.epoch + 1)\n        elif isinstance(meta, dict):\n            meta.update(iter=self.iter + 1, epoch=self.epoch + 1)\n        else:\n            raise TypeError(\n                f'meta should be a dict or None, but got {type(meta)}')\n        if self.meta is not None:\n            meta.update(self.meta)\n\n        filename = filename_tmpl.format(self.iter + 1)\n        filepath = osp.join(out_dir, filename)\n        optimizer = self.optimizer if save_optimizer else None\n        save_checkpoint(self.model, filepath, optimizer=optimizer, meta=meta)\n        # in some environments, `os.symlink` is not supported, you may need to\n        # set `create_symlink` to False\n        # if create_symlink:\n        #     dst_file = osp.join(out_dir, 'latest.pth')\n        #     if platform.system() != 'Windows':\n        #         mmcv.symlink(filename, dst_file)\n        #     else:\n        #         shutil.copy(filepath, dst_file)\n\n    def resume(self,\n               checkpoint,\n               resume_optimizer=True,\n               map_location='default'):\n        if map_location == 'default':\n            if torch.cuda.is_available():\n                device_id = torch.cuda.current_device()\n                checkpoint = self.load_checkpoint(\n                    checkpoint,\n                    map_location=lambda storage, loc: storage.cuda(device_id))\n            else:\n                checkpoint = self.load_checkpoint(checkpoint)\n        else:\n            checkpoint = self.load_checkpoint(\n                checkpoint, map_location=map_location)\n\n        self._epoch = checkpoint['meta']['epoch']\n        self._iter = checkpoint['meta']['iter']\n        self._inner_iter = checkpoint['meta']['iter']\n        if 'optimizer' in checkpoint and resume_optimizer:\n            if isinstance(self.optimizer, Optimizer):\n                self.optimizer.load_state_dict(checkpoint['optimizer'])\n            elif isinstance(self.optimizer, dict):\n                for k in self.optimizer.keys():\n                    self.optimizer[k].load_state_dict(\n                        checkpoint['optimizer'][k])\n            else:\n                raise TypeError(\n                    'Optimizer should be dict or torch.optim.Optimizer '\n                    f'but got {type(self.optimizer)}')\n\n        if 'amp' in checkpoint:\n            apex.amp.load_state_dict(checkpoint['amp'])\n            self.logger.info('load amp state dict')\n\n        self.logger.info(f'resumed from epoch: {self.epoch}, iter {self.iter}')\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/apex_runner/checkpoint.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\nimport os.path as osp\nimport time\nfrom tempfile import TemporaryDirectory\n\nimport torch\nfrom torch.optim import Optimizer\n\nimport mmcv\nfrom mmcv.parallel import is_module_wrapper\nfrom mmcv.runner.checkpoint import weights_to_cpu, get_state_dict\n\ntry:\n    import apex\nexcept:\n    print('apex is not installed')\n\n\ndef save_checkpoint(model, filename, optimizer=None, meta=None):\n    \"\"\"Save checkpoint to file.\n\n    The checkpoint will have 4 fields: ``meta``, ``state_dict`` and\n    ``optimizer``, ``amp``. By default ``meta`` will contain version\n    and time info.\n\n    Args:\n        model (Module): Module whose params are to be saved.\n        filename (str): Checkpoint filename.\n        optimizer (:obj:`Optimizer`, optional): Optimizer to be saved.\n        meta (dict, optional): Metadata to be saved in checkpoint.\n    \"\"\"\n    if meta is None:\n        meta = {}\n    elif not isinstance(meta, dict):\n        raise TypeError(f'meta must be a dict or None, but got {type(meta)}')\n    meta.update(mmcv_version=mmcv.__version__, time=time.asctime())\n\n    if is_module_wrapper(model):\n        model = model.module\n\n    if hasattr(model, 'CLASSES') and model.CLASSES is not None:\n        # save class name to the meta\n        meta.update(CLASSES=model.CLASSES)\n\n    checkpoint = {\n        'meta': meta,\n        'state_dict': weights_to_cpu(get_state_dict(model))\n    }\n    # save optimizer state dict in the checkpoint\n    if isinstance(optimizer, Optimizer):\n        checkpoint['optimizer'] = optimizer.state_dict()\n    elif isinstance(optimizer, dict):\n        checkpoint['optimizer'] = {}\n        for name, optim in optimizer.items():\n            checkpoint['optimizer'][name] = optim.state_dict()\n\n    # save amp state dict in the checkpoint\n    checkpoint['amp'] = apex.amp.state_dict()\n\n    if filename.startswith('pavi://'):\n        try:\n            from pavi import modelcloud\n            from pavi.exception import NodeNotFoundError\n        except ImportError:\n            raise ImportError(\n                'Please install pavi to load checkpoint from modelcloud.')\n        model_path = filename[7:]\n        root = modelcloud.Folder()\n        model_dir, model_name = osp.split(model_path)\n        try:\n            model = modelcloud.get(model_dir)\n        except NodeNotFoundError:\n            model = root.create_training_model(model_dir)\n        with TemporaryDirectory() as tmp_dir:\n            checkpoint_file = osp.join(tmp_dir, model_name)\n            with open(checkpoint_file, 'wb') as f:\n                torch.save(checkpoint, f)\n                f.flush()\n            model.create_file(checkpoint_file, name=model_name)\n    else:\n        mmcv.mkdir_or_exist(osp.dirname(filename))\n        # immediately flush buffer\n        with open(filename, 'wb') as f:\n            torch.save(checkpoint, f)\n            f.flush()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/apex_runner/optimizer.py",
    "content": "from mmcv.runner import OptimizerHook, HOOKS\ntry:\n    import apex\nexcept:\n    print('apex is not installed')\n\n\n@HOOKS.register_module()\nclass DistOptimizerHook(OptimizerHook):\n    \"\"\"Optimizer hook for distributed training.\"\"\"\n\n    def __init__(self, update_interval=1, grad_clip=None, coalesce=True, bucket_size_mb=-1, use_fp16=False):\n        self.grad_clip = grad_clip\n        self.coalesce = coalesce\n        self.bucket_size_mb = bucket_size_mb\n        self.update_interval = update_interval\n        self.use_fp16 = use_fp16\n\n    def before_run(self, runner):\n        runner.optimizer.zero_grad()\n\n    def after_train_iter(self, runner):\n        runner.outputs['loss'] /= self.update_interval\n        if self.use_fp16:\n            with apex.amp.scale_loss(runner.outputs['loss'], runner.optimizer) as scaled_loss:\n                scaled_loss.backward()\n        else:\n            runner.outputs['loss'].backward()\n        if self.every_n_iters(runner, self.update_interval):\n            if self.grad_clip is not None:\n                self.clip_grads(runner.model.parameters())\n            runner.optimizer.step()\n            runner.optimizer.zero_grad()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/checkpoint.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\nimport io\nimport os\nimport os.path as osp\nimport pkgutil\nimport time\nimport warnings\nfrom collections import OrderedDict\nfrom importlib import import_module\nfrom tempfile import TemporaryDirectory\n\nimport torch\nimport torchvision\nfrom torch.optim import Optimizer\nfrom torch.utils import model_zoo\nfrom torch.nn import functional as F\n\nimport mmcv\nfrom mmcv.fileio import FileClient\nfrom mmcv.fileio import load as load_file\nfrom mmcv.parallel import is_module_wrapper\nfrom mmcv.utils import mkdir_or_exist\nfrom mmcv.runner import get_dist_info\n\nfrom scipy import interpolate\nimport numpy as np\nimport math\n\nENV_MMCV_HOME = 'MMCV_HOME'\nENV_XDG_CACHE_HOME = 'XDG_CACHE_HOME'\nDEFAULT_CACHE_DIR = '~/.cache'\n\n\ndef _get_mmcv_home():\n    mmcv_home = os.path.expanduser(\n        os.getenv(\n            ENV_MMCV_HOME,\n            os.path.join(\n                os.getenv(ENV_XDG_CACHE_HOME, DEFAULT_CACHE_DIR), 'mmcv')))\n\n    mkdir_or_exist(mmcv_home)\n    return mmcv_home\n\n\ndef load_state_dict(module, state_dict, strict=False, logger=None):\n    \"\"\"Load state_dict to a module.\n\n    This method is modified from :meth:`torch.nn.Module.load_state_dict`.\n    Default value for ``strict`` is set to ``False`` and the message for\n    param mismatch will be shown even if strict is False.\n\n    Args:\n        module (Module): Module that receives the state_dict.\n        state_dict (OrderedDict): Weights.\n        strict (bool): whether to strictly enforce that the keys\n            in :attr:`state_dict` match the keys returned by this module's\n            :meth:`~torch.nn.Module.state_dict` function. Default: ``False``.\n        logger (:obj:`logging.Logger`, optional): Logger to log the error\n            message. If not specified, print function will be used.\n    \"\"\"\n    unexpected_keys = []\n    all_missing_keys = []\n    err_msg = []\n\n    metadata = getattr(state_dict, '_metadata', None)\n    state_dict = state_dict.copy()\n    if metadata is not None:\n        state_dict._metadata = metadata\n\n    # use _load_from_state_dict to enable checkpoint version control\n    def load(module, prefix=''):\n        # recursively check parallel module in case that the model has a\n        # complicated structure, e.g., nn.Module(nn.Module(DDP))\n        if is_module_wrapper(module):\n            module = module.module\n        local_metadata = {} if metadata is None else metadata.get(\n            prefix[:-1], {})\n        module._load_from_state_dict(state_dict, prefix, local_metadata, True,\n                                     all_missing_keys, unexpected_keys,\n                                     err_msg)\n        for name, child in module._modules.items():\n            if child is not None:\n                load(child, prefix + name + '.')\n\n    load(module)\n    load = None  # break load->load reference cycle\n\n    # ignore \"num_batches_tracked\" of BN layers\n    missing_keys = [\n        key for key in all_missing_keys if 'num_batches_tracked' not in key\n    ]\n\n    if unexpected_keys:\n        err_msg.append('unexpected key in source '\n                       f'state_dict: {\", \".join(unexpected_keys)}\\n')\n    if missing_keys:\n        err_msg.append(\n            f'missing keys in source state_dict: {\", \".join(missing_keys)}\\n')\n\n    rank, _ = get_dist_info()\n    if len(err_msg) > 0 and rank == 0:\n        err_msg.insert(\n            0, 'The model and loaded state dict do not match exactly\\n')\n        err_msg = '\\n'.join(err_msg)\n        if strict:\n            raise RuntimeError(err_msg)\n        elif logger is not None:\n            logger.warning(err_msg)\n        else:\n            print(err_msg)\n\n\ndef load_url_dist(url, model_dir=None, map_location=\"cpu\"):\n    \"\"\"In distributed setting, this function only download checkpoint at local\n    rank 0.\"\"\"\n    rank, world_size = get_dist_info()\n    rank = int(os.environ.get('LOCAL_RANK', rank))\n    if rank == 0:\n        checkpoint = model_zoo.load_url(url, model_dir=model_dir, map_location=map_location)\n    if world_size > 1:\n        torch.distributed.barrier()\n        if rank > 0:\n            checkpoint = model_zoo.load_url(url, model_dir=model_dir, map_location=map_location)\n    return checkpoint\n\n\ndef load_pavimodel_dist(model_path, map_location=None):\n    \"\"\"In distributed setting, this function only download checkpoint at local\n    rank 0.\"\"\"\n    try:\n        from pavi import modelcloud\n    except ImportError:\n        raise ImportError(\n            'Please install pavi to load checkpoint from modelcloud.')\n    rank, world_size = get_dist_info()\n    rank = int(os.environ.get('LOCAL_RANK', rank))\n    if rank == 0:\n        model = modelcloud.get(model_path)\n        with TemporaryDirectory() as tmp_dir:\n            downloaded_file = osp.join(tmp_dir, model.name)\n            model.download(downloaded_file)\n            checkpoint = torch.load(downloaded_file, map_location=map_location)\n    if world_size > 1:\n        torch.distributed.barrier()\n        if rank > 0:\n            model = modelcloud.get(model_path)\n            with TemporaryDirectory() as tmp_dir:\n                downloaded_file = osp.join(tmp_dir, model.name)\n                model.download(downloaded_file)\n                checkpoint = torch.load(\n                    downloaded_file, map_location=map_location)\n    return checkpoint\n\n\ndef load_fileclient_dist(filename, backend, map_location):\n    \"\"\"In distributed setting, this function only download checkpoint at local\n    rank 0.\"\"\"\n    rank, world_size = get_dist_info()\n    rank = int(os.environ.get('LOCAL_RANK', rank))\n    allowed_backends = ['ceph']\n    if backend not in allowed_backends:\n        raise ValueError(f'Load from Backend {backend} is not supported.')\n    if rank == 0:\n        fileclient = FileClient(backend=backend)\n        buffer = io.BytesIO(fileclient.get(filename))\n        checkpoint = torch.load(buffer, map_location=map_location)\n    if world_size > 1:\n        torch.distributed.barrier()\n        if rank > 0:\n            fileclient = FileClient(backend=backend)\n            buffer = io.BytesIO(fileclient.get(filename))\n            checkpoint = torch.load(buffer, map_location=map_location)\n    return checkpoint\n\n\ndef get_torchvision_models():\n    model_urls = dict()\n    for _, name, ispkg in pkgutil.walk_packages(torchvision.models.__path__):\n        if ispkg:\n            continue\n        _zoo = import_module(f'torchvision.models.{name}')\n        if hasattr(_zoo, 'model_urls'):\n            _urls = getattr(_zoo, 'model_urls')\n            model_urls.update(_urls)\n    return model_urls\n\n\ndef get_external_models():\n    mmcv_home = _get_mmcv_home()\n    default_json_path = osp.join(mmcv.__path__[0], 'model_zoo/open_mmlab.json')\n    default_urls = load_file(default_json_path)\n    assert isinstance(default_urls, dict)\n    external_json_path = osp.join(mmcv_home, 'open_mmlab.json')\n    if osp.exists(external_json_path):\n        external_urls = load_file(external_json_path)\n        assert isinstance(external_urls, dict)\n        default_urls.update(external_urls)\n\n    return default_urls\n\n\ndef get_mmcls_models():\n    mmcls_json_path = osp.join(mmcv.__path__[0], 'model_zoo/mmcls.json')\n    mmcls_urls = load_file(mmcls_json_path)\n\n    return mmcls_urls\n\n\ndef get_deprecated_model_names():\n    deprecate_json_path = osp.join(mmcv.__path__[0],\n                                   'model_zoo/deprecated.json')\n    deprecate_urls = load_file(deprecate_json_path)\n    assert isinstance(deprecate_urls, dict)\n\n    return deprecate_urls\n\n\ndef _process_mmcls_checkpoint(checkpoint):\n    state_dict = checkpoint['state_dict']\n    new_state_dict = OrderedDict()\n    for k, v in state_dict.items():\n        if k.startswith('backbone.'):\n            new_state_dict[k[9:]] = v\n    new_checkpoint = dict(state_dict=new_state_dict)\n\n    return new_checkpoint\n\n\ndef _load_checkpoint(filename, map_location=None):\n    \"\"\"Load checkpoint from somewhere (modelzoo, file, url).\n\n    Args:\n        filename (str): Accept local filepath, URL, ``torchvision://xxx``,\n            ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for\n            details.\n        map_location (str | None): Same as :func:`torch.load`. Default: None.\n\n    Returns:\n        dict | OrderedDict: The loaded checkpoint. It can be either an\n            OrderedDict storing model weights or a dict containing other\n            information, which depends on the checkpoint.\n    \"\"\"\n    if filename.startswith('modelzoo://'):\n        warnings.warn('The URL scheme of \"modelzoo://\" is deprecated, please '\n                      'use \"torchvision://\" instead')\n        model_urls = get_torchvision_models()\n        model_name = filename[11:]\n        checkpoint = load_url_dist(model_urls[model_name])\n    elif filename.startswith('torchvision://'):\n        model_urls = get_torchvision_models()\n        model_name = filename[14:]\n        checkpoint = load_url_dist(model_urls[model_name])\n    elif filename.startswith('open-mmlab://'):\n        model_urls = get_external_models()\n        model_name = filename[13:]\n        deprecated_urls = get_deprecated_model_names()\n        if model_name in deprecated_urls:\n            warnings.warn(f'open-mmlab://{model_name} is deprecated in favor '\n                          f'of open-mmlab://{deprecated_urls[model_name]}')\n            model_name = deprecated_urls[model_name]\n        model_url = model_urls[model_name]\n        # check if is url\n        if model_url.startswith(('http://', 'https://')):\n            checkpoint = load_url_dist(model_url)\n        else:\n            filename = osp.join(_get_mmcv_home(), model_url)\n            if not osp.isfile(filename):\n                raise IOError(f'{filename} is not a checkpoint file')\n            checkpoint = torch.load(filename, map_location=map_location)\n    elif filename.startswith('mmcls://'):\n        model_urls = get_mmcls_models()\n        model_name = filename[8:]\n        checkpoint = load_url_dist(model_urls[model_name])\n        checkpoint = _process_mmcls_checkpoint(checkpoint)\n    elif filename.startswith(('http://', 'https://')):\n        checkpoint = load_url_dist(filename)\n    elif filename.startswith('pavi://'):\n        model_path = filename[7:]\n        checkpoint = load_pavimodel_dist(model_path, map_location=map_location)\n    elif filename.startswith('s3://'):\n        checkpoint = load_fileclient_dist(\n            filename, backend='ceph', map_location=map_location)\n    else:\n        if not osp.isfile(filename):\n            raise IOError(f'{filename} is not a checkpoint file')\n        checkpoint = torch.load(filename, map_location=map_location)\n    return checkpoint\n\n\ndef cosine_scheduler(base_value, final_value, epochs, niter_per_ep, warmup_epochs=0,\n                     start_warmup_value=0, warmup_steps=-1):\n    warmup_schedule = np.array([])\n    warmup_iters = warmup_epochs * niter_per_ep\n    if warmup_steps > 0:\n        warmup_iters = warmup_steps\n    print(\"Set warmup steps = %d\" % warmup_iters)\n    if warmup_epochs > 0:\n        warmup_schedule = np.linspace(start_warmup_value, base_value, warmup_iters)\n\n    iters = np.arange(epochs * niter_per_ep - warmup_iters)\n    schedule = np.array(\n        [final_value + 0.5 * (base_value - final_value) * (1 + math.cos(math.pi * i / (len(iters)))) for i in iters])\n\n    schedule = np.concatenate((warmup_schedule, schedule))\n\n    assert len(schedule) == epochs * niter_per_ep\n    return schedule\n\n\ndef load_checkpoint(model,\n                    filename,\n                    map_location='cpu',\n                    strict=False,\n                    logger=None):\n    \"\"\"Load checkpoint from a file or URI.\n\n    Args:\n        model (Module): Module to load checkpoint.\n        filename (str): Accept local filepath, URL, ``torchvision://xxx``,\n            ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for\n            details.\n        map_location (str): Same as :func:`torch.load`.\n        strict (bool): Whether to allow different params for the model and\n            checkpoint.\n        logger (:mod:`logging.Logger` or None): The logger for error message.\n\n    Returns:\n        dict or OrderedDict: The loaded checkpoint.\n    \"\"\"\n    checkpoint = _load_checkpoint(filename, map_location)\n    # OrderedDict is a subclass of dict\n    if not isinstance(checkpoint, dict):\n        raise RuntimeError(\n            f'No state_dict found in checkpoint file {filename}')\n    # get state_dict from checkpoint\n    if 'state_dict' in checkpoint:\n        state_dict = checkpoint['state_dict']\n    elif 'model' in checkpoint:\n        state_dict = checkpoint['model']\n    elif 'module' in checkpoint:\n        state_dict = checkpoint['module']\n    else:\n        state_dict = checkpoint\n    # strip prefix of state_dict\n    if list(state_dict.keys())[0].startswith('module.'):\n        state_dict = {k[7:]: v for k, v in state_dict.items()}\n\n    # for MoBY, load model of online branch\n    if sorted(list(state_dict.keys()))[0].startswith('encoder'):\n        state_dict = {k.replace('encoder.', ''): v for k, v in state_dict.items() if k.startswith('encoder.')}\n\n    # reshape absolute position embedding for Swin\n    if state_dict.get('absolute_pos_embed') is not None:\n        absolute_pos_embed = state_dict['absolute_pos_embed']\n        N1, L, C1 = absolute_pos_embed.size()\n        N2, C2, H, W = model.absolute_pos_embed.size()\n        if N1 != N2 or C1 != C2 or L != H*W:\n            logger.warning(\"Error in loading absolute_pos_embed, pass\")\n        else:\n            state_dict['absolute_pos_embed'] = absolute_pos_embed.view(N2, H, W, C2).permute(0, 3, 1, 2)\n\n    rank, _ = get_dist_info()\n    all_keys = list(state_dict.keys())\n    for key in all_keys:\n        if \"relative_position_index\" in key:\n            state_dict.pop(key)\n\n        if \"relative_position_bias_table\" in key:\n            rel_pos_bias = state_dict[key]\n            src_num_pos, num_attn_heads = rel_pos_bias.size()\n            dst_num_pos, _ = model.state_dict()[key].size()\n            dst_patch_shape = model.patch_embed.patch_shape\n            if dst_patch_shape[0] != dst_patch_shape[1]:\n                raise NotImplementedError()\n            num_extra_tokens = dst_num_pos - (dst_patch_shape[0] * 2 - 1) * (dst_patch_shape[1] * 2 - 1)\n            src_size = int((src_num_pos - num_extra_tokens) ** 0.5)\n            dst_size = int((dst_num_pos - num_extra_tokens) ** 0.5)\n            if src_size != dst_size:\n                if rank == 0:\n                    print(\"Position interpolate for %s from %dx%d to %dx%d\" % (\n                        key, src_size, src_size, dst_size, dst_size))\n                extra_tokens = rel_pos_bias[-num_extra_tokens:, :]\n                rel_pos_bias = rel_pos_bias[:-num_extra_tokens, :]\n\n                def geometric_progression(a, r, n):\n                    return a * (1.0 - r ** n) / (1.0 - r)\n\n                left, right = 1.01, 1.5\n                while right - left > 1e-6:\n                    q = (left + right) / 2.0\n                    gp = geometric_progression(1, q, src_size // 2)\n                    if gp > dst_size // 2:\n                        right = q\n                    else:\n                        left = q\n\n                # if q > 1.13492:\n                #     q = 1.13492\n\n                dis = []\n                cur = 1\n                for i in range(src_size // 2):\n                    dis.append(cur)\n                    cur += q ** (i + 1)\n\n                r_ids = [-_ for _ in reversed(dis)]\n\n                x = r_ids + [0] + dis\n                y = r_ids + [0] + dis\n\n                t = dst_size // 2.0\n                dx = np.arange(-t, t + 0.1, 1.0)\n                dy = np.arange(-t, t + 0.1, 1.0)\n                if rank == 0:\n                    print(\"x = {}\".format(x))\n                    print(\"dx = {}\".format(dx))\n\n                all_rel_pos_bias = []\n\n                for i in range(num_attn_heads):\n                    z = rel_pos_bias[:, i].view(src_size, src_size).float().numpy()\n                    f = interpolate.interp2d(x, y, z, kind='cubic')\n                    all_rel_pos_bias.append(\n                        torch.Tensor(f(dx, dy)).contiguous().view(-1, 1).to(rel_pos_bias.device))\n\n                rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n                new_rel_pos_bias = torch.cat((rel_pos_bias, extra_tokens), dim=0)\n                state_dict[key] = new_rel_pos_bias\n\n    if 'pos_embed' in state_dict:\n        pos_embed_checkpoint = state_dict['pos_embed']\n        embedding_size = pos_embed_checkpoint.shape[-1]\n        num_patches = model.patch_embed.num_patches\n        num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n        # height (== width) for the checkpoint position embedding\n        orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n        # height (== width) for the new position embedding\n        new_size = int(num_patches ** 0.5)\n        # class_token and dist_token are kept unchanged\n        if orig_size != new_size:\n            if rank == 0:\n                print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n            extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n            # only the position tokens are interpolated\n            pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n            pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n            pos_tokens = torch.nn.functional.interpolate(\n                pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n            pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n            new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n            state_dict['pos_embed'] = new_pos_embed\n\n    # interpolate position bias table if needed\n    relative_position_bias_table_keys = [k for k in state_dict.keys() if \"relative_position_bias_table\" in k]\n    for table_key in relative_position_bias_table_keys:\n        table_pretrained = state_dict[table_key]\n        table_current = model.state_dict()[table_key]\n        L1, nH1 = table_pretrained.size()\n        L2, nH2 = table_current.size()\n        if nH1 != nH2:\n            logger.warning(f\"Error in loading {table_key}, pass\")\n        else:\n            if L1 != L2:\n                S1 = int(L1 ** 0.5)\n                S2 = int(L2 ** 0.5)\n                table_pretrained_resized = F.interpolate(\n                     table_pretrained.permute(1, 0).view(1, nH1, S1, S1),\n                     size=(S2, S2), mode='bicubic')\n                state_dict[table_key] = table_pretrained_resized.view(nH2, L2).permute(1, 0)\n\n    # load state_dict\n    load_state_dict(model, state_dict, strict, logger)\n    return checkpoint\n\n\ndef weights_to_cpu(state_dict):\n    \"\"\"Copy a model state_dict to cpu.\n\n    Args:\n        state_dict (OrderedDict): Model weights on GPU.\n\n    Returns:\n        OrderedDict: Model weights on GPU.\n    \"\"\"\n    state_dict_cpu = OrderedDict()\n    for key, val in state_dict.items():\n        state_dict_cpu[key] = val.cpu()\n    return state_dict_cpu\n\n\ndef _save_to_state_dict(module, destination, prefix, keep_vars):\n    \"\"\"Saves module state to `destination` dictionary.\n\n    This method is modified from :meth:`torch.nn.Module._save_to_state_dict`.\n\n    Args:\n        module (nn.Module): The module to generate state_dict.\n        destination (dict): A dict where state will be stored.\n        prefix (str): The prefix for parameters and buffers used in this\n            module.\n    \"\"\"\n    for name, param in module._parameters.items():\n        if param is not None:\n            destination[prefix + name] = param if keep_vars else param.detach()\n    for name, buf in module._buffers.items():\n        # remove check of _non_persistent_buffers_set to allow nn.BatchNorm2d\n        if buf is not None:\n            destination[prefix + name] = buf if keep_vars else buf.detach()\n\n\ndef get_state_dict(module, destination=None, prefix='', keep_vars=False):\n    \"\"\"Returns a dictionary containing a whole state of the module.\n\n    Both parameters and persistent buffers (e.g. running averages) are\n    included. Keys are corresponding parameter and buffer names.\n\n    This method is modified from :meth:`torch.nn.Module.state_dict` to\n    recursively check parallel module in case that the model has a complicated\n    structure, e.g., nn.Module(nn.Module(DDP)).\n\n    Args:\n        module (nn.Module): The module to generate state_dict.\n        destination (OrderedDict): Returned dict for the state of the\n            module.\n        prefix (str): Prefix of the key.\n        keep_vars (bool): Whether to keep the variable property of the\n            parameters. Default: False.\n\n    Returns:\n        dict: A dictionary containing a whole state of the module.\n    \"\"\"\n    # recursively check parallel module in case that the model has a\n    # complicated structure, e.g., nn.Module(nn.Module(DDP))\n    if is_module_wrapper(module):\n        module = module.module\n\n    # below is the same as torch.nn.Module.state_dict()\n    if destination is None:\n        destination = OrderedDict()\n        destination._metadata = OrderedDict()\n    destination._metadata[prefix[:-1]] = local_metadata = dict(\n        version=module._version)\n    _save_to_state_dict(module, destination, prefix, keep_vars)\n    for name, child in module._modules.items():\n        if child is not None:\n            get_state_dict(\n                child, destination, prefix + name + '.', keep_vars=keep_vars)\n    for hook in module._state_dict_hooks.values():\n        hook_result = hook(module, destination, prefix, local_metadata)\n        if hook_result is not None:\n            destination = hook_result\n    return destination\n\n\ndef save_checkpoint(model, filename, optimizer=None, meta=None):\n    \"\"\"Save checkpoint to file.\n\n    The checkpoint will have 3 fields: ``meta``, ``state_dict`` and\n    ``optimizer``. By default ``meta`` will contain version and time info.\n\n    Args:\n        model (Module): Module whose params are to be saved.\n        filename (str): Checkpoint filename.\n        optimizer (:obj:`Optimizer`, optional): Optimizer to be saved.\n        meta (dict, optional): Metadata to be saved in checkpoint.\n    \"\"\"\n    if meta is None:\n        meta = {}\n    elif not isinstance(meta, dict):\n        raise TypeError(f'meta must be a dict or None, but got {type(meta)}')\n    meta.update(mmcv_version=mmcv.__version__, time=time.asctime())\n\n    if is_module_wrapper(model):\n        model = model.module\n\n    if hasattr(model, 'CLASSES') and model.CLASSES is not None:\n        # save class name to the meta\n        meta.update(CLASSES=model.CLASSES)\n\n    checkpoint = {\n        'meta': meta,\n        'state_dict': weights_to_cpu(get_state_dict(model))\n    }\n    # save optimizer state dict in the checkpoint\n    if isinstance(optimizer, Optimizer):\n        checkpoint['optimizer'] = optimizer.state_dict()\n    elif isinstance(optimizer, dict):\n        checkpoint['optimizer'] = {}\n        for name, optim in optimizer.items():\n            checkpoint['optimizer'][name] = optim.state_dict()\n\n    if filename.startswith('pavi://'):\n        try:\n            from pavi import modelcloud\n            from pavi.exception import NodeNotFoundError\n        except ImportError:\n            raise ImportError(\n                'Please install pavi to load checkpoint from modelcloud.')\n        model_path = filename[7:]\n        root = modelcloud.Folder()\n        model_dir, model_name = osp.split(model_path)\n        try:\n            model = modelcloud.get(model_dir)\n        except NodeNotFoundError:\n            model = root.create_training_model(model_dir)\n        with TemporaryDirectory() as tmp_dir:\n            checkpoint_file = osp.join(tmp_dir, model_name)\n            with open(checkpoint_file, 'wb') as f:\n                torch.save(checkpoint, f)\n                f.flush()\n            model.create_file(checkpoint_file, name=model_name)\n    else:\n        mmcv.mkdir_or_exist(osp.dirname(filename))\n        # immediately flush buffer\n        with open(filename, 'wb') as f:\n            torch.save(checkpoint, f)\n            f.flush()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/layer_decay_optimizer_constructor.py",
    "content": "import json\nfrom mmcv.runner import OPTIMIZER_BUILDERS, DefaultOptimizerConstructor\nfrom mmcv.runner import get_dist_info\n\n\ndef get_num_layer_for_vit(var_name, num_max_layer):\n    if var_name in (\"backbone.cls_token\", \"backbone.mask_token\", \"backbone.pos_embed\"):\n        return 0\n    elif var_name.startswith(\"backbone.patch_embed\"):\n        return 0\n    elif var_name.startswith(\"backbone.blocks\"):\n        layer_id = int(var_name.split('.')[2])\n        return layer_id + 1\n    else:\n        return num_max_layer - 1\n\n\n@OPTIMIZER_BUILDERS.register_module()\nclass LayerDecayOptimizerConstructor(DefaultOptimizerConstructor):\n    def add_params(self, params, module, prefix='', is_dcn_module=None):\n        \"\"\"Add all parameters of module to the params list.\n        The parameters of the given module will be added to the list of param\n        groups, with specific rules defined by paramwise_cfg.\n        Args:\n            params (list[dict]): A list of param groups, it will be modified\n                in place.\n            module (nn.Module): The module to be added.\n            prefix (str): The prefix of the module\n            is_dcn_module (int|float|None): If the current module is a\n                submodule of DCN, `is_dcn_module` will be passed to\n                control conv_offset layer's learning rate. Defaults to None.\n        \"\"\"\n        parameter_groups = {}\n        print(self.paramwise_cfg)\n        num_layers = self.paramwise_cfg.get('num_layers') + 2\n        layer_decay_rate = self.paramwise_cfg.get('layer_decay_rate')\n        print(\"Build LayerDecayOptimizerConstructor %f - %d\" % (layer_decay_rate, num_layers))\n        weight_decay = self.base_wd\n\n        for name, param in module.named_parameters():\n            if not param.requires_grad:\n                continue  # frozen weights\n            if len(param.shape) == 1 or name.endswith(\".bias\") or name in ('pos_embed', 'cls_token'):\n                group_name = \"no_decay\"\n                this_weight_decay = 0.\n            else:\n                group_name = \"decay\"\n                this_weight_decay = weight_decay\n\n            layer_id = get_num_layer_for_vit(name, num_layers)\n            group_name = \"layer_%d_%s\" % (layer_id, group_name)\n\n            if group_name not in parameter_groups:\n                scale = layer_decay_rate ** (num_layers - layer_id - 1)\n\n                parameter_groups[group_name] = {\n                    \"weight_decay\": this_weight_decay,\n                    \"params\": [],\n                    \"param_names\": [], \n                    \"lr_scale\": scale, \n                    \"group_name\": group_name, \n                    \"lr\": scale * self.base_lr, \n                }\n\n            parameter_groups[group_name][\"params\"].append(param)\n            parameter_groups[group_name][\"param_names\"].append(name)\n        rank, _ = get_dist_info()\n        if rank == 0:\n            to_display = {}\n            for key in parameter_groups:\n                to_display[key] = {\n                    \"param_names\": parameter_groups[key][\"param_names\"], \n                    \"lr_scale\": parameter_groups[key][\"lr_scale\"], \n                    \"lr\": parameter_groups[key][\"lr\"], \n                    \"weight_decay\": parameter_groups[key][\"weight_decay\"], \n                }\n            print(\"Param groups = %s\" % json.dumps(to_display, indent=2))\n        \n        # state_dict = module.state_dict()\n        # for group_name in parameter_groups:\n        #     group = parameter_groups[group_name]\n        #     for name in group[\"param_names\"]:\n        #         group[\"params\"].append(state_dict[name])\n        params.extend(parameter_groups.values())\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/resize_transform.py",
    "content": "import mmcv\nimport numpy as np\n\nfrom mmseg.datasets.builder import PIPELINES\n\n\n@PIPELINES.register_module()\nclass SETR_Resize(object):\n    \"\"\"Resize images & seg.\n\n    This transform resizes the input image to some scale. If the input dict\n    contains the key \"scale\", then the scale in the input dict is used,\n    otherwise the specified scale in the init method is used.\n\n    ``img_scale`` can either be a tuple (single-scale) or a list of tuple\n    (multi-scale). There are 3 multiscale modes:\n\n    - ``ratio_range is not None``: randomly sample a ratio from the ratio range\n    and multiply it with the image scale.\n\n    - ``ratio_range is None and multiscale_mode == \"range\"``: randomly sample a\n    scale from the a range.\n\n    - ``ratio_range is None and multiscale_mode == \"value\"``: randomly sample a\n    scale from multiple scales.\n\n    Args:\n        img_scale (tuple or list[tuple]): Images scales for resizing.\n        multiscale_mode (str): Either \"range\" or \"value\".\n        ratio_range (tuple[float]): (min_ratio, max_ratio)\n        keep_ratio (bool): Whether to keep the aspect ratio when resizing the\n            image.\n    \"\"\"\n\n    def __init__(self,\n                 img_scale=None,\n                 multiscale_mode='range',\n                 ratio_range=None,\n                 keep_ratio=True,\n                 crop_size=None,\n                 setr_multi_scale=False):\n\n        if img_scale is None:\n            self.img_scale = None\n        else:\n            if isinstance(img_scale, list):\n                self.img_scale = img_scale\n            else:\n                self.img_scale = [img_scale]\n            # assert mmcv.is_list_of(self.img_scale, tuple)\n\n        if ratio_range is not None:\n            # mode 1: given a scale and a range of image ratio\n            assert len(self.img_scale) == 1\n        else:\n            # mode 2: given multiple scales or a range of scales\n            assert multiscale_mode in ['value', 'range']\n\n        self.multiscale_mode = multiscale_mode\n        self.ratio_range = ratio_range\n        self.keep_ratio = keep_ratio\n        self.crop_size = crop_size\n        self.setr_multi_scale = setr_multi_scale\n\n    @staticmethod\n    def random_select(img_scales):\n        \"\"\"Randomly select an img_scale from given candidates.\n\n        Args:\n            img_scales (list[tuple]): Images scales for selection.\n\n        Returns:\n            (tuple, int): Returns a tuple ``(img_scale, scale_dix)``,\n                where ``img_scale`` is the selected image scale and\n                ``scale_idx`` is the selected index in the given candidates.\n        \"\"\"\n\n        assert mmcv.is_list_of(img_scales, tuple)\n        scale_idx = np.random.randint(len(img_scales))\n        img_scale = img_scales[scale_idx]\n        return img_scale, scale_idx\n\n    @staticmethod\n    def random_sample(img_scales):\n        \"\"\"Randomly sample an img_scale when ``multiscale_mode=='range'``.\n\n        Args:\n            img_scales (list[tuple]): Images scale range for sampling.\n                There must be two tuples in img_scales, which specify the lower\n                and uper bound of image scales.\n\n        Returns:\n            (tuple, None): Returns a tuple ``(img_scale, None)``, where\n                ``img_scale`` is sampled scale and None is just a placeholder\n                to be consistent with :func:`random_select`.\n        \"\"\"\n\n        assert mmcv.is_list_of(img_scales, tuple) and len(img_scales) == 2\n        img_scale_long = [max(s) for s in img_scales]\n        img_scale_short = [min(s) for s in img_scales]\n        long_edge = np.random.randint(\n            min(img_scale_long),\n            max(img_scale_long) + 1)\n        short_edge = np.random.randint(\n            min(img_scale_short),\n            max(img_scale_short) + 1)\n        img_scale = (long_edge, short_edge)\n        return img_scale, None\n\n    @staticmethod\n    def random_sample_ratio(img_scale, ratio_range):\n        \"\"\"Randomly sample an img_scale when ``ratio_range`` is specified.\n\n        A ratio will be randomly sampled from the range specified by\n        ``ratio_range``. Then it would be multiplied with ``img_scale`` to\n        generate sampled scale.\n\n        Args:\n            img_scale (tuple): Images scale base to multiply with ratio.\n            ratio_range (tuple[float]): The minimum and maximum ratio to scale\n                the ``img_scale``.\n\n        Returns:\n            (tuple, None): Returns a tuple ``(scale, None)``, where\n                ``scale`` is sampled ratio multiplied with ``img_scale`` and\n                None is just a placeholder to be consistent with\n                :func:`random_select`.\n        \"\"\"\n\n        assert isinstance(img_scale, tuple) and len(img_scale) == 2\n        min_ratio, max_ratio = ratio_range\n        assert min_ratio <= max_ratio\n        ratio = np.random.random_sample() * (max_ratio - min_ratio) + min_ratio\n        scale = int(img_scale[0] * ratio), int(img_scale[1] * ratio)\n        return scale, None\n\n    def _random_scale(self, results):\n        \"\"\"Randomly sample an img_scale according to ``ratio_range`` and\n        ``multiscale_mode``.\n\n        If ``ratio_range`` is specified, a ratio will be sampled and be\n        multiplied with ``img_scale``.\n        If multiple scales are specified by ``img_scale``, a scale will be\n        sampled according to ``multiscale_mode``.\n        Otherwise, single scale will be used.\n\n        Args:\n            results (dict): Result dict from :obj:`dataset`.\n\n        Returns:\n            dict: Two new keys 'scale` and 'scale_idx` are added into\n                ``results``, which would be used by subsequent pipelines.\n        \"\"\"\n\n        if self.ratio_range is not None:\n            scale, scale_idx = self.random_sample_ratio(\n                self.img_scale[0], self.ratio_range)\n        elif len(self.img_scale) == 1:\n            scale, scale_idx = self.img_scale[0], 0\n        elif self.multiscale_mode == 'range':\n            scale, scale_idx = self.random_sample(self.img_scale)\n        elif self.multiscale_mode == 'value':\n            scale, scale_idx = self.random_select(self.img_scale)\n        else:\n            raise NotImplementedError\n\n        results['scale'] = scale\n        results['scale_idx'] = scale_idx\n\n    def _resize_img(self, results):\n        \"\"\"Resize images with ``results['scale']``.\"\"\"\n\n        if self.keep_ratio:\n            if self.setr_multi_scale:\n                if min(results['scale']) < self.crop_size[0]:\n                    new_short = self.crop_size[0]\n                else:\n                    new_short = min(results['scale'])\n                    \n                h, w = results['img'].shape[:2]\n                if h > w:\n                    new_h, new_w = new_short * h / w, new_short\n                else:\n                    new_h, new_w = new_short, new_short * w / h\n                results['scale'] = (new_h, new_w)\n\n            img, scale_factor = mmcv.imrescale(\n                results['img'], results['scale'], return_scale=True)\n            # the w_scale and h_scale has minor difference\n            # a real fix should be done in the mmcv.imrescale in the future\n            new_h, new_w = img.shape[:2]\n            h, w = results['img'].shape[:2]\n            w_scale = new_w / w\n            h_scale = new_h / h\n        else:\n            img, w_scale, h_scale = mmcv.imresize(\n                results['img'], results['scale'], return_scale=True)\n        scale_factor = np.array([w_scale, h_scale, w_scale, h_scale],\n                                dtype=np.float32)\n        results['img'] = img\n        results['img_shape'] = img.shape\n        results['pad_shape'] = img.shape  # in case that there is no padding\n        results['scale_factor'] = scale_factor\n        results['keep_ratio'] = self.keep_ratio\n\n    def _resize_seg(self, results):\n        \"\"\"Resize semantic segmentation map with ``results['scale']``.\"\"\"\n        for key in results.get('seg_fields', []):\n            if self.keep_ratio:\n                gt_seg = mmcv.imrescale(\n                    results[key], results['scale'], interpolation='nearest')\n            else:\n                gt_seg = mmcv.imresize(\n                    results[key], results['scale'], interpolation='nearest')\n            results['gt_semantic_seg'] = gt_seg\n\n    def __call__(self, results):\n        \"\"\"Call function to resize images, bounding boxes, masks, semantic\n        segmentation map.\n\n        Args:\n            results (dict): Result dict from loading pipeline.\n\n        Returns:\n            dict: Resized results, 'img_shape', 'pad_shape', 'scale_factor',\n                'keep_ratio' keys are added into result dict.\n        \"\"\"\n\n        if 'scale' not in results:\n            self._random_scale(results)\n        self._resize_img(results)\n        self._resize_seg(results)\n        return results\n\n    def __repr__(self):\n        repr_str = self.__class__.__name__\n        repr_str += (f'(img_scale={self.img_scale}, '\n                     f'multiscale_mode={self.multiscale_mode}, '\n                     f'ratio_range={self.ratio_range}, '\n                     f'keep_ratio={self.keep_ratio})')\n        return repr_str\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/mmcv_custom/train_api.py",
    "content": "import random\nimport warnings\n\nimport numpy as np\nimport torch\nfrom mmcv.parallel import MMDataParallel, MMDistributedDataParallel\nfrom mmcv.runner import build_optimizer, build_runner\n\nfrom mmseg.core import DistEvalHook, EvalHook\nfrom mmseg.datasets import build_dataloader, build_dataset\nfrom mmseg.utils import get_root_logger\ntry:\n    import apex\nexcept:\n    print('apex is not installed')\n\n\ndef set_random_seed(seed, deterministic=False):\n    \"\"\"Set random seed.\n\n    Args:\n        seed (int): Seed to be used.\n        deterministic (bool): Whether to set the deterministic option for\n            CUDNN backend, i.e., set `torch.backends.cudnn.deterministic`\n            to True and `torch.backends.cudnn.benchmark` to False.\n            Default: False.\n    \"\"\"\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    if deterministic:\n        torch.backends.cudnn.deterministic = True\n        torch.backends.cudnn.benchmark = False\n\n\ndef train_segmentor(model,\n                    dataset,\n                    cfg,\n                    distributed=False,\n                    validate=False,\n                    timestamp=None,\n                    meta=None):\n    \"\"\"Launch segmentor training.\"\"\"\n    logger = get_root_logger(cfg.log_level)\n\n    # prepare data loaders\n    dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset]\n    data_loaders = [\n        build_dataloader(\n            ds,\n            cfg.data.samples_per_gpu,\n            cfg.data.workers_per_gpu,\n            # cfg.gpus will be ignored if distributed\n            len(cfg.gpu_ids),\n            dist=distributed,\n            seed=cfg.seed,\n            drop_last=True) for ds in dataset\n    ]\n\n    # build optimizer\n    optimizer = build_optimizer(model, cfg.optimizer)\n\n    # use apex fp16 optimizer\n    if cfg.optimizer_config.get(\"type\", None) and cfg.optimizer_config[\"type\"] == \"DistOptimizerHook\":\n        if cfg.optimizer_config.get(\"use_fp16\", False):\n            model, optimizer = apex.amp.initialize(\n                model.cuda(), optimizer, opt_level=\"O1\")\n            for m in model.modules():\n                if hasattr(m, \"fp16_enabled\"):\n                    m.fp16_enabled = True\n\n    # put model on gpus\n    if distributed:\n        find_unused_parameters = cfg.get('find_unused_parameters', False)\n        # Sets the `find_unused_parameters` parameter in\n        # torch.nn.parallel.DistributedDataParallel\n        model = MMDistributedDataParallel(\n            model.cuda(),\n            device_ids=[torch.cuda.current_device()],\n            broadcast_buffers=False,\n            find_unused_parameters=find_unused_parameters)\n    else:\n        model = MMDataParallel(\n            model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids)\n\n    if cfg.get('runner') is None:\n        cfg.runner = {'type': 'IterBasedRunner', 'max_iters': cfg.total_iters}\n        warnings.warn(\n            'config is now expected to have a `runner` section, '\n            'please set `runner` in your config.', UserWarning)\n\n    runner = build_runner(\n        cfg.runner,\n        default_args=dict(\n            model=model,\n            batch_processor=None,\n            optimizer=optimizer,\n            work_dir=cfg.work_dir,\n            logger=logger,\n            meta=meta))\n\n    # register hooks\n    runner.register_training_hooks(cfg.lr_config, cfg.optimizer_config,\n                                   cfg.checkpoint_config, cfg.log_config,\n                                   cfg.get('momentum_config', None))\n\n    # an ugly walkaround to make the .log and .log.json filenames the same\n    runner.timestamp = timestamp\n\n    # register eval hooks\n    if validate:\n        val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))\n        val_dataloader = build_dataloader(\n            val_dataset,\n            samples_per_gpu=1,\n            workers_per_gpu=cfg.data.workers_per_gpu,\n            dist=distributed,\n            shuffle=False)\n        eval_cfg = cfg.get('evaluation', {})\n        eval_cfg['by_epoch'] = 'IterBasedRunner' not in cfg.runner['type']\n        eval_hook = DistEvalHook if distributed else EvalHook\n        runner.register_hook(eval_hook(val_dataloader, **eval_cfg))\n\n    if cfg.resume_from:\n        runner.resume(cfg.resume_from)\n    elif cfg.load_from:\n        runner.load_checkpoint(cfg.load_from)\n    runner.run(data_loaders, cfg.workflow)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/tools/dist_test.sh",
    "content": "#!/usr/bin/env bash\n\nCONFIG=$1\nCHECKPOINT=$2\nGPUS=$3\nPORT=${PORT:-29500}\nPYTHONPATH=\"$(dirname $0)/..\":$PYTHONPATH \\\npython -m torch.distributed.launch --nproc_per_node=$GPUS --master_port=$PORT \\\n    $(dirname \"$0\")/test.py $CONFIG $CHECKPOINT --launcher pytorch ${@:4}\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/tools/dist_train.sh",
    "content": "#!/usr/bin/env bash\n\nCONFIG=$1\nGPUS=$2\nPORT=${PORT:-29500}\n\nPYTHONPATH=\"$(dirname $0)/..\":$PYTHONPATH \\\npython -m torch.distributed.launch --nproc_per_node=$GPUS --master_port=$PORT \\\n    $(dirname \"$0\")/train.py $CONFIG --launcher pytorch ${@:3}\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/tools/test.py",
    "content": "import argparse\nimport os\n\nimport mmcv\nimport torch\nfrom mmcv.parallel import MMDataParallel, MMDistributedDataParallel\nfrom mmcv.runner import get_dist_info, init_dist, load_checkpoint\nfrom mmcv.utils import DictAction\n\nfrom mmseg.apis import multi_gpu_test, single_gpu_test\nfrom mmseg.datasets import build_dataloader, build_dataset\nfrom mmseg.models import build_segmentor\n\nfrom backbone import beit\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='mmseg test (and eval) a model')\n    parser.add_argument('config', help='test config file path')\n    parser.add_argument('checkpoint', help='checkpoint file')\n    parser.add_argument(\n        '--aug-test', action='store_true', help='Use Flip and Multi scale aug')\n    parser.add_argument('--out', help='output result file in pickle format')\n    parser.add_argument(\n        '--format-only',\n        action='store_true',\n        help='Format the output results without perform evaluation. It is'\n        'useful when you want to format the result to a specific format and '\n        'submit it to the test server')\n    parser.add_argument(\n        '--eval',\n        type=str,\n        nargs='+',\n        help='evaluation metrics, which depends on the dataset, e.g., \"mIoU\"'\n        ' for generic datasets, and \"cityscapes\" for Cityscapes')\n    parser.add_argument('--show', action='store_true', help='show results')\n    parser.add_argument(\n        '--show-dir', help='directory where painted images will be saved')\n    parser.add_argument(\n        '--gpu-collect',\n        action='store_true',\n        help='whether to use gpu to collect results.')\n    parser.add_argument(\n        '--tmpdir',\n        help='tmp directory used for collecting results from multiple '\n        'workers, available when gpu_collect is not specified')\n    parser.add_argument(\n        '--options', nargs='+', action=DictAction, help='custom options')\n    parser.add_argument(\n        '--eval-options',\n        nargs='+',\n        action=DictAction,\n        help='custom options for evaluation')\n    parser.add_argument(\n        '--launcher',\n        choices=['none', 'pytorch', 'slurm', 'mpi'],\n        default='none',\n        help='job launcher')\n    parser.add_argument('--local_rank', type=int, default=0)\n    args = parser.parse_args()\n    if 'LOCAL_RANK' not in os.environ:\n        os.environ['LOCAL_RANK'] = str(args.local_rank)\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    assert args.out or args.eval or args.format_only or args.show \\\n        or args.show_dir, \\\n        ('Please specify at least one operation (save/eval/format/show the '\n         'results / save the results) with the argument \"--out\", \"--eval\"'\n         ', \"--format-only\", \"--show\" or \"--show-dir\"')\n\n    if args.eval and args.format_only:\n        raise ValueError('--eval and --format_only cannot be both specified')\n\n    if args.out is not None and not args.out.endswith(('.pkl', '.pickle')):\n        raise ValueError('The output file must be a pkl file.')\n\n    cfg = mmcv.Config.fromfile(args.config)\n    if args.options is not None:\n        cfg.merge_from_dict(args.options)\n    # set cudnn_benchmark\n    if cfg.get('cudnn_benchmark', False):\n        torch.backends.cudnn.benchmark = True\n    if args.aug_test:\n        # hard code index\n        cfg.data.test.pipeline[1].img_ratios = [\n            0.5, 0.75, 1.0, 1.25, 1.5, 1.75\n        ]\n        cfg.data.test.pipeline[1].flip = True\n    cfg.model.pretrained = None\n    cfg.data.test.test_mode = True\n\n    # init distributed env first, since logger depends on the dist info.\n    if args.launcher == 'none':\n        distributed = False\n    else:\n        distributed = True\n        init_dist(args.launcher, **cfg.dist_params)\n\n    # build the dataloader\n    # TODO: support multiple images per gpu (only minor changes are needed)\n    dataset = build_dataset(cfg.data.test)\n    data_loader = build_dataloader(\n        dataset,\n        samples_per_gpu=1,\n        workers_per_gpu=cfg.data.workers_per_gpu,\n        dist=distributed,\n        shuffle=False)\n\n    # build the model and load checkpoint\n    cfg.model.train_cfg = None\n    model = build_segmentor(cfg.model, test_cfg=cfg.get('test_cfg'))\n    checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu')\n    model.CLASSES = checkpoint['meta']['CLASSES']\n    model.PALETTE = checkpoint['meta']['PALETTE']\n\n    efficient_test = False\n    if args.eval_options is not None:\n        efficient_test = args.eval_options.get('efficient_test', False)\n\n    if not distributed:\n        model = MMDataParallel(model, device_ids=[0])\n        outputs = single_gpu_test(model, data_loader, args.show, args.show_dir,\n                                  efficient_test)\n    else:\n        model = MMDistributedDataParallel(\n            model.cuda(),\n            device_ids=[torch.cuda.current_device()],\n            broadcast_buffers=False)\n        outputs = multi_gpu_test(model, data_loader, args.tmpdir,\n                                 args.gpu_collect, efficient_test)\n\n    rank, _ = get_dist_info()\n    if rank == 0:\n        if args.out:\n            print(f'\\nwriting results to {args.out}')\n            mmcv.dump(outputs, args.out)\n        kwargs = {} if args.eval_options is None else args.eval_options\n        if args.format_only:\n            dataset.format_results(outputs, **kwargs)\n        if args.eval:\n            dataset.evaluate(outputs, args.eval, **kwargs)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/semantic_segmentation/tools/train.py",
    "content": "import argparse\nimport copy\nimport os\nimport os.path as osp\nimport time\n\nimport mmcv\nimport mmcv_custom\nimport torch\nfrom mmcv.runner import init_dist\nfrom mmcv.utils import Config, DictAction, get_git_hash\n\nfrom mmseg import __version__\nfrom mmseg.apis import set_random_seed\nfrom mmcv_custom import train_segmentor\nfrom mmseg.datasets import build_dataset\nfrom mmseg.models import build_segmentor\nfrom mmseg.utils import collect_env, get_root_logger\n\nfrom backbone import beit\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Train a segmentor')\n    parser.add_argument('config', help='train config file path')\n    parser.add_argument('--work-dir', help='the dir to save logs and models')\n    parser.add_argument(\n        '--load-from', help='the checkpoint file to load weights from')\n    parser.add_argument(\n        '--resume-from', help='the checkpoint file to resume from')\n    parser.add_argument(\n        '--no-validate',\n        action='store_true',\n        help='whether not to evaluate the checkpoint during training')\n    group_gpus = parser.add_mutually_exclusive_group()\n    group_gpus.add_argument(\n        '--gpus',\n        type=int,\n        help='number of gpus to use '\n        '(only applicable to non-distributed training)')\n    group_gpus.add_argument(\n        '--gpu-ids',\n        type=int,\n        nargs='+',\n        help='ids of gpus to use '\n        '(only applicable to non-distributed training)')\n    parser.add_argument('--seed', type=int, default=None, help='random seed')\n    parser.add_argument(\n        '--deterministic',\n        action='store_true',\n        help='whether to set deterministic options for CUDNN backend.')\n    parser.add_argument(\n        '--options', nargs='+', action=DictAction, help='custom options')\n    parser.add_argument(\n        '--launcher',\n        choices=['none', 'pytorch', 'slurm', 'mpi'],\n        default='none',\n        help='job launcher')\n    parser.add_argument('--local_rank', type=int, default=0)\n    args = parser.parse_args()\n    if 'LOCAL_RANK' not in os.environ:\n        os.environ['LOCAL_RANK'] = str(args.local_rank)\n\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    cfg = Config.fromfile(args.config)\n    if args.options is not None:\n        cfg.merge_from_dict(args.options)\n    # set cudnn_benchmark\n    if cfg.get('cudnn_benchmark', False):\n        torch.backends.cudnn.benchmark = True\n\n    # work_dir is determined in this priority: CLI > segment in file > filename\n    if args.work_dir is not None:\n        # update configs according to CLI args if args.work_dir is not None\n        cfg.work_dir = args.work_dir\n    elif cfg.get('work_dir', None) is None:\n        # use config filename as default work_dir if cfg.work_dir is None\n        cfg.work_dir = osp.join('./work_dirs',\n                                osp.splitext(osp.basename(args.config))[0])\n    if args.load_from is not None:\n        cfg.load_from = args.load_from\n    if args.resume_from is not None:\n        cfg.resume_from = args.resume_from\n    if args.gpu_ids is not None:\n        cfg.gpu_ids = args.gpu_ids\n    else:\n        cfg.gpu_ids = range(1) if args.gpus is None else range(args.gpus)\n\n    # init distributed env first, since logger depends on the dist info.\n    if args.launcher == 'none':\n        distributed = False\n    else:\n        distributed = True\n        init_dist(args.launcher, **cfg.dist_params)\n\n    # create work_dir\n    mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))\n    # dump config\n    cfg.dump(osp.join(cfg.work_dir, osp.basename(args.config)))\n    # init the logger before other steps\n    timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())\n    log_file = osp.join(cfg.work_dir, f'{timestamp}.log')\n    logger = get_root_logger(log_file=log_file, log_level=cfg.log_level)\n\n    # init the meta dict to record some important information such as\n    # environment info and seed, which will be logged\n    meta = dict()\n    # log env info\n    env_info_dict = collect_env()\n    env_info = '\\n'.join([f'{k}: {v}' for k, v in env_info_dict.items()])\n    dash_line = '-' * 60 + '\\n'\n    logger.info('Environment info:\\n' + dash_line + env_info + '\\n' +\n                dash_line)\n    meta['env_info'] = env_info\n\n    # log some basic info\n    logger.info(f'Distributed training: {distributed}')\n    logger.info(f'Config:\\n{cfg.pretty_text}')\n\n    # set random seeds\n    if args.seed is not None:\n        logger.info(f'Set random seed to {args.seed}, deterministic: '\n                    f'{args.deterministic}')\n        set_random_seed(args.seed, deterministic=args.deterministic)\n    cfg.seed = args.seed\n    meta['seed'] = args.seed\n    meta['exp_name'] = osp.basename(args.config)\n\n    model = build_segmentor(\n        cfg.model,\n        train_cfg=cfg.get('train_cfg'),\n        test_cfg=cfg.get('test_cfg'))\n\n    logger.info(model)\n\n    datasets = [build_dataset(cfg.data.train)]\n    if len(cfg.workflow) == 2:\n        val_dataset = copy.deepcopy(cfg.data.val)\n        val_dataset.pipeline = cfg.data.train.pipeline\n        datasets.append(build_dataset(val_dataset))\n    if cfg.checkpoint_config is not None:\n        # save mmseg version, config file content and class names in\n        # checkpoints as meta data\n        cfg.checkpoint_config.meta = dict(\n            mmseg_version=f'{__version__}+{get_git_hash()[:7]}',\n            config=cfg.pretty_text,\n            CLASSES=datasets[0].CLASSES,\n            PALETTE=datasets[0].PALETTE)\n    # add an attribute for visualization convenience\n    model.CLASSES = datasets[0].CLASSES\n    train_segmentor(\n        model,\n        datasets,\n        cfg,\n        distributed=distributed,\n        validate=(not args.no_validate),\n        timestamp=timestamp,\n        meta=meta)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/transforms.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport torch\nimport torchvision.transforms.functional as F\nfrom PIL import Image\nimport warnings\nimport math\nimport random\nimport numpy as np\n\n\nclass ToNumpy:\n\n    def __call__(self, pil_img):\n        np_img = np.array(pil_img, dtype=np.uint8)\n        if np_img.ndim < 3:\n            np_img = np.expand_dims(np_img, axis=-1)\n        np_img = np.rollaxis(np_img, 2)  # HWC to CHW\n        return np_img\n\n\nclass ToTensor:\n\n    def __init__(self, dtype=torch.float32):\n        self.dtype = dtype\n\n    def __call__(self, pil_img):\n        np_img = np.array(pil_img, dtype=np.uint8)\n        if np_img.ndim < 3:\n            np_img = np.expand_dims(np_img, axis=-1)\n        np_img = np.rollaxis(np_img, 2)  # HWC to CHW\n        return torch.from_numpy(np_img).to(dtype=self.dtype)\n\n\n_pil_interpolation_to_str = {\n    Image.NEAREST: 'PIL.Image.NEAREST',\n    Image.BILINEAR: 'PIL.Image.BILINEAR',\n    Image.BICUBIC: 'PIL.Image.BICUBIC',\n    Image.LANCZOS: 'PIL.Image.LANCZOS',\n    Image.HAMMING: 'PIL.Image.HAMMING',\n    Image.BOX: 'PIL.Image.BOX',\n}\n\n\ndef _pil_interp(method):\n    if method == 'bicubic':\n        return Image.BICUBIC\n    elif method == 'lanczos':\n        return Image.LANCZOS\n    elif method == 'hamming':\n        return Image.HAMMING\n    else:\n        # default bilinear, do we want to allow nearest?\n        return Image.BILINEAR\n\n\n_RANDOM_INTERPOLATION = (Image.BILINEAR, Image.BICUBIC)\n\n\nclass RandomResizedCropAndInterpolationWithTwoPic:\n    \"\"\"Crop the given PIL Image to random size and aspect ratio with random interpolation.\n\n    A crop of random size (default: of 0.08 to 1.0) of the original size and a random\n    aspect ratio (default: of 3/4 to 4/3) of the original aspect ratio is made. This crop\n    is finally resized to given size.\n    This is popularly used to train the Inception networks.\n\n    Args:\n        size: expected output size of each edge\n        scale: range of size of the origin size cropped\n        ratio: range of aspect ratio of the origin aspect ratio cropped\n        interpolation: Default: PIL.Image.BILINEAR\n    \"\"\"\n\n    def __init__(self, size, second_size=None, scale=(0.08, 1.0), ratio=(3. / 4., 4. / 3.),\n                 interpolation='bilinear', second_interpolation='lanczos'):\n        if isinstance(size, tuple):\n            self.size = size\n        else:\n            self.size = (size, size)\n        if second_size is not None:\n            if isinstance(second_size, tuple):\n                self.second_size = second_size\n            else:\n                self.second_size = (second_size, second_size)\n        else:\n            self.second_size = None\n        if (scale[0] > scale[1]) or (ratio[0] > ratio[1]):\n            warnings.warn(\"range should be of kind (min, max)\")\n\n        if interpolation == 'random':\n            self.interpolation = _RANDOM_INTERPOLATION\n        else:\n            self.interpolation = _pil_interp(interpolation)\n\n        self.second_interpolation = _pil_interp(second_interpolation) if second_interpolation is not None else None\n        self.scale = scale\n        self.ratio = ratio\n\n    @staticmethod\n    def get_params(img, scale, ratio):\n        \"\"\"Get parameters for ``crop`` for a random sized crop.\n\n        Args:\n            img (PIL Image): Image to be cropped.\n            scale (tuple): range of size of the origin size cropped\n            ratio (tuple): range of aspect ratio of the origin aspect ratio cropped\n\n        Returns:\n            tuple: params (i, j, h, w) to be passed to ``crop`` for a random\n                sized crop.\n        \"\"\"\n        area = img.size[0] * img.size[1]\n\n        for attempt in range(10):\n            target_area = random.uniform(*scale) * area\n            log_ratio = (math.log(ratio[0]), math.log(ratio[1]))\n            aspect_ratio = math.exp(random.uniform(*log_ratio))\n\n            w = int(round(math.sqrt(target_area * aspect_ratio)))\n            h = int(round(math.sqrt(target_area / aspect_ratio)))\n\n            if w <= img.size[0] and h <= img.size[1]:\n                i = random.randint(0, img.size[1] - h)\n                j = random.randint(0, img.size[0] - w)\n                return i, j, h, w\n\n        # Fallback to central crop\n        in_ratio = img.size[0] / img.size[1]\n        if in_ratio < min(ratio):\n            w = img.size[0]\n            h = int(round(w / min(ratio)))\n        elif in_ratio > max(ratio):\n            h = img.size[1]\n            w = int(round(h * max(ratio)))\n        else:  # whole image\n            w = img.size[0]\n            h = img.size[1]\n        i = (img.size[1] - h) // 2\n        j = (img.size[0] - w) // 2\n        return i, j, h, w\n\n    def __call__(self, img):\n        \"\"\"\n        Args:\n            img (PIL Image): Image to be cropped and resized.\n\n        Returns:\n            PIL Image: Randomly cropped and resized image.\n        \"\"\"\n        i, j, h, w = self.get_params(img, self.scale, self.ratio)\n        if isinstance(self.interpolation, (tuple, list)):\n            interpolation = random.choice(self.interpolation)\n        else:\n            interpolation = self.interpolation\n        if self.second_size is None:\n            return F.resized_crop(img, i, j, h, w, self.size, interpolation)\n        else:\n            return F.resized_crop(img, i, j, h, w, self.size, interpolation), \\\n                   F.resized_crop(img, i, j, h, w, self.second_size, self.second_interpolation)\n\n    def __repr__(self):\n        if isinstance(self.interpolation, (tuple, list)):\n            interpolate_str = ' '.join([_pil_interpolation_to_str[x] for x in self.interpolation])\n        else:\n            interpolate_str = _pil_interpolation_to_str[self.interpolation]\n        format_string = self.__class__.__name__ + '(size={0}'.format(self.size)\n        format_string += ', scale={0}'.format(tuple(round(s, 4) for s in self.scale))\n        format_string += ', ratio={0}'.format(tuple(round(r, 4) for r in self.ratio))\n        format_string += ', interpolation={0}'.format(interpolate_str)\n        if self.second_size is not None:\n            format_string += ', second_size={0}'.format(self.second_size)\n            format_string += ', second_interpolation={0}'.format(_pil_interpolation_to_str[self.second_interpolation])\n        format_string += ')'\n        return format_string\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/data2vec/utils.py",
    "content": "# --------------------------------------------------------\n# BEIT: BERT Pre-Training of Image Transformers (https://arxiv.org/abs/2106.08254)\n# Github source: https://github.com/microsoft/unilm/tree/master/beit\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# By Hangbo Bao\n# Based on timm, DINO and DeiT code bases\n# https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# https://github.com/facebookresearch/deit\n# https://github.com/facebookresearch/dino\n# --------------------------------------------------------'\n# Copyright (c) Meta Platforms, Inc. and affiliates\nimport io\nimport os\nimport math\nimport time\nimport json\nfrom collections import defaultdict, deque\nimport datetime\nimport numpy as np\nfrom timm.utils import get_state_dict\n\nfrom pathlib import Path\n\nimport torch\nimport torch.distributed as dist\nfrom torch._six import inf\nfrom .modeling_discrete_vae import Dalle_VAE, DiscreteVAE\n\nfrom tensorboardX import SummaryWriter\n\n\nclass SmoothedValue(object):\n    \"\"\"Track a series of values and provide access to smoothed values over a\n    window or the global series average.\n    \"\"\"\n\n    def __init__(self, window_size=20, fmt=None):\n        if fmt is None:\n            fmt = \"{median:.4f} ({global_avg:.4f})\"\n        self.deque = deque(maxlen=window_size)\n        self.total = 0.0\n        self.count = 0\n        self.fmt = fmt\n\n    def update(self, value, n=1):\n        self.deque.append(value)\n        self.count += n\n        self.total += value * n\n\n    def synchronize_between_processes(self):\n        \"\"\"\n        Warning: does not synchronize the deque!\n        \"\"\"\n        if not is_dist_avail_and_initialized():\n            return\n        t = torch.tensor([self.count, self.total], dtype=torch.float64, device='cuda')\n        dist.barrier()\n        dist.all_reduce(t)\n        t = t.tolist()\n        self.count = int(t[0])\n        self.total = t[1]\n\n    @property\n    def median(self):\n        d = torch.tensor(list(self.deque))\n        return d.median().item()\n\n    @property\n    def avg(self):\n        d = torch.tensor(list(self.deque), dtype=torch.float32)\n        return d.mean().item()\n\n    @property\n    def global_avg(self):\n        return self.total / self.count\n\n    @property\n    def max(self):\n        return max(self.deque)\n\n    @property\n    def value(self):\n        return self.deque[-1]\n\n    def __str__(self):\n        return self.fmt.format(\n            median=self.median,\n            avg=self.avg,\n            global_avg=self.global_avg,\n            max=self.max,\n            value=self.value)\n\n\nclass MetricLogger(object):\n    def __init__(self, delimiter=\"\\t\"):\n        self.meters = defaultdict(SmoothedValue)\n        self.delimiter = delimiter\n\n    def update(self, **kwargs):\n        for k, v in kwargs.items():\n            if v is None:\n                continue\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.meters[k].update(v)\n\n    def __getattr__(self, attr):\n        if attr in self.meters:\n            return self.meters[attr]\n        if attr in self.__dict__:\n            return self.__dict__[attr]\n        raise AttributeError(\"'{}' object has no attribute '{}'\".format(\n            type(self).__name__, attr))\n\n    def __str__(self):\n        loss_str = []\n        for name, meter in self.meters.items():\n            loss_str.append(\n                \"{}: {}\".format(name, str(meter))\n            )\n        return self.delimiter.join(loss_str)\n\n    def synchronize_between_processes(self):\n        for meter in self.meters.values():\n            meter.synchronize_between_processes()\n\n    def add_meter(self, name, meter):\n        self.meters[name] = meter\n\n    def log_every(self, iterable, print_freq, header=None):\n        i = 0\n        if not header:\n            header = ''\n        start_time = time.time()\n        end = time.time()\n        iter_time = SmoothedValue(fmt='{avg:.4f}')\n        data_time = SmoothedValue(fmt='{avg:.4f}')\n        space_fmt = ':' + str(len(str(len(iterable)))) + 'd'\n        log_msg = [\n            header,\n            '[{0' + space_fmt + '}/{1}]',\n            'eta: {eta}',\n            '{meters}',\n            'time: {time}',\n            'data: {data}'\n        ]\n        if torch.cuda.is_available():\n            log_msg.append('max mem: {memory:.0f}')\n        log_msg = self.delimiter.join(log_msg)\n        MB = 1024.0 * 1024.0\n        for obj in iterable:\n            data_time.update(time.time() - end)\n            yield obj\n            iter_time.update(time.time() - end)\n            if i % print_freq == 0 or i == len(iterable) - 1:\n                eta_seconds = iter_time.global_avg * (len(iterable) - i)\n                eta_string = str(datetime.timedelta(seconds=int(eta_seconds)))\n                if torch.cuda.is_available():\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time),\n                        memory=torch.cuda.max_memory_allocated() / MB))\n                else:\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time)))\n            i += 1\n            end = time.time()\n        total_time = time.time() - start_time\n        total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n        print('{} Total time: {} ({:.4f} s / it)'.format(\n            header, total_time_str, total_time / len(iterable)))\n\n\nclass TensorboardLogger(object):\n    def __init__(self, log_dir):\n        self.writer = SummaryWriter(logdir=log_dir)\n        self.step = 0\n\n    def set_step(self, step=None):\n        if step is not None:\n            self.step = step\n        else:\n            self.step += 1\n\n    def update(self, head='scalar', step=None, **kwargs):\n        for k, v in kwargs.items():\n            if v is None:\n                continue\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.writer.add_scalar(head + \"/\" + k, v, self.step if step is None else step)\n\n    def flush(self):\n        self.writer.flush()\n\n\ndef _load_checkpoint_for_ema(model_ema, checkpoint):\n    \"\"\"\n    Workaround for ModelEma._load_checkpoint to accept an already-loaded object\n    \"\"\"\n\n    if hasattr(model_ema, \"module\"):\n        model_ema.module.load_state_dict(checkpoint['model_ema'])\n    else:\n        mem_file = io.BytesIO()\n        torch.save(checkpoint, mem_file)\n        mem_file.seek(0)\n        model_ema._load_checkpoint(mem_file)\n\n\ndef setup_for_distributed(is_master):\n    \"\"\"\n    This function disables printing when not in master process\n    \"\"\"\n    import builtins as __builtin__\n    builtin_print = __builtin__.print\n\n    def print(*args, **kwargs):\n        force = kwargs.pop('force', False)\n        if is_master or force:\n            builtin_print(*args, **kwargs)\n\n    __builtin__.print = print\n\n\ndef is_dist_avail_and_initialized():\n    if not dist.is_available():\n        return False\n    if not dist.is_initialized():\n        return False\n    return True\n\n\ndef get_world_size():\n    if not is_dist_avail_and_initialized():\n        return 1\n    return dist.get_world_size()\n\n\ndef get_rank():\n    if not is_dist_avail_and_initialized():\n        return 0\n    return dist.get_rank()\n\n\ndef is_main_process():\n    return get_rank() == 0\n\n\ndef save_on_master(*args, **kwargs):\n    if is_main_process():\n        torch.save(*args, **kwargs)\n\n\ndef init_distributed_mode(args):\n    if args.dist_on_itp:\n        args.rank = int(os.environ['OMPI_COMM_WORLD_RANK'])\n        args.world_size = int(os.environ['OMPI_COMM_WORLD_SIZE'])\n        args.gpu = int(os.environ['OMPI_COMM_WORLD_LOCAL_RANK'])\n        args.dist_url = \"tcp://%s:%s\" % (os.environ['MASTER_ADDR'], os.environ['MASTER_PORT'])\n        os.environ['LOCAL_RANK'] = str(args.gpu)\n        os.environ['RANK'] = str(args.rank)\n        os.environ['WORLD_SIZE'] = str(args.world_size)\n        # [\"RANK\", \"WORLD_SIZE\", \"MASTER_ADDR\", \"MASTER_PORT\", \"LOCAL_RANK\"]\n    elif 'RANK' in os.environ and 'WORLD_SIZE' in os.environ and 'SLURM_NODEID' not in os.environ:\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ['WORLD_SIZE'])\n        args.gpu = int(os.environ['LOCAL_RANK'])\n    elif 'RANK' in os.environ and 'WORLD_SIZE' in os.environ and 'SLURM_NODEID' in os.environ:\n        # args.rank = int(os.environ[\"RANK\"])\n        # print(os.environ)\n\n        gpus_per_node = torch.cuda.device_count()\n        node_id = int(os.environ.get(\"SLURM_NODEID\"))\n        args.rank = int(os.environ[\"RANK\"]) + node_id * gpus_per_node\n\n        args.world_size = int(os.environ['WORLD_SIZE'])\n        args.gpu = int(os.environ['LOCAL_RANK'])\n    elif 'SLURM_PROCID' in os.environ:\n        os.environ['RANK'] = os.environ['SLURM_PROCID']\n        args.rank = int(os.environ['SLURM_PROCID'])\n        os.environ['LOCAL_RANK'] = str(args.rank % torch.cuda.device_count())\n        args.gpu = args.rank % torch.cuda.device_count()\n        print(\"utils.py SLURM_PROCID in os.environ\")\n        print(\"args.rank \"+str(args.rank))\n        print(\"args.gpu \"+str(args.gpu))\n        print(\"args.world_size \"+str(args.world_size))\n        print(\"SLURM_NTASKS \"+str(os.environ['SLURM_NTASKS']))\n        assert int(args.world_size) == int(os.environ['SLURM_NTASKS'])\n        os.environ['WORLD_SIZE'] = str(args.world_size)\n    else:\n        print('Not using distributed mode')\n        args.distributed = False\n        return\n\n    args.distributed = True\n\n    torch.cuda.set_device(args.gpu)\n    args.dist_backend = 'nccl'\n    print('| distributed init (rank {}): {}, gpu {}, world_size {}'.format(\n        args.rank, args.dist_url, args.gpu, args.world_size), flush=True)\n    torch.distributed.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                         world_size=args.world_size, rank=args.rank)\n    # torch.distributed.init_process_group(backend=args.dist_backend, init_method='env://')\n    setup_for_distributed(args.rank == 0)\n\n\ndef load_state_dict(model, state_dict, prefix='', ignore_missing=\"relative_position_index\"):\n    missing_keys = []\n    unexpected_keys = []\n    error_msgs = []\n    # copy state_dict so _load_from_state_dict can modify it\n    metadata = getattr(state_dict, '_metadata', None)\n    state_dict = state_dict.copy()\n    if metadata is not None:\n        state_dict._metadata = metadata\n\n    def load(module, prefix=''):\n        local_metadata = {} if metadata is None else metadata.get(\n            prefix[:-1], {})\n        module._load_from_state_dict(\n            state_dict, prefix, local_metadata, True, missing_keys, unexpected_keys, error_msgs)\n        for name, child in module._modules.items():\n            if child is not None:\n                load(child, prefix + name + '.')\n\n    load(model, prefix=prefix)\n\n    warn_missing_keys = []\n    ignore_missing_keys = []\n    for key in missing_keys:\n        keep_flag = True\n        for ignore_key in ignore_missing.split('|'):\n            if ignore_key in key:\n                keep_flag = False\n                break\n        if keep_flag:\n            warn_missing_keys.append(key)\n        else:\n            ignore_missing_keys.append(key)\n\n    missing_keys = warn_missing_keys\n\n    if len(missing_keys) > 0:\n        print(\"Weights of {} not initialized from pretrained model: {}\".format(\n            model.__class__.__name__, missing_keys))\n    if len(unexpected_keys) > 0:\n        print(\"Weights from pretrained model not used in {}: {}\".format(\n            model.__class__.__name__, unexpected_keys))\n    if len(ignore_missing_keys) > 0:\n        print(\"Ignored weights of {} not initialized from pretrained model: {}\".format(\n            model.__class__.__name__, ignore_missing_keys))\n    if len(error_msgs) > 0:\n        print('\\n'.join(error_msgs))\n\n\nclass NativeScalerWithGradNormCount:\n    state_dict_key = \"amp_scaler\"\n\n    def __init__(self):\n        self._scaler = torch.cuda.amp.GradScaler()\n\n    def __call__(self, loss, optimizer, clip_grad=None, parameters=None, create_graph=False, update_grad=True):\n        self._scaler.scale(loss).backward(create_graph=create_graph)\n        if update_grad:\n            if clip_grad is not None:\n                assert parameters is not None\n                self._scaler.unscale_(optimizer)  # unscale the gradients of optimizer's assigned params in-place\n                norm = torch.nn.utils.clip_grad_norm_(parameters, clip_grad)\n            else:\n                self._scaler.unscale_(optimizer)\n                norm = get_grad_norm_(parameters)\n            self._scaler.step(optimizer)\n            self._scaler.update()\n        else:\n            norm = None\n        return norm\n\n    def state_dict(self):\n        return self._scaler.state_dict()\n\n    def load_state_dict(self, state_dict):\n        self._scaler.load_state_dict(state_dict)\n\n\ndef get_grad_norm_(parameters, norm_type: float = 2.0) -> torch.Tensor:\n    if isinstance(parameters, torch.Tensor):\n        parameters = [parameters]\n    parameters = [p for p in parameters if p.grad is not None]\n    norm_type = float(norm_type)\n    if len(parameters) == 0:\n        return torch.tensor(0.)\n    device = parameters[0].grad.device\n    if norm_type == inf:\n        total_norm = max(p.grad.detach().abs().max().to(device) for p in parameters)\n    else:\n        total_norm = torch.norm(torch.stack([torch.norm(p.grad.detach(), norm_type).to(device) for p in parameters]), norm_type)\n    return total_norm\n\n\ndef cosine_scheduler(base_value, final_value, epochs, niter_per_ep, warmup_epochs=0,\n                     start_warmup_value=0, warmup_steps=-1):\n    warmup_schedule = np.array([])\n    warmup_iters = warmup_epochs * niter_per_ep\n    if warmup_steps > 0:\n        warmup_iters = warmup_steps\n    print(\"Set warmup steps = %d\" % warmup_iters)\n    if warmup_epochs > 0:\n        warmup_schedule = np.linspace(start_warmup_value, base_value, warmup_iters)\n\n    iters = np.arange(epochs * niter_per_ep - warmup_iters)\n    schedule = np.array(\n        [final_value + 0.5 * (base_value - final_value) * (1 + math.cos(math.pi * i / (len(iters)))) for i in iters])\n\n    schedule = np.concatenate((warmup_schedule, schedule))\n\n    assert len(schedule) == epochs * niter_per_ep\n    return schedule\n\ndef tri_phase_scheduler(base_value, final_value, epochs, niter_per_ep, warmup_perc=0.05, decay_perc=0.05,\n                     start_warmup_value=0):\n\n    assert warmup_perc + decay_perc <= 1\n\n    total_updates = int(epochs * niter_per_ep)\n\n    warmup_iters = int(warmup_perc * total_updates)\n    decay_iters = int(decay_perc * total_updates)\n    hold_iters = total_updates - warmup_iters - decay_iters\n\n    print(\"Set warmup steps = %d\" % warmup_iters)\n    if warmup_iters > 0:\n        warmup_schedule = np.linspace(start_warmup_value, base_value, warmup_iters)\n    else:\n        warmup_schedule = np.array([])\n\n    if hold_iters > 0:\n        hold_schedule = np.full(hold_iters, base_value)\n    else:\n        hold_schedule = np.array([])\n\n    if decay_iters > 0:\n        decay_schedule = np.linspace(base_value, final_value, decay_iters)\n    else:\n        decay_schedule = np.array([])\n\n    schedule = np.concatenate((warmup_schedule, hold_schedule, decay_schedule))\n\n    assert len(schedule) == epochs * niter_per_ep, \\\n        f\"e: {epochs}, it: {niter_per_ep}, tot: {epochs*niter_per_ep}, \" \\\n        f\"w: {warmup_iters}, h: {hold_iters}, d: {decay_iters}, len: {len(schedule)}\"\n    return schedule\n\n\ndef save_model(args, epoch, model, model_without_ddp, optimizer, loss_scaler, model_ema=None):\n    output_dir = Path(args.output_dir)\n    epoch_name = str(epoch)\n    if loss_scaler is not None:\n        checkpoint_paths = [output_dir / ('checkpoint-%s.pth' % epoch_name)]\n        for checkpoint_path in checkpoint_paths:\n            to_save = {\n                'model': model_without_ddp.state_dict(),\n                'optimizer': optimizer.state_dict(),\n                'epoch': epoch,\n                'scaler': loss_scaler.state_dict(),\n                'args': args,\n            }\n\n            if model_ema is not None:\n                to_save['model_ema'] = get_state_dict(model_ema)\n\n            save_on_master(to_save, checkpoint_path)\n    else:\n        client_state = {'epoch': epoch}\n        if model_ema is not None:\n            client_state['model_ema'] = get_state_dict(model_ema)\n        model.save_checkpoint(save_dir=args.output_dir, tag=\"checkpoint-%s\" % epoch_name, client_state=client_state)\n\n\ndef auto_load_model(args, model, model_without_ddp, optimizer, loss_scaler, model_ema=None):\n    output_dir = Path(args.output_dir)\n    if loss_scaler is not None:\n        # torch.amp\n        if args.auto_resume and len(args.resume) == 0:\n            import glob\n            all_checkpoints = glob.glob(os.path.join(glob.escape(output_dir), 'checkpoint-*.pth'))\n            latest_ckpt = -1\n            for ckpt in all_checkpoints:\n                t = ckpt.split('-')[-1].split('.')[0]\n                if t.isdigit():\n                    latest_ckpt = max(int(t), latest_ckpt)\n\n            print(output_dir, latest_ckpt, all_checkpoints)\n\n            if latest_ckpt >= 0:\n                args.resume = os.path.join(output_dir, 'checkpoint-%d.pth' % latest_ckpt)\n            print(\"Auto resume checkpoint: %s\" % args.resume)\n\n        if args.resume:\n            if args.resume.startswith('https'):\n                checkpoint = torch.hub.load_state_dict_from_url(\n                    args.resume, map_location='cpu', check_hash=True)\n            else:\n                checkpoint = torch.load(args.resume, map_location='cpu')\n            model_without_ddp.load_state_dict(checkpoint['model'])\n            print(\"Resume checkpoint %s\" % args.resume)\n            if 'optimizer' in checkpoint and 'epoch' in checkpoint and not getattr(args, \"reset_resume\", False): # and len(getattr(args, \"seed_model\", '') or []) == 0:\n                optimizer.load_state_dict(checkpoint['optimizer'])\n                args.start_epoch = checkpoint['epoch'] + 1\n                if hasattr(args, 'model_ema') and args.model_ema:\n                    _load_checkpoint_for_ema(model_ema, checkpoint['model_ema'])\n                if 'scaler' in checkpoint:\n                    loss_scaler.load_state_dict(checkpoint['scaler'])\n                print(\"With optim & sched!\")\n    else:\n        # deepspeed, only support '--auto_resume'.\n        if args.auto_resume:\n            import glob\n            all_checkpoints = glob.glob(os.path.join(output_dir, 'checkpoint-*'))\n            latest_ckpt = -1\n            for ckpt in all_checkpoints:\n                t = ckpt.split('-')[-1].split('.')[0]\n                if t.isdigit():\n                    latest_ckpt = max(int(t), latest_ckpt)\n            if latest_ckpt >= 0:\n                args.resume = os.path.join(output_dir, 'checkpoint-%d' % latest_ckpt)\n                print(\"Auto resume checkpoint: %d\" % latest_ckpt)\n                _, client_states = model.load_checkpoint(args.output_dir, tag='checkpoint-%d' % latest_ckpt)\n                args.start_epoch = client_states['epoch'] + 1\n                if model_ema is not None:\n                    if args.model_ema:\n                        _load_checkpoint_for_ema(model_ema, client_states['model_ema'])\n\n\ndef create_d_vae(weight_path, d_vae_type, image_size, device):\n    if d_vae_type == \"dall-e\":\n        return get_dalle_vae(weight_path, image_size, device)\n    elif d_vae_type == \"customized\":\n        return get_d_vae(weight_path, image_size, device)\n    else:\n        raise NotImplementedError()\n\n\ndef get_dalle_vae(weight_path, image_size, device):\n    vae = Dalle_VAE(image_size)\n    vae.load_model(model_dir=weight_path, device=device)\n    return vae\n\n\ndef get_d_vae(weight_path, image_size, device):\n    NUM_TOKENS = 8192\n    NUM_LAYERS = 3\n    EMB_DIM = 512\n    HID_DIM = 256\n\n    state_dict = torch.load(os.path.join(weight_path, \"pytorch_model.bin\"), map_location=\"cpu\")[\"weights\"]\n\n    model = DiscreteVAE(\n        image_size=image_size,\n        num_layers=NUM_LAYERS,\n        num_tokens=NUM_TOKENS,\n        codebook_dim=EMB_DIM,\n        hidden_dim=HID_DIM,\n    ).to(device)\n\n    model.load_state_dict(state_dict)\n    return model\n\n\ndef create_ds_config(args):\n    args.deepspeed_config = os.path.join(args.output_dir, \"deepspeed_config.json\")\n    with open(args.deepspeed_config, mode=\"w\") as writer:\n        ds_config = {\n            \"train_batch_size\": args.batch_size * args.update_freq * get_world_size(),\n            \"train_micro_batch_size_per_gpu\": args.batch_size,\n            \"steps_per_print\": 1000,\n            \"optimizer\": {\n                \"type\": \"Adam\",\n                \"adam_w_mode\": True,\n                \"params\": {\n                    \"lr\": args.lr,\n                    \"weight_decay\": args.weight_decay,\n                    \"bias_correction\": True,\n                    \"betas\": [\n                        0.9,\n                        0.999\n                    ],\n                    \"eps\": 1e-8\n                }\n            },\n            \"fp16\": {\n                \"enabled\": True,\n                \"loss_scale\": 0,\n                \"initial_scale_power\": 7,\n                \"loss_scale_window\": 128\n            }\n        }\n\n        writer.write(json.dumps(ds_config, indent=2))\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/dino/utils.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#     http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nMisc functions.\n\nMostly copy-paste from torchvision references or other public repos like DETR:\nhttps://github.com/facebookresearch/detr/blob/master/util/misc.py\n\"\"\"\nimport os\nimport sys\nimport time\nimport math\nimport random\nimport datetime\nimport subprocess\nfrom collections import defaultdict, deque\n\nimport numpy as np\nimport torch\nfrom torch import nn\nimport torch.distributed as dist\nfrom PIL import ImageFilter, ImageOps\n\nimport cv2\n\nclass GaussianBlur(object):\n    \"\"\"\n    Apply Gaussian Blur to the PIL image.\n    \"\"\"\n    def __init__(self, p=0.5, radius_min=0.1, radius_max=2.):\n        self.prob = p\n        self.radius_min = radius_min\n        self.radius_max = radius_max\n\n    def __call__(self, img):\n        do_it = random.random() <= self.prob\n        if not do_it:\n            return img\n\n        return img.filter(\n            ImageFilter.GaussianBlur(\n                radius=random.uniform(self.radius_min, self.radius_max)\n            )\n        )\n\n\nclass cvGaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, p=0.5, sigma=[.1, 2.]):\n        self.sigma = sigma\n        self.prob = p\n\n    def __call__(self, x):\n        do_it = random.random() <= self.prob\n        if not do_it:\n            return x        \n    \n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)\n\n\n\n\nclass Solarization(object):\n    \"\"\"\n    Apply Solarization to the PIL image.\n    \"\"\"\n    def __init__(self, p):\n        self.p = p\n\n    def __call__(self, img):\n        if random.random() < self.p:\n            return ImageOps.solarize(img)\n        else:\n            return img\n\n\ndef load_pretrained_weights(model, pretrained_weights, checkpoint_key, model_name, patch_size):\n    if os.path.isfile(pretrained_weights):\n        state_dict = torch.load(pretrained_weights, map_location=\"cpu\")\n        if checkpoint_key is not None and checkpoint_key in state_dict:\n            print(f\"Take key {checkpoint_key} in provided checkpoint dict\")\n            state_dict = state_dict[checkpoint_key]\n        # remove `module.` prefix\n        state_dict = {k.replace(\"module.\", \"\"): v for k, v in state_dict.items()}\n        # remove `backbone.` prefix induced by multicrop wrapper\n        state_dict = {k.replace(\"backbone.\", \"\"): v for k, v in state_dict.items()}\n        msg = model.load_state_dict(state_dict, strict=False)\n        print('Pretrained weights found at {} and loaded with msg: {}'.format(pretrained_weights, msg))\n    else:\n        print(\"Please use the `--pretrained_weights` argument to indicate the path of the checkpoint to evaluate.\")\n        url = None\n        if model_name == \"vit_small\" and patch_size == 16:\n            url = \"dino_deitsmall16_pretrain/dino_deitsmall16_pretrain.pth\"\n        elif model_name == \"vit_small\" and patch_size == 8:\n            url = \"dino_deitsmall8_pretrain/dino_deitsmall8_pretrain.pth\"\n        elif model_name == \"vit_base\" and patch_size == 16:\n            url = \"dino_vitbase16_pretrain/dino_vitbase16_pretrain.pth\"\n        elif model_name == \"vit_base\" and patch_size == 8:\n            url = \"dino_vitbase8_pretrain/dino_vitbase8_pretrain.pth\"\n        elif model_name == \"xcit_small_12_p16\":\n            url = \"dino_xcit_small_12_p16_pretrain/dino_xcit_small_12_p16_pretrain.pth\"\n        elif model_name == \"xcit_small_12_p8\":\n            url = \"dino_xcit_small_12_p8_pretrain/dino_xcit_small_12_p8_pretrain.pth\"\n        elif model_name == \"xcit_medium_24_p16\":\n            url = \"dino_xcit_medium_24_p16_pretrain/dino_xcit_medium_24_p16_pretrain.pth\"\n        elif model_name == \"xcit_medium_24_p8\":\n            url = \"dino_xcit_medium_24_p8_pretrain/dino_xcit_medium_24_p8_pretrain.pth\"\n        elif model_name == \"resnet50\":\n            url = \"dino_resnet50_pretrain/dino_resnet50_pretrain.pth\"\n        if url is not None:\n            print(\"Since no pretrained weights have been provided, we load the reference pretrained DINO weights.\")\n            state_dict = torch.hub.load_state_dict_from_url(url=\"https://dl.fbaipublicfiles.com/dino/\" + url)\n            model.load_state_dict(state_dict, strict=True)\n        else:\n            print(\"There is no reference weights available for this model => We use random weights.\")\n\n\ndef load_pretrained_linear_weights(linear_classifier, model_name, patch_size):\n    url = None\n    if model_name == \"vit_small\" and patch_size == 16:\n        url = \"dino_deitsmall16_pretrain/dino_deitsmall16_linearweights.pth\"\n    elif model_name == \"vit_small\" and patch_size == 8:\n        url = \"dino_deitsmall8_pretrain/dino_deitsmall8_linearweights.pth\"\n    elif model_name == \"vit_base\" and patch_size == 16:\n        url = \"dino_vitbase16_pretrain/dino_vitbase16_linearweights.pth\"\n    elif model_name == \"vit_base\" and patch_size == 8:\n        url = \"dino_vitbase8_pretrain/dino_vitbase8_linearweights.pth\"\n    elif model_name == \"resnet50\":\n        url = \"dino_resnet50_pretrain/dino_resnet50_linearweights.pth\"\n    if url is not None:\n        print(\"We load the reference pretrained linear weights.\")\n        state_dict = torch.hub.load_state_dict_from_url(url=\"https://dl.fbaipublicfiles.com/dino/\" + url)[\"state_dict\"]\n        linear_classifier.load_state_dict(state_dict, strict=True)\n    else:\n        print(\"We use random linear weights.\")\n\n\ndef clip_gradients(model, clip):\n    norms = []\n    for name, p in model.named_parameters():\n        if p.grad is not None:\n            param_norm = p.grad.data.norm(2)\n            norms.append(param_norm.item())\n            clip_coef = clip / (param_norm + 1e-6)\n            if clip_coef < 1:\n                p.grad.data.mul_(clip_coef)\n    return norms\n\n\ndef cancel_gradients_last_layer(epoch, model, freeze_last_layer):\n    if epoch >= freeze_last_layer:\n        return\n    for n, p in model.named_parameters():\n        if \"last_layer\" in n:\n            p.grad = None\n\n\ndef restart_from_checkpoint(ckp_path, run_variables=None, **kwargs):\n    \"\"\"\n    Re-start from checkpoint\n    \"\"\"\n    if not os.path.isfile(ckp_path):\n        return\n    print(\"Found checkpoint at {}\".format(ckp_path))\n\n    # open checkpoint file\n    checkpoint = torch.load(ckp_path, map_location=\"cpu\")\n\n    # key is what to look for in the checkpoint file\n    # value is the object to load\n    # example: {'state_dict': model}\n    for key, value in kwargs.items():\n        if key in checkpoint and value is not None:\n            try:\n                msg = value.load_state_dict(checkpoint[key], strict=False)\n                print(\"=> loaded '{}' from checkpoint '{}' with msg {}\".format(key, ckp_path, msg))\n            except TypeError:\n                try:\n                    msg = value.load_state_dict(checkpoint[key])\n                    print(\"=> loaded '{}' from checkpoint: '{}'\".format(key, ckp_path))\n                except ValueError:\n                    print(\"=> failed to load '{}' from checkpoint: '{}'\".format(key, ckp_path))\n        else:\n            print(\"=> key '{}' not found in checkpoint: '{}'\".format(key, ckp_path))\n\n    # re load variable important for the run\n    if run_variables is not None:\n        for var_name in run_variables:\n            if var_name in checkpoint:\n                run_variables[var_name] = checkpoint[var_name]\n\n\ndef cosine_scheduler(base_value, final_value, epochs, niter_per_ep, warmup_epochs=0, start_warmup_value=0):\n    warmup_schedule = np.array([])\n    warmup_iters = warmup_epochs * niter_per_ep\n    if warmup_epochs > 0:\n        warmup_schedule = np.linspace(start_warmup_value, base_value, warmup_iters)\n\n    iters = np.arange(epochs * niter_per_ep - warmup_iters)\n    schedule = final_value + 0.5 * (base_value - final_value) * (1 + np.cos(np.pi * iters / len(iters)))\n\n    schedule = np.concatenate((warmup_schedule, schedule))\n    assert len(schedule) == epochs * niter_per_ep\n    return schedule\n\n\ndef bool_flag(s):\n    \"\"\"\n    Parse boolean arguments from the command line.\n    \"\"\"\n    FALSY_STRINGS = {\"off\", \"false\", \"0\"}\n    TRUTHY_STRINGS = {\"on\", \"true\", \"1\"}\n    if s.lower() in FALSY_STRINGS:\n        return False\n    elif s.lower() in TRUTHY_STRINGS:\n        return True\n    else:\n        raise argparse.ArgumentTypeError(\"invalid value for a boolean flag\")\n\n\ndef fix_random_seeds(seed=31):\n    \"\"\"\n    Fix random seeds.\n    \"\"\"\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    np.random.seed(seed)\n\n\nclass SmoothedValue(object):\n    \"\"\"Track a series of values and provide access to smoothed values over a\n    window or the global series average.\n    \"\"\"\n\n    def __init__(self, window_size=20, fmt=None):\n        if fmt is None:\n            fmt = \"{median:.6f} ({global_avg:.6f})\"\n        self.deque = deque(maxlen=window_size)\n        self.total = 0.0\n        self.count = 0\n        self.fmt = fmt\n\n    def update(self, value, n=1):\n        self.deque.append(value)\n        self.count += n\n        self.total += value * n\n\n    def synchronize_between_processes(self):\n        \"\"\"\n        Warning: does not synchronize the deque!\n        \"\"\"\n        if not is_dist_avail_and_initialized():\n            return\n        t = torch.tensor([self.count, self.total], dtype=torch.float64, device='cuda')\n        dist.barrier()\n        dist.all_reduce(t)\n        t = t.tolist()\n        self.count = int(t[0])\n        self.total = t[1]\n\n    @property\n    def median(self):\n        d = torch.tensor(list(self.deque))\n        return d.median().item()\n\n    @property\n    def avg(self):\n        d = torch.tensor(list(self.deque), dtype=torch.float32)\n        return d.mean().item()\n\n    @property\n    def global_avg(self):\n        return self.total / self.count\n\n    @property\n    def max(self):\n        return max(self.deque)\n\n    @property\n    def value(self):\n        return self.deque[-1]\n\n    def __str__(self):\n        return self.fmt.format(\n            median=self.median,\n            avg=self.avg,\n            global_avg=self.global_avg,\n            max=self.max,\n            value=self.value)\n\n\ndef reduce_dict(input_dict, average=True):\n    \"\"\"\n    Args:\n        input_dict (dict): all the values will be reduced\n        average (bool): whether to do average or sum\n    Reduce the values in the dictionary from all processes so that all processes\n    have the averaged results. Returns a dict with the same fields as\n    input_dict, after reduction.\n    \"\"\"\n    world_size = get_world_size()\n    if world_size < 2:\n        return input_dict\n    with torch.no_grad():\n        names = []\n        values = []\n        # sort the keys so that they are consistent across processes\n        for k in sorted(input_dict.keys()):\n            names.append(k)\n            values.append(input_dict[k])\n        values = torch.stack(values, dim=0)\n        dist.all_reduce(values)\n        if average:\n            values /= world_size\n        reduced_dict = {k: v for k, v in zip(names, values)}\n    return reduced_dict\n\n\nclass MetricLogger(object):\n    def __init__(self, delimiter=\"\\t\"):\n        self.meters = defaultdict(SmoothedValue)\n        self.delimiter = delimiter\n\n    def update(self, **kwargs):\n        for k, v in kwargs.items():\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.meters[k].update(v)\n\n    def __getattr__(self, attr):\n        if attr in self.meters:\n            return self.meters[attr]\n        if attr in self.__dict__:\n            return self.__dict__[attr]\n        raise AttributeError(\"'{}' object has no attribute '{}'\".format(\n            type(self).__name__, attr))\n\n    def __str__(self):\n        loss_str = []\n        for name, meter in self.meters.items():\n            loss_str.append(\n                \"{}: {}\".format(name, str(meter))\n            )\n        return self.delimiter.join(loss_str)\n\n    def synchronize_between_processes(self):\n        for meter in self.meters.values():\n            meter.synchronize_between_processes()\n\n    def add_meter(self, name, meter):\n        self.meters[name] = meter\n\n    def log_every(self, iterable, print_freq, header=None):\n        i = 0\n        if not header:\n            header = ''\n        start_time = time.time()\n        end = time.time()\n        iter_time = SmoothedValue(fmt='{avg:.6f}')\n        data_time = SmoothedValue(fmt='{avg:.6f}')\n        space_fmt = ':' + str(len(str(len(iterable)))) + 'd'\n        if torch.cuda.is_available():\n            log_msg = self.delimiter.join([\n                header,\n                '[{0' + space_fmt + '}/{1}]',\n                'eta: {eta}',\n                '{meters}',\n                'time: {time}',\n                'data: {data}',\n                'max mem: {memory:.0f}'\n            ])\n        else:\n            log_msg = self.delimiter.join([\n                header,\n                '[{0' + space_fmt + '}/{1}]',\n                'eta: {eta}',\n                '{meters}',\n                'time: {time}',\n                'data: {data}'\n            ])\n        MB = 1024.0 * 1024.0\n        for obj in iterable:\n            data_time.update(time.time() - end)\n            yield obj\n            iter_time.update(time.time() - end)\n            if i % print_freq == 0 or i == len(iterable) - 1:\n                eta_seconds = iter_time.global_avg * (len(iterable) - i)\n                eta_string = str(datetime.timedelta(seconds=int(eta_seconds)))\n                if torch.cuda.is_available():\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time),\n                        memory=torch.cuda.max_memory_allocated() / MB))\n                else:\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time)))\n            i += 1\n            end = time.time()\n        total_time = time.time() - start_time\n        total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n        print('{} Total time: {} ({:.6f} s / it)'.format(\n            header, total_time_str, total_time / len(iterable)))\n\n\ndef get_sha():\n    cwd = os.path.dirname(os.path.abspath(__file__))\n\n    def _run(command):\n        return subprocess.check_output(command, cwd=cwd).decode('ascii').strip()\n    sha = 'N/A'\n    diff = \"clean\"\n    branch = 'N/A'\n    try:\n        sha = _run(['git', 'rev-parse', 'HEAD'])\n        subprocess.check_output(['git', 'diff'], cwd=cwd)\n        diff = _run(['git', 'diff-index', 'HEAD'])\n        diff = \"has uncommited changes\" if diff else \"clean\"\n        branch = _run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])\n    except Exception:\n        pass\n    message = f\"sha: {sha}, status: {diff}, branch: {branch}\"\n    return message\n\n\ndef is_dist_avail_and_initialized():\n    if not dist.is_available():\n        return False\n    if not dist.is_initialized():\n        return False\n    return True\n\n\ndef get_world_size():\n    if not is_dist_avail_and_initialized():\n        return 1\n    return dist.get_world_size()\n\n\ndef get_rank():\n    if not is_dist_avail_and_initialized():\n        return 0\n    return dist.get_rank()\n\n\ndef is_main_process():\n    return get_rank() == 0\n\n\ndef save_on_master(*args, **kwargs):\n    if is_main_process():\n        torch.save(*args, **kwargs)\n\n\ndef setup_for_distributed(is_master):\n    \"\"\"\n    This function disables printing when not in master process\n    \"\"\"\n    import builtins as __builtin__\n    builtin_print = __builtin__.print\n\n    def print(*args, **kwargs):\n        force = kwargs.pop('force', False)\n        if is_master or force:\n            builtin_print(*args, **kwargs)\n\n    __builtin__.print = print\n\n\ndef init_distributed_mode(args):\n    # launched with torch.distributed.launch\n    if 'RANK' in os.environ and 'WORLD_SIZE' in os.environ:\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ['WORLD_SIZE'])\n        args.gpu = int(os.environ['LOCAL_RANK'])\n    # launched with submitit on a slurm cluster\n    elif 'SLURM_PROCID' in os.environ:\n        args.rank = int(os.environ['SLURM_PROCID'])\n        args.gpu = args.rank % torch.cuda.device_count()\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(os.environ[\"SLURM_TASKS_PER_NODE\"][0])\n        args.is_slurm_job = True\n\n    # launched naively with `python main_dino.py`\n    # we manually add MASTER_ADDR and MASTER_PORT to env variables\n    elif torch.cuda.is_available():\n        print('Will run the code on one GPU.')\n        args.rank, args.gpu, args.world_size = 0, 0, 1\n        os.environ['MASTER_ADDR'] = '127.0.0.1'\n        os.environ['MASTER_PORT'] = '29500'\n    else:\n        print('Does not support training without GPU.')\n        sys.exit(1)\n\n    dist.init_process_group(\n        backend=\"nccl\",\n        init_method=args.dist_url,\n        world_size=args.world_size,\n        rank=args.rank,\n    )\n\n    torch.cuda.set_device(args.gpu)\n    #print('| distributed init (rank {}): {}'.format(\n    #    args.rank, args.dist_url), flush=True)\n    #dist.barrier()\n    #setup_for_distributed(args.rank == 0)\n\n\ndef accuracy(output, target, topk=(1,)):\n    \"\"\"Computes the accuracy over the k top predictions for the specified values of k\"\"\"\n    maxk = max(topk)\n    batch_size = target.size(0)\n    _, pred = output.topk(maxk, 1, True, True)\n    pred = pred.t()\n    correct = pred.eq(target.reshape(1, -1).expand_as(pred))\n    return [correct[:k].reshape(-1).float().sum(0) * 100. / batch_size for k in topk]\n\n\ndef _no_grad_trunc_normal_(tensor, mean, std, a, b):\n    # Cut & paste from PyTorch official master until it's in a few official releases - RW\n    # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf\n    def norm_cdf(x):\n        # Computes standard normal cumulative distribution function\n        return (1. + math.erf(x / math.sqrt(2.))) / 2.\n\n    if (mean < a - 2 * std) or (mean > b + 2 * std):\n        warnings.warn(\"mean is more than 2 std from [a, b] in nn.init.trunc_normal_. \"\n                      \"The distribution of values may be incorrect.\",\n                      stacklevel=2)\n\n    with torch.no_grad():\n        # Values are generated by using a truncated uniform distribution and\n        # then using the inverse CDF for the normal distribution.\n        # Get upper and lower cdf values\n        l = norm_cdf((a - mean) / std)\n        u = norm_cdf((b - mean) / std)\n\n        # Uniformly fill tensor with values from [l, u], then translate to\n        # [2l-1, 2u-1].\n        tensor.uniform_(2 * l - 1, 2 * u - 1)\n\n        # Use inverse cdf transform for normal distribution to get truncated\n        # standard normal\n        tensor.erfinv_()\n\n        # Transform to proper mean, std\n        tensor.mul_(std * math.sqrt(2.))\n        tensor.add_(mean)\n\n        # Clamp to ensure it's in the proper range\n        tensor.clamp_(min=a, max=b)\n        return tensor\n\n\ndef trunc_normal_(tensor, mean=0., std=1., a=-2., b=2.):\n    # type: (Tensor, float, float, float, float) -> Tensor\n    return _no_grad_trunc_normal_(tensor, mean, std, a, b)\n\n\nclass LARS(torch.optim.Optimizer):\n    \"\"\"\n    Almost copy-paste from https://github.com/facebookresearch/barlowtwins/blob/main/main.py\n    \"\"\"\n    def __init__(self, params, lr=0, weight_decay=0, momentum=0.9, eta=0.001,\n                 weight_decay_filter=None, lars_adaptation_filter=None):\n        defaults = dict(lr=lr, weight_decay=weight_decay, momentum=momentum,\n                        eta=eta, weight_decay_filter=weight_decay_filter,\n                        lars_adaptation_filter=lars_adaptation_filter)\n        super().__init__(params, defaults)\n\n    @torch.no_grad()\n    def step(self):\n        for g in self.param_groups:\n            for p in g['params']:\n                dp = p.grad\n\n                if dp is None:\n                    continue\n\n                if p.ndim != 1:\n                    dp = dp.add(p, alpha=g['weight_decay'])\n\n                if p.ndim != 1:\n                    param_norm = torch.norm(p)\n                    update_norm = torch.norm(dp)\n                    one = torch.ones_like(param_norm)\n                    q = torch.where(param_norm > 0.,\n                                    torch.where(update_norm > 0,\n                                                (g['eta'] * param_norm / update_norm), one), one)\n                    dp = dp.mul(q)\n\n                param_state = self.state[p]\n                if 'mu' not in param_state:\n                    param_state['mu'] = torch.zeros_like(p)\n                mu = param_state['mu']\n                mu.mul_(g['momentum']).add_(dp)\n\n                p.add_(mu, alpha=-g['lr'])\n\n\nclass MultiCropWrapper(nn.Module):\n    \"\"\"\n    Perform forward pass separately on each resolution input.\n    The inputs corresponding to a single resolution are clubbed and single\n    forward is run on the same resolution inputs. Hence we do several\n    forward passes = number of different resolutions used. We then\n    concatenate all the output features and run the head forward on these\n    concatenated features.\n    \"\"\"\n    def __init__(self, backbone, head):\n        super(MultiCropWrapper, self).__init__()\n        # disable layers dedicated to ImageNet labels classification\n        backbone.fc, backbone.head = nn.Identity(), nn.Identity()\n        self.backbone = backbone\n        self.head = head\n\n    def forward(self, x):\n        # convert to list\n        if not isinstance(x, list):\n            x = [x]\n        idx_crops = torch.cumsum(torch.unique_consecutive(\n            torch.tensor([inp.shape[-1] for inp in x]),\n            return_counts=True,\n        )[1], 0)\n        start_idx, output = 0, torch.empty(0).to(x[0].device)\n        for end_idx in idx_crops:\n            _out = self.backbone(torch.cat(x[start_idx: end_idx]))\n            # The output is a tuple with XCiT model. See:\n            # https://github.com/facebookresearch/xcit/blob/master/xcit.py#L404-L405\n            if isinstance(_out, tuple):\n                _out = _out[0]\n            # accumulate outputs\n            output = torch.cat((output, _out))\n            start_idx = end_idx\n        # Run the head forward on the concatenated features.\n        return self.head(output)\n\n\ndef get_params_groups(model):\n    regularized = []\n    not_regularized = []\n    for name, param in model.named_parameters():\n        if not param.requires_grad:\n            continue\n        # we do not regularize biases nor Norm parameters\n        if name.endswith(\".bias\") or len(param.shape) == 1:\n            not_regularized.append(param)\n        else:\n            regularized.append(param)\n    return [{'params': regularized}, {'params': not_regularized, 'weight_decay': 0.}]\n\n\ndef has_batchnorms(model):\n    bn_types = (nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d, nn.SyncBatchNorm)\n    for name, module in model.named_modules():\n        if isinstance(module, bn_types):\n            return True\n    return False\n\n\nclass PCA():\n    \"\"\"\n    Class to  compute and apply PCA.\n    \"\"\"\n    def __init__(self, dim=256, whit=0.5):\n        self.dim = dim\n        self.whit = whit\n        self.mean = None\n\n    def train_pca(self, cov):\n        \"\"\"\n        Takes a covariance matrix (np.ndarray) as input.\n        \"\"\"\n        d, v = np.linalg.eigh(cov)\n        eps = d.max() * 1e-5\n        n_0 = (d < eps).sum()\n        if n_0 > 0:\n            d[d < eps] = eps\n\n        # total energy\n        totenergy = d.sum()\n\n        # sort eigenvectors with eigenvalues order\n        idx = np.argsort(d)[::-1][:self.dim]\n        d = d[idx]\n        v = v[:, idx]\n\n        print(\"keeping %.2f %% of the energy\" % (d.sum() / totenergy * 100.0))\n\n        # for the whitening\n        d = np.diag(1. / d**self.whit)\n\n        # principal components\n        self.dvt = np.dot(d, v.T)\n\n    def apply(self, x):\n        # input is from numpy\n        if isinstance(x, np.ndarray):\n            if self.mean is not None:\n                x -= self.mean\n            return np.dot(self.dvt, x.T).T\n\n        # input is from torch and is on GPU\n        if x.is_cuda:\n            if self.mean is not None:\n                x -= torch.cuda.FloatTensor(self.mean)\n            return torch.mm(torch.cuda.FloatTensor(self.dvt), x.transpose(0, 1)).transpose(0, 1)\n\n        # input if from torch, on CPU\n        if self.mean is not None:\n            x -= torch.FloatTensor(self.mean)\n        return torch.mm(torch.FloatTensor(self.dvt), x.transpose(0, 1)).transpose(0, 1)\n\n\ndef compute_ap(ranks, nres):\n    \"\"\"\n    Computes average precision for given ranked indexes.\n    Arguments\n    ---------\n    ranks : zerro-based ranks of positive images\n    nres  : number of positive images\n    Returns\n    -------\n    ap    : average precision\n    \"\"\"\n\n    # number of images ranked by the system\n    nimgranks = len(ranks)\n\n    # accumulate trapezoids in PR-plot\n    ap = 0\n\n    recall_step = 1. / nres\n\n    for j in np.arange(nimgranks):\n        rank = ranks[j]\n\n        if rank == 0:\n            precision_0 = 1.\n        else:\n            precision_0 = float(j) / rank\n\n        precision_1 = float(j + 1) / (rank + 1)\n\n        ap += (precision_0 + precision_1) * recall_step / 2.\n\n    return ap\n\n\ndef compute_map(ranks, gnd, kappas=[]):\n    \"\"\"\n    Computes the mAP for a given set of returned results.\n         Usage:\n           map = compute_map (ranks, gnd)\n                 computes mean average precsion (map) only\n           map, aps, pr, prs = compute_map (ranks, gnd, kappas)\n                 computes mean average precision (map), average precision (aps) for each query\n                 computes mean precision at kappas (pr), precision at kappas (prs) for each query\n         Notes:\n         1) ranks starts from 0, ranks.shape = db_size X #queries\n         2) The junk results (e.g., the query itself) should be declared in the gnd stuct array\n         3) If there are no positive images for some query, that query is excluded from the evaluation\n    \"\"\"\n\n    map = 0.\n    nq = len(gnd) # number of queries\n    aps = np.zeros(nq)\n    pr = np.zeros(len(kappas))\n    prs = np.zeros((nq, len(kappas)))\n    nempty = 0\n\n    for i in np.arange(nq):\n        qgnd = np.array(gnd[i]['ok'])\n\n        # no positive images, skip from the average\n        if qgnd.shape[0] == 0:\n            aps[i] = float('nan')\n            prs[i, :] = float('nan')\n            nempty += 1\n            continue\n\n        try:\n            qgndj = np.array(gnd[i]['junk'])\n        except:\n            qgndj = np.empty(0)\n\n        # sorted positions of positive and junk images (0 based)\n        pos  = np.arange(ranks.shape[0])[np.in1d(ranks[:,i], qgnd)]\n        junk = np.arange(ranks.shape[0])[np.in1d(ranks[:,i], qgndj)]\n\n        k = 0;\n        ij = 0;\n        if len(junk):\n            # decrease positions of positives based on the number of\n            # junk images appearing before them\n            ip = 0\n            while (ip < len(pos)):\n                while (ij < len(junk) and pos[ip] > junk[ij]):\n                    k += 1\n                    ij += 1\n                pos[ip] = pos[ip] - k\n                ip += 1\n\n        # compute ap\n        ap = compute_ap(pos, len(qgnd))\n        map = map + ap\n        aps[i] = ap\n\n        # compute precision @ k\n        pos += 1 # get it to 1-based\n        for j in np.arange(len(kappas)):\n            kq = min(max(pos), kappas[j]); \n            prs[i, j] = (pos <= kq).sum() / kq\n        pr = pr + prs[i, :]\n\n    map = map / (nq - nempty)\n    pr = pr / (nq - nempty)\n\n    return map, aps, pr, prs\n\n\ndef multi_scale(samples, model):\n    v = None\n    for s in [1, 1/2**(1/2), 1/2]:  # we use 3 different scales\n        if s == 1:\n            inp = samples.clone()\n        else:\n            inp = nn.functional.interpolate(samples, scale_factor=s, mode='bilinear', align_corners=False)\n        feats = model(inp).clone()\n        if v is None:\n            v = feats\n        else:\n            v += feats\n    v /= 3\n    v /= v.norm()\n    return v\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/dino/vision_transformer.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n#     http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nMostly copy-paste from timm library.\nhttps://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py\n\"\"\"\nimport math\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\n\nfrom models.dino.utils import trunc_normal_\n\n\ndef drop_path(x, drop_prob: float = 0., training: bool = False):\n    if drop_prob == 0. or not training:\n        return x\n    keep_prob = 1 - drop_prob\n    shape = (x.shape[0],) + (1,) * (x.ndim - 1)  # work with diff dim tensors, not just 2D ConvNets\n    random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device)\n    random_tensor.floor_()  # binarize\n    output = x.div(keep_prob) * random_tensor\n    return output\n\n\nclass DropPath(nn.Module):\n    \"\"\"Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).\n    \"\"\"\n    def __init__(self, drop_prob=None):\n        super(DropPath, self).__init__()\n        self.drop_prob = drop_prob\n\n    def forward(self, x):\n        return drop_path(x, self.drop_prob, self.training)\n\n\nclass Mlp(nn.Module):\n    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        x = self.drop(x)\n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\nclass Attention(nn.Module):\n    def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        self.scale = qk_scale or head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n    def forward(self, x):\n        B, N, C = x.shape\n        qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[2]\n\n        attn = (q @ k.transpose(-2, -1)) * self.scale\n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, C)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x, attn\n\n\nclass Block(nn.Module):\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,\n                 drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm):\n        super().__init__()\n        self.norm1 = norm_layer(dim)\n        self.attn = Attention(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n    def forward(self, x, return_attention=False):\n        y, attn = self.attn(self.norm1(x))\n        if return_attention:\n            return attn\n        x = x + self.drop_path(y)\n        x = x + self.drop_path(self.mlp(self.norm2(x)))\n        return x\n\n\nclass PatchEmbed(nn.Module):\n    \"\"\" Image to Patch Embedding\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):\n        super().__init__()\n        num_patches = (img_size // patch_size) * (img_size // patch_size)\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.num_patches = num_patches\n\n        self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n        x = self.proj(x).flatten(2).transpose(1, 2)\n        return x\n\n\nclass VisionTransformer(nn.Module):\n    \"\"\" Vision Transformer \"\"\"\n    def __init__(self, img_size=[224], patch_size=16, in_chans=3, num_classes=0, embed_dim=768, depth=12,\n                 num_heads=12, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0., norm_layer=nn.LayerNorm, **kwargs):\n        super().__init__()\n        self.num_features = self.embed_dim = embed_dim\n\n        self.patch_embed = PatchEmbed(\n            img_size=img_size[0], patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]  # stochastic depth decay rule\n        self.blocks = nn.ModuleList([\n            Block(\n                dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer)\n            for i in range(depth)])\n        self.norm = norm_layer(embed_dim)\n\n        # Classifier head\n        self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity()\n\n        trunc_normal_(self.pos_embed, std=.02)\n        trunc_normal_(self.cls_token, std=.02)\n        self.apply(self._init_weights)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    def interpolate_pos_encoding(self, x, w, h):\n        npatch = x.shape[1] - 1\n        N = self.pos_embed.shape[1] - 1\n        if npatch == N and w == h:\n            return self.pos_embed\n        class_pos_embed = self.pos_embed[:, 0]\n        patch_pos_embed = self.pos_embed[:, 1:]\n        dim = x.shape[-1]\n        w0 = w // self.patch_embed.patch_size\n        h0 = h // self.patch_embed.patch_size\n        # we add a small number to avoid floating point error in the interpolation\n        # see discussion at https://github.com/facebookresearch/dino/issues/8\n        w0, h0 = w0 + 0.1, h0 + 0.1\n        patch_pos_embed = nn.functional.interpolate(\n            patch_pos_embed.reshape(1, int(math.sqrt(N)), int(math.sqrt(N)), dim).permute(0, 3, 1, 2),\n            scale_factor=(w0 / math.sqrt(N), h0 / math.sqrt(N)),\n            mode='bicubic',\n        )\n        assert int(w0) == patch_pos_embed.shape[-2] and int(h0) == patch_pos_embed.shape[-1]\n        patch_pos_embed = patch_pos_embed.permute(0, 2, 3, 1).view(1, -1, dim)\n        return torch.cat((class_pos_embed.unsqueeze(0), patch_pos_embed), dim=1)\n\n    def prepare_tokens(self, x):\n        B, nc, w, h = x.shape\n        x = self.patch_embed(x)  # patch linear embedding\n\n        # add the [CLS] token to the embed patch tokens\n        cls_tokens = self.cls_token.expand(B, -1, -1)\n        x = torch.cat((cls_tokens, x), dim=1)\n\n        # add positional encoding to each token\n        x = x + self.interpolate_pos_encoding(x, w, h)\n\n        return self.pos_drop(x)\n\n    def forward(self, x):\n        x = self.prepare_tokens(x)\n        for blk in self.blocks:\n            x = blk(x)\n        x = self.norm(x)\n        return x[:, 0]\n\n    def get_last_selfattention(self, x):\n        x = self.prepare_tokens(x)\n        for i, blk in enumerate(self.blocks):\n            if i < len(self.blocks) - 1:\n                x = blk(x)\n            else:\n                # return attention of the last block\n                return blk(x, return_attention=True)\n\n    def get_intermediate_layers(self, x, n=1):\n        x = self.prepare_tokens(x)\n        # we return the output tokens from the `n` last blocks\n        output = []\n        for i, blk in enumerate(self.blocks):\n            x = blk(x)\n            if len(self.blocks) - i <= n:\n                output.append(self.norm(x))\n        return output\n\n\ndef vit_tiny(patch_size=16, **kwargs):\n    model = VisionTransformer(\n        patch_size=patch_size, embed_dim=192, depth=12, num_heads=3, mlp_ratio=4,\n        qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef vit_small(patch_size=16, **kwargs):\n    model = VisionTransformer(\n        patch_size=patch_size, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4,\n        qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef vit_base(patch_size=16, **kwargs):\n    model = VisionTransformer(\n        patch_size=patch_size, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4,\n        qkv_bias=True, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\nclass DINOHead(nn.Module):\n    def __init__(self, in_dim, out_dim, use_bn=False, norm_last_layer=True, nlayers=3, hidden_dim=2048, bottleneck_dim=256):\n        super().__init__()\n        nlayers = max(nlayers, 1)\n        if nlayers == 1:\n            self.mlp = nn.Linear(in_dim, bottleneck_dim)\n        else:\n            layers = [nn.Linear(in_dim, hidden_dim)]\n            if use_bn:\n                layers.append(nn.BatchNorm1d(hidden_dim))\n            layers.append(nn.GELU())\n            for _ in range(nlayers - 2):\n                layers.append(nn.Linear(hidden_dim, hidden_dim))\n                if use_bn:\n                    layers.append(nn.BatchNorm1d(hidden_dim))\n                layers.append(nn.GELU())\n            layers.append(nn.Linear(hidden_dim, bottleneck_dim))\n            self.mlp = nn.Sequential(*layers)\n        self.apply(self._init_weights)\n        self.last_layer = nn.utils.weight_norm(nn.Linear(bottleneck_dim, out_dim, bias=False))\n        self.last_layer.weight_g.data.fill_(1)\n        if norm_last_layer:\n            self.last_layer.weight_g.requires_grad = False\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n    def forward(self, x):\n        x = self.mlp(x)\n        x = nn.functional.normalize(x, dim=-1, p=2)\n        x = self.last_layer(x)\n        return x\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/engine_finetune.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy\n\nimport util.misc as misc\nimport util.lr_sched as lr_sched\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n\n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n\n        with torch.cuda.amp.autocast():\n            outputs = model(samples)\n            loss = criterion(outputs, targets)\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, clip_grad=max_norm,\n                    parameters=model.parameters(), create_graph=False,\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', max_lr, epoch_1000x)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device):\n    criterion = torch.nn.CrossEntropyLoss()\n\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n        images = batch[0]\n        target = batch[-1]\n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, target)\n\n        acc1, acc5 = accuracy(output, target, topk=(1, 5))\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/engine_finetune_BE.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy\n\n#import util.misc as misc\n#import util.lr_sched as lr_sched\nfrom .util import misc\nfrom .util import lr_sched\n\nfrom sklearn.metrics import average_precision_score\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n\n        b_zeros = torch.zeros((samples.shape[0],1,samples.shape[2],samples.shape[3]),dtype=torch.float32)\n        samples = torch.cat((samples[:,:10,:,:],b_zeros,samples[:,10:,:,:]),dim=1)\n            \n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n        \n        #print(samples.shape,samples.dtype,targets.shape,targets.dtype)\n        with torch.cuda.amp.autocast():\n            outputs = model(samples)\n            loss = criterion(outputs, targets.long())\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, clip_grad=max_norm,\n                    parameters=model.parameters(), create_graph=False,\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', max_lr, epoch_1000x)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device, criterion):\n    #criterion = torch.nn.CrossEntropyLoss()\n\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n        images = batch[0]\n        target = batch[-1]\n        \n        b_zeros = torch.zeros((images.shape[0],1,images.shape[2],images.shape[3]),dtype=torch.float32)\n        images = torch.cat((images[:,:10,:,:],b_zeros,images[:,10:,:,:]),dim=1)  \n        \n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        #print(images.shape,images.dtype,target.shape,target.dtype)\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, target)\n\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = average_precision_score(target.cpu(), score, average='micro') * 100.0\n        acc5 = acc1\n        #acc1, acc5 = accuracy(output, target, topk=(1, 5))\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/engine_finetune_EU.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy\n\n#import util.misc as misc\n#import util.lr_sched as lr_sched\nfrom .util import misc\nfrom .util import lr_sched\n\nfrom sklearn.metrics import accuracy_score\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n            \n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n        \n        #print(samples.shape,samples.dtype,targets.shape,targets.dtype)\n        with torch.cuda.amp.autocast():\n            outputs = model(samples)\n            loss = criterion(outputs, targets.long())\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, clip_grad=max_norm,\n                    parameters=model.parameters(), create_graph=False,\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', max_lr, epoch_1000x)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device, criterion):\n    #criterion = torch.nn.CrossEntropyLoss()\n\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n        images = batch[0]\n        target = batch[-1] \n        \n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        #print(images.shape,images.dtype,target.shape,target.dtype)\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, target)\n\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = accuracy_score(target.cpu(), torch.argmax(score,axis=1)) * 100.0\n        acc5 = acc1\n        #acc1, acc5 = accuracy(output, target, topk=(1, 5))\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/engine_finetune_SS.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport math\nimport sys\nfrom typing import Iterable, Optional\n\nimport torch\n\nfrom timm.data import Mixup\nfrom timm.utils import accuracy\n\n#import util.misc as misc\n#import util.lr_sched as lr_sched\nfrom .util import misc\nfrom .util import lr_sched\n\nfrom sklearn.metrics import accuracy_score\n\n\ndef train_one_epoch(model: torch.nn.Module, criterion: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler, max_norm: float = 0,\n                    mixup_fn: Optional[Mixup] = None, log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, (samples, targets) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n            \n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n        targets = targets.to(device, non_blocking=True)\n\n        if mixup_fn is not None:\n            samples, targets = mixup_fn(samples, targets)\n        \n        #print(samples.shape,samples.dtype,targets.shape,targets.dtype)\n        with torch.cuda.amp.autocast():\n            outputs = model(samples)\n            loss = criterion(outputs, torch.argmax(targets,axis=1).long())\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, clip_grad=max_norm,\n                    parameters=model.parameters(), create_graph=False,\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n        min_lr = 10.\n        max_lr = 0.\n        for group in optimizer.param_groups:\n            min_lr = min(min_lr, group[\"lr\"])\n            max_lr = max(max_lr, group[\"lr\"])\n\n        metric_logger.update(lr=max_lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', max_lr, epoch_1000x)\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}\n\n\n@torch.no_grad()\ndef evaluate(data_loader, model, device, criterion):\n    #criterion = torch.nn.CrossEntropyLoss()\n\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n\n    # switch to evaluation mode\n    model.eval()\n\n    for batch in metric_logger.log_every(data_loader, 10, header):\n        images = batch[0]\n        target = batch[-1] \n        \n        images = images.to(device, non_blocking=True)\n        target = target.to(device, non_blocking=True)\n\n        # compute output\n        #print(images.shape,images.dtype,target.shape,target.dtype)\n        with torch.cuda.amp.autocast():\n            output = model(images)\n            loss = criterion(output, torch.argmax(target,axis=1).long())\n\n        score = torch.sigmoid(output).detach().cpu()\n        acc1 = accuracy_score(torch.argmax(target,axis=1).cpu(), torch.argmax(score,axis=1)) * 100.0\n        acc5 = acc1\n        #acc1, acc5 = accuracy(output, target, topk=(1, 5))\n\n        batch_size = images.shape[0]\n        metric_logger.update(loss=loss.item())\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print('* Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f} loss {losses.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5, losses=metric_logger.loss))\n\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/engine_pretrain.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\nimport math\nimport sys\nfrom typing import Iterable\n\nimport torch\n\n#import util.misc as misc\n#import util.lr_sched as lr_sched\nfrom .util import misc\nfrom .util import lr_sched\n\n\ndef train_one_epoch(model: torch.nn.Module,\n                    data_loader: Iterable, optimizer: torch.optim.Optimizer,\n                    device: torch.device, epoch: int, loss_scaler,\n                    log_writer=None,\n                    args=None):\n    model.train(True)\n    metric_logger = misc.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', misc.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n    print_freq = 20\n\n    accum_iter = args.accum_iter\n\n    optimizer.zero_grad()\n\n    if log_writer is not None:\n        print('log_dir: {}'.format(log_writer.log_dir))\n\n    for data_iter_step, samples in enumerate(metric_logger.log_every(data_loader, print_freq, header)):\n\n        # we use a per iteration (instead of per epoch) lr scheduler\n        if data_iter_step % accum_iter == 0:\n            lr_sched.adjust_learning_rate(optimizer, data_iter_step / len(data_loader) + epoch, args)\n\n        samples = samples.to(device, non_blocking=True)\n\n        with torch.cuda.amp.autocast():\n            loss, _, _ = model(samples, mask_ratio=args.mask_ratio)\n\n        loss_value = loss.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            sys.exit(1)\n\n        loss /= accum_iter\n        loss_scaler(loss, optimizer, parameters=model.parameters(),\n                    update_grad=(data_iter_step + 1) % accum_iter == 0)\n        if (data_iter_step + 1) % accum_iter == 0:\n            optimizer.zero_grad()\n\n        torch.cuda.synchronize()\n\n        metric_logger.update(loss=loss_value)\n\n        lr = optimizer.param_groups[0][\"lr\"]\n        metric_logger.update(lr=lr)\n\n        loss_value_reduce = misc.all_reduce_mean(loss_value)\n        if log_writer is not None and (data_iter_step + 1) % accum_iter == 0:\n            \"\"\" We use epoch_1000x as the x-axis in tensorboard.\n            This calibrates different curves when batch size changes.\n            \"\"\"\n            epoch_1000x = int((data_iter_step / len(data_loader) + epoch) * 1000)\n            log_writer.add_scalar('train_loss', loss_value_reduce, epoch_1000x)\n            log_writer.add_scalar('lr', lr, epoch_1000x)\n\n\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n    print(\"Averaged stats:\", metric_logger)\n    return {k: meter.global_avg for k, meter in metric_logger.meters.items()}"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/main_finetune.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\n\nimport timm\n\nassert timm.__version__ == \"0.3.2\" # version check\nfrom timm.models.layers import trunc_normal_\nfrom timm.data.mixup import Mixup\nfrom timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy\n\nimport util.lr_decay as lrd\nimport util.misc as misc\nfrom util.datasets import build_dataset\nfrom util.pos_embed import interpolate_pos_embed\nfrom util.misc import NativeScalerWithGradNormCount as NativeScaler\n\nimport models_vit\n\nfrom engine_finetune import train_one_epoch, evaluate\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE fine-tuning for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=50, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--drop_path', type=float, default=0.1, metavar='PCT',\n                        help='Drop path rate (default: 0.1)')\n\n    # Optimizer parameters\n    parser.add_argument('--clip_grad', type=float, default=None, metavar='NORM',\n                        help='Clip gradient norm (default: None, no clipping)')\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=1e-3, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n    parser.add_argument('--layer_decay', type=float, default=0.75,\n                        help='layer-wise lr decay from ELECTRA/BEiT')\n\n    parser.add_argument('--min_lr', type=float, default=1e-6, metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=5, metavar='N',\n                        help='epochs to warmup LR')\n\n    # Augmentation parameters\n    parser.add_argument('--color_jitter', type=float, default=None, metavar='PCT',\n                        help='Color jitter factor (enabled only when not using Auto/RandAug)')\n    parser.add_argument('--aa', type=str, default='rand-m9-mstd0.5-inc1', metavar='NAME',\n                        help='Use AutoAugment policy. \"v0\" or \"original\". \" + \"(default: rand-m9-mstd0.5-inc1)'),\n    parser.add_argument('--smoothing', type=float, default=0.1,\n                        help='Label smoothing (default: 0.1)')\n\n    # * Random Erase params\n    parser.add_argument('--reprob', type=float, default=0.25, metavar='PCT',\n                        help='Random erase prob (default: 0.25)')\n    parser.add_argument('--remode', type=str, default='pixel',\n                        help='Random erase mode (default: \"pixel\")')\n    parser.add_argument('--recount', type=int, default=1,\n                        help='Random erase count (default: 1)')\n    parser.add_argument('--resplit', action='store_true', default=False,\n                        help='Do not random erase first (clean) augmentation split')\n\n    # * Mixup params\n    parser.add_argument('--mixup', type=float, default=0,\n                        help='mixup alpha, mixup enabled if > 0.')\n    parser.add_argument('--cutmix', type=float, default=0,\n                        help='cutmix alpha, cutmix enabled if > 0.')\n    parser.add_argument('--cutmix_minmax', type=float, nargs='+', default=None,\n                        help='cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None)')\n    parser.add_argument('--mixup_prob', type=float, default=1.0,\n                        help='Probability of performing mixup or cutmix when either/both is enabled')\n    parser.add_argument('--mixup_switch_prob', type=float, default=0.5,\n                        help='Probability of switching to cutmix when both mixup and cutmix enabled')\n    parser.add_argument('--mixup_mode', type=str, default='batch',\n                        help='How to apply mixup/cutmix params. Per \"batch\", \"pair\", or \"elem\"')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--global_pool', action='store_true')\n    parser.set_defaults(global_pool=True)\n    parser.add_argument('--cls_token', action='store_false', dest='global_pool',\n                        help='Use class token instead of global pool for classification')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--nb_classes', default=1000, type=int,\n                        help='number of the classification types')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation (recommended during training for faster monitor')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    return parser\n\n\ndef main(args):\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n\n    dataset_train = build_dataset(is_train=True, args=args)\n    dataset_val = build_dataset(is_train=False, args=args)\n\n    if True:  # args.distributed:\n        num_tasks = misc.get_world_size()\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=True)  # shuffle=True to reduce monitor bias\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None and not args.eval:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    data_loader_val = torch.utils.data.DataLoader(\n        dataset_val, sampler=sampler_val,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=False\n    )\n\n    mixup_fn = None\n    mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None\n    if mixup_active:\n        print(\"Mixup is activated!\")\n        mixup_fn = Mixup(\n            mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax,\n            prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode,\n            label_smoothing=args.smoothing, num_classes=args.nb_classes)\n    \n    model = models_vit.__dict__[args.model](\n        num_classes=args.nb_classes,\n        drop_path_rate=args.drop_path,\n        global_pool=args.global_pool,\n    )\n\n    if args.finetune and not args.eval:\n        checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load pre-trained checkpoint from: %s\" % args.finetune)\n        checkpoint_model = checkpoint['model']\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        # interpolate position embedding\n        interpolate_pos_embed(model, checkpoint_model)\n\n        # load pre-trained model\n        msg = model.load_state_dict(checkpoint_model, strict=False)\n        print(msg)\n\n        if args.global_pool:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias', 'fc_norm.weight', 'fc_norm.bias'}\n        else:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias'}\n\n        # manually initialize fc layer\n        trunc_normal_(model.head.weight, std=2e-5)\n\n    model.to(device)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params (M): %.2f' % (n_parameters / 1.e6))\n\n    eff_batch_size = args.batch_size * args.accum_iter * misc.get_world_size()\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        model_without_ddp = model.module\n\n    # build optimizer with layer-wise lr decay (lrd)\n    param_groups = lrd.param_groups_lrd(model_without_ddp, args.weight_decay,\n        no_weight_decay_list=model_without_ddp.no_weight_decay(),\n        layer_decay=args.layer_decay\n    )\n    optimizer = torch.optim.AdamW(param_groups, lr=args.lr)\n    loss_scaler = NativeScaler()\n\n    if mixup_fn is not None:\n        # smoothing is handled with mixup label transform\n        criterion = SoftTargetCrossEntropy()\n    elif args.smoothing > 0.:\n        criterion = LabelSmoothingCrossEntropy(smoothing=args.smoothing)\n    else:\n        criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            args.clip_grad, mixup_fn,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir:\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        max_accuracy = max(max_accuracy, test_stats[\"acc1\"])\n        print(f'Max accuracy: {max_accuracy:.2f}%')\n\n        if log_writer is not None:\n            log_writer.add_scalar('perf/test_acc1', test_stats['acc1'], epoch)\n            log_writer.add_scalar('perf/test_acc5', test_stats['acc5'], epoch)\n            log_writer.add_scalar('perf/test_loss', test_stats['loss'], epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        **{f'test_{k}': v for k, v in test_stats.items()},\n                        'epoch': epoch,\n                        'n_parameters': n_parameters}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/main_linprobe.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# MoCo v3: https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\n\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\n\nimport timm\n\nassert timm.__version__ == \"0.3.2\" # version check\nfrom timm.models.layers import trunc_normal_\n\nimport util.misc as misc\nfrom util.pos_embed import interpolate_pos_embed\nfrom util.misc import NativeScalerWithGradNormCount as NativeScaler\nfrom util.lars import LARS\nfrom util.crop import RandomResizedCrop\n\nimport models_vit\n\nfrom engine_finetune import train_one_epoch, evaluate\n\n\nfrom datasets.BigEarthNet.bigearthnet_dataset_seco_lmdb_s2_uint8 import LMDBDataset,random_subset\nfrom cvtorchvision import cvtransforms\nfrom sklearn.metrics import average_precision_score\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE linear probing for image classification', add_help=False)\n    parser.add_argument('--batch_size', default=512, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=90, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    # Optimizer parameters\n    parser.add_argument('--weight_decay', type=float, default=0,\n                        help='weight decay (default: 0 for linear probe following MoCo v1)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=0.1, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n\n    parser.add_argument('--min_lr', type=float, default=0., metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=10, metavar='N',\n                        help='epochs to warmup LR')\n\n    # * Finetuning params\n    parser.add_argument('--finetune', default='',\n                        help='finetune from checkpoint')\n    parser.add_argument('--global_pool', action='store_true')\n    parser.set_defaults(global_pool=False)\n    parser.add_argument('--cls_token', action='store_false', dest='global_pool',\n                        help='Use class token instead of global pool for classification')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n    parser.add_argument('--nb_classes', default=1000, type=int,\n                        help='number of the classification types')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--eval', action='store_true',\n                        help='Perform evaluation only')\n    parser.add_argument('--dist_eval', action='store_true', default=False,\n                        help='Enabling distributed evaluation (recommended during training for faster monitor')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n\n    return parser\n\n\ndef main(args):\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n\n    # linear probe: weak augmentation\n    transform_train = transforms.Compose([\n            RandomResizedCrop(224, interpolation=3),\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    transform_val = transforms.Compose([\n            transforms.Resize(256, interpolation=3),\n            transforms.CenterCrop(224),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    dataset_train = datasets.ImageFolder(os.path.join(args.data_path, 'train'), transform=transform_train)\n    dataset_val = datasets.ImageFolder(os.path.join(args.data_path, 'val'), transform=transform_val)\n    print(dataset_train)\n    print(dataset_val)\n\n    if True:  # args.distributed:\n        num_tasks = misc.get_world_size()\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n        if args.dist_eval:\n            if len(dataset_val) % num_tasks != 0:\n                print('Warning: Enabling distributed evaluation with an eval dataset not divisible by process number. '\n                      'This will slightly alter validation results as extra duplicate entries are added to achieve '\n                      'equal num of samples per-process.')\n            sampler_val = torch.utils.data.DistributedSampler(\n                dataset_val, num_replicas=num_tasks, rank=global_rank, shuffle=True)  # shuffle=True to reduce monitor bias\n        else:\n            sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n        sampler_val = torch.utils.data.SequentialSampler(dataset_val)\n\n    if global_rank == 0 and args.log_dir is not None and not args.eval:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n\n    data_loader_val = torch.utils.data.DataLoader(\n        dataset_val, sampler=sampler_val,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=False\n    )\n\n    model = models_vit.__dict__[args.model](\n        num_classes=args.nb_classes,\n        global_pool=args.global_pool,\n    )\n\n    if args.finetune and not args.eval:\n        checkpoint = torch.load(args.finetune, map_location='cpu')\n\n        print(\"Load pre-trained checkpoint from: %s\" % args.finetune)\n        checkpoint_model = checkpoint['model']\n        state_dict = model.state_dict()\n        for k in ['head.weight', 'head.bias']:\n            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:\n                print(f\"Removing key {k} from pretrained checkpoint\")\n                del checkpoint_model[k]\n\n        # interpolate position embedding\n        interpolate_pos_embed(model, checkpoint_model)\n\n        # load pre-trained model\n        msg = model.load_state_dict(checkpoint_model, strict=False)\n        print(msg)\n\n        if args.global_pool:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias', 'fc_norm.weight', 'fc_norm.bias'}\n        else:\n            assert set(msg.missing_keys) == {'head.weight', 'head.bias'}\n\n        # manually initialize fc layer: following MoCo v3\n        trunc_normal_(model.head.weight, std=0.01)\n\n    # for linear prob only\n    # hack: revise model's head with BN\n    model.head = torch.nn.Sequential(torch.nn.BatchNorm1d(model.head.in_features, affine=False, eps=1e-6), model.head)\n    # freeze all but the head\n    for _, p in model.named_parameters():\n        p.requires_grad = False\n    for _, p in model.head.named_parameters():\n        p.requires_grad = True\n\n    model.to(device)\n\n    model_without_ddp = model\n    n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    print(\"Model = %s\" % str(model_without_ddp))\n    print('number of params (M): %.2f' % (n_parameters / 1.e6))\n\n    eff_batch_size = args.batch_size * args.accum_iter * misc.get_world_size()\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        model_without_ddp = model.module\n\n    optimizer = LARS(model_without_ddp.head.parameters(), lr=args.lr, weight_decay=args.weight_decay)\n    print(optimizer)\n    loss_scaler = NativeScaler()\n\n    criterion = torch.nn.CrossEntropyLoss()\n\n    print(\"criterion = %s\" % str(criterion))\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    if args.eval:\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        exit(0)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    max_accuracy = 0.0\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, criterion, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            max_norm=None,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir:\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        test_stats = evaluate(data_loader_val, model, device)\n        print(f\"Accuracy of the network on the {len(dataset_val)} test images: {test_stats['acc1']:.1f}%\")\n        max_accuracy = max(max_accuracy, test_stats[\"acc1\"])\n        print(f'Max accuracy: {max_accuracy:.2f}%')\n\n        if log_writer is not None:\n            log_writer.add_scalar('perf/test_acc1', test_stats['acc1'], epoch)\n            log_writer.add_scalar('perf/test_acc5', test_stats['acc5'], epoch)\n            log_writer.add_scalar('perf/test_loss', test_stats['loss'], epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        **{f'test_{k}': v for k, v in test_stats.items()},\n                        'epoch': epoch,\n                        'n_parameters': n_parameters}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/main_pretrain.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\nimport argparse\nimport datetime\nimport json\nimport numpy as np\nimport os\nimport time\nfrom pathlib import Path\n\nimport torch\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.tensorboard import SummaryWriter\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\n\nimport timm\n\nassert timm.__version__ == \"0.3.2\"  # version check\nimport timm.optim.optim_factory as optim_factory\n\nimport util.misc as misc\nfrom util.misc import NativeScalerWithGradNormCount as NativeScaler\n\nimport models_mae\n\nfrom engine_pretrain import train_one_epoch\n\nfrom ..datasets.SSL4EO.ssl4eo_dataset_lmdb import LMDBDataset\nfrom cvtorchvision import cvtransforms\n\n\nclass SeasonTransform:\n\n    def __init__(self, base_transform, season='fixed'):\n        self.base_transform = base_transform\n        self.season = season\n\n    def __call__(self, x):\n\n        if self.season=='augment':\n            season1 = np.random.choice([0,1,2,3])\n            season2 = np.random.choice([0,1,2,3])\n            \n            x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n            x2 = np.transpose(x[season2,:,:,:],(1,2,0))            \n            image = self.base_transform(x1)\n            target = self.base_transform2(x2)\n            return image, target\n            \n        elif self.season=='fixed':\n            np.random.seed(42)\n            season1 = np.random.choice([0,1,2,3])\n\n        elif self.season=='random':\n            season1 = np.random.choice([0,1,2,3])\n\n        x1 = np.transpose(x[season1,:,:,:],(1,2,0))\n        image = self.base_transform(x1)\n        \n        return q\n\n\ndef get_args_parser():\n    parser = argparse.ArgumentParser('MAE pre-training', add_help=False)\n    parser.add_argument('--batch_size', default=64, type=int,\n                        help='Batch size per GPU (effective batch size is batch_size * accum_iter * # gpus')\n    parser.add_argument('--epochs', default=400, type=int)\n    parser.add_argument('--accum_iter', default=1, type=int,\n                        help='Accumulate gradient iterations (for increasing the effective batch size under memory constraints)')\n\n    # Model parameters\n    parser.add_argument('--model', default='mae_vit_large_patch16', type=str, metavar='MODEL',\n                        help='Name of model to train')\n\n    parser.add_argument('--input_size', default=224, type=int,\n                        help='images input size')\n\n    parser.add_argument('--mask_ratio', default=0.75, type=float,\n                        help='Masking ratio (percentage of removed patches).')\n\n    parser.add_argument('--norm_pix_loss', action='store_true',\n                        help='Use (per-patch) normalized pixels as targets for computing loss')\n    parser.set_defaults(norm_pix_loss=False)\n\n    # Optimizer parameters\n    parser.add_argument('--weight_decay', type=float, default=0.05,\n                        help='weight decay (default: 0.05)')\n\n    parser.add_argument('--lr', type=float, default=None, metavar='LR',\n                        help='learning rate (absolute lr)')\n    parser.add_argument('--blr', type=float, default=1e-3, metavar='LR',\n                        help='base learning rate: absolute_lr = base_lr * total_batch_size / 256')\n    parser.add_argument('--min_lr', type=float, default=0., metavar='LR',\n                        help='lower lr bound for cyclic schedulers that hit 0')\n\n    parser.add_argument('--warmup_epochs', type=int, default=40, metavar='N',\n                        help='epochs to warmup LR')\n\n    # Dataset parameters\n    parser.add_argument('--data_path', default='/datasets01/imagenet_full_size/061417/', type=str,\n                        help='dataset path')\n\n    parser.add_argument('--output_dir', default='./output_dir',\n                        help='path where to save, empty for no saving')\n    parser.add_argument('--log_dir', default='./output_dir',\n                        help='path where to tensorboard log')\n    parser.add_argument('--device', default='cuda',\n                        help='device to use for training / testing')\n    parser.add_argument('--seed', default=0, type=int)\n    parser.add_argument('--resume', default='',\n                        help='resume from checkpoint')\n\n    parser.add_argument('--start_epoch', default=0, type=int, metavar='N',\n                        help='start epoch')\n    parser.add_argument('--num_workers', default=10, type=int)\n    parser.add_argument('--pin_mem', action='store_true',\n                        help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.')\n    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')\n    parser.set_defaults(pin_mem=True)\n\n    # distributed training parameters\n    parser.add_argument('--world_size', default=1, type=int,\n                        help='number of distributed processes')\n    parser.add_argument('--local_rank', default=-1, type=int)\n    parser.add_argument('--dist_on_itp', action='store_true')\n    parser.add_argument('--dist_url', default='env://',\n                        help='url used to set up distributed training')\n    # new                    \n    parser.add_argument('--rank', default=-1, type=int,\n                        help='node rank for distributed training')                        \n    parser.add_argument('--dist-backend', default='nccl', type=str,\n                        help='distributed backend')\n                        \n    parser.add_argument('--normalize', action='store_true', default=False)\n    parser.add_argument('--mode', nargs='*', default=['s2c'])\n    parser.add_argument('--dtype', type=str, default='uint8')\n    parser.add_argument('--season', type=str, default='augment')\n\n    return parser\n\n\ndef main(args):\n    # slurm setting\n    misc.init_distributed_mode(args)\n\n    print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))\n    print(\"{}\".format(args).replace(', ', ',\\n'))\n\n    device = torch.device(args.device)\n\n    # fix the seed for reproducibility\n    seed = args.seed + misc.get_rank()\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n\n    cudnn.benchmark = True\n    '''\n    # simple augmentation\n    transform_train = transforms.Compose([\n            transforms.RandomResizedCrop(args.input_size, scale=(0.2, 1.0), interpolation=3),  # 3 is bicubic\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    dataset_train = datasets.ImageFolder(os.path.join(args.data_path, 'train'), transform=transform_train)\n    print(dataset_train)\n    '''\n\n    transform_train = cvtransforms.Compose([\n            cvtransforms.RandomResizedCrop(args.input_size, scale=(0.2, 1.0), interpolation=3),  # 3 is bicubic\n            cvtransforms.RandomHorizontalFlip(),\n            cvtransforms.ToTensor(),\n            ])\n    \n    \n    dataset_train = LMDBDataset(\n        lmdb_file=args.data_path,\n        s2c_transform=SeasonTransform(base_transform=transform_train,season=args.season),\n        is_slurm_job=args.is_slurm_job,\n        normalize=args.normalize,\n        dtype=args.dtype,\n        mode=args.mode\n    )\n\n\n    if True:  # args.distributed:\n        num_tasks = misc.get_world_size()\n        global_rank = misc.get_rank()\n        sampler_train = torch.utils.data.DistributedSampler(\n            dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True\n        )\n        print(\"Sampler_train = %s\" % str(sampler_train))\n    else:\n        sampler_train = torch.utils.data.RandomSampler(dataset_train)\n\n    if global_rank == 0 and args.log_dir is not None:\n        os.makedirs(args.log_dir, exist_ok=True)\n        log_writer = SummaryWriter(log_dir=args.log_dir)\n    else:\n        log_writer = None\n\n    data_loader_train = torch.utils.data.DataLoader(\n        dataset_train, sampler=sampler_train,\n        batch_size=args.batch_size,\n        num_workers=args.num_workers,\n        pin_memory=args.pin_mem,\n        drop_last=True,\n    )\n    \n    # define the model\n    model = models_mae.__dict__[args.model](norm_pix_loss=args.norm_pix_loss)\n\n    model.to(device)\n\n    model_without_ddp = model\n    print(\"Model = %s\" % str(model_without_ddp))\n\n    eff_batch_size = args.batch_size * args.accum_iter * misc.get_world_size()\n    \n    if args.lr is None:  # only base_lr is specified\n        args.lr = args.blr * eff_batch_size / 256\n\n    print(\"base lr: %.2e\" % (args.lr * 256 / eff_batch_size))\n    print(\"actual lr: %.2e\" % args.lr)\n\n    print(\"accumulate grad iterations: %d\" % args.accum_iter)\n    print(\"effective batch size: %d\" % eff_batch_size)\n\n    if args.distributed:\n        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu], find_unused_parameters=True)\n        model_without_ddp = model.module\n    \n    # following timm: set wd as 0 for bias and norm layers\n    param_groups = optim_factory.add_weight_decay(model_without_ddp, args.weight_decay)\n    optimizer = torch.optim.AdamW(param_groups, lr=args.lr, betas=(0.9, 0.95))\n    print(optimizer)\n    loss_scaler = NativeScaler()\n\n    misc.load_model(args=args, model_without_ddp=model_without_ddp, optimizer=optimizer, loss_scaler=loss_scaler)\n\n    print(f\"Start training for {args.epochs} epochs\")\n    start_time = time.time()\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            data_loader_train.sampler.set_epoch(epoch)\n        train_stats = train_one_epoch(\n            model, data_loader_train,\n            optimizer, device, epoch, loss_scaler,\n            log_writer=log_writer,\n            args=args\n        )\n        if args.output_dir and (epoch % 20 == 0 or epoch + 1 == args.epochs):\n            misc.save_model(\n                args=args, model=model, model_without_ddp=model_without_ddp, optimizer=optimizer,\n                loss_scaler=loss_scaler, epoch=epoch)\n\n        log_stats = {**{f'train_{k}': v for k, v in train_stats.items()},\n                        'epoch': epoch,}\n\n        if args.output_dir and misc.is_main_process():\n            if log_writer is not None:\n                log_writer.flush()\n            with open(os.path.join(args.output_dir, \"log.txt\"), mode=\"a\", encoding=\"utf-8\") as f:\n                f.write(json.dumps(log_stats) + \"\\n\")\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))\n\n\nif __name__ == '__main__':\n    args = get_args_parser()\n    args = args.parse_args()\n    if args.output_dir:\n        Path(args.output_dir).mkdir(parents=True, exist_ok=True)\n    main(args)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/models_mae.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# timm: https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# DeiT: https://github.com/facebookresearch/deit\n# --------------------------------------------------------\n\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\n\nfrom timm.models.vision_transformer import PatchEmbed, Block\n\nfrom .util.pos_embed import get_2d_sincos_pos_embed\n\n\nclass MaskedAutoencoderViT(nn.Module):\n    \"\"\" Masked Autoencoder with VisionTransformer backbone\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3,\n                 embed_dim=1024, depth=24, num_heads=16,\n                 decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n                 mlp_ratio=4., norm_layer=nn.LayerNorm, norm_pix_loss=False):\n        super().__init__()\n\n        self.in_chans = in_chans\n        \n        # --------------------------------------------------------------------------\n        # MAE encoder specifics\n        self.patch_embed = PatchEmbed(img_size, patch_size, in_chans, embed_dim)\n        num_patches = self.patch_embed.num_patches\n\n        self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))\n        self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim), requires_grad=False)  # fixed sin-cos embedding\n\n        self.blocks = nn.ModuleList([\n            Block(embed_dim, num_heads, mlp_ratio, qkv_bias=True, norm_layer=norm_layer)\n            for i in range(depth)])\n        self.norm = norm_layer(embed_dim)\n        # --------------------------------------------------------------------------\n\n        # --------------------------------------------------------------------------\n        # MAE decoder specifics\n        self.decoder_embed = nn.Linear(embed_dim, decoder_embed_dim, bias=True)\n\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, decoder_embed_dim))\n\n        self.decoder_pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, decoder_embed_dim), requires_grad=False)  # fixed sin-cos embedding\n\n        self.decoder_blocks = nn.ModuleList([\n            Block(decoder_embed_dim, decoder_num_heads, mlp_ratio, qkv_bias=True, norm_layer=norm_layer)\n            for i in range(decoder_depth)])\n\n        self.decoder_norm = norm_layer(decoder_embed_dim)\n        self.decoder_pred = nn.Linear(decoder_embed_dim, patch_size**2 * in_chans, bias=True) # decoder to patch\n        # --------------------------------------------------------------------------\n\n        self.norm_pix_loss = norm_pix_loss\n\n        self.initialize_weights()\n\n    def initialize_weights(self):\n        # initialization\n        # initialize (and freeze) pos_embed by sin-cos embedding\n        pos_embed = get_2d_sincos_pos_embed(self.pos_embed.shape[-1], int(self.patch_embed.num_patches**.5), cls_token=True)\n        self.pos_embed.data.copy_(torch.from_numpy(pos_embed).float().unsqueeze(0))\n\n        decoder_pos_embed = get_2d_sincos_pos_embed(self.decoder_pos_embed.shape[-1], int(self.patch_embed.num_patches**.5), cls_token=True)\n        self.decoder_pos_embed.data.copy_(torch.from_numpy(decoder_pos_embed).float().unsqueeze(0))\n\n        # initialize patch_embed like nn.Linear (instead of nn.Conv2d)\n        w = self.patch_embed.proj.weight.data\n        torch.nn.init.xavier_uniform_(w.view([w.shape[0], -1]))\n\n        # timm's trunc_normal_(std=.02) is effectively normal_(std=0.02) as cutoff is too big (2.)\n        torch.nn.init.normal_(self.cls_token, std=.02)\n        torch.nn.init.normal_(self.mask_token, std=.02)\n\n        # initialize nn.Linear and nn.LayerNorm\n        self.apply(self._init_weights)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            # we use xavier_uniform following official JAX ViT:\n            torch.nn.init.xavier_uniform_(m.weight)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    def patchify(self, imgs):\n        \"\"\"\n        imgs: (N, 3, H, W)\n        x: (N, L, patch_size**2 *3)\n        \"\"\"\n        p = self.patch_embed.patch_size[0]\n        assert imgs.shape[2] == imgs.shape[3] and imgs.shape[2] % p == 0\n\n        h = w = imgs.shape[2] // p\n        x = imgs.reshape(shape=(imgs.shape[0], self.in_chans, h, p, w, p))\n        x = torch.einsum('nchpwq->nhwpqc', x)\n        x = x.reshape(shape=(imgs.shape[0], h * w, p**2 * self.in_chans))\n        return x\n\n    def unpatchify(self, x):\n        \"\"\"\n        x: (N, L, patch_size**2 *3)\n        imgs: (N, 3, H, W)\n        \"\"\"\n        p = self.patch_embed.patch_size[0]\n        h = w = int(x.shape[1]**.5)\n        assert h * w == x.shape[1]\n        \n        x = x.reshape(shape=(x.shape[0], h, w, p, p, self.in_chans))\n        x = torch.einsum('nhwpqc->nchpwq', x)\n        imgs = x.reshape(shape=(x.shape[0], self.in_chans, h * p, h * p))\n        return imgs\n\n    def random_masking(self, x, mask_ratio):\n        \"\"\"\n        Perform per-sample random masking by per-sample shuffling.\n        Per-sample shuffling is done by argsort random noise.\n        x: [N, L, D], sequence\n        \"\"\"\n        N, L, D = x.shape  # batch, length, dim\n        len_keep = int(L * (1 - mask_ratio))\n        \n        noise = torch.rand(N, L, device=x.device)  # noise in [0, 1]\n        \n        # sort noise for each sample\n        ids_shuffle = torch.argsort(noise, dim=1)  # ascend: small is keep, large is remove\n        ids_restore = torch.argsort(ids_shuffle, dim=1)\n\n        # keep the first subset\n        ids_keep = ids_shuffle[:, :len_keep]\n        x_masked = torch.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))\n\n        # generate the binary mask: 0 is keep, 1 is remove\n        mask = torch.ones([N, L], device=x.device)\n        mask[:, :len_keep] = 0\n        # unshuffle to get the binary mask\n        mask = torch.gather(mask, dim=1, index=ids_restore)\n\n        return x_masked, mask, ids_restore\n\n    def forward_encoder(self, x, mask_ratio):\n        # embed patches\n        x = self.patch_embed(x)\n\n        # add pos embed w/o cls token\n        x = x + self.pos_embed[:, 1:, :]\n\n        # masking: length -> length * mask_ratio\n        x, mask, ids_restore = self.random_masking(x, mask_ratio)\n\n        # append cls token\n        cls_token = self.cls_token + self.pos_embed[:, :1, :]\n        cls_tokens = cls_token.expand(x.shape[0], -1, -1)\n        x = torch.cat((cls_tokens, x), dim=1)\n\n        # apply Transformer blocks\n        for blk in self.blocks:\n            x = blk(x)\n        x = self.norm(x)\n\n        return x, mask, ids_restore\n\n    def forward_decoder(self, x, ids_restore):\n        # embed tokens\n        x = self.decoder_embed(x)\n\n        # append mask tokens to sequence\n        mask_tokens = self.mask_token.repeat(x.shape[0], ids_restore.shape[1] + 1 - x.shape[1], 1)\n        x_ = torch.cat([x[:, 1:, :], mask_tokens], dim=1)  # no cls token\n        x_ = torch.gather(x_, dim=1, index=ids_restore.unsqueeze(-1).repeat(1, 1, x.shape[2]))  # unshuffle\n        x = torch.cat([x[:, :1, :], x_], dim=1)  # append cls token\n\n        # add pos embed\n        x = x + self.decoder_pos_embed\n\n        # apply Transformer blocks\n        for blk in self.decoder_blocks:\n            x = blk(x)\n        x = self.decoder_norm(x)\n\n        # predictor projection\n        x = self.decoder_pred(x)\n\n        # remove cls token\n        x = x[:, 1:, :]\n\n        return x\n\n    def forward_loss(self, imgs, pred, mask):\n        \"\"\"\n        imgs: [N, 3, H, W]\n        pred: [N, L, p*p*3]\n        mask: [N, L], 0 is keep, 1 is remove, \n        \"\"\"\n        target = self.patchify(imgs)\n        if self.norm_pix_loss:\n            mean = target.mean(dim=-1, keepdim=True)\n            var = target.var(dim=-1, keepdim=True)\n            target = (target - mean) / (var + 1.e-6)**.5\n\n        loss = (pred - target) ** 2\n        loss = loss.mean(dim=-1)  # [N, L], mean loss per patch\n\n        loss = (loss * mask).sum() / mask.sum()  # mean loss on removed patches\n        return loss\n\n    def forward(self, imgs, mask_ratio=0.75):\n        latent, mask, ids_restore = self.forward_encoder(imgs, mask_ratio)\n        pred = self.forward_decoder(latent, ids_restore)  # [N, L, p*p*3]\n        loss = self.forward_loss(imgs, pred, mask)\n        return loss, pred, mask\n\n\ndef mae_vit_small_patch16_dec512d8b(**kwargs):\n    model = MaskedAutoencoderViT(\n        patch_size=16, embed_dim=384, depth=12, num_heads=6,\n        decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n        mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\ndef mae_vit_base_patch16_dec512d8b(**kwargs):\n    model = MaskedAutoencoderViT(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12,\n        decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n        mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef mae_vit_large_patch16_dec512d8b(**kwargs):\n    model = MaskedAutoencoderViT(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16,\n        decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n        mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef mae_vit_huge_patch14_dec512d8b(**kwargs):\n    model = MaskedAutoencoderViT(\n        patch_size=14, embed_dim=1280, depth=32, num_heads=16,\n        decoder_embed_dim=512, decoder_depth=8, decoder_num_heads=16,\n        mlp_ratio=4, norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\n# set recommended archs\nmae_vit_base_patch16 = mae_vit_base_patch16_dec512d8b  # decoder: 512 dim, 8 blocks\nmae_vit_large_patch16 = mae_vit_large_patch16_dec512d8b  # decoder: 512 dim, 8 blocks\nmae_vit_huge_patch14 = mae_vit_huge_patch14_dec512d8b  # decoder: 512 dim, 8 blocks\n# new\nmae_vit_small_patch16 = mae_vit_small_patch16_dec512d8b  # decoder: 512 dim, 8 blocks"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/models_vit.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# timm: https://github.com/rwightman/pytorch-image-models/tree/master/timm\n# DeiT: https://github.com/facebookresearch/deit\n# --------------------------------------------------------\n\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\n\nimport timm.models.vision_transformer\n\n\nclass VisionTransformer(timm.models.vision_transformer.VisionTransformer):\n    \"\"\" Vision Transformer with support for global average pooling\n    \"\"\"\n    def __init__(self, global_pool=False, **kwargs):\n        super(VisionTransformer, self).__init__(**kwargs)\n\n        self.global_pool = global_pool\n        if self.global_pool:\n            norm_layer = kwargs['norm_layer']\n            embed_dim = kwargs['embed_dim']\n            self.fc_norm = norm_layer(embed_dim)\n\n            del self.norm  # remove the original norm\n\n    def forward_features(self, x):\n        B = x.shape[0]\n        x = self.patch_embed(x)\n\n        cls_tokens = self.cls_token.expand(B, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks\n        x = torch.cat((cls_tokens, x), dim=1)\n        x = x + self.pos_embed\n        x = self.pos_drop(x)\n\n        for blk in self.blocks:\n            x = blk(x)\n\n        if self.global_pool:\n            x = x[:, 1:, :].mean(dim=1)  # global pool without cls token\n            outcome = self.fc_norm(x)\n        else:\n            x = self.norm(x)\n            outcome = x[:, 0]\n\n        return outcome\n\ndef vit_small_patch16(**kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\ndef vit_base_patch16(**kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef vit_large_patch16(**kwargs):\n    model = VisionTransformer(\n        patch_size=16, embed_dim=1024, depth=24, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model\n\n\ndef vit_huge_patch14(**kwargs):\n    model = VisionTransformer(\n        patch_size=14, embed_dim=1280, depth=32, num_heads=16, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    return model"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/submitit_finetune.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# A script to run multinode training with submitit.\n# --------------------------------------------------------\n\nimport argparse\nimport os\nimport uuid\nfrom pathlib import Path\n\nimport main_finetune as classification\nimport submitit\n\n\ndef parse_args():\n    classification_parser = classification.get_args_parser()\n    parser = argparse.ArgumentParser(\"Submitit for MAE finetune\", parents=[classification_parser])\n    parser.add_argument(\"--ngpus\", default=8, type=int, help=\"Number of gpus to request on each node\")\n    parser.add_argument(\"--nodes\", default=2, type=int, help=\"Number of nodes to request\")\n    parser.add_argument(\"--timeout\", default=4320, type=int, help=\"Duration of the job\")\n    parser.add_argument(\"--job_dir\", default=\"\", type=str, help=\"Job dir. Leave empty for automatic.\")\n\n    parser.add_argument(\"--partition\", default=\"learnfair\", type=str, help=\"Partition where to submit\")\n    parser.add_argument(\"--use_volta32\", action='store_true', help=\"Request 32G V100 GPUs\")\n    parser.add_argument('--comment', default=\"\", type=str, help=\"Comment to pass to scheduler\")\n    return parser.parse_args()\n\n\ndef get_shared_folder() -> Path:\n    user = os.getenv(\"USER\")\n    if Path(\"/checkpoint/\").is_dir():\n        p = Path(f\"/checkpoint/{user}/experiments\")\n        p.mkdir(exist_ok=True)\n        return p\n    raise RuntimeError(\"No shared folder available\")\n\n\ndef get_init_file():\n    # Init file must not exist, but it's parent dir must exist.\n    os.makedirs(str(get_shared_folder()), exist_ok=True)\n    init_file = get_shared_folder() / f\"{uuid.uuid4().hex}_init\"\n    if init_file.exists():\n        os.remove(str(init_file))\n    return init_file\n\n\nclass Trainer(object):\n    def __init__(self, args):\n        self.args = args\n\n    def __call__(self):\n        import main_finetune as classification\n\n        self._setup_gpu_args()\n        classification.main(self.args)\n\n    def checkpoint(self):\n        import os\n        import submitit\n\n        self.args.dist_url = get_init_file().as_uri()\n        checkpoint_file = os.path.join(self.args.output_dir, \"checkpoint.pth\")\n        if os.path.exists(checkpoint_file):\n            self.args.resume = checkpoint_file\n        print(\"Requeuing \", self.args)\n        empty_trainer = type(self)(self.args)\n        return submitit.helpers.DelayedSubmission(empty_trainer)\n\n    def _setup_gpu_args(self):\n        import submitit\n        from pathlib import Path\n\n        job_env = submitit.JobEnvironment()\n        self.args.output_dir = Path(str(self.args.output_dir).replace(\"%j\", str(job_env.job_id)))\n        self.args.log_dir = self.args.output_dir\n        self.args.gpu = job_env.local_rank\n        self.args.rank = job_env.global_rank\n        self.args.world_size = job_env.num_tasks\n        print(f\"Process group: {job_env.num_tasks} tasks, rank: {job_env.global_rank}\")\n\n\ndef main():\n    args = parse_args()\n    if args.job_dir == \"\":\n        args.job_dir = get_shared_folder() / \"%j\"\n\n    # Note that the folder will depend on the job_id, to easily track experiments\n    executor = submitit.AutoExecutor(folder=args.job_dir, slurm_max_num_timeout=30)\n\n    num_gpus_per_node = args.ngpus\n    nodes = args.nodes\n    timeout_min = args.timeout\n\n    partition = args.partition\n    kwargs = {}\n    if args.use_volta32:\n        kwargs['slurm_constraint'] = 'volta32gb'\n    if args.comment:\n        kwargs['slurm_comment'] = args.comment\n\n    executor.update_parameters(\n        mem_gb=40 * num_gpus_per_node,\n        gpus_per_node=num_gpus_per_node,\n        tasks_per_node=num_gpus_per_node, # one task per GPU\n        cpus_per_task=10,\n        nodes=nodes,\n        timeout_min=timeout_min,\n        # Below are cluster dependent parameters\n        slurm_partition=partition,\n        slurm_signal_delay_s=120,\n        **kwargs\n    )\n\n    executor.update_parameters(name=\"mae\")\n\n    args.dist_url = get_init_file().as_uri()\n    args.output_dir = args.job_dir\n\n    trainer = Trainer(args)\n    job = executor.submit(trainer)\n\n    # print(\"Submitted job_id:\", job.job_id)\n    print(job.job_id)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/submitit_linprobe.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# A script to run multinode training with submitit.\n# --------------------------------------------------------\n\nimport argparse\nimport os\nimport uuid\nfrom pathlib import Path\n\nimport main_linprobe as classification\nimport submitit\n\n\ndef parse_args():\n    classification_parser = classification.get_args_parser()\n    parser = argparse.ArgumentParser(\"Submitit for MAE linear probe\", parents=[classification_parser])\n    parser.add_argument(\"--ngpus\", default=8, type=int, help=\"Number of gpus to request on each node\")\n    parser.add_argument(\"--nodes\", default=2, type=int, help=\"Number of nodes to request\")\n    parser.add_argument(\"--timeout\", default=4320, type=int, help=\"Duration of the job\")\n    parser.add_argument(\"--job_dir\", default=\"\", type=str, help=\"Job dir. Leave empty for automatic.\")\n\n    parser.add_argument(\"--partition\", default=\"learnfair\", type=str, help=\"Partition where to submit\")\n    parser.add_argument(\"--use_volta32\", action='store_true', help=\"Request 32G V100 GPUs\")\n    parser.add_argument('--comment', default=\"\", type=str, help=\"Comment to pass to scheduler\")\n    return parser.parse_args()\n\n\ndef get_shared_folder() -> Path:\n    user = os.getenv(\"USER\")\n    if Path(\"/checkpoint/\").is_dir():\n        p = Path(f\"/checkpoint/{user}/experiments\")\n        p.mkdir(exist_ok=True)\n        return p\n    raise RuntimeError(\"No shared folder available\")\n\n\ndef get_init_file():\n    # Init file must not exist, but it's parent dir must exist.\n    os.makedirs(str(get_shared_folder()), exist_ok=True)\n    init_file = get_shared_folder() / f\"{uuid.uuid4().hex}_init\"\n    if init_file.exists():\n        os.remove(str(init_file))\n    return init_file\n\n\nclass Trainer(object):\n    def __init__(self, args):\n        self.args = args\n\n    def __call__(self):\n        import main_linprobe as classification\n\n        self._setup_gpu_args()\n        classification.main(self.args)\n\n    def checkpoint(self):\n        import os\n        import submitit\n\n        self.args.dist_url = get_init_file().as_uri()\n        checkpoint_file = os.path.join(self.args.output_dir, \"checkpoint.pth\")\n        if os.path.exists(checkpoint_file):\n            self.args.resume = checkpoint_file\n        print(\"Requeuing \", self.args)\n        empty_trainer = type(self)(self.args)\n        return submitit.helpers.DelayedSubmission(empty_trainer)\n\n    def _setup_gpu_args(self):\n        import submitit\n        from pathlib import Path\n\n        job_env = submitit.JobEnvironment()\n        self.args.output_dir = Path(str(self.args.output_dir).replace(\"%j\", str(job_env.job_id)))\n        self.args.log_dir = self.args.output_dir\n        self.args.gpu = job_env.local_rank\n        self.args.rank = job_env.global_rank\n        self.args.world_size = job_env.num_tasks\n        print(f\"Process group: {job_env.num_tasks} tasks, rank: {job_env.global_rank}\")\n\n\ndef main():\n    args = parse_args()\n    if args.job_dir == \"\":\n        args.job_dir = get_shared_folder() / \"%j\"\n\n    # Note that the folder will depend on the job_id, to easily track experiments\n    executor = submitit.AutoExecutor(folder=args.job_dir, slurm_max_num_timeout=30)\n\n    num_gpus_per_node = args.ngpus\n    nodes = args.nodes\n    timeout_min = args.timeout\n\n    partition = args.partition\n    kwargs = {}\n    if args.use_volta32:\n        kwargs['slurm_constraint'] = 'volta32gb'\n    if args.comment:\n        kwargs['slurm_comment'] = args.comment\n\n    executor.update_parameters(\n        mem_gb=40 * num_gpus_per_node,\n        gpus_per_node=num_gpus_per_node,\n        tasks_per_node=num_gpus_per_node, # one task per GPU\n        cpus_per_task=10,\n        nodes=nodes,\n        timeout_min=timeout_min,\n        # Below are cluster dependent parameters\n        slurm_partition=partition,\n        slurm_signal_delay_s=120,\n        **kwargs\n    )\n\n    executor.update_parameters(name=\"mae\")\n\n    args.dist_url = get_init_file().as_uri()\n    args.output_dir = args.job_dir\n\n    trainer = Trainer(args)\n    job = executor.submit(trainer)\n\n    # print(\"Submitted job_id:\", job.job_id)\n    print(job.job_id)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/submitit_pretrain.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# A script to run multinode training with submitit.\n# --------------------------------------------------------\n\nimport argparse\nimport os\nimport uuid\nfrom pathlib import Path\n\nimport main_pretrain as trainer\nimport submitit\n\n\ndef parse_args():\n    trainer_parser = trainer.get_args_parser()\n    parser = argparse.ArgumentParser(\"Submitit for MAE pretrain\", parents=[trainer_parser])\n    parser.add_argument(\"--ngpus\", default=8, type=int, help=\"Number of gpus to request on each node\")\n    parser.add_argument(\"--nodes\", default=2, type=int, help=\"Number of nodes to request\")\n    parser.add_argument(\"--timeout\", default=4320, type=int, help=\"Duration of the job\")\n    parser.add_argument(\"--job_dir\", default=\"\", type=str, help=\"Job dir. Leave empty for automatic.\")\n\n    parser.add_argument(\"--partition\", default=\"learnfair\", type=str, help=\"Partition where to submit\")\n    parser.add_argument(\"--use_volta32\", action='store_true', help=\"Request 32G V100 GPUs\")\n    parser.add_argument('--comment', default=\"\", type=str, help=\"Comment to pass to scheduler\")\n    return parser.parse_args()\n\n\ndef get_shared_folder() -> Path:\n    user = os.getenv(\"USER\")\n    if Path(\"/checkpoint/\").is_dir():\n        p = Path(f\"/checkpoint/{user}/experiments\")\n        p.mkdir(exist_ok=True)\n        return p\n    raise RuntimeError(\"No shared folder available\")\n\n\ndef get_init_file():\n    # Init file must not exist, but it's parent dir must exist.\n    os.makedirs(str(get_shared_folder()), exist_ok=True)\n    init_file = get_shared_folder() / f\"{uuid.uuid4().hex}_init\"\n    if init_file.exists():\n        os.remove(str(init_file))\n    return init_file\n\n\nclass Trainer(object):\n    def __init__(self, args):\n        self.args = args\n\n    def __call__(self):\n        import main_pretrain as trainer\n\n        self._setup_gpu_args()\n        trainer.main(self.args)\n\n    def checkpoint(self):\n        import os\n        import submitit\n\n        self.args.dist_url = get_init_file().as_uri()\n        checkpoint_file = os.path.join(self.args.output_dir, \"checkpoint.pth\")\n        if os.path.exists(checkpoint_file):\n            self.args.resume = checkpoint_file\n        print(\"Requeuing \", self.args)\n        empty_trainer = type(self)(self.args)\n        return submitit.helpers.DelayedSubmission(empty_trainer)\n\n    def _setup_gpu_args(self):\n        import submitit\n        from pathlib import Path\n\n        job_env = submitit.JobEnvironment()\n        self.args.output_dir = Path(str(self.args.output_dir).replace(\"%j\", str(job_env.job_id)))\n        self.args.log_dir = self.args.output_dir\n        self.args.gpu = job_env.local_rank\n        self.args.rank = job_env.global_rank\n        self.args.world_size = job_env.num_tasks\n        print(f\"Process group: {job_env.num_tasks} tasks, rank: {job_env.global_rank}\")\n\n\ndef main():\n    args = parse_args()\n    if args.job_dir == \"\":\n        args.job_dir = get_shared_folder() / \"%j\"\n\n    # Note that the folder will depend on the job_id, to easily track experiments\n    executor = submitit.AutoExecutor(folder=args.job_dir, slurm_max_num_timeout=30)\n\n    num_gpus_per_node = args.ngpus\n    nodes = args.nodes\n    timeout_min = args.timeout\n\n    partition = args.partition\n    kwargs = {}\n    if args.use_volta32:\n        kwargs['slurm_constraint'] = 'volta32gb'\n    if args.comment:\n        kwargs['slurm_comment'] = args.comment\n\n    executor.update_parameters(\n        mem_gb=40 * num_gpus_per_node,\n        gpus_per_node=num_gpus_per_node,\n        tasks_per_node=num_gpus_per_node,  # one task per GPU\n        cpus_per_task=10,\n        nodes=nodes,\n        timeout_min=timeout_min,  # max is 60 * 72\n        # Below are cluster dependent parameters\n        slurm_partition=partition,\n        slurm_signal_delay_s=120,\n        **kwargs\n    )\n\n    executor.update_parameters(name=\"mae\")\n\n    args.dist_url = get_init_file().as_uri()\n    args.output_dir = args.job_dir\n\n    trainer = Trainer(args)\n    job = executor.submit(trainer)\n\n    # print(\"Submitted job_id:\", job.job_id)\n    print(job.job_id)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/util/__init__.py",
    "content": ""
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/util/crop.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport math\n\nimport torch\n\nfrom torchvision import transforms\nfrom torchvision.transforms import functional as F\n\n\nclass RandomResizedCrop(transforms.RandomResizedCrop):\n    \"\"\"\n    RandomResizedCrop for matching TF/TPU implementation: no for-loop is used.\n    This may lead to results different with torchvision's version.\n    Following BYOL's TF code:\n    https://github.com/deepmind/deepmind-research/blob/master/byol/utils/dataset.py#L206\n    \"\"\"\n    @staticmethod\n    def get_params(img, scale, ratio):\n        width, height = F._get_image_size(img)\n        area = height * width\n\n        target_area = area * torch.empty(1).uniform_(scale[0], scale[1]).item()\n        log_ratio = torch.log(torch.tensor(ratio))\n        aspect_ratio = torch.exp(\n            torch.empty(1).uniform_(log_ratio[0], log_ratio[1])\n        ).item()\n\n        w = int(round(math.sqrt(target_area * aspect_ratio)))\n        h = int(round(math.sqrt(target_area / aspect_ratio)))\n\n        w = min(w, width)\n        h = min(h, height)\n\n        i = torch.randint(0, height - h + 1, size=(1,)).item()\n        j = torch.randint(0, width - w + 1, size=(1,)).item()\n\n        return i, j, h, w"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/util/datasets.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# --------------------------------------------------------\n\nimport os\nimport PIL\n\nfrom torchvision import datasets, transforms\n\nfrom timm.data import create_transform\nfrom timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD\n\n\ndef build_dataset(is_train, args):\n    transform = build_transform(is_train, args)\n\n    root = os.path.join(args.data_path, 'train' if is_train else 'val')\n    dataset = datasets.ImageFolder(root, transform=transform)\n\n    print(dataset)\n\n    return dataset\n\n\ndef build_transform(is_train, args):\n    mean = IMAGENET_DEFAULT_MEAN\n    std = IMAGENET_DEFAULT_STD\n    # train transform\n    if is_train:\n        # this should always dispatch to transforms_imagenet_train\n        transform = create_transform(\n            input_size=args.input_size,\n            is_training=True,\n            color_jitter=args.color_jitter,\n            auto_augment=args.aa,\n            interpolation='bicubic',\n            re_prob=args.reprob,\n            re_mode=args.remode,\n            re_count=args.recount,\n            mean=mean,\n            std=std,\n        )\n        return transform\n\n    # eval transform\n    t = []\n    if args.input_size <= 224:\n        crop_pct = 224 / 256\n    else:\n        crop_pct = 1.0\n    size = int(args.input_size / crop_pct)\n    t.append(\n        transforms.Resize(size, interpolation=PIL.Image.BICUBIC),  # to maintain same ratio w.r.t. 224 images\n    )\n    t.append(transforms.CenterCrop(args.input_size))\n\n    t.append(transforms.ToTensor())\n    t.append(transforms.Normalize(mean, std))\n    return transforms.Compose(t)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/util/lars.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# LARS optimizer, implementation from MoCo v3:\n# https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\n\nimport torch\n\n\nclass LARS(torch.optim.Optimizer):\n    \"\"\"\n    LARS optimizer, no rate scaling or weight decay for parameters <= 1D.\n    \"\"\"\n    def __init__(self, params, lr=0, weight_decay=0, momentum=0.9, trust_coefficient=0.001):\n        defaults = dict(lr=lr, weight_decay=weight_decay, momentum=momentum, trust_coefficient=trust_coefficient)\n        super().__init__(params, defaults)\n\n    @torch.no_grad()\n    def step(self):\n        for g in self.param_groups:\n            for p in g['params']:\n                dp = p.grad\n\n                if dp is None:\n                    continue\n\n                if p.ndim > 1: # if not normalization gamma/beta or bias\n                    dp = dp.add(p, alpha=g['weight_decay'])\n                    param_norm = torch.norm(p)\n                    update_norm = torch.norm(dp)\n                    one = torch.ones_like(param_norm)\n                    q = torch.where(param_norm > 0.,\n                                    torch.where(update_norm > 0,\n                                    (g['trust_coefficient'] * param_norm / update_norm), one),\n                                    one)\n                    dp = dp.mul(q)\n\n                param_state = self.state[p]\n                if 'mu' not in param_state:\n                    param_state['mu'] = torch.zeros_like(p)\n                mu = param_state['mu']\n                mu.mul_(g['momentum']).add_(dp)\n                p.add_(mu, alpha=-g['lr'])"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/util/lr_decay.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# ELECTRA https://github.com/google-research/electra\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport json\n\n\ndef param_groups_lrd(model, weight_decay=0.05, no_weight_decay_list=[], layer_decay=.75):\n    \"\"\"\n    Parameter groups for layer-wise lr decay\n    Following BEiT: https://github.com/microsoft/unilm/blob/master/beit/optim_factory.py#L58\n    \"\"\"\n    param_group_names = {}\n    param_groups = {}\n\n    num_layers = len(model.blocks) + 1\n\n    layer_scales = list(layer_decay ** (num_layers - i) for i in range(num_layers + 1))\n\n    for n, p in model.named_parameters():\n        if not p.requires_grad:\n            continue\n\n        # no decay: all 1D parameters and model specific ones\n        if p.ndim == 1 or n in no_weight_decay_list:\n            g_decay = \"no_decay\"\n            this_decay = 0.\n        else:\n            g_decay = \"decay\"\n            this_decay = weight_decay\n            \n        layer_id = get_layer_id_for_vit(n, num_layers)\n        group_name = \"layer_%d_%s\" % (layer_id, g_decay)\n\n        if group_name not in param_group_names:\n            this_scale = layer_scales[layer_id]\n\n            param_group_names[group_name] = {\n                \"lr_scale\": this_scale,\n                \"weight_decay\": this_decay,\n                \"params\": [],\n            }\n            param_groups[group_name] = {\n                \"lr_scale\": this_scale,\n                \"weight_decay\": this_decay,\n                \"params\": [],\n            }\n\n        param_group_names[group_name][\"params\"].append(n)\n        param_groups[group_name][\"params\"].append(p)\n\n    # print(\"parameter groups: \\n%s\" % json.dumps(param_group_names, indent=2))\n\n    return list(param_groups.values())\n\n\ndef get_layer_id_for_vit(name, num_layers):\n    \"\"\"\n    Assign a parameter with its layer id\n    Following BEiT: https://github.com/microsoft/unilm/blob/master/beit/optim_factory.py#L33\n    \"\"\"\n    if name in ['cls_token', 'pos_embed']:\n        return 0\n    elif name.startswith('patch_embed'):\n        return 0\n    elif name.startswith('blocks'):\n        return int(name.split('.')[1]) + 1\n    else:\n        return num_layers"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/util/lr_sched.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport math\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate with half-cycle cosine after warmup\"\"\"\n    if epoch < args.warmup_epochs:\n        lr = args.lr * epoch / args.warmup_epochs \n    else:\n        lr = args.min_lr + (args.lr - args.min_lr) * 0.5 * \\\n            (1. + math.cos(math.pi * (epoch - args.warmup_epochs) / (args.epochs - args.warmup_epochs)))\n    for param_group in optimizer.param_groups:\n        if \"lr_scale\" in param_group:\n            param_group[\"lr\"] = lr * param_group[\"lr_scale\"]\n        else:\n            param_group[\"lr\"] = lr\n    return lr\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/util/misc.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# BEiT: https://github.com/microsoft/unilm/tree/master/beit\n# --------------------------------------------------------\n\nimport builtins\nimport datetime\nimport os\nimport time\nfrom collections import defaultdict, deque\nfrom pathlib import Path\n\nimport torch\nimport torch.distributed as dist\nfrom torch._six import inf\n\n\nclass SmoothedValue(object):\n    \"\"\"Track a series of values and provide access to smoothed values over a\n    window or the global series average.\n    \"\"\"\n\n    def __init__(self, window_size=20, fmt=None):\n        if fmt is None:\n            fmt = \"{median:.4f} ({global_avg:.4f})\"\n        self.deque = deque(maxlen=window_size)\n        self.total = 0.0\n        self.count = 0\n        self.fmt = fmt\n\n    def update(self, value, n=1):\n        self.deque.append(value)\n        self.count += n\n        self.total += value * n\n\n    def synchronize_between_processes(self):\n        \"\"\"\n        Warning: does not synchronize the deque!\n        \"\"\"\n        if not is_dist_avail_and_initialized():\n            return\n        t = torch.tensor([self.count, self.total], dtype=torch.float64, device='cuda')\n        dist.barrier()\n        dist.all_reduce(t)\n        t = t.tolist()\n        self.count = int(t[0])\n        self.total = t[1]\n\n    @property\n    def median(self):\n        d = torch.tensor(list(self.deque))\n        return d.median().item()\n\n    @property\n    def avg(self):\n        d = torch.tensor(list(self.deque), dtype=torch.float32)\n        return d.mean().item()\n\n    @property\n    def global_avg(self):\n        return self.total / self.count\n\n    @property\n    def max(self):\n        return max(self.deque)\n\n    @property\n    def value(self):\n        return self.deque[-1]\n\n    def __str__(self):\n        return self.fmt.format(\n            median=self.median,\n            avg=self.avg,\n            global_avg=self.global_avg,\n            max=self.max,\n            value=self.value)\n\n\nclass MetricLogger(object):\n    def __init__(self, delimiter=\"\\t\"):\n        self.meters = defaultdict(SmoothedValue)\n        self.delimiter = delimiter\n\n    def update(self, **kwargs):\n        for k, v in kwargs.items():\n            if v is None:\n                continue\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.meters[k].update(v)\n\n    def __getattr__(self, attr):\n        if attr in self.meters:\n            return self.meters[attr]\n        if attr in self.__dict__:\n            return self.__dict__[attr]\n        raise AttributeError(\"'{}' object has no attribute '{}'\".format(\n            type(self).__name__, attr))\n\n    def __str__(self):\n        loss_str = []\n        for name, meter in self.meters.items():\n            loss_str.append(\n                \"{}: {}\".format(name, str(meter))\n            )\n        return self.delimiter.join(loss_str)\n\n    def synchronize_between_processes(self):\n        for meter in self.meters.values():\n            meter.synchronize_between_processes()\n\n    def add_meter(self, name, meter):\n        self.meters[name] = meter\n\n    def log_every(self, iterable, print_freq, header=None):\n        i = 0\n        if not header:\n            header = ''\n        start_time = time.time()\n        end = time.time()\n        iter_time = SmoothedValue(fmt='{avg:.4f}')\n        data_time = SmoothedValue(fmt='{avg:.4f}')\n        space_fmt = ':' + str(len(str(len(iterable)))) + 'd'\n        log_msg = [\n            header,\n            '[{0' + space_fmt + '}/{1}]',\n            'eta: {eta}',\n            '{meters}',\n            'time: {time}',\n            'data: {data}'\n        ]\n        if torch.cuda.is_available():\n            log_msg.append('max mem: {memory:.0f}')\n        log_msg = self.delimiter.join(log_msg)\n        MB = 1024.0 * 1024.0\n        for obj in iterable:\n            data_time.update(time.time() - end)\n            yield obj\n            iter_time.update(time.time() - end)\n            if i % print_freq == 0 or i == len(iterable) - 1:\n                eta_seconds = iter_time.global_avg * (len(iterable) - i)\n                eta_string = str(datetime.timedelta(seconds=int(eta_seconds)))\n                if torch.cuda.is_available():\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time),\n                        memory=torch.cuda.max_memory_allocated() / MB))\n                else:\n                    print(log_msg.format(\n                        i, len(iterable), eta=eta_string,\n                        meters=str(self),\n                        time=str(iter_time), data=str(data_time)))\n            i += 1\n            end = time.time()\n        total_time = time.time() - start_time\n        total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n        print('{} Total time: {} ({:.4f} s / it)'.format(\n            header, total_time_str, total_time / len(iterable)))\n\n\ndef setup_for_distributed(is_master):\n    \"\"\"\n    This function disables printing when not in master process\n    \"\"\"\n    builtin_print = builtins.print\n\n    def print(*args, **kwargs):\n        force = kwargs.pop('force', False)\n        force = force or (get_world_size() > 8)\n        if is_master or force:\n            now = datetime.datetime.now().time()\n            builtin_print('[{}] '.format(now), end='')  # print with time stamp\n            builtin_print(*args, **kwargs)\n\n    builtins.print = print\n\n\ndef is_dist_avail_and_initialized():\n    if not dist.is_available():\n        return False\n    if not dist.is_initialized():\n        return False\n    return True\n\n\ndef get_world_size():\n    if not is_dist_avail_and_initialized():\n        return 1\n    return dist.get_world_size()\n\n\ndef get_rank():\n    if not is_dist_avail_and_initialized():\n        return 0\n    return dist.get_rank()\n\n\ndef is_main_process():\n    return get_rank() == 0\n\n\ndef save_on_master(*args, **kwargs):\n    if is_main_process():\n        torch.save(*args, **kwargs)\n\n\ndef init_distributed_mode(args):\n    if args.dist_on_itp:\n        args.rank = int(os.environ['OMPI_COMM_WORLD_RANK'])\n        args.world_size = int(os.environ['OMPI_COMM_WORLD_SIZE'])\n        args.gpu = int(os.environ['OMPI_COMM_WORLD_LOCAL_RANK'])\n        args.dist_url = \"tcp://%s:%s\" % (os.environ['MASTER_ADDR'], os.environ['MASTER_PORT'])\n        os.environ['LOCAL_RANK'] = str(args.gpu)\n        os.environ['RANK'] = str(args.rank)\n        os.environ['WORLD_SIZE'] = str(args.world_size)\n        # [\"RANK\", \"WORLD_SIZE\", \"MASTER_ADDR\", \"MASTER_PORT\", \"LOCAL_RANK\"]\n    elif 'RANK' in os.environ and 'WORLD_SIZE' in os.environ:\n        args.rank = int(os.environ[\"RANK\"])\n        args.world_size = int(os.environ['WORLD_SIZE'])\n        args.gpu = int(os.environ['LOCAL_RANK'])\n    elif 'SLURM_PROCID' in os.environ:\n        args.rank = int(os.environ['SLURM_PROCID'])\n        args.gpu = args.rank % torch.cuda.device_count()\n        args.world_size = int(os.environ[\"SLURM_NNODES\"]) * int(\n            os.environ[\"SLURM_TASKS_PER_NODE\"][0]\n        )\n    else:\n        print('Not using distributed mode')\n        setup_for_distributed(is_master=True)  # hack\n        args.distributed = False\n        return\n\n    args.distributed = True\n\n    torch.cuda.set_device(args.gpu)\n    args.dist_backend = 'nccl'\n    print('World Size {} | distributed init (rank {}): {}, gpu {}'.format(args.world_size, args.rank, args.dist_url, args.gpu), flush=True)\n    torch.distributed.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                         world_size=args.world_size, rank=args.rank)\n    torch.distributed.barrier()\n    setup_for_distributed(args.rank == 0)\n\n\nclass NativeScalerWithGradNormCount:\n    state_dict_key = \"amp_scaler\"\n\n    def __init__(self):\n        self._scaler = torch.cuda.amp.GradScaler()\n\n    def __call__(self, loss, optimizer, clip_grad=None, parameters=None, create_graph=False, update_grad=True):\n        self._scaler.scale(loss).backward(create_graph=create_graph)\n        if update_grad:\n            if clip_grad is not None:\n                assert parameters is not None\n                self._scaler.unscale_(optimizer)  # unscale the gradients of optimizer's assigned params in-place\n                norm = torch.nn.utils.clip_grad_norm_(parameters, clip_grad)\n            else:\n                self._scaler.unscale_(optimizer)\n                norm = get_grad_norm_(parameters)\n            self._scaler.step(optimizer)\n            self._scaler.update()\n        else:\n            norm = None\n        return norm\n\n    def state_dict(self):\n        return self._scaler.state_dict()\n\n    def load_state_dict(self, state_dict):\n        self._scaler.load_state_dict(state_dict)\n\n\ndef get_grad_norm_(parameters, norm_type: float = 2.0) -> torch.Tensor:\n    if isinstance(parameters, torch.Tensor):\n        parameters = [parameters]\n    parameters = [p for p in parameters if p.grad is not None]\n    norm_type = float(norm_type)\n    if len(parameters) == 0:\n        return torch.tensor(0.)\n    device = parameters[0].grad.device\n    if norm_type == inf:\n        total_norm = max(p.grad.detach().abs().max().to(device) for p in parameters)\n    else:\n        total_norm = torch.norm(torch.stack([torch.norm(p.grad.detach(), norm_type).to(device) for p in parameters]), norm_type)\n    return total_norm\n\n\ndef save_model(args, epoch, model, model_without_ddp, optimizer, loss_scaler):\n    output_dir = Path(args.output_dir)\n    epoch_name = str(epoch)\n    if loss_scaler is not None:\n        checkpoint_paths = [output_dir / ('checkpoint-%s.pth' % epoch_name)]\n        for checkpoint_path in checkpoint_paths:\n            to_save = {\n                'model': model_without_ddp.state_dict(),\n                'optimizer': optimizer.state_dict(),\n                'epoch': epoch,\n                'scaler': loss_scaler.state_dict(),\n                'args': args,\n            }\n\n            save_on_master(to_save, checkpoint_path)\n    else:\n        client_state = {'epoch': epoch}\n        model.save_checkpoint(save_dir=args.output_dir, tag=\"checkpoint-%s\" % epoch_name, client_state=client_state)\n\n\ndef load_model(args, model_without_ddp, optimizer, loss_scaler):\n    if args.resume:\n        if args.resume.startswith('https'):\n            checkpoint = torch.hub.load_state_dict_from_url(\n                args.resume, map_location='cpu', check_hash=True)\n        else:\n            checkpoint = torch.load(args.resume, map_location='cpu')\n        model_without_ddp.load_state_dict(checkpoint['model'])\n        print(\"Resume checkpoint %s\" % args.resume)\n        if 'optimizer' in checkpoint and 'epoch' in checkpoint and not (hasattr(args, 'eval') and args.eval):\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            args.start_epoch = checkpoint['epoch'] + 1\n            if 'scaler' in checkpoint:\n                loss_scaler.load_state_dict(checkpoint['scaler'])\n            print(\"With optim & sched!\")\n\n\ndef all_reduce_mean(x):\n    world_size = get_world_size()\n    if world_size > 1:\n        x_reduce = torch.tensor(x).cuda()\n        dist.all_reduce(x_reduce)\n        x_reduce /= world_size\n        return x_reduce.item()\n    else:\n        return x"
  },
  {
    "path": "src/benchmark/transfer_classification/models/mae/util/pos_embed.py",
    "content": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n# --------------------------------------------------------\n# Position embedding utils\n# --------------------------------------------------------\n\nimport numpy as np\n\nimport torch\n\n# --------------------------------------------------------\n# 2D sine-cosine position embedding\n# References:\n# Transformer: https://github.com/tensorflow/models/blob/master/official/nlp/transformer/model_utils.py\n# MoCo v3: https://github.com/facebookresearch/moco-v3\n# --------------------------------------------------------\ndef get_2d_sincos_pos_embed(embed_dim, grid_size, cls_token=False):\n    \"\"\"\n    grid_size: int of the grid height and width\n    return:\n    pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)\n    \"\"\"\n    grid_h = np.arange(grid_size, dtype=np.float32)\n    grid_w = np.arange(grid_size, dtype=np.float32)\n    grid = np.meshgrid(grid_w, grid_h)  # here w goes first\n    grid = np.stack(grid, axis=0)\n\n    grid = grid.reshape([2, 1, grid_size, grid_size])\n    pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid)\n    if cls_token:\n        pos_embed = np.concatenate([np.zeros([1, embed_dim]), pos_embed], axis=0)\n    return pos_embed\n\n\ndef get_2d_sincos_pos_embed_from_grid(embed_dim, grid):\n    assert embed_dim % 2 == 0\n\n    # use half of dimensions to encode grid_h\n    emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0])  # (H*W, D/2)\n    emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1])  # (H*W, D/2)\n\n    emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D)\n    return emb\n\n\ndef get_1d_sincos_pos_embed_from_grid(embed_dim, pos):\n    \"\"\"\n    embed_dim: output dimension for each position\n    pos: a list of positions to be encoded: size (M,)\n    out: (M, D)\n    \"\"\"\n    assert embed_dim % 2 == 0\n    omega = np.arange(embed_dim // 2, dtype=np.float)\n    omega /= embed_dim / 2.\n    omega = 1. / 10000**omega  # (D/2,)\n\n    pos = pos.reshape(-1)  # (M,)\n    out = np.einsum('m,d->md', pos, omega)  # (M, D/2), outer product\n\n    emb_sin = np.sin(out) # (M, D/2)\n    emb_cos = np.cos(out) # (M, D/2)\n\n    emb = np.concatenate([emb_sin, emb_cos], axis=1)  # (M, D)\n    return emb\n\n\n# --------------------------------------------------------\n# Interpolate position embeddings for high-resolution\n# References:\n# DeiT: https://github.com/facebookresearch/deit\n# --------------------------------------------------------\ndef interpolate_pos_embed(model, checkpoint_model):\n    if 'pos_embed' in checkpoint_model:\n        pos_embed_checkpoint = checkpoint_model['pos_embed']\n        embedding_size = pos_embed_checkpoint.shape[-1]\n        num_patches = model.patch_embed.num_patches\n        num_extra_tokens = model.pos_embed.shape[-2] - num_patches\n        # height (== width) for the checkpoint position embedding\n        orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)\n        # height (== width) for the new position embedding\n        new_size = int(num_patches ** 0.5)\n        # class_token and dist_token are kept unchanged\n        if orig_size != new_size:\n            print(\"Position interpolate from %dx%d to %dx%d\" % (orig_size, orig_size, new_size, new_size))\n            extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]\n            # only the position tokens are interpolated\n            pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]\n            pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)\n            pos_tokens = torch.nn.functional.interpolate(\n                pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)\n            pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)\n            new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)\n            checkpoint_model['pos_embed'] = new_pos_embed\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco/builder.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport torch\nimport torch.nn as nn\n\n\nclass MoCo(nn.Module):\n    \"\"\"\n    Build a MoCo model with: a query encoder, a key encoder, and a queue\n    https://arxiv.org/abs/1911.05722\n    \"\"\"\n    def __init__(self, base_encoder, dim=128, K=65536, m=0.999, T=0.07, mlp=False, bands='all'):\n        \"\"\"\n        dim: feature dimension (default: 128)\n        K: queue size; number of negative keys (default: 65536)\n        m: moco momentum of updating key encoder (default: 0.999)\n        T: softmax temperature (default: 0.07)\n        \"\"\"\n        super(MoCo, self).__init__()\n\n        self.K = K\n        self.m = m\n        self.T = T\n\n        # create the encoders\n        # num_classes is the output fc dimension\n        self.encoder_q = base_encoder(num_classes=dim)\n        self.encoder_k = base_encoder(num_classes=dim)\n\n        if bands=='B12':\n            self.encoder_q.conv1 = torch.nn.Conv2d(12,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(12,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n        elif bands=='B13':\n            #self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            #self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n        elif bands=='B15':\n            #self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            #self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            self.encoder_q.conv1 = torch.nn.Conv2d(15,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(15,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n        elif bands=='B2':\n            #self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            #self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            self.encoder_q.conv1 = torch.nn.Conv2d(2,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(2,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            \n            \n            #self.encoder_q.maxpool = torch.nn.Identity()\n            #self.encoder_k.maxpool = torch.nn.Identity()\n\n        if mlp:  # hack: brute-force replacement\n            dim_mlp = self.encoder_q.fc.weight.shape[1]\n            self.encoder_q.fc = nn.Sequential(nn.Linear(dim_mlp, dim_mlp), nn.ReLU(), self.encoder_q.fc)\n            self.encoder_k.fc = nn.Sequential(nn.Linear(dim_mlp, dim_mlp), nn.ReLU(), self.encoder_k.fc)\n\n        for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):\n            param_k.data.copy_(param_q.data)  # initialize\n            param_k.requires_grad = False  # not update by gradient\n\n        # create the queue\n        self.register_buffer(\"queue\", torch.randn(dim, K))\n        self.queue = nn.functional.normalize(self.queue, dim=0)\n\n        self.register_buffer(\"queue_ptr\", torch.zeros(1, dtype=torch.long))\n\n    @torch.no_grad()\n    def _momentum_update_key_encoder(self):\n        \"\"\"\n        Momentum update of the key encoder\n        \"\"\"\n        for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):\n            param_k.data = param_k.data * self.m + param_q.data * (1. - self.m)\n\n    @torch.no_grad()\n    def _dequeue_and_enqueue(self, keys):\n        # gather keys before updating queue\n        keys = concat_all_gather(keys)\n\n        batch_size = keys.shape[0]\n\n        ptr = int(self.queue_ptr)\n        assert self.K % batch_size == 0  # for simplicity\n\n        # replace the keys at ptr (dequeue and enqueue)\n        self.queue[:, ptr:ptr + batch_size] = keys.T\n        ptr = (ptr + batch_size) % self.K  # move pointer\n\n        self.queue_ptr[0] = ptr\n\n    @torch.no_grad()\n    def _batch_shuffle_ddp(self, x):\n        \"\"\"\n        Batch shuffle, for making use of BatchNorm.\n        *** Only support DistributedDataParallel (DDP) model. ***\n        \"\"\"\n        # gather from all gpus\n        batch_size_this = x.shape[0]\n        x_gather = concat_all_gather(x)\n        batch_size_all = x_gather.shape[0]\n\n        num_gpus = batch_size_all // batch_size_this\n\n        # random shuffle index\n        idx_shuffle = torch.randperm(batch_size_all).cuda()\n\n        # broadcast to all gpus\n        torch.distributed.broadcast(idx_shuffle, src=0)\n\n        # index for restoring\n        idx_unshuffle = torch.argsort(idx_shuffle)\n\n        # shuffled index for this gpu\n        gpu_idx = torch.distributed.get_rank()\n        idx_this = idx_shuffle.view(num_gpus, -1)[gpu_idx]\n\n        return x_gather[idx_this], idx_unshuffle\n\n    @torch.no_grad()\n    def _batch_unshuffle_ddp(self, x, idx_unshuffle):\n        \"\"\"\n        Undo batch shuffle.\n        *** Only support DistributedDataParallel (DDP) model. ***\n        \"\"\"\n        # gather from all gpus\n        batch_size_this = x.shape[0]\n        x_gather = concat_all_gather(x)\n        batch_size_all = x_gather.shape[0]\n\n        num_gpus = batch_size_all // batch_size_this\n\n        # restored index for this gpu\n        gpu_idx = torch.distributed.get_rank()\n        idx_this = idx_unshuffle.view(num_gpus, -1)[gpu_idx]\n\n        return x_gather[idx_this]\n\n    def forward(self, im_q, im_k):\n        \"\"\"\n        Input:\n            im_q: a batch of query images\n            im_k: a batch of key images\n        Output:\n            logits, targets\n        \"\"\"\n\n        # compute query features\n        q = self.encoder_q(im_q)  # queries: NxC\n        q = nn.functional.normalize(q, dim=1)\n\n        # compute key features\n        with torch.no_grad():  # no gradient to keys\n            self._momentum_update_key_encoder()  # update the key encoder\n\n            # shuffle for making use of BN\n            im_k, idx_unshuffle = self._batch_shuffle_ddp(im_k)\n\n            k = self.encoder_k(im_k)  # keys: NxC\n            k = nn.functional.normalize(k, dim=1)\n\n            # undo shuffle\n            k = self._batch_unshuffle_ddp(k, idx_unshuffle)\n\n        # compute logits\n        # Einstein sum is more intuitive\n        # positive logits: Nx1\n        l_pos = torch.einsum('nc,nc->n', [q, k]).unsqueeze(-1)\n        # negative logits: NxK\n        l_neg = torch.einsum('nc,ck->nk', [q, self.queue.clone().detach()])\n\n        # logits: Nx(1+K)\n        logits = torch.cat([l_pos, l_neg], dim=1)\n\n        # apply temperature\n        logits /= self.T\n\n        # labels: positive key indicators\n        labels = torch.zeros(logits.shape[0], dtype=torch.long).cuda()\n\n        # dequeue and enqueue\n        self._dequeue_and_enqueue(k)\n\n        return logits, labels\n\n\n# utils\n@torch.no_grad()\ndef concat_all_gather(tensor):\n    \"\"\"\n    Performs all_gather operation on the provided tensors.\n    *** Warning ***: torch.distributed.all_gather has no gradient.\n    \"\"\"\n    tensors_gather = [torch.ones_like(tensor)\n        for _ in range(torch.distributed.get_world_size())]\n    torch.distributed.all_gather(tensors_gather, tensor, async_op=False)\n\n    output = torch.cat(tensors_gather, dim=0)\n    return output\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco/loader.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nfrom PIL import ImageFilter\nimport random\nimport cv2\n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n    def __init__(self, base_transform):\n        self.base_transform = base_transform\n\n    def __call__(self, x):\n        q = self.base_transform(x)\n        k = self.base_transform(x)\n        return [q, k]\n\n\nclass GaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, sigma=[.1, 2.]):\n        self.sigma = sigma\n\n    def __call__(self, x):\n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/README.md",
    "content": "## MoCo: Momentum Contrast for Unsupervised Visual Representation Learning\n\n<p align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/11435359/71603927-0ca98d00-2b14-11ea-9fd8-10d984a2de45.png\" width=\"300\">\n</p>\n\nThis is a PyTorch implementation of the [MoCo paper](https://arxiv.org/abs/1911.05722):\n```\n@Article{he2019moco,\n  author  = {Kaiming He and Haoqi Fan and Yuxin Wu and Saining Xie and Ross Girshick},\n  title   = {Momentum Contrast for Unsupervised Visual Representation Learning},\n  journal = {arXiv preprint arXiv:1911.05722},\n  year    = {2019},\n}\n```\nIt also includes the implementation of the [MoCo v2 paper](https://arxiv.org/abs/2003.04297):\n```\n@Article{chen2020mocov2,\n  author  = {Xinlei Chen and Haoqi Fan and Ross Girshick and Kaiming He},\n  title   = {Improved Baselines with Momentum Contrastive Learning},\n  journal = {arXiv preprint arXiv:2003.04297},\n  year    = {2020},\n}\n```\n\n\n### Preparation\n\nInstall PyTorch and ImageNet dataset following the [official PyTorch ImageNet training code](https://github.com/pytorch/examples/tree/master/imagenet).\n\nThis repo aims to be minimal modifications on that code. Check the modifications by:\n```\ndiff main_moco.py <(curl https://raw.githubusercontent.com/pytorch/examples/master/imagenet/main.py)\ndiff main_lincls.py <(curl https://raw.githubusercontent.com/pytorch/examples/master/imagenet/main.py)\n```\n\n\n### Unsupervised Training\n\nThis implementation only supports **multi-gpu**, **DistributedDataParallel** training, which is faster and simpler; single-gpu or DataParallel training is not supported.\n\nTo do unsupervised pre-training of a ResNet-50 model on ImageNet in an 8-gpu machine, run:\n```\npython main_moco.py \\\n  -a resnet50 \\\n  --lr 0.03 \\\n  --batch-size 256 \\\n  --dist-url 'tcp://localhost:10001' --multiprocessing-distributed --world-size 1 --rank 0 \\\n  [your imagenet-folder with train and val folders]\n```\nThis script uses all the default hyper-parameters as described in the MoCo v1 paper. To run MoCo v2, set `--mlp --moco-t 0.2 --aug-plus --cos`.\n\n***Note***: for 4-gpu training, we recommend following the [linear lr scaling recipe](https://arxiv.org/abs/1706.02677): `--lr 0.015 --batch-size 128` with 4 gpus. We got similar results using this setting.\n\n\n### Linear Classification\n\nWith a pre-trained model, to train a supervised linear classifier on frozen features/weights in an 8-gpu machine, run:\n```\npython main_lincls.py \\\n  -a resnet50 \\\n  --lr 30.0 \\\n  --batch-size 256 \\\n  --pretrained [your checkpoint path]/checkpoint_0199.pth.tar \\\n  --dist-url 'tcp://localhost:10001' --multiprocessing-distributed --world-size 1 --rank 0 \\\n  [your imagenet-folder with train and val folders]\n```\n\nLinear classification results on ImageNet using this repo with 8 NVIDIA V100 GPUs :\n<table><tbody>\n<!-- START TABLE -->\n<!-- TABLE HEADER -->\n<th valign=\"bottom\"></th>\n<th valign=\"bottom\">pre-train<br/>epochs</th>\n<th valign=\"bottom\">pre-train<br/>time</th>\n<th valign=\"bottom\">MoCo v1<br/>top-1 acc.</th>\n<th valign=\"bottom\">MoCo v2<br/>top-1 acc.</th>\n<!-- TABLE BODY -->\n<tr><td align=\"left\">ResNet-50</td>\n<td align=\"center\">200</td>\n<td align=\"center\">53 hours</td>\n<td align=\"center\">60.8&plusmn;0.2</td>\n<td align=\"center\">67.5&plusmn;0.1</td>\n</tr>\n</tbody></table>\n\nHere we run 5 trials (of pre-training and linear classification) and report mean&plusmn;std: the 5 results of MoCo v1 are {60.6, 60.6, 60.7, 60.9, 61.1}, and of MoCo v2 are {67.7, 67.6, 67.4, 67.6, 67.3}.\n\n\n### Models\n\nOur pre-trained ResNet-50 models can be downloaded as following:\n<table><tbody>\n<!-- START TABLE -->\n<!-- TABLE HEADER -->\n<th valign=\"bottom\"></th>\n<th valign=\"bottom\">epochs</th>\n<th valign=\"bottom\">mlp</th>\n<th valign=\"bottom\">aug+</th>\n<th valign=\"bottom\">cos</th>\n<th valign=\"bottom\">top-1 acc.</th>\n<th valign=\"bottom\">model</th>\n<th valign=\"bottom\">md5</th>\n<!-- TABLE BODY -->\n<tr><td align=\"left\"><a href=\"https://arxiv.org/abs/1911.05722\">MoCo v1</a></td>\n<td align=\"center\">200</td>\n<td align=\"center\"></td>\n<td align=\"center\"></td>\n<td align=\"center\"></td>\n<td align=\"center\">60.6</td>\n<td align=\"center\"><a href=\"https://dl.fbaipublicfiles.com/moco/moco_checkpoints/moco_v1_200ep/moco_v1_200ep_pretrain.pth.tar\">download</a></td>\n<td align=\"center\"><tt>b251726a</tt></td>\n</tr>\n<tr><td align=\"left\"><a href=\"https://arxiv.org/abs/2003.04297\">MoCo v2</a></td>\n<td align=\"center\">200</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">67.7</td>\n<td align=\"center\"><a href=\"https://dl.fbaipublicfiles.com/moco/moco_checkpoints/moco_v2_200ep/moco_v2_200ep_pretrain.pth.tar\">download</a></td>\n<td align=\"center\"><tt>59fd9945</tt></td>\n</tr>\n<tr><td align=\"left\"><a href=\"https://arxiv.org/abs/2003.04297\">MoCo v2</a></td>\n<td align=\"center\">800</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">&#x2713</td>\n<td align=\"center\">71.1</td>\n<td align=\"center\"><a href=\"https://dl.fbaipublicfiles.com/moco/moco_checkpoints/moco_v2_800ep/moco_v2_800ep_pretrain.pth.tar\">download</a></td>\n<td align=\"center\"><tt>a04e12f8</tt></td>\n</tr>\n</tbody></table>\n\n\n### Transferring to Object Detection\n\nSee [./detection](detection).\n\n\n### License\n\nThis project is under the CC-BY-NC 4.0 license. See [LICENSE](LICENSE) for details.\n\n### See Also\n* [moco.tensorflow](https://github.com/ppwwyyxx/moco.tensorflow): A TensorFlow re-implementation.\n* [Colab notebook](https://colab.research.google.com/github/facebookresearch/moco/blob/colab-notebook/colab/moco_cifar10_demo.ipynb): CIFAR demo on Colab GPU.\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/__init__.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/builder.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport torch\nimport torch.nn as nn\n\n\nclass MoCo(nn.Module):\n    \"\"\"\n    Build a MoCo model with: a query encoder, a key encoder, and a queue\n    https://arxiv.org/abs/1911.05722\n    \"\"\"\n    def __init__(self, base_encoder, dim=128, K=65536, m=0.999, T=0.07, mlp=False, bands='all'):\n        \"\"\"\n        dim: feature dimension (default: 128)\n        K: queue size; number of negative keys (default: 65536)\n        m: moco momentum of updating key encoder (default: 0.999)\n        T: softmax temperature (default: 0.07)\n        \"\"\"\n        super(MoCo, self).__init__()\n\n        self.K = K\n        self.m = m\n        self.T = T\n\n        # create the encoders\n        # num_classes is the output fc dimension\n        self.encoder_q = base_encoder(num_classes=dim)\n        self.encoder_k = base_encoder(num_classes=dim)\n\n        if bands=='B12':\n            self.encoder_q.conv1 = torch.nn.Conv2d(12,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(12,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n        elif bands=='B13':\n            #self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            #self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(3,3),stride=(1,1),padding=(1,1),bias=False)\n            self.encoder_q.conv1 = torch.nn.Conv2d(13,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            self.encoder_k.conv1 = torch.nn.Conv2d(13,64,kernel_size=(7,7),stride=(2,2),padding=(3,3),bias=False)\n            \n            #self.encoder_q.maxpool = torch.nn.Identity()\n            #self.encoder_k.maxpool = torch.nn.Identity()\n\n        if mlp:  # hack: brute-force replacement\n            dim_mlp = self.encoder_q.fc.weight.shape[1]\n            self.encoder_q.fc = nn.Sequential(nn.Linear(dim_mlp, dim_mlp), nn.ReLU(), self.encoder_q.fc)\n            self.encoder_k.fc = nn.Sequential(nn.Linear(dim_mlp, dim_mlp), nn.ReLU(), self.encoder_k.fc)\n\n        for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):\n            param_k.data.copy_(param_q.data)  # initialize\n            param_k.requires_grad = False  # not update by gradient\n\n        # create the queue\n        self.register_buffer(\"queue\", torch.randn(dim, K))\n        self.queue = nn.functional.normalize(self.queue, dim=0)\n\n        self.register_buffer(\"queue_ptr\", torch.zeros(1, dtype=torch.long))\n\n    @torch.no_grad()\n    def _momentum_update_key_encoder(self):\n        \"\"\"\n        Momentum update of the key encoder\n        \"\"\"\n        for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()):\n            param_k.data = param_k.data * self.m + param_q.data * (1. - self.m)\n\n    @torch.no_grad()\n    def _dequeue_and_enqueue(self, keys):\n        # gather keys before updating queue\n        keys = concat_all_gather(keys)\n\n        batch_size = keys.shape[0]\n\n        ptr = int(self.queue_ptr)\n        assert self.K % batch_size == 0  # for simplicity\n\n        # replace the keys at ptr (dequeue and enqueue)\n        self.queue[:, ptr:ptr + batch_size] = keys.T\n        ptr = (ptr + batch_size) % self.K  # move pointer\n\n        self.queue_ptr[0] = ptr\n\n    @torch.no_grad()\n    def _batch_shuffle_ddp(self, x):\n        \"\"\"\n        Batch shuffle, for making use of BatchNorm.\n        *** Only support DistributedDataParallel (DDP) model. ***\n        \"\"\"\n        # gather from all gpus\n        batch_size_this = x.shape[0]\n        x_gather = concat_all_gather(x)\n        batch_size_all = x_gather.shape[0]\n\n        num_gpus = batch_size_all // batch_size_this\n\n        # random shuffle index\n        idx_shuffle = torch.randperm(batch_size_all).cuda()\n\n        # broadcast to all gpus\n        torch.distributed.broadcast(idx_shuffle, src=0)\n\n        # index for restoring\n        idx_unshuffle = torch.argsort(idx_shuffle)\n\n        # shuffled index for this gpu\n        gpu_idx = torch.distributed.get_rank()\n        idx_this = idx_shuffle.view(num_gpus, -1)[gpu_idx]\n\n        return x_gather[idx_this], idx_unshuffle\n\n    @torch.no_grad()\n    def _batch_unshuffle_ddp(self, x, idx_unshuffle):\n        \"\"\"\n        Undo batch shuffle.\n        *** Only support DistributedDataParallel (DDP) model. ***\n        \"\"\"\n        # gather from all gpus\n        batch_size_this = x.shape[0]\n        x_gather = concat_all_gather(x)\n        batch_size_all = x_gather.shape[0]\n\n        num_gpus = batch_size_all // batch_size_this\n\n        # restored index for this gpu\n        gpu_idx = torch.distributed.get_rank()\n        idx_this = idx_unshuffle.view(num_gpus, -1)[gpu_idx]\n\n        return x_gather[idx_this]\n\n    def forward(self, im_q, im_k):\n        \"\"\"\n        Input:\n            im_q: a batch of query images\n            im_k: a batch of key images\n        Output:\n            logits, targets\n        \"\"\"\n\n        # compute query features\n        q = self.encoder_q(im_q)  # queries: NxC\n        q = nn.functional.normalize(q, dim=1)\n\n        # compute key features\n        with torch.no_grad():  # no gradient to keys\n            self._momentum_update_key_encoder()  # update the key encoder\n\n            # shuffle for making use of BN\n            im_k, idx_unshuffle = self._batch_shuffle_ddp(im_k)\n\n            k = self.encoder_k(im_k)  # keys: NxC\n            k = nn.functional.normalize(k, dim=1)\n\n            # undo shuffle\n            k = self._batch_unshuffle_ddp(k, idx_unshuffle)\n\n        # compute logits\n        # Einstein sum is more intuitive\n        # positive logits: Nx1\n        l_pos = torch.einsum('nc,nc->n', [q, k]).unsqueeze(-1)\n        # negative logits: NxK\n        l_neg = torch.einsum('nc,ck->nk', [q, self.queue.clone().detach()])\n\n        # logits: Nx(1+K)\n        logits = torch.cat([l_pos, l_neg], dim=1)\n\n        # apply temperature\n        logits /= self.T\n\n        # labels: positive key indicators\n        labels = torch.zeros(logits.shape[0], dtype=torch.long).cuda()\n\n        # dequeue and enqueue\n        self._dequeue_and_enqueue(k)\n\n        return logits, labels\n\n\n# utils\n@torch.no_grad()\ndef concat_all_gather(tensor):\n    \"\"\"\n    Performs all_gather operation on the provided tensors.\n    *** Warning ***: torch.distributed.all_gather has no gradient.\n    \"\"\"\n    tensors_gather = [torch.ones_like(tensor)\n        for _ in range(torch.distributed.get_world_size())]\n    torch.distributed.all_gather(tensors_gather, tensor, async_op=False)\n\n    output = torch.cat(tensors_gather, dim=0)\n    return output\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/detection/README.md",
    "content": "\n## MoCo: Transferring to Detection\n\nThe `train_net.py` script reproduces the object detection experiments on Pascal VOC and COCO.\n\n### Instruction\n\n1. Install [detectron2](https://github.com/facebookresearch/detectron2/blob/master/INSTALL.md).\n\n1. Convert a pre-trained MoCo model to detectron2's format:\n   ```\n   python3 convert-pretrain-to-detectron2.py input.pth.tar output.pkl\n   ```\n\n1. Put dataset under \"./datasets\" directory,\n   following the [directory structure](https://github.com/facebookresearch/detectron2/tree/master/datasets)\n\t requried by detectron2.\n\n1. Run training:\n   ```\n   python train_net.py --config-file configs/pascal_voc_R_50_C4_24k_moco.yaml \\\n\t--num-gpus 8 MODEL.WEIGHTS ./output.pkl\n   ```\n\n### Results\n\nBelow are the results on Pascal VOC 2007 test, fine-tuned on 2007+2012 trainval for 24k iterations using Faster R-CNN with a R50-C4 backbone:\n\n<table><tbody>\n<!-- START TABLE -->\n<!-- TABLE HEADER -->\n<th valign=\"bottom\">pretrain</th>\n<th valign=\"bottom\">AP50</th>\n<th valign=\"bottom\">AP</th>\n<th valign=\"bottom\">AP75</th>\n<!-- TABLE BODY -->\n<tr><td align=\"left\">ImageNet-1M, supervised</td>\n<td align=\"center\">81.3</td>\n<td align=\"center\">53.5</td>\n<td align=\"center\">58.8</td>\n</tr>\n<tr><td align=\"left\">ImageNet-1M, MoCo v1, 200ep</td>\n<td align=\"center\">81.5</td>\n<td align=\"center\">55.9</td>\n<td align=\"center\">62.6</td>\n</tr>\n</tr>\n<tr><td align=\"left\">ImageNet-1M, MoCo v2, 200ep</td>\n<td align=\"center\">82.4</td>\n<td align=\"center\">57.0</td>\n<td align=\"center\">63.6</td>\n</tr>\n</tr>\n<tr><td align=\"left\">ImageNet-1M, MoCo v2, 800ep</td>\n<td align=\"center\">82.5</td>\n<td align=\"center\">57.4</td>\n<td align=\"center\">64.0</td>\n</tr>\n</tbody></table>\n\n***Note:*** These results are means of 5 trials. Variation on Pascal VOC is large: the std of AP50, AP, AP75 is expected to be 0.2, 0.2, 0.4 in most cases. We recommend to run 5 trials and compute means.\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/detection/configs/Base-RCNN-C4-BN.yaml",
    "content": "MODEL:\n  META_ARCHITECTURE: \"GeneralizedRCNN\"\n  RPN:\n    PRE_NMS_TOPK_TEST: 6000\n    POST_NMS_TOPK_TEST: 1000\n  ROI_HEADS:\n    NAME: \"Res5ROIHeadsExtraNorm\"\n  BACKBONE:\n    FREEZE_AT: 0\n  RESNETS:\n    NORM: \"SyncBN\"\nTEST:\n  PRECISE_BN:\n    ENABLED: True\nSOLVER:\n  IMS_PER_BATCH: 16\n  BASE_LR: 0.02\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/detection/configs/coco_R_50_C4_2x.yaml",
    "content": "_BASE_: \"Base-RCNN-C4-BN.yaml\"\nMODEL:\n  MASK_ON: True\n  WEIGHTS: \"detectron2://ImageNetPretrained/MSRA/R-50.pkl\"\nINPUT:\n  MIN_SIZE_TRAIN: (640, 672, 704, 736, 768, 800)\n  MIN_SIZE_TEST: 800\nDATASETS:\n  TRAIN: (\"coco_2017_train\",)\n  TEST: (\"coco_2017_val\",)\nSOLVER:\n  STEPS: (120000, 160000)\n  MAX_ITER: 180000\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/detection/configs/coco_R_50_C4_2x_moco.yaml",
    "content": "_BASE_: \"coco_R_50_C4_2x.yaml\"\nMODEL:\n  PIXEL_MEAN: [123.675, 116.280, 103.530]\n  PIXEL_STD: [58.395, 57.120, 57.375]\n  WEIGHTS: \"See Instructions\"\n  RESNETS:\n    STRIDE_IN_1X1: False\nINPUT:\n  FORMAT: \"RGB\"\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/detection/configs/pascal_voc_R_50_C4_24k.yaml",
    "content": "_BASE_: \"Base-RCNN-C4-BN.yaml\"\nMODEL:\n  MASK_ON: False\n  WEIGHTS: \"detectron2://ImageNetPretrained/MSRA/R-50.pkl\"\n  ROI_HEADS:\n    NUM_CLASSES: 20\nINPUT:\n  MIN_SIZE_TRAIN: (480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800)\n  MIN_SIZE_TEST: 800\nDATASETS:\n  TRAIN: ('voc_2007_trainval', 'voc_2012_trainval')\n  TEST: ('voc_2007_test',)\nSOLVER:\n  STEPS: (18000, 22000)\n  MAX_ITER: 24000\n  WARMUP_ITERS: 100\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/detection/configs/pascal_voc_R_50_C4_24k_moco.yaml",
    "content": "_BASE_: \"pascal_voc_R_50_C4_24k.yaml\"\nMODEL:\n  PIXEL_MEAN: [123.675, 116.280, 103.530]\n  PIXEL_STD: [58.395, 57.120, 57.375]\n  WEIGHTS: \"See Instructions\"\n  RESNETS:\n    STRIDE_IN_1X1: False\nINPUT:\n  FORMAT: \"RGB\"\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/detection/convert-pretrain-to-detectron2.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n\nimport pickle as pkl\nimport sys\nimport torch\n\nif __name__ == \"__main__\":\n    input = sys.argv[1]\n\n    obj = torch.load(input, map_location=\"cpu\")\n    obj = obj[\"state_dict\"]\n\n    newmodel = {}\n    for k, v in obj.items():\n        if not k.startswith(\"module.encoder_q.\"):\n            continue\n        old_k = k\n        k = k.replace(\"module.encoder_q.\", \"\")\n        if \"layer\" not in k:\n            k = \"stem.\" + k\n        for t in [1, 2, 3, 4]:\n            k = k.replace(\"layer{}\".format(t), \"res{}\".format(t + 1))\n        for t in [1, 2, 3]:\n            k = k.replace(\"bn{}\".format(t), \"conv{}.norm\".format(t))\n        k = k.replace(\"downsample.0\", \"shortcut\")\n        k = k.replace(\"downsample.1\", \"shortcut.norm\")\n        print(old_k, \"->\", k)\n        newmodel[k] = v.numpy()\n\n    res = {\"model\": newmodel, \"__author__\": \"MOCO\", \"matching_heuristics\": True}\n\n    with open(sys.argv[2], \"wb\") as f:\n        pkl.dump(res, f)\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/detection/train_net.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n\nimport os\n\nfrom detectron2.checkpoint import DetectionCheckpointer\nfrom detectron2.config import get_cfg\nfrom detectron2.engine import DefaultTrainer, default_argument_parser, default_setup, launch\nfrom detectron2.evaluation import COCOEvaluator, PascalVOCDetectionEvaluator\nfrom detectron2.layers import get_norm\nfrom detectron2.modeling.roi_heads import ROI_HEADS_REGISTRY, Res5ROIHeads\n\n\n@ROI_HEADS_REGISTRY.register()\nclass Res5ROIHeadsExtraNorm(Res5ROIHeads):\n    \"\"\"\n    As described in the MOCO paper, there is an extra BN layer\n    following the res5 stage.\n    \"\"\"\n    def _build_res5_block(self, cfg):\n        seq, out_channels = super()._build_res5_block(cfg)\n        norm = cfg.MODEL.RESNETS.NORM\n        norm = get_norm(norm, out_channels)\n        seq.add_module(\"norm\", norm)\n        return seq, out_channels\n\n\nclass Trainer(DefaultTrainer):\n    @classmethod\n    def build_evaluator(cls, cfg, dataset_name, output_folder=None):\n        if output_folder is None:\n            output_folder = os.path.join(cfg.OUTPUT_DIR, \"inference\")\n        if \"coco\" in dataset_name:\n            return COCOEvaluator(dataset_name, cfg, True, output_folder)\n        else:\n            assert \"voc\" in dataset_name\n            return PascalVOCDetectionEvaluator(dataset_name)\n\n\ndef setup(args):\n    cfg = get_cfg()\n    cfg.merge_from_file(args.config_file)\n    cfg.merge_from_list(args.opts)\n    cfg.freeze()\n    default_setup(cfg, args)\n    return cfg\n\n\ndef main(args):\n    cfg = setup(args)\n\n    if args.eval_only:\n        model = Trainer.build_model(cfg)\n        DetectionCheckpointer(model, save_dir=cfg.OUTPUT_DIR).resume_or_load(\n            cfg.MODEL.WEIGHTS, resume=args.resume\n        )\n        res = Trainer.test(cfg, model)\n        return res\n\n    trainer = Trainer(cfg)\n    trainer.resume_or_load(resume=args.resume)\n    return trainer.train()\n\n\nif __name__ == \"__main__\":\n    args = default_argument_parser().parse_args()\n    print(\"Command Line Args:\", args)\n    launch(\n        main,\n        args.num_gpus,\n        num_machines=args.num_machines,\n        machine_rank=args.machine_rank,\n        dist_url=args.dist_url,\n        args=(args,),\n    )\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/loader.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nfrom PIL import ImageFilter\nimport random\nimport cv2\n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image as the query and key.\"\"\"\n\n    def __init__(self, base_transform):\n        self.base_transform = base_transform\n\n    def __call__(self, x):\n        q = self.base_transform(x)\n        k = self.base_transform(x)\n        return [q, k]\n\n\nclass GaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, sigma=[.1, 2.]):\n        self.sigma = sigma\n\n    def __call__(self, x):\n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v2/main_lincls.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport argparse\nimport builtins\nimport os\nimport random\nimport shutil\nimport time\nimport warnings\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.parallel\nimport torch.backends.cudnn as cudnn\nimport torch.distributed as dist\nimport torch.optim\nimport torch.multiprocessing as mp\nimport torch.utils.data\nimport torch.utils.data.distributed\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\nimport torchvision.models as models\n\nmodel_names = sorted(name for name in models.__dict__\n    if name.islower() and not name.startswith(\"__\")\n    and callable(models.__dict__[name]))\n\nparser = argparse.ArgumentParser(description='PyTorch ImageNet Training')\nparser.add_argument('data', metavar='DIR',\n                    help='path to dataset')\nparser.add_argument('-a', '--arch', metavar='ARCH', default='resnet50',\n                    choices=model_names,\n                    help='model architecture: ' +\n                        ' | '.join(model_names) +\n                        ' (default: resnet50)')\nparser.add_argument('-j', '--workers', default=32, type=int, metavar='N',\n                    help='number of data loading workers (default: 32)')\nparser.add_argument('--epochs', default=100, type=int, metavar='N',\n                    help='number of total epochs to run')\nparser.add_argument('--start-epoch', default=0, type=int, metavar='N',\n                    help='manual epoch number (useful on restarts)')\nparser.add_argument('-b', '--batch-size', default=256, type=int,\n                    metavar='N',\n                    help='mini-batch size (default: 256), this is the total '\n                         'batch size of all GPUs on the current node when '\n                         'using Data Parallel or Distributed Data Parallel')\nparser.add_argument('--lr', '--learning-rate', default=30., type=float,\n                    metavar='LR', help='initial learning rate', dest='lr')\nparser.add_argument('--schedule', default=[60, 80], nargs='*', type=int,\n                    help='learning rate schedule (when to drop lr by a ratio)')\nparser.add_argument('--momentum', default=0.9, type=float, metavar='M',\n                    help='momentum')\nparser.add_argument('--wd', '--weight-decay', default=0., type=float,\n                    metavar='W', help='weight decay (default: 0.)',\n                    dest='weight_decay')\nparser.add_argument('-p', '--print-freq', default=10, type=int,\n                    metavar='N', help='print frequency (default: 10)')\nparser.add_argument('--resume', default='', type=str, metavar='PATH',\n                    help='path to latest checkpoint (default: none)')\nparser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',\n                    help='evaluate model on validation set')\nparser.add_argument('--world-size', default=-1, type=int,\n                    help='number of nodes for distributed training')\nparser.add_argument('--rank', default=-1, type=int,\n                    help='node rank for distributed training')\nparser.add_argument('--dist-url', default='tcp://224.66.41.62:23456', type=str,\n                    help='url used to set up distributed training')\nparser.add_argument('--dist-backend', default='nccl', type=str,\n                    help='distributed backend')\nparser.add_argument('--seed', default=None, type=int,\n                    help='seed for initializing training. ')\nparser.add_argument('--gpu', default=None, type=int,\n                    help='GPU id to use.')\nparser.add_argument('--multiprocessing-distributed', action='store_true',\n                    help='Use multi-processing distributed training to launch '\n                         'N processes per node, which has N GPUs. This is the '\n                         'fastest way to use PyTorch for either single node or '\n                         'multi node data parallel training')\n\nparser.add_argument('--pretrained', default='', type=str,\n                    help='path to moco pretrained checkpoint')\n\nbest_acc1 = 0\n\n\ndef main():\n    args = parser.parse_args()\n\n    if args.seed is not None:\n        random.seed(args.seed)\n        torch.manual_seed(args.seed)\n        cudnn.deterministic = True\n        warnings.warn('You have chosen to seed training. '\n                      'This will turn on the CUDNN deterministic setting, '\n                      'which can slow down your training considerably! '\n                      'You may see unexpected behavior when restarting '\n                      'from checkpoints.')\n\n    if args.gpu is not None:\n        warnings.warn('You have chosen a specific GPU. This will completely '\n                      'disable data parallelism.')\n\n    if args.dist_url == \"env://\" and args.world_size == -1:\n        args.world_size = int(os.environ[\"WORLD_SIZE\"])\n\n    args.distributed = args.world_size > 1 or args.multiprocessing_distributed\n\n    ngpus_per_node = torch.cuda.device_count()\n    if args.multiprocessing_distributed:\n        # Since we have ngpus_per_node processes per node, the total world_size\n        # needs to be adjusted accordingly\n        args.world_size = ngpus_per_node * args.world_size\n        # Use torch.multiprocessing.spawn to launch distributed processes: the\n        # main_worker process function\n        mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args))\n    else:\n        # Simply call main_worker function\n        main_worker(args.gpu, ngpus_per_node, args)\n\n\ndef main_worker(gpu, ngpus_per_node, args):\n    global best_acc1\n    args.gpu = gpu\n\n    # suppress printing if not master\n    if args.multiprocessing_distributed and args.gpu != 0:\n        def print_pass(*args):\n            pass\n        builtins.print = print_pass\n\n    if args.gpu is not None:\n        print(\"Use GPU: {} for training\".format(args.gpu))\n\n    if args.distributed:\n        if args.dist_url == \"env://\" and args.rank == -1:\n            args.rank = int(os.environ[\"RANK\"])\n        if args.multiprocessing_distributed:\n            # For multiprocessing distributed training, rank needs to be the\n            # global rank among all the processes\n            args.rank = args.rank * ngpus_per_node + gpu\n        dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url,\n                                world_size=args.world_size, rank=args.rank)\n    # create model\n    print(\"=> creating model '{}'\".format(args.arch))\n    model = models.__dict__[args.arch]()\n\n    # freeze all layers but the last fc\n    for name, param in model.named_parameters():\n        if name not in ['fc.weight', 'fc.bias']:\n            param.requires_grad = False\n    # init the fc layer\n    model.fc.weight.data.normal_(mean=0.0, std=0.01)\n    model.fc.bias.data.zero_()\n\n    # load from pre-trained, before DistributedDataParallel constructor\n    if args.pretrained:\n        if os.path.isfile(args.pretrained):\n            print(\"=> loading checkpoint '{}'\".format(args.pretrained))\n            checkpoint = torch.load(args.pretrained, map_location=\"cpu\")\n\n            # rename moco pre-trained keys\n            state_dict = checkpoint['state_dict']\n            for k in list(state_dict.keys()):\n                # retain only encoder_q up to before the embedding layer\n                if k.startswith('module.encoder_q') and not k.startswith('module.encoder_q.fc'):\n                    # remove prefix\n                    state_dict[k[len(\"module.encoder_q.\"):]] = state_dict[k]\n                # delete renamed or unused k\n                del state_dict[k]\n\n            args.start_epoch = 0\n            msg = model.load_state_dict(state_dict, strict=False)\n            assert set(msg.missing_keys) == {\"fc.weight\", \"fc.bias\"}\n\n            print(\"=> loaded pre-trained model '{}'\".format(args.pretrained))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.pretrained))\n\n    if args.distributed:\n        # For multiprocessing distributed, DistributedDataParallel constructor\n        # should always set the single device scope, otherwise,\n        # DistributedDataParallel will use all available devices.\n        if args.gpu is not None:\n            torch.cuda.set_device(args.gpu)\n            model.cuda(args.gpu)\n            # When using a single GPU per process and per\n            # DistributedDataParallel, we need to divide the batch size\n            # ourselves based on the total number of GPUs we have\n            args.batch_size = int(args.batch_size / ngpus_per_node)\n            args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node)\n            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])\n        else:\n            model.cuda()\n            # DistributedDataParallel will divide and allocate batch_size to all\n            # available GPUs if device_ids are not set\n            model = torch.nn.parallel.DistributedDataParallel(model)\n    elif args.gpu is not None:\n        torch.cuda.set_device(args.gpu)\n        model = model.cuda(args.gpu)\n    else:\n        # DataParallel will divide and allocate batch_size to all available GPUs\n        if args.arch.startswith('alexnet') or args.arch.startswith('vgg'):\n            model.features = torch.nn.DataParallel(model.features)\n            model.cuda()\n        else:\n            model = torch.nn.DataParallel(model).cuda()\n\n    # define loss function (criterion) and optimizer\n    criterion = nn.CrossEntropyLoss().cuda(args.gpu)\n\n    # optimize only the linear classifier\n    parameters = list(filter(lambda p: p.requires_grad, model.parameters()))\n    assert len(parameters) == 2  # fc.weight, fc.bias\n    optimizer = torch.optim.SGD(parameters, args.lr,\n                                momentum=args.momentum,\n                                weight_decay=args.weight_decay)\n\n    # optionally resume from a checkpoint\n    if args.resume:\n        if os.path.isfile(args.resume):\n            print(\"=> loading checkpoint '{}'\".format(args.resume))\n            if args.gpu is None:\n                checkpoint = torch.load(args.resume)\n            else:\n                # Map model to be loaded to specified single gpu.\n                loc = 'cuda:{}'.format(args.gpu)\n                checkpoint = torch.load(args.resume, map_location=loc)\n            args.start_epoch = checkpoint['epoch']\n            best_acc1 = checkpoint['best_acc1']\n            if args.gpu is not None:\n                # best_acc1 may be from a checkpoint from a different GPU\n                best_acc1 = best_acc1.to(args.gpu)\n            model.load_state_dict(checkpoint['state_dict'])\n            optimizer.load_state_dict(checkpoint['optimizer'])\n            print(\"=> loaded checkpoint '{}' (epoch {})\"\n                  .format(args.resume, checkpoint['epoch']))\n        else:\n            print(\"=> no checkpoint found at '{}'\".format(args.resume))\n\n    cudnn.benchmark = True\n\n    # Data loading code\n    traindir = os.path.join(args.data, 'train')\n    valdir = os.path.join(args.data, 'val')\n    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                     std=[0.229, 0.224, 0.225])\n\n    train_dataset = datasets.ImageFolder(\n        traindir,\n        transforms.Compose([\n            transforms.RandomResizedCrop(224),\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            normalize,\n        ]))\n\n    if args.distributed:\n        train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)\n    else:\n        train_sampler = None\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None),\n        num_workers=args.workers, pin_memory=True, sampler=train_sampler)\n\n    val_loader = torch.utils.data.DataLoader(\n        datasets.ImageFolder(valdir, transforms.Compose([\n            transforms.Resize(256),\n            transforms.CenterCrop(224),\n            transforms.ToTensor(),\n            normalize,\n        ])),\n        batch_size=args.batch_size, shuffle=False,\n        num_workers=args.workers, pin_memory=True)\n\n    if args.evaluate:\n        validate(val_loader, model, criterion, args)\n        return\n\n    for epoch in range(args.start_epoch, args.epochs):\n        if args.distributed:\n            train_sampler.set_epoch(epoch)\n        adjust_learning_rate(optimizer, epoch, args)\n\n        # train for one epoch\n        train(train_loader, model, criterion, optimizer, epoch, args)\n\n        # evaluate on validation set\n        acc1 = validate(val_loader, model, criterion, args)\n\n        # remember best acc@1 and save checkpoint\n        is_best = acc1 > best_acc1\n        best_acc1 = max(acc1, best_acc1)\n\n        if not args.multiprocessing_distributed or (args.multiprocessing_distributed\n                and args.rank % ngpus_per_node == 0):\n            save_checkpoint({\n                'epoch': epoch + 1,\n                'arch': args.arch,\n                'state_dict': model.state_dict(),\n                'best_acc1': best_acc1,\n                'optimizer' : optimizer.state_dict(),\n            }, is_best)\n            if epoch == args.start_epoch:\n                sanity_check(model.state_dict(), args.pretrained)\n\n\ndef train(train_loader, model, criterion, optimizer, epoch, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    data_time = AverageMeter('Data', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(train_loader),\n        [batch_time, data_time, losses, top1, top5],\n        prefix=\"Epoch: [{}]\".format(epoch))\n\n    \"\"\"\n    Switch to eval mode:\n    Under the protocol of linear classification on frozen features/models,\n    it is not legitimate to change any part of the pre-trained model.\n    BatchNorm in train mode may revise running mean/std (even if it receives\n    no gradient), which are part of the model parameters too.\n    \"\"\"\n    model.eval()\n\n    end = time.time()\n    for i, (images, target) in enumerate(train_loader):\n        # measure data loading time\n        data_time.update(time.time() - end)\n\n        if args.gpu is not None:\n            images = images.cuda(args.gpu, non_blocking=True)\n        target = target.cuda(args.gpu, non_blocking=True)\n\n        # compute output\n        output = model(images)\n        loss = criterion(output, target)\n\n        # measure accuracy and record loss\n        acc1, acc5 = accuracy(output, target, topk=(1, 5))\n        losses.update(loss.item(), images.size(0))\n        top1.update(acc1[0], images.size(0))\n        top5.update(acc5[0], images.size(0))\n\n        # compute gradient and do SGD step\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        # measure elapsed time\n        batch_time.update(time.time() - end)\n        end = time.time()\n\n        if i % args.print_freq == 0:\n            progress.display(i)\n\n\ndef validate(val_loader, model, criterion, args):\n    batch_time = AverageMeter('Time', ':6.3f')\n    losses = AverageMeter('Loss', ':.4e')\n    top1 = AverageMeter('Acc@1', ':6.2f')\n    top5 = AverageMeter('Acc@5', ':6.2f')\n    progress = ProgressMeter(\n        len(val_loader),\n        [batch_time, losses, top1, top5],\n        prefix='Test: ')\n\n    # switch to evaluate mode\n    model.eval()\n\n    with torch.no_grad():\n        end = time.time()\n        for i, (images, target) in enumerate(val_loader):\n            if args.gpu is not None:\n                images = images.cuda(args.gpu, non_blocking=True)\n            target = target.cuda(args.gpu, non_blocking=True)\n\n            # compute output\n            output = model(images)\n            loss = criterion(output, target)\n\n            # measure accuracy and record loss\n            acc1, acc5 = accuracy(output, target, topk=(1, 5))\n            losses.update(loss.item(), images.size(0))\n            top1.update(acc1[0], images.size(0))\n            top5.update(acc5[0], images.size(0))\n\n            # measure elapsed time\n            batch_time.update(time.time() - end)\n            end = time.time()\n\n            if i % args.print_freq == 0:\n                progress.display(i)\n\n        # TODO: this should also be done with the ProgressMeter\n        print(' * Acc@1 {top1.avg:.3f} Acc@5 {top5.avg:.3f}'\n              .format(top1=top1, top5=top5))\n\n    return top1.avg\n\n\ndef save_checkpoint(state, is_best, filename='checkpoint.pth.tar'):\n    torch.save(state, filename)\n    if is_best:\n        shutil.copyfile(filename, 'model_best.pth.tar')\n\n\ndef sanity_check(state_dict, pretrained_weights):\n    \"\"\"\n    Linear classifier should not change any weights other than the linear layer.\n    This sanity check asserts nothing wrong happens (e.g., BN stats updated).\n    \"\"\"\n    print(\"=> loading '{}' for sanity check\".format(pretrained_weights))\n    checkpoint = torch.load(pretrained_weights, map_location=\"cpu\")\n    state_dict_pre = checkpoint['state_dict']\n\n    for k in list(state_dict.keys()):\n        # only ignore fc layer\n        if 'fc.weight' in k or 'fc.bias' in k:\n            continue\n\n        # name in pretrained model\n        k_pre = 'module.encoder_q.' + k[len('module.'):] \\\n            if k.startswith('module.') else 'module.encoder_q.' + k\n\n        assert ((state_dict[k].cpu() == state_dict_pre[k_pre]).all()), \\\n            '{} is changed in linear classifier training.'.format(k)\n\n    print(\"=> sanity check passed.\")\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self, name, fmt=':f'):\n        self.name = name\n        self.fmt = fmt\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count\n\n    def __str__(self):\n        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'\n        return fmtstr.format(**self.__dict__)\n\n\nclass ProgressMeter(object):\n    def __init__(self, num_batches, meters, prefix=\"\"):\n        self.batch_fmtstr = self._get_batch_fmtstr(num_batches)\n        self.meters = meters\n        self.prefix = prefix\n\n    def display(self, batch):\n        entries = [self.prefix + self.batch_fmtstr.format(batch)]\n        entries += [str(meter) for meter in self.meters]\n        print('\\t'.join(entries))\n\n    def _get_batch_fmtstr(self, num_batches):\n        num_digits = len(str(num_batches // 1))\n        fmt = '{:' + str(num_digits) + 'd}'\n        return '[' + fmt + '/' + fmt.format(num_batches) + ']'\n\n\ndef adjust_learning_rate(optimizer, epoch, args):\n    \"\"\"Decay the learning rate based on schedule\"\"\"\n    lr = args.lr\n    for milestone in args.schedule:\n        lr *= 0.1 if epoch >= milestone else 1.\n    for param_group in optimizer.param_groups:\n        param_group['lr'] = lr\n\n\ndef accuracy(output, target, topk=(1,)):\n    \"\"\"Computes the accuracy over the k top predictions for the specified values of k\"\"\"\n    with torch.no_grad():\n        maxk = max(topk)\n        batch_size = target.size(0)\n\n        _, pred = output.topk(maxk, 1, True, True)\n        pred = pred.t()\n        correct = pred.eq(target.view(1, -1).expand_as(pred))\n\n        res = []\n        for k in topk:\n            correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)\n            res.append(correct_k.mul_(100.0 / batch_size))\n        return res\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v3/__init__.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v3/builder.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport torch\nimport torch.nn as nn\n\n\nclass MoCo(nn.Module):\n    \"\"\"\n    Build a MoCo model with a base encoder, a momentum encoder, and two MLPs\n    https://arxiv.org/abs/1911.05722\n    \"\"\"\n    def __init__(self, base_encoder, dim=256, mlp_dim=4096, T=1.0):\n        \"\"\"\n        dim: feature dimension (default: 256)\n        mlp_dim: hidden dimension in MLPs (default: 4096)\n        T: softmax temperature (default: 1.0)\n        \"\"\"\n        super(MoCo, self).__init__()\n\n        self.T = T\n\n        # build encoders\n        self.base_encoder = base_encoder(num_classes=mlp_dim)\n        self.momentum_encoder = base_encoder(num_classes=mlp_dim)\n\n        self._build_projector_and_predictor_mlps(dim, mlp_dim)\n\n        for param_b, param_m in zip(self.base_encoder.parameters(), self.momentum_encoder.parameters()):\n            param_m.data.copy_(param_b.data)  # initialize\n            param_m.requires_grad = False  # not update by gradient\n\n    def _build_mlp(self, num_layers, input_dim, mlp_dim, output_dim, last_bn=True):\n        mlp = []\n        for l in range(num_layers):\n            dim1 = input_dim if l == 0 else mlp_dim\n            dim2 = output_dim if l == num_layers - 1 else mlp_dim\n\n            mlp.append(nn.Linear(dim1, dim2, bias=False))\n\n            if l < num_layers - 1:\n                mlp.append(nn.BatchNorm1d(dim2))\n                mlp.append(nn.ReLU(inplace=True))\n            elif last_bn:\n                # follow SimCLR's design: https://github.com/google-research/simclr/blob/master/model_util.py#L157\n                # for simplicity, we further removed gamma in BN\n                mlp.append(nn.BatchNorm1d(dim2, affine=False))\n\n        return nn.Sequential(*mlp)\n\n    def _build_projector_and_predictor_mlps(self, dim, mlp_dim):\n        pass\n\n    @torch.no_grad()\n    def _update_momentum_encoder(self, m):\n        \"\"\"Momentum update of the momentum encoder\"\"\"\n        for param_b, param_m in zip(self.base_encoder.parameters(), self.momentum_encoder.parameters()):\n            param_m.data = param_m.data * m + param_b.data * (1. - m)\n\n    def contrastive_loss(self, q, k):\n        # normalize\n        q = nn.functional.normalize(q, dim=1)\n        k = nn.functional.normalize(k, dim=1)\n        # gather all targets\n        k = concat_all_gather(k)\n        # Einstein sum is more intuitive\n        logits = torch.einsum('nc,mc->nm', [q, k]) / self.T\n        N = logits.shape[0]  # batch size per GPU\n        labels = (torch.arange(N, dtype=torch.long) + N * torch.distributed.get_rank()).cuda()\n        return nn.CrossEntropyLoss()(logits, labels) * (2 * self.T)\n\n    def forward(self, x1, x2, m):\n        \"\"\"\n        Input:\n            x1: first views of images\n            x2: second views of images\n            m: moco momentum\n        Output:\n            loss\n        \"\"\"\n\n        # compute features\n        q1 = self.predictor(self.base_encoder(x1))\n        q2 = self.predictor(self.base_encoder(x2))\n\n        with torch.no_grad():  # no gradient\n            self._update_momentum_encoder(m)  # update the momentum encoder\n\n            # compute momentum features as targets\n            k1 = self.momentum_encoder(x1)\n            k2 = self.momentum_encoder(x2)\n\n        return self.contrastive_loss(q1, k2) + self.contrastive_loss(q2, k1)\n\n\nclass MoCo_ResNet(MoCo):\n    def _build_projector_and_predictor_mlps(self, dim, mlp_dim):\n        hidden_dim = self.base_encoder.fc.weight.shape[1]\n        del self.base_encoder.fc, self.momentum_encoder.fc # remove original fc layer\n\n        # projectors\n        self.base_encoder.fc = self._build_mlp(2, hidden_dim, mlp_dim, dim)\n        self.momentum_encoder.fc = self._build_mlp(2, hidden_dim, mlp_dim, dim)\n\n        # predictor\n        self.predictor = self._build_mlp(2, dim, mlp_dim, dim, False)\n\n\nclass MoCo_ViT(MoCo):\n    def _build_projector_and_predictor_mlps(self, dim, mlp_dim):\n        hidden_dim = self.base_encoder.head.weight.shape[1]\n        del self.base_encoder.head, self.momentum_encoder.head # remove original fc layer\n\n        # projectors\n        self.base_encoder.head = self._build_mlp(3, hidden_dim, mlp_dim, dim)\n        self.momentum_encoder.head = self._build_mlp(3, hidden_dim, mlp_dim, dim)\n\n        # predictor\n        self.predictor = self._build_mlp(2, dim, mlp_dim, dim)\n\n\n# utils\n@torch.no_grad()\ndef concat_all_gather(tensor):\n    \"\"\"\n    Performs all_gather operation on the provided tensors.\n    *** Warning ***: torch.distributed.all_gather has no gradient.\n    \"\"\"\n    tensors_gather = [torch.ones_like(tensor)\n        for _ in range(torch.distributed.get_world_size())]\n    torch.distributed.all_gather(tensors_gather, tensor, async_op=False)\n\n    output = torch.cat(tensors_gather, dim=0)\n    return output\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v3/loader.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nfrom PIL import Image, ImageFilter, ImageOps\nimport math\nimport random\nimport torchvision.transforms.functional as tf\n\nimport cv2\n\nclass TwoCropsTransform:\n    \"\"\"Take two random crops of one image\"\"\"\n\n    def __init__(self, base_transform1, base_transform2):\n        self.base_transform1 = base_transform1\n        self.base_transform2 = base_transform2\n\n    def __call__(self, x):\n        im1 = self.base_transform1(x)\n        im2 = self.base_transform2(x)\n        return [im1, im2]\n\n\nclass GaussianBlur(object):\n    \"\"\"Gaussian blur augmentation from SimCLR: https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, sigma=[.1, 2.]):\n        self.sigma = sigma\n\n    def __call__(self, x):\n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)\n\n\nclass Solarize(object):\n    \"\"\"Solarize augmentation from BYOL: https://arxiv.org/abs/2006.07733\"\"\"\n\n    def __call__(self, x):\n        return ImageOps.solarize(x)\n        \n        \n        \n        \n        \nclass cvGaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, p=0.5, sigma=[.1, 2.]):\n        self.sigma = sigma\n        self.prob = p\n\n    def __call__(self, x):\n        do_it = random.random() <= self.prob\n        if not do_it:\n            return x        \n    \n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v3/optimizer.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport torch\n\n\nclass LARS(torch.optim.Optimizer):\n    \"\"\"\n    LARS optimizer, no rate scaling or weight decay for parameters <= 1D.\n    \"\"\"\n    def __init__(self, params, lr=0, weight_decay=0, momentum=0.9, trust_coefficient=0.001):\n        defaults = dict(lr=lr, weight_decay=weight_decay, momentum=momentum, trust_coefficient=trust_coefficient)\n        super().__init__(params, defaults)\n\n    @torch.no_grad()\n    def step(self):\n        for g in self.param_groups:\n            for p in g['params']:\n                dp = p.grad\n\n                if dp is None:\n                    continue\n\n                if p.ndim > 1: # if not normalization gamma/beta or bias\n                    dp = dp.add(p, alpha=g['weight_decay'])\n                    param_norm = torch.norm(p)\n                    update_norm = torch.norm(dp)\n                    one = torch.ones_like(param_norm)\n                    q = torch.where(param_norm > 0.,\n                                    torch.where(update_norm > 0,\n                                    (g['trust_coefficient'] * param_norm / update_norm), one),\n                                    one)\n                    dp = dp.mul(q)\n\n                param_state = self.state[p]\n                if 'mu' not in param_state:\n                    param_state['mu'] = torch.zeros_like(p)\n                mu = param_state['mu']\n                mu.mul_(g['momentum']).add_(dp)\n                p.add_(mu, alpha=-g['lr'])\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/moco_v3/vits.py",
    "content": "# Copyright (c) Facebook, Inc. and its affiliates.\n# All rights reserved.\n\n# This source code is licensed under the license found in the\n# LICENSE file in the root directory of this source tree.\n\nimport math\nimport torch\nimport torch.nn as nn\nfrom functools import partial, reduce\nfrom operator import mul\n\nfrom timm.models.vision_transformer import VisionTransformer, _cfg\nfrom timm.models.layers.helpers import to_2tuple\nfrom timm.models.layers import PatchEmbed\n\n__all__ = [\n    'vit_small', \n    'vit_base',\n    'vit_conv_small',\n    'vit_conv_base',\n]\n\n\nclass VisionTransformerMoCo(VisionTransformer):\n    def __init__(self, stop_grad_conv1=False, **kwargs):\n        super().__init__(**kwargs)\n        # Use fixed 2D sin-cos position embedding\n        self.build_2d_sincos_position_embedding()\n\n        # weight initialization\n        for name, m in self.named_modules():\n            if isinstance(m, nn.Linear):\n                if 'qkv' in name:\n                    # treat the weights of Q, K, V separately\n                    val = math.sqrt(6. / float(m.weight.shape[0] // 3 + m.weight.shape[1]))\n                    nn.init.uniform_(m.weight, -val, val)\n                else:\n                    nn.init.xavier_uniform_(m.weight)\n                nn.init.zeros_(m.bias)\n        nn.init.normal_(self.cls_token, std=1e-6)\n\n        if isinstance(self.patch_embed, PatchEmbed):\n            # xavier_uniform initialization\n            val = math.sqrt(6. / float(3 * reduce(mul, self.patch_embed.patch_size, 1) + self.embed_dim))\n            nn.init.uniform_(self.patch_embed.proj.weight, -val, val)\n            nn.init.zeros_(self.patch_embed.proj.bias)\n\n            if stop_grad_conv1:\n                self.patch_embed.proj.weight.requires_grad = False\n                self.patch_embed.proj.bias.requires_grad = False\n\n    def build_2d_sincos_position_embedding(self, temperature=10000.):\n        h, w = self.patch_embed.grid_size\n        grid_w = torch.arange(w, dtype=torch.float32)\n        grid_h = torch.arange(h, dtype=torch.float32)\n        grid_w, grid_h = torch.meshgrid(grid_w, grid_h)\n        assert self.embed_dim % 4 == 0, 'Embed dimension must be divisible by 4 for 2D sin-cos position embedding'\n        pos_dim = self.embed_dim // 4\n        omega = torch.arange(pos_dim, dtype=torch.float32) / pos_dim\n        omega = 1. / (temperature**omega)\n        out_w = torch.einsum('m,d->md', [grid_w.flatten(), omega])\n        out_h = torch.einsum('m,d->md', [grid_h.flatten(), omega])\n        pos_emb = torch.cat([torch.sin(out_w), torch.cos(out_w), torch.sin(out_h), torch.cos(out_h)], dim=1)[None, :, :]\n\n        assert self.num_tokens == 1, 'Assuming one and only one token, [cls]'\n        pe_token = torch.zeros([1, 1, self.embed_dim], dtype=torch.float32)\n        self.pos_embed = nn.Parameter(torch.cat([pe_token, pos_emb], dim=1))\n        self.pos_embed.requires_grad = False\n\n\nclass ConvStem(nn.Module):\n    \"\"\" \n    ConvStem, from Early Convolutions Help Transformers See Better, Tete et al. https://arxiv.org/abs/2106.14881\n    \"\"\"\n    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768, norm_layer=None, flatten=True):\n        super().__init__()\n\n        assert patch_size == 16, 'ConvStem only supports patch size of 16'\n        assert embed_dim % 8 == 0, 'Embed dimension must be divisible by 8 for ConvStem'\n\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.grid_size = (img_size[0] // patch_size[0], img_size[1] // patch_size[1])\n        self.num_patches = self.grid_size[0] * self.grid_size[1]\n        self.flatten = flatten\n\n        # build stem, similar to the design in https://arxiv.org/abs/2106.14881\n        stem = []\n        input_dim, output_dim = 3, embed_dim // 8\n        for l in range(4):\n            stem.append(nn.Conv2d(input_dim, output_dim, kernel_size=3, stride=2, padding=1, bias=False))\n            stem.append(nn.BatchNorm2d(output_dim))\n            stem.append(nn.ReLU(inplace=True))\n            input_dim = output_dim\n            output_dim *= 2\n        stem.append(nn.Conv2d(input_dim, embed_dim, kernel_size=1))\n        self.proj = nn.Sequential(*stem)\n\n        self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n        assert H == self.img_size[0] and W == self.img_size[1], \\\n            f\"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]}).\"\n        x = self.proj(x)\n        if self.flatten:\n            x = x.flatten(2).transpose(1, 2)  # BCHW -> BNC\n        x = self.norm(x)\n        return x\n\n## original moco_v3 has 12 num_heads\ndef vit_small(**kwargs):\n    model = VisionTransformerMoCo(\n        patch_size=16, embed_dim=384, depth=12, num_heads=6, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\ndef vit_base(**kwargs):\n    model = VisionTransformerMoCo(\n        patch_size=16, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\ndef vit_conv_small(**kwargs):\n    # minus one ViT block\n    model = VisionTransformerMoCo(\n        patch_size=16, embed_dim=384, depth=11, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), embed_layer=ConvStem, **kwargs)\n    model.default_cfg = _cfg()\n    return model\n\ndef vit_conv_base(**kwargs):\n    # minus one ViT block\n    model = VisionTransformerMoCo(\n        patch_size=16, embed_dim=768, depth=11, num_heads=12, mlp_ratio=4, qkv_bias=True,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6), embed_layer=ConvStem, **kwargs)\n    model.default_cfg = _cfg()\n    return model"
  },
  {
    "path": "src/benchmark/transfer_classification/models/rs_transforms_float32.py",
    "content": "import numpy as np\nimport torch\nimport random\n\n\n\nclass RandomBrightness(object):\n    \"\"\" Random Brightness \"\"\"\n    \n    def __init__(self, brightness=0.4):\n        self.brightness = brightness\n\n    def __call__(self, sample):\n        s = np.random.uniform(max(0, 1 - self.brightness), 1 + self.brightness)\n        img = sample * s\n        \n        return img\n    \nclass RandomContrast(object):\n    \"\"\" Random Contrast \"\"\"\n    \n    def __init__(self, contrast=0.4):\n        self.contrast = contrast\n\n    def __call__(self, sample):\n        s = np.random.uniform(max(0, 1 - self.contrast), 1 + self.contrast)\n        mean = np.mean(sample, axis=(0, 1))\n        \n        return ((sample - mean) * s + mean)\n    \nclass ToGray(object):\n    def __init__(self, out_channels):\n        self.out_channels = out_channels\n    def __call__(self,sample):\n        gray_img = np.mean(sample, axis=-1)\n        gray_img = np.tile(gray_img, (self.out_channels, 1, 1))\n        gray_img = np.transpose(gray_img, [1, 2, 0])\n        return gray_img\n        \n        \nclass RandomChannelDrop(object):\n    \"\"\" Random Channel Drop \"\"\"\n    \n    def __init__(self, min_n_drop=1, max_n_drop=8):\n        self.min_n_drop = min_n_drop\n        self.max_n_drop = max_n_drop\n\n    def __call__(self, sample):\n        n_channels = random.randint(self.min_n_drop, self.max_n_drop)\n        channels = np.random.choice(range(sample.shape[0]), size=n_channels, replace=False)\n\n        for c in channels:\n            sample[c, :, :] = 0        \n        return sample        \n\n\n"
  },
  {
    "path": "src/benchmark/transfer_classification/models/rs_transforms_uint8.py",
    "content": "import numpy as np\nimport torch\nimport random\nimport cv2\n\n\nclass RandomBrightness(object):\n    \"\"\" Random Brightness \"\"\"\n    \n    def __init__(self, brightness=0.4):\n        self.brightness = brightness\n\n    def __call__(self, sample):\n        s = np.random.uniform(max(0, 1 - self.brightness), 1 + self.brightness)\n        img = sample * s\n        \n        return img.astype(np.uint8)\n    \nclass RandomContrast(object):\n    \"\"\" Random Contrast \"\"\"\n    \n    def __init__(self, contrast=0.4):\n        self.contrast = contrast\n\n    def __call__(self, sample):\n        s = np.random.uniform(max(0, 1 - self.contrast), 1 + self.contrast)\n        mean = np.mean(sample, axis=(0, 1))\n        \n        return ((sample - mean) * s + mean).astype(np.uint8)\n    \nclass ToGray(object):\n    def __init__(self, out_channels):\n        self.out_channels = out_channels\n    def __call__(self,sample):\n        gray_img = np.mean(sample, axis=-1)\n        gray_img = np.tile(gray_img, (self.out_channels, 1, 1))\n        gray_img = np.transpose(gray_img, [1, 2, 0])\n        return gray_img.astype(np.uint8)\n        \n        \nclass RandomChannelDrop(object):\n    \"\"\" Random Channel Drop \"\"\"\n    \n    def __init__(self, min_n_drop=1, max_n_drop=8):\n        self.min_n_drop = min_n_drop\n        self.max_n_drop = max_n_drop\n\n    def __call__(self, sample):\n        n_channels = random.randint(self.min_n_drop, self.max_n_drop)\n        channels = np.random.choice(range(sample.shape[0]), size=n_channels, replace=False)\n\n        for c in channels:\n            sample[c, :, :] = 0        \n        return sample        \n\n\nclass GaussianBlur(object):\n    \"\"\"Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709\"\"\"\n\n    def __init__(self, sigma=[.1, 2.]):\n        self.sigma = sigma\n\n    def __call__(self, x):\n        sigma = random.uniform(self.sigma[0], self.sigma[1])\n        #x = x.filter(ImageFilter.GaussianBlur(radius=sigma))\n        #return x\n        return cv2.GaussianBlur(x,(0,0),sigma)\n        \n        \nclass Solarize(object):\n\n    def __init__(self, threshold=0.5):\n        self.threshold = threshold\n        \n    def __call__(self, x):\n        x1 = x.copy()          \n        one = np.ones(x.shape) * 255\n        x1[x<self.threshold] = one[x<self.threshold] - x[x<self.threshold]\n        \n        return x1.astype(np.uint8)\n        \nclass RandomSensorDrop_S1S2(object):\n    \"\"\" Random Channel Drop \"\"\"\n    \n    def __init__(self):\n        pass\n\n    def __call__(self, sample):\n        sensor = np.random.choice([1,2], replace=False)\n\n        if sensor==2:\n            sample[:13, :, :] = 0\n        elif sensor==1:\n            sample[13:,:,:] = 0\n        \n        return sample\n    \nclass SensorDrop_S1S2(object):\n    def __init__(self, sensor):\n        self.sensor = sensor\n    def __call__(self,sample):\n        if self.sensor == 'S1':\n            sample[13:,:,:] = 0\n        elif self.sensor == 'S2':\n            sample[:13,:,:] = 0\n        return sample\n    \n    \nclass RandomSensorDrop_RGBD(object):\n    \"\"\" Random Channel Drop \"\"\"\n    \n    def __init__(self):\n        pass\n\n    def __call__(self, sample):\n        sensor = np.random.choice([1,2], replace=False, p=[0.8,0.2])\n\n        if sensor==2:\n            sample[:3, :, :] = 0\n        elif sensor==1:\n            sample[3:,:,:] = 0\n        \n        return sample\n    \nclass SensorDrop_RGBD(object):\n    def __init__(self, sensor):\n        self.sensor = sensor\n    def __call__(self,sample):\n        if self.sensor == 'D':\n            sample[3:,:,:] = 0\n        elif self.sensor == 'RGB':\n            sample[:3,:,:] = 0\n        return sample"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_ImageNet_ft_moco-v2-ep800_pad_rn50_s2c_BE_10.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/ImageNet_BE_moco-v2-ep800_pad_FT_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/ImageNet_BE_moco-v2-ep800_pad_FT_rn50_10_%j.err\n#SBATCH --time=02:00:00\n#SBATCH --job-name=BE_FT_IN\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_sup.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands B12 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/ImageNet_BE_ft_B12_moco-v2-ep800_pad_rn50_10 \\\n--backbone resnet50 \\\n--train_frac 0.1 \\\n--batchsize 64 \\\n--lr 0.05 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/pretrained_weights/rn50_B3_moco-v2_imagenet_800ep.pth \\\n--pretrain_style pad \\\n#--linear \\\n#--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_10/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_ImageNet_lc_moco-v2-ep200_pad_rn50_s2c_BE_10.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/ImageNet_BE_moco-v2-ep200_pad_LC_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/ImageNet_BE_moco-v2-ep200_pad_LC_rn50_10_%j.err\n#SBATCH --time=02:00:00\n#SBATCH --job-name=BE_LC_IN\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_sup.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands B12 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/ImageNet_BE_lc_B12_moco-v2-ep200_pad_rn50_10 \\\n--backbone resnet50 \\\n--train_frac 0.1 \\\n--batchsize 256 \\\n--lr 8.0 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/pretrained_weights/rn50_B3_moco-v2_imagenet_200ep.pth \\\n--pretrain_style pad \\\n#--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_10/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_ImageNet_lc_moco-v2-ep800_pad_rn50_s2c_BE_10.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/ImageNet_BE_moco-v2-ep800_pad_LC_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/ImageNet_BE_moco-v2-ep800_pad_LC_rn50_10_%j.err\n#SBATCH --time=02:00:00\n#SBATCH --job-name=BE_LC_IN\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_sup.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands B12 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/ImageNet_BE_lc_B12_moco-v2-ep800_pad_rn50_10 \\\n--backbone resnet50 \\\n--train_frac 0.1 \\\n--batchsize 256 \\\n--lr 16 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/pretrained_weights/rn50_B3_moco-v2_imagenet_800ep.pth \\\n--pretrain_style pad \\\n#--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_10/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_ImageNet_lc_sup_pad_rn50_s2c_BE_10.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/ImageNet_BE_sup_pad_LC_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/ImageNet_BE_sup_pad_LC_rn50_10_%j.err\n#SBATCH --time=02:00:00\n#SBATCH --job-name=BE_LC_IN\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_sup.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands B12 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/ImageNet_BE_lc_B12_sup_pad_rn50_10 \\\n--backbone resnet50 \\\n--train_frac 0.1 \\\n--batchsize 256 \\\n--lr 8.0 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/pretrained_weights/rn50_B3_sup_imagenet_600ep.pth \\\n--pretrain_style pad \\\n#--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_10/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_ImageNet_lc_sup_reinit_rn50_s2c_BE_10.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/ImageNet_BE_sup_reinit_LC_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/ImageNet_BE_sup_reinit_LC_rn50_10_%j.err\n#SBATCH --time=02:00:00\n#SBATCH --job-name=BE_LC_IN\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_sup.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands B12 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/ImageNet_BE_lc_B12_sup_reinit_rn50_10 \\\n--backbone resnet50 \\\n--train_frac 0.1 \\\n--batchsize 256 \\\n--lr 8.0 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/pretrained_weights/rn50_B3_sup_imagenet_600ep.pth \\\n--pretrain_style reinit \\\n#--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_10/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SEN12MS_lc_moco_rn50_rgb_BE_10.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SEN12MS_BE_B3_moco_LC_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/SEN12MS_BE_B3_moco_LC_rn50_10_%j.err\n#SBATCH --time=03:00:00\n#SBATCH --job-name=BE_LC_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands RGB \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B3_moco_rn50_10 \\\n--backbone resnet50 \\\n--train_frac 0.1 \\\n--batchsize 256 \\\n--lr 8.0 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B3_rn50_224/checkpoint_0099.pth.tar \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_10_r112/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SEN12MS_lc_moco_rn50_rgb_BE_100.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SEN12MS_BE_B3_moco_LC_rn50_100_%j.out\n#SBATCH --error=srun_outputs/classification/SEN12MS_BE_B3_moco_LC_rn50_100_%j.err\n#SBATCH --time=04:00:00\n#SBATCH --job-name=BE_LC_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands RGB \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B3_moco_rn50_100 \\\n--backbone resnet50 \\\n--train_frac 1 \\\n--batchsize 256 \\\n--lr 8.0 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B3_rn50_224/checkpoint_0099.pth.tar \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_10_r112/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SEN12MS_lc_moco_rn50_rgb_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SEN12MS_EU_B3_moco_LC_rn50_%j.out\n#SBATCH --error=srun_outputs/classification/SEN12MS_EU_B3_moco_LC_rn50_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_lc_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_moco.py \\\n--data_dir /p/project/hai_dm4eo/wang_yi/data/eurosat/tif/ \\\n--bands RGB \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_EU_lc_B3_moco_rn50 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.1 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B3_rn50_224/checkpoint_0099.pth.tar \\\n--in_size 224 \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SEN12MS_lc_moco_rn50_s2c_BE_10.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SEN12MS_BE_moco_LC_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/SEN12MS_BE_moco_LC_rn50_10_%j.err\n#SBATCH --time=03:00:00\n#SBATCH --job-name=BE_LC_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands all \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_10 \\\n--backbone resnet50 \\\n--train_frac 0.1 \\\n--batchsize 256 \\\n--lr 8.0 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B13_rn50_224/checkpoint_0099.pth.tar \\\n--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_10/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SEN12MS_lc_moco_rn50_s2c_BE_100.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SEN12MS_BE_moco_LC_rn50_100_%j.out\n#SBATCH --error=srun_outputs/classification/SEN12MS_BE_moco_LC_rn50_100_%j.err\n#SBATCH --time=04:00:00\n#SBATCH --job-name=BE_LC_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands all \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_100 \\\n--backbone resnet50 \\\n--train_frac 1 \\\n--batchsize 256 \\\n--lr 8.0 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B13_rn50_224/checkpoint_0099.pth.tar \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_10_r112/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SEN12MS_lc_moco_rn50_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SEN12MS_EU_moco_LC_rn50_%j.out\n#SBATCH --error=srun_outputs/classification/SEN12MS_EU_moco_LC_rn50_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_lc_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_moco.py \\\n--data_dir /p/project/hai_dm4eo/wang_yi/data/eurosat/tif/ \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_EU_lc_B13_moco_rn50 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.1 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SEN12MS_B13_rn50_224/checkpoint_0099.pth.tar \\\n--in_size 224 \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SeCo_lc_moco_rn50_s2c_BE_10.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SeCo_BE_moco_LC_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/SeCo_BE_moco_LC_rn50_10_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=BE_LC_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands B12 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SeCo_BE_lc_B12_moco_rn50_10 \\\n--backbone resnet50 \\\n--train_frac 0.1 \\\n--batchsize 256 \\\n--lr 0.1 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SeCo_B12_rn50_224/checkpoint_0099.pth.tar \\\n#--resume /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SEN12MS_BE_lc_B13_moco_rn50_10/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SeCo_lc_moco_rn50_s2c_BE_100.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SeCo_BE_moco_LC_rn50_100_%j.out\n#SBATCH --error=srun_outputs/classification/SeCo_BE_moco_LC_rn50_100_%j.err\n#SBATCH --time=02:00:00\n#SBATCH --job-name=BE_LC_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco.py \\\n--lmdb_dir /p/project/hai_dm4eo/wang_yi/data/BigEarthNet/ \\\n--bands B12 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SeCo_BE_lc_B12_moco_rn50_100 \\\n--backbone resnet50 \\\n--train_frac 1 \\\n--batchsize 256 \\\n--lr 1.0 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SeCo_B12_rn50_224/checkpoint_0099.pth.tar \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_10_r112/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/ablation/srun_SeCo_lc_moco_rn50_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SeCo_EU_moco_LC_rn50_%j.out\n#SBATCH --error=srun_outputs/classification/SeCo_EU_moco_LC_rn50_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_lc_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nexport SRUN_CPUS_PER_TASK=${SLURM_CPUS_PER_TASK}\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_moco.py \\\n--data_dir /p/project/hai_dm4eo/wang_yi/data/eurosat/tif/ \\\n--bands B12 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/transfer_classification/checkpoints/SeCo_EU_lc_B12_moco_rn50 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.5 \\\n--schedule 20 40 \\\n--epochs 50 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/SSL4EO-S12/src/benchmark/pretrain_ssl/checkpoints/moco/SeCo_B12_rn50_224/checkpoint_0099.pth.tar \\\n--in_size 224 \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/ft_data2vec_vit16_s2c_BE_100.sh",
    "content": "OMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=4 linear_BE_data2vec.py \\\n        --model beit_small_patch16_224 \\\n        --finetune /p/project/hai_ssl4eo/nassim/data2vec/experiments/data2vec/pretrain/output/checkpoint-99.pth \\\n        --train_frac 1.0 \\\n        --data_path '/p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8' \\\n        --output_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_ft/BE_vits16' --log_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_ft/BE_vits16/logs' \\\n        --batch_size 64 --lr 1e-3 --update_freq 1 \\\n        --warmup_epochs 10 --epochs 100 --layer_decay 0.65 --drop_path 0.2 --drop 0.0 \\\n        --weight_decay 0.0001 --nb_classes 19 \\\n        --target_layer -1 --world_size 1 --dist_url 'tcp://localhost:10002'"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/ft_data2vec_vits16_s2c_EU_100.sh",
    "content": "OMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=4 linear_EU_data2vec.py \\\n        --model beit_small_patch16_224 \\\n        --finetune /p/project/hai_ssl4eo/nassim/data2vec/experiments/data2vec/pretrain/output/checkpoint-99.pth \\\n        --train_frac 1.0 \\\n        --data_path '/p/scratch/hai_ssl4eo/data/eurosat/tif' \\\n        --output_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_ft/EU_vits16' --log_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_ft/EU_vits16/logs' \\\n        --batch_size 64 --lr 1e-3  --update_freq 1 \\\n        --warmup_epochs 10 --epochs 100 --layer_decay 0.65 --drop_path 0.2 --drop 0.0 \\\n        --weight_decay 0.0001 --nb_classes 10 \\\n        --target_layer -1 --world_size 1 --dist_url 'tcp://localhost:10002'"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/ft_data2vec_vits16_s2c_SS_100.sh",
    "content": "OMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=4 linear_SS_data2vec.py \\\n        --model beit_small_patch16_224 \\\n        --finetune /p/project/hai_ssl4eo/nassim/data2vec/experiments/data2vec/pretrain/output/checkpoint-99.pth \\\n        --bands 'B13' \\\n        --onehot \\\n        --train_frac 1.0 \\\n        --data_path '/p/scratch/hai_ssl4eo/data/so2sat-lcz42' \\\n        --output_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_ft/SS_vits16' --log_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_ft/SS_vits16/logs' \\\n        --batch_size 64 --lr 1e-3  --update_freq 1 \\\n        --warmup_epochs 10 --epochs 100 --layer_decay 0.65 --drop_path 0.2 --drop 0.0 \\\n        --weight_decay 0.0001 --nb_classes 17 \\\n        --target_layer -1 --world_size 1 --dist_url 'tcp://localhost:10002'"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/lc_data2vec_vit16_s2c_BE_100.sh",
    "content": "OMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=4 linear_BE_data2vec.py \\\n        --model beit_small_patch16_224 \\\n        --finetune /p/project/hai_ssl4eo/nassim/data2vec/experiments/data2vec/pretrain/output/checkpoint-99.pth \\\n        --linear_classifier \\\n        --train_frac 1.0 \\\n        --data_path '/p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8' \\\n        --output_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_lc/BE_vits16' --log_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_lc/BE_vits16/logs' \\\n        --batch_size 64 --lr 1e-3 --update_freq 1 \\\n        --warmup_epochs 10 --epochs 100 --layer_decay 0.65 --drop_path 0.2 --drop 0.0 \\\n        --weight_decay 0.0001 --nb_classes 19 \\\n        --target_layer -1 --world_size 1 --dist_url 'tcp://localhost:10002'"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/lc_data2vec_vits16_s2c_EU_100.sh",
    "content": "OMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=4 linear_EU_data2vec.py \\\n        --model beit_small_patch16_224 \\\n        --finetune /p/project/hai_ssl4eo/nassim/data2vec/experiments/data2vec/pretrain/output/checkpoint-99.pth \\\n        --linear_classifier \\\n        --train_frac 1.0 \\\n        --data_path '/p/scratch/hai_ssl4eo/data/eurosat/tif' \\\n        --output_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_lc/EU_vits16' --log_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_lc/EU_vits16/logs' \\\n        --batch_size 64 --lr 0.1 --update_freq 1 \\\n        --warmup_epochs 10 --epochs 100 --layer_decay 0.65 --drop_path 0.2 --drop 0.0 \\\n        --weight_decay 0.0001 --nb_classes 10 \\\n        --target_layer -1 --world_size 1 --dist_url 'tcp://localhost:10002'"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/lc_data2vec_vits16_s2c_SS_100.sh",
    "content": "OMP_NUM_THREADS=1 python -m torch.distributed.launch --nproc_per_node=4 linear_SS_data2vec.py \\\n        --model beit_small_patch16_224 \\\n        --finetune /p/project/hai_ssl4eo/nassim/data2vec/experiments/data2vec/pretrain/output/checkpoint-99.pth \\\n        --linear_classifier \\\n        --bands 'B13' \\\n        --onehot \\\n        --train_frac 0.1 \\\n        --data_path '/p/scratch/hai_ssl4eo/data/so2sat-lcz42' \\\n        --output_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_lc/SS_vits16' --log_dir '/p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/data2vec_lc/SS_vits16/logs' \\\n        --batch_size 64 --lr 0.1 --update_freq 1 \\\n        --warmup_epochs 10 --epochs 100 --layer_decay 0.65 --drop_path 0.2 --drop 0.0 \\\n        --weight_decay 0.0001 --nb_classes 17 \\\n        --target_layer -1 --world_size 1 --dist_url 'tcp://localhost:10002'"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_rn50_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_dino_FT_rn50_lr3_%j.out\n#SBATCH --error=srun_outputs/classification/BE_dino_FT_rn50_lr3_%j.err\n#SBATCH --time=06:00:00\n#SBATCH --job-name=BE_FT_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u finetune_BE_dino.py \\\n--data_path /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/dino_ft/BE_rn50_lr3 \\\n--arch resnet50 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.01 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_rn50_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_rn50_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_dino_FT_rn50_lr3_%j.out\n#SBATCH --error=srun_outputs/classification/EU_dino_FT_rn50_lr3_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u finetune_EU_dino.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints//dino_ft/EU_rn50_lr3 \\\n--arch resnet50 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.001 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_rn50_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_rn50_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_dino_FT_rn50_lr12_%j.out\n#SBATCH --error=srun_outputs/classification/SS_dino_FT_rn50_lr12_%j.err\n#SBATCH --time=18:00:00\n#SBATCH --job-name=SS_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u finetune_SS_dino.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/dino_ft/SS_rn50_lr12 \\\n--arch resnet50 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.000003 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_rn50_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_vits16_s2_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_dino_FT_vits16_lr2_%j.out\n#SBATCH --error=srun_outputs/classification/BE_dino_FT_vits16_lr2_%j.err\n#SBATCH --time=22:00:00\n#SBATCH --job-name=BE_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u finetune_BE_dino.py \\\n--data /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/dino_ft/BE_vits16_lr2 \\\n--arch vit_small \\\n--train_frac 1.0 \\\n--patch_size 16 \\\n--batch_size_per_gpu 64 \\\n--lr 0.01 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_vits16_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_vits16_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_dino_FT_vits16_lr3_%j.out\n#SBATCH --error=srun_outputs/classification/EU_dino_FT_vits16_lr3_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_FT_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u finetune_EU_dino.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/dino_ft/EU_vits16_lr3 \\\n--arch vit_small \\\n--patch_size 16 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.001 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_vits16_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_dino_vits16_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_dino_FT_vits16_lr7_%j.out\n#SBATCH --error=srun_outputs/classification/SS_dino_FT_vits16_lr7_%j.err\n#SBATCH --time=18:00:00\n#SBATCH --job-name=SS_FT_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u finetune_SS_dino.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/dino_ft/SS_vits16_lr7 \\\n--arch vit_small \\\n--patch_size 16 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.00003 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_vits16_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_mae_vits16_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_mae_FT_vits16_lr1_decay1_%j.out\n#SBATCH --error=srun_outputs/classification/BE_mae_FT_vits16_lr1_decay1_%j.err\n#SBATCH --time=18:00:00\n#SBATCH --job-name=BE_FT_mae_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_mae.py \\\n--is_slurm_job \\\n--data_path /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--output_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/mae_ft/BE_vits16_lr1_decay1 \\\n--log_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/mae_ft/BE_vits16_lr1_decay1/log \\\n--model vit_small_patch16 \\\n--nb_classes 19 \\\n--train_frac 1.0 \\\n--num_workers 10 \\\n--batch_size 64 \\\n--epochs 100 \\\n--lr 0.1 \\\n--weight_decay 0.00001 \\\n--warmup_epochs 10 \\\n--dist_url $dist_url \\\n--dist_backend 'nccl' \\\n--seed 42 \\\n--finetune /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae/B13_vits16_70/checkpoint-99.pth \\\n--fine_tune \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_mae_vits16_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_mae_FT_vits16_70_lr1_decay_%j.out\n#SBATCH --error=srun_outputs/classification/EU_mae_FT_vits16_70_lr1_decay_%j.err\n#SBATCH --time=02:00:00\n#SBATCH --job-name=EU_LC_mae_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_mae.py \\\n--is_slurm_job \\\n--data_path /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--output_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/mae_ft/EU_vits16_lr1_decay \\\n--log_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/mae_ft/EU_vits16_lr1_decay/log \\\n--model vit_small_patch16 \\\n--nb_classes 10 \\\n--train_frac 1.0 \\\n--num_workers 10 \\\n--batch_size 64 \\\n--epochs 100 \\\n--lr 0.1 \\\n--weight_decay 0.0001 \\\n--warmup_epochs 10 \\\n--dist_url $dist_url \\\n--dist_backend 'nccl' \\\n--seed 42 \\\n--finetune /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae/B13_vits16_70/checkpoint-99.pth \\\n--fine_tune \\\n\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_mae_vits16_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_mae_FT_vits16_70_lr1_decay_%j.out\n#SBATCH --error=srun_outputs/classification/SS_mae_FT_vits16_70_lr1_decay_%j.err\n#SBATCH --time=22:00:00\n#SBATCH --job-name=SS_LC_mae_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_SS_mae.py \\\n--is_slurm_job \\\n--data_path /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--output_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/mae_ft/SS_vits16_lr1_decay \\\n--log_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/mae_ft/SS_vits16_lr1_decay/log \\\n--model vit_small_patch16 \\\n--nb_classes 17 \\\n--train_frac 1.0 \\\n--num_workers 10 \\\n--batch_size 64 \\\n--epochs 100 \\\n--lr 0.1 \\\n--weight_decay 0.0001 \\\n--warmup_epochs 10 \\\n--dist_url $dist_url \\\n--dist_backend 'nccl' \\\n--seed 42 \\\n--finetune /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae/B13_vits16_70/checkpoint-99.pth \\\n--fine_tune \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_rn50_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_moco_FT_rn50_%j.out\n#SBATCH --error=srun_outputs/classification/BE_moco_FT_rn50_%j.err\n#SBATCH --time=03:00:00\n#SBATCH --job-name=BE_FT_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco.py \\\n--lmdb_dir /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--bands all \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_ft/BE_rn50 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.1 \\\n--cos \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn50/checkpoint_0099.pth.tar \\\n#--linear \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_10_r112/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_rn50_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_moco_FT_rn50_lr1_%j.out\n#SBATCH --error=srun_outputs/classification/EU_moco_FT_rn50_lr1_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_FT_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_moco.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/moco_ft/EU_rn50_lr1 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.1 \\\n--schedule 60 80 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn50/checkpoint_0099.pth.tar \\\n--in_size 224 \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_rn50_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_moco_FT_rn50_lr3_%j.out\n#SBATCH --error=srun_outputs/classification/SS_moco_FT_rn50_lr3_%j.err\n#SBATCH --time=16:00:00\n#SBATCH --job-name=SS_FT_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_SS_moco.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/moco_ft/SS_rn50_100_lr3 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.01 \\\n--schedule 60 80 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn50/checkpoint_0099.pth.tar \\\n--in_size 224 \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/SS_rn50_100/checkpoint_0049.pth.tar\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_vits16_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_moco_FT_vits16_%j.out\n#SBATCH --error=srun_outputs/classification/BE_moco_FT_vits16_%j.err\n#SBATCH --time=04:00:00\n#SBATCH --job-name=BE_FT_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco_v3.py \\\n--data /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--bands all \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_ft/BE_vits16 \\\n--arch vit_small \\\n--train_frac 1.0 \\\n--batch_size 64 \\\n--lr 0.01 \\\n--cos \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_vits16_224/checkpoint_0099.pth.tar \\\n#--linear \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_10_r112/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_vits16_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_moco_FT_vits16_lr1_%j.out\n#SBATCH --error=srun_outputs/classification/EU_moco_FT_vits16_lr1_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_ft_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_moco_v3.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/moco_ft/EU_vits16_lr1 \\\n--backbone vit_small \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.1 \\\n--cos \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--in_size 224 \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_vits16_224/checkpoint_0099.pth.tar \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_ft_moco_vits16_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_100_moco_FT_vits16_lr1%j.out\n#SBATCH --error=srun_outputs/classification/SS_100_moco_FT_vits16_lr1%j.err\n#SBATCH --time=22:00:00\n#SBATCH --job-name=SS_FT_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_SS_moco_v3.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/nassim/ssl-sentinel/src/benchmark/fullset_temp/checkpoints/moco_ft/SS_vits16_100_lr1 \\\n--backbone vit_small \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.1 \\\n--cos \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--in_size 224 \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_vits16_224/checkpoint_0099.pth.tar \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_dino_rn50_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_dino_LC_rn50_100_%j.out\n#SBATCH --error=srun_outputs/classification/BE_dino_LC_rn50_100_%j.err\n#SBATCH --time=10:00:00\n#SBATCH --job-name=BE_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_dino.py \\\n--data /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino_lc/BE_rn50_100 \\\n--arch resnet50 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.1 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_rn50_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_dino_rn50_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_dino_LC_rn50_10_%j.out\n#SBATCH --error=srun_outputs/classification/EU_dino_LC_rn50_10_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_dino.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino_lc/EU_rn50_10 \\\n--arch resnet50 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.01 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_rn50_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_dino_rn50_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_dino_LC_rn50_100_%j.out\n#SBATCH --error=srun_outputs/classification/SS_dino_LC_rn50_100_%j.err\n#SBATCH --time=04:00:00\n#SBATCH --job-name=SS_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_SS_dino.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino_lc/SS_rn50_100 \\\n--arch resnet50 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.01 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_rn50_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_dino_vits16_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_dino_LC_vits16_100_%j.out\n#SBATCH --error=srun_outputs/classification/BE_dino_LC_vits16_100_%j.err\n#SBATCH --time=10:00:00\n#SBATCH --job-name=BE_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_dino.py \\\n--data /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino_lc/BE_vits16_100 \\\n--arch vit_small \\\n--train_frac 1.0 \\\n--patch_size 16 \\\n--batch_size_per_gpu 64 \\\n--lr 0.1 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_vits16_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_dino_vits16_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_dino_LC_vits16_10_%j.out\n#SBATCH --error=srun_outputs/classification/EU_dino_LC_vits16_10_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_dino.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino_lc/EU_vits16_10 \\\n--arch vit_small \\\n--patch_size 16 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.01 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_vits16_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_dino_vits16_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_dino_LC_vits16_100_%j.out\n#SBATCH --error=srun_outputs/classification/SS_dino_LC_vits16_100_%j.err\n#SBATCH --time=04:00:00\n#SBATCH --job-name=SS_LC_dino\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_SS_dino.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino_lc/SS_vits16_100 \\\n--arch vit_small \\\n--patch_size 16 \\\n--train_frac 1.0 \\\n--batch_size_per_gpu 64 \\\n--lr 0.01 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/dino/B13_vits16_224/checkpoint.pth \\"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_mae_vits16_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_mae_LC_vits16_100_%j.out\n#SBATCH --error=srun_outputs/classification/BE_mae_LC_vits16_100_%j.err\n#SBATCH --time=10:00:00\n#SBATCH --job-name=BE_LC_mae_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_mae.py \\\n--is_slurm_job \\\n--data_path /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--output_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae_lc/BE_vits16_100 \\\n--log_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae_lc/BE_vits16_100/log \\\n--model vit_small_patch16 \\\n--nb_classes 19 \\\n--train_frac 1.0 \\\n--num_workers 10 \\\n--batch_size 64 \\\n--epochs 100 \\\n--lr 1.0 \\\n--warmup_epochs 0 \\\n--dist_url $dist_url \\\n--dist_backend 'nccl' \\\n--seed 42 \\\n--finetune /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae/B13_vits16_70/checkpoint-99.pth\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_mae_vits16_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_mae_LC_vits16_70_%j.out\n#SBATCH --error=srun_outputs/classification/EU_mae_LC_vits16_70_%j.err\n#SBATCH --time=02:00:00\n#SBATCH --job-name=EU_LC_mae_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_mae.py \\\n--is_slurm_job \\\n--data_path /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--output_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae_lc/EU_vits16_10 \\\n--log_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae_lc/EU_vits16_10/log \\\n--model vit_small_patch16 \\\n--nb_classes 10 \\\n--train_frac 1.0 \\\n--num_workers 10 \\\n--batch_size 64 \\\n--epochs 100 \\\n--lr 0.1 \\\n--warmup_epochs 0 \\\n--dist_url $dist_url \\\n--dist_backend 'nccl' \\\n--seed 42 \\\n--finetune /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae/B13_vits16_70_ep200/checkpoint-199.pth\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_mae_vits16_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_mae_LC_vits16_100_%j.out\n#SBATCH --error=srun_outputs/classification/SS_mae_LC_vits16_100_%j.err\n#SBATCH --time=04:00:00\n#SBATCH --job-name=SS_LC_mae_vits16\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_SS_mae.py \\\n--is_slurm_job \\\n--data_path /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--output_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae_lc/SS_vits16_100 \\\n--log_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae_lc/SS_vits16_100/log \\\n--model vit_small_patch16 \\\n--nb_classes 17 \\\n--train_frac 1.0 \\\n--num_workers 10 \\\n--batch_size 64 \\\n--epochs 100 \\\n--lr 0.1 \\\n--warmup_epochs 0 \\\n--dist_url $dist_url \\\n--dist_backend 'nccl' \\\n--seed 42 \\\n--finetune /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/mae/B13_vits16_70/checkpoint-99.pth\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_moco_rn50_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_moco_LC_rn50_100_%j.out\n#SBATCH --error=srun_outputs/classification/BE_moco_LC_rn50_100_%j.err\n#SBATCH --time=10:00:00\n#SBATCH --job-name=BE_LC_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco.py \\\n--lmdb_dir /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--bands all \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_100 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 256 \\\n--lr 8.0 \\\n--schedule 60 80 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn50/checkpoint_0099.pth.tar \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_100/checkpoint_0069.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_moco_rn50_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_moco_LC_rn50_%j.out\n#SBATCH --error=srun_outputs/classification/EU_moco_LC_rn50_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_lc_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_moco.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/EU_rn50 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 8 \\\n--schedule 60 80 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn50/checkpoint_0099.pth.tar \\\n--in_size 224 \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_moco_rn50_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_moco_LC_rn50_100_%j.out\n#SBATCH --error=srun_outputs/classification/SS_moco_LC_rn50_100_%j.err\n#SBATCH --time=04:00:00\n#SBATCH --job-name=SS_lc_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_SS_moco.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/SS_rn50_100 \\\n--backbone resnet50 \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 8 \\\n--schedule 60 80 \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_rn50/checkpoint_0099.pth.tar \\\n--in_size 224 \\\n--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/SS_rn50_100/checkpoint_0049.pth.tar\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_moco_vits16_s2c_BE.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/BE_moco_LC_vits16_100_%j.out\n#SBATCH --error=srun_outputs/classification/BE_moco_LC_vits16_100_%j.err\n#SBATCH --time=10:00:00\n#SBATCH --job-name=BE_LC_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_BE_moco_v3.py \\\n--data /p/scratch/hai_ssl4eo/data/bigearthnet/BigEarthNet_LMDB_uint8 \\\n--bands all \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_vits16_100 \\\n--arch vit_small \\\n--train_frac 1.0 \\\n--batch_size 64 \\\n--lr 0.1 \\\n--cos \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_vits16_224/checkpoint_0099.pth.tar \\\n#--resume /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/BE_rn50_10_r112/checkpoint_0009.pth.tar\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_moco_vits16_s2c_EU.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/EU_moco_LC_vits16_%j.out\n#SBATCH --error=srun_outputs/classification/EU_moco_LC_vits16_%j.err\n#SBATCH --time=01:00:00\n#SBATCH --job-name=EU_lc_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=develbooster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_EU_moco_v3.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/eurosat/tif \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/EU_vits16 \\\n--backbone vit_small \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.1 \\\n--cos \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--in_size 224 \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_vits16_224/checkpoint_0099.pth.tar \\\n--linear \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_classification/scripts/benchmark/srun_lc_moco_vits16_s2c_SS.sh",
    "content": "#!/usr/bin/env bash\n\n# slurm job configuration\n#SBATCH --nodes=1\n#SBATCH --ntasks=4\n#SBATCH --ntasks-per-node=4\n#SBATCH --output=srun_outputs/classification/SS_moco_LC_vits16_100_%j.out\n#SBATCH --error=srun_outputs/classification/SS_moco_LC_vits16_100_%j.err\n#SBATCH --time=04:00:00\n#SBATCH --job-name=SS_lc_moco\n#SBATCH --gres=gpu:4\n#SBATCH --cpus-per-task=10\n#SBATCH --partition=booster\n\nmaster_node=${SLURM_NODELIST:0:9}${SLURM_NODELIST:10:4}\ndist_url=\"tcp://\"\ndist_url+=$master_node\ndist_url+=:40000\n\n\n# load required modules\nmodule load Stages/2022\nmodule load GCCcore/.11.2.0\nmodule load Python\n\n# activate virtual environment\nsource /p/project/hai_dm4eo/wang_yi/env2/bin/activate\n\n\n# define available gpus\nexport CUDA_VISIBLE_DEVICES=0,1,2,3\n\n# run script as slurm job\nsrun python -u linear_SS_moco_v3.py \\\n--data_dir /p/scratch/hai_ssl4eo/data/so2sat-lcz42 \\\n--bands B13 \\\n--checkpoints_dir /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco_lc/SS_vits16_100 \\\n--backbone vit_small \\\n--train_frac 1.0 \\\n--batchsize 64 \\\n--lr 0.1 \\\n--cos \\\n--epochs 100 \\\n--num_workers 10 \\\n--seed 42 \\\n--dist_url $dist_url \\\n--in_size 224 \\\n--linear \\\n--pretrained /p/project/hai_ssl4eo/wang_yi/ssl4eo-s12-dataset/src/benchmark/fullset_temp/checkpoints/moco/B13_vits16_224/checkpoint_0099.pth.tar \\\n#--normalize \\\n"
  },
  {
    "path": "src/benchmark/transfer_segmentation/readme.md",
    "content": "Refer to [DeepAI4EO/RSI-Segmentation](https://github.com/DeepAI4EO/RSI-Segmentation) and [DeepAI4EO/Dataset4EO](https://github.com/DeepAI4EO/Dataset4EO)"
  },
  {
    "path": "src/benchmark/utils/convert_model_torchvision.py",
    "content": "import torch\r\nimport os\r\nimport argparse\r\n\r\nparser = argparse.ArgumentParser(description='Convert pretrained model to torchvision or timm format')\r\n\r\nparser.add_argument('--in_ckpt', help='input model path')\r\nparser.add_argument('--out_ckpt', help='output model path')\r\nparser.add_argument('--model', type=str, default='moco_v2_rn50')\r\n\r\nargs = parser.parse_args()\r\n\r\n### MoCo-v2 + ResNet50\r\nif os.path.isfile(args.in_ckpt):\r\n    print(\"=> loading checkpoint '{}'\".format(args.in_ckpt))\r\n    checkpoint = torch.load(args.in_ckpt, map_location=\"cpu\")\r\n    \r\n    \r\n    \r\n    if args.model=='moco_v2_rn50':\r\n        state_dict = checkpoint['state_dict']    \r\n        for k in list(state_dict.keys()):\r\n            # retain only encoder up to before the embedding layer\r\n            if k.startswith('module.encoder_q') and not k.startswith('module.encoder_q.fc'):\r\n                # remove prefix\r\n                state_dict[k[len(\"module.encoder_q.\"):]] = state_dict[k]\r\n            # delete renamed or unused k\r\n            del state_dict[k]\r\n            \r\n        torch.save({'state_dict':state_dict},args.out_ckpt)\r\n        \r\n        print('Convert to:',args.out_ckpt)\r\n        \r\n    else:\r\n        print('Error: unknown model.')\r\n    "
  },
  {
    "path": "src/benchmark/utils/vis_tsne.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 29,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import torch\\n\",\n    \"import torchvision\\n\",\n    \"from torch.utils.data import DataLoader\\n\",\n    \"from torchvision import transforms\\n\",\n    \"import numpy as np\\n\",\n    \"import pandas as pd\\n\",\n    \"from sklearn.decomposition import PCA\\n\",\n    \"from sklearn.manifold import TSNE\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"import seaborn as sns\\n\",\n    \"import time\\n\",\n    \"import os\\n\",\n    \"from tqdm import tqdm\\n\",\n    \"import torch.nn.functional as F\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"test_transform = transforms.Compose([\\n\",\n    \"    transforms.ToTensor(),\\n\",\n    \"    #transforms.Normalize([0.4914, 0.4822, 0.4465], [0.2023, 0.1994, 0.2010])\\n\",\n    \"    ])\\n\",\n    \"\\n\",\n    \"memory_data = torchvision.datasets.ImageFolder(root='eurosat_new/train', transform=test_transform)\\n\",\n    \"memory_loader = DataLoader(memory_data, batch_size=256, shuffle=False, num_workers=0, pin_memory=True)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"### raw data\\n\",\n    \"\\n\",\n    \"raw_list = []\\n\",\n    \"for i in range(len(memory_data)):\\n\",\n    \"  raw_list.append(memory_data[i][0])\\n\",\n    \"raw_data = np.stack(raw_list,axis=0).reshape(len(memory_data),-1)\\n\",\n    \"\\n\",\n    \"df = pd.DataFrame(raw_data)\\n\",\n    \"df['y'] = memory_data.targets\\n\",\n    \"\\n\",\n    \"pca = PCA(n_components=50)\\n\",\n    \"pca_result = pca.fit_transform(raw_data)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 9,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"[t-SNE] Computing 121 nearest neighbors...\\n\",\n      \"[t-SNE] Indexed 24300 samples in 0.001s...\\n\",\n      \"[t-SNE] Computed neighbors for 24300 samples in 6.187s...\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 1000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 2000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 3000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 4000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 5000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 6000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 7000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 8000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 9000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 10000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 11000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 12000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 13000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 14000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 15000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 16000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 17000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 18000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 19000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 20000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 21000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 22000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 23000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 24000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 24300 / 24300\\n\",\n      \"[t-SNE] Mean sigma: 0.502686\\n\",\n      \"[t-SNE] Computed conditional probabilities in 0.677s\\n\",\n      \"[t-SNE] Iteration 50: error = 77.0136719, gradient norm = 0.0095105 (50 iterations in 3.258s)\\n\",\n      \"[t-SNE] Iteration 100: error = 81.4315491, gradient norm = 0.0023158 (50 iterations in 3.600s)\\n\",\n      \"[t-SNE] Iteration 150: error = 81.3708801, gradient norm = 0.0033667 (50 iterations in 4.445s)\\n\",\n      \"[t-SNE] Iteration 200: error = 81.2286072, gradient norm = 0.0036936 (50 iterations in 4.386s)\\n\",\n      \"[t-SNE] Iteration 250: error = 80.4161148, gradient norm = 0.0082354 (50 iterations in 4.404s)\\n\",\n      \"[t-SNE] KL divergence after 250 iterations with early exaggeration: 80.416115\\n\",\n      \"[t-SNE] Iteration 300: error = 3.4735575, gradient norm = 0.0008989 (50 iterations in 5.544s)\\n\",\n      \"[t-SNE] Iteration 350: error = 3.2336564, gradient norm = 0.0004668 (50 iterations in 3.738s)\\n\",\n      \"[t-SNE] Iteration 400: error = 3.0819910, gradient norm = 0.0002952 (50 iterations in 3.050s)\\n\",\n      \"[t-SNE] Iteration 450: error = 2.9938548, gradient norm = 0.0002254 (50 iterations in 2.862s)\\n\",\n      \"[t-SNE] Iteration 500: error = 2.9220386, gradient norm = 0.0001770 (50 iterations in 2.783s)\\n\",\n      \"[t-SNE] Iteration 550: error = 2.8619726, gradient norm = 0.0001430 (50 iterations in 2.759s)\\n\",\n      \"[t-SNE] Iteration 600: error = 2.8125024, gradient norm = 0.0001184 (50 iterations in 2.723s)\\n\",\n      \"[t-SNE] Iteration 650: error = 2.7714367, gradient norm = 0.0000998 (50 iterations in 2.807s)\\n\",\n      \"[t-SNE] Iteration 700: error = 2.7370024, gradient norm = 0.0000862 (50 iterations in 2.822s)\\n\",\n      \"[t-SNE] Iteration 750: error = 2.7077568, gradient norm = 0.0000750 (50 iterations in 2.735s)\\n\",\n      \"[t-SNE] Iteration 800: error = 2.6827154, gradient norm = 0.0000663 (50 iterations in 2.835s)\\n\",\n      \"[t-SNE] Iteration 850: error = 2.6610854, gradient norm = 0.0000591 (50 iterations in 2.763s)\\n\",\n      \"[t-SNE] Iteration 900: error = 2.6422527, gradient norm = 0.0000534 (50 iterations in 2.793s)\\n\",\n      \"[t-SNE] Iteration 950: error = 2.6256990, gradient norm = 0.0000489 (50 iterations in 2.814s)\\n\",\n      \"[t-SNE] Iteration 1000: error = 2.6110616, gradient norm = 0.0000452 (50 iterations in 2.808s)\\n\",\n      \"[t-SNE] KL divergence after 1000 iterations: 2.611062\\n\",\n      \"t-SNE done! Time elapsed: 72.82303237915039 seconds\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"time_start = time.time()\\n\",\n    \"tsne = TSNE(n_components=2, verbose=2, perplexity=40, n_iter=1000, n_iter_without_progress=300, init='pca')\\n\",\n    \"tsne_results = tsne.fit_transform(pca_result)\\n\",\n    \"print('t-SNE done! Time elapsed: {} seconds'.format(time.time()-time_start))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 21,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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\",\n      \"text/plain\": [\n       \"<Figure size 1152x720 with 1 Axes>\"\n      ]\n     },\n     \"metadata\": {\n      \"needs_background\": \"light\"\n     },\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"df['tsne-2d-one'] = tsne_results[:,0]\\n\",\n    \"df['tsne-2d-two'] = tsne_results[:,1]\\n\",\n    \"plt.figure(figsize=(16,10))\\n\",\n    \"plt.rcParams.update({'font.size': 24})\\n\",\n    \"tsne_plot = sns.scatterplot(\\n\",\n    \"    x=\\\"tsne-2d-one\\\", y=\\\"tsne-2d-two\\\",\\n\",\n    \"    hue=\\\"y\\\",\\n\",\n    \"    palette=sns.color_palette(\\\"hls\\\", 10),\\n\",\n    \"    data=df,\\n\",\n    \"    legend=None,\\n\",\n    \"    alpha=0.3\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"tsne_plot.set(xticklabels=[])  # remove the tick labels\\n\",\n    \"tsne_plot.set(yticklabels=[])  # remove the tick labels\\n\",\n    \"tsne_plot.set(xlabel=None)  # remove the axis label\\n\",\n    \"tsne_plot.set(ylabel=None)  # remove the axis label\\n\",\n    \"tsne_plot.tick_params(bottom=False,left=False)\\n\",\n    \"fig = tsne_plot.get_figure()\\n\",\n    \"\\n\",\n    \"fig.savefig('tsne_raw.svg',transparent=True)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 46,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"text/plain\": [\n       \"ResNet(\\n\",\n       \"  (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\\n\",\n       \"  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"  (relu): ReLU(inplace=True)\\n\",\n       \"  (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\\n\",\n       \"  (layer1): Sequential(\\n\",\n       \"    (0): BasicBlock(\\n\",\n       \"      (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (relu): ReLU(inplace=True)\\n\",\n       \"      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"    )\\n\",\n       \"    (1): BasicBlock(\\n\",\n       \"      (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (relu): ReLU(inplace=True)\\n\",\n       \"      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"    )\\n\",\n       \"  )\\n\",\n       \"  (layer2): Sequential(\\n\",\n       \"    (0): BasicBlock(\\n\",\n       \"      (conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n       \"      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (relu): ReLU(inplace=True)\\n\",\n       \"      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (downsample): Sequential(\\n\",\n       \"        (0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)\\n\",\n       \"        (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      )\\n\",\n       \"    )\\n\",\n       \"    (1): BasicBlock(\\n\",\n       \"      (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (relu): ReLU(inplace=True)\\n\",\n       \"      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"    )\\n\",\n       \"  )\\n\",\n       \"  (layer3): Sequential(\\n\",\n       \"    (0): BasicBlock(\\n\",\n       \"      (conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n       \"      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (relu): ReLU(inplace=True)\\n\",\n       \"      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (downsample): Sequential(\\n\",\n       \"        (0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)\\n\",\n       \"        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      )\\n\",\n       \"    )\\n\",\n       \"    (1): BasicBlock(\\n\",\n       \"      (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (relu): ReLU(inplace=True)\\n\",\n       \"      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"    )\\n\",\n       \"  )\\n\",\n       \"  (layer4): Sequential(\\n\",\n       \"    (0): BasicBlock(\\n\",\n       \"      (conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n       \"      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (relu): ReLU(inplace=True)\\n\",\n       \"      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (downsample): Sequential(\\n\",\n       \"        (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)\\n\",\n       \"        (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      )\\n\",\n       \"    )\\n\",\n       \"    (1): BasicBlock(\\n\",\n       \"      (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"      (relu): ReLU(inplace=True)\\n\",\n       \"      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n       \"      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n       \"    )\\n\",\n       \"  )\\n\",\n       \"  (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))\\n\",\n       \"  (fc): Linear(in_features=512, out_features=128, bias=True)\\n\",\n       \")\"\n      ]\n     },\n     \"execution_count\": 46,\n     \"metadata\": {},\n     \"output_type\": \"execute_result\"\n    }\n   ],\n   \"source\": [\n    \"net = torchvision.models.resnet18(pretrained=False)\\n\",\n    \"net.fc = torch.nn.Linear(512,128)\\n\",\n    \"#net.conv1 = torch.nn.Conv2d(13, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\\n\",\n    \"net.cuda()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 47,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Feature extracting: 100%|██████████| 95/95 [00:56<00:00,  1.67it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"[t-SNE] Computing 121 nearest neighbors...\\n\",\n      \"[t-SNE] Indexed 24300 samples in 0.001s...\\n\",\n      \"[t-SNE] Computed neighbors for 24300 samples in 5.016s...\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 1000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 2000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 3000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 4000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 5000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 6000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 7000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 8000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 9000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 10000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 11000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 12000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 13000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 14000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 15000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 16000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 17000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 18000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 19000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 20000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 21000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 22000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 23000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 24000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 24300 / 24300\\n\",\n      \"[t-SNE] Mean sigma: 0.007523\\n\",\n      \"[t-SNE] Computed conditional probabilities in 0.962s\\n\",\n      \"[t-SNE] Iteration 50: error = 100.9140472, gradient norm = 0.0000761 (50 iterations in 3.010s)\\n\",\n      \"[t-SNE] Iteration 100: error = 94.3392487, gradient norm = 0.0008309 (50 iterations in 2.961s)\\n\",\n      \"[t-SNE] Iteration 150: error = 93.7863617, gradient norm = 0.0002194 (50 iterations in 2.463s)\\n\",\n      \"[t-SNE] Iteration 200: error = 93.7417221, gradient norm = 0.0001862 (50 iterations in 2.427s)\\n\",\n      \"[t-SNE] Iteration 250: error = 93.7290497, gradient norm = 0.0001895 (50 iterations in 2.545s)\\n\",\n      \"[t-SNE] KL divergence after 250 iterations with early exaggeration: 93.729050\\n\",\n      \"[t-SNE] Iteration 300: error = 4.1156006, gradient norm = 0.0012263 (50 iterations in 2.713s)\\n\",\n      \"[t-SNE] Iteration 350: error = 3.7002711, gradient norm = 0.0005181 (50 iterations in 2.402s)\\n\",\n      \"[t-SNE] Iteration 400: error = 3.5018396, gradient norm = 0.0003236 (50 iterations in 2.438s)\\n\",\n      \"[t-SNE] Iteration 450: error = 3.3809366, gradient norm = 0.0002301 (50 iterations in 2.383s)\\n\",\n      \"[t-SNE] Iteration 500: error = 3.2975826, gradient norm = 0.0001710 (50 iterations in 2.404s)\\n\",\n      \"[t-SNE] Iteration 550: error = 3.2359033, gradient norm = 0.0001354 (50 iterations in 2.401s)\\n\",\n      \"[t-SNE] Iteration 600: error = 3.1881859, gradient norm = 0.0001101 (50 iterations in 2.433s)\\n\",\n      \"[t-SNE] Iteration 650: error = 3.1499760, gradient norm = 0.0000928 (50 iterations in 2.387s)\\n\",\n      \"[t-SNE] Iteration 700: error = 3.1186781, gradient norm = 0.0000800 (50 iterations in 2.423s)\\n\",\n      \"[t-SNE] Iteration 750: error = 3.0923545, gradient norm = 0.0000698 (50 iterations in 2.352s)\\n\",\n      \"[t-SNE] Iteration 800: error = 3.0699303, gradient norm = 0.0000621 (50 iterations in 2.385s)\\n\",\n      \"[t-SNE] Iteration 850: error = 3.0505881, gradient norm = 0.0000552 (50 iterations in 2.431s)\\n\",\n      \"[t-SNE] Iteration 900: error = 3.0338259, gradient norm = 0.0000491 (50 iterations in 2.429s)\\n\",\n      \"[t-SNE] Iteration 950: error = 3.0191100, gradient norm = 0.0000444 (50 iterations in 2.367s)\\n\",\n      \"[t-SNE] Iteration 1000: error = 3.0061233, gradient norm = 0.0000404 (50 iterations in 2.380s)\\n\",\n      \"[t-SNE] KL divergence after 1000 iterations: 3.006123\\n\",\n      \"t-SNE done! Time elapsed: 55.72247838973999 seconds\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# random\\n\",\n    \"\\n\",\n    \"net.eval()\\n\",\n    \"feature_bank = []\\n\",\n    \"targets = []\\n\",\n    \"with torch.no_grad():  \\n\",\n    \"    for data, target in tqdm(memory_loader, desc='Feature extracting'):\\n\",\n    \"        feature = net(data.cuda(non_blocking=True))\\n\",\n    \"        feature = F.normalize(feature, dim=1)\\n\",\n    \"        feature_bank.append(feature)\\n\",\n    \"        targets.append(target)\\n\",\n    \"    feature_data = torch.cat(feature_bank).cpu().reshape(len(memory_data),-1)\\n\",\n    \"    target_data = memory_data.targets\\n\",\n    \"    df = pd.DataFrame(feature_data)\\n\",\n    \"    df['y'] = target_data\\n\",\n    \"    pca = PCA(n_components=50)\\n\",\n    \"    pca_result = pca.fit_transform(feature_data)\\n\",\n    \"\\n\",\n    \"    time_start = time.time()\\n\",\n    \"    tsne = TSNE(n_components=2, verbose=2, perplexity=40, n_iter=1000, n_iter_without_progress=300)\\n\",\n    \"    tsne_results = tsne.fit_transform(pca_result)\\n\",\n    \"    tsne_time = time.time()-time_start\\n\",\n    \"    print('t-SNE done! Time elapsed: {} seconds'.format(tsne_time))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 48,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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\",\n      \"text/plain\": [\n       \"<Figure size 1152x720 with 1 Axes>\"\n      ]\n     },\n     \"metadata\": {\n      \"needs_background\": \"light\"\n     },\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"df['tsne-2d-one'] = tsne_results[:,0]\\n\",\n    \"df['tsne-2d-two'] = tsne_results[:,1]\\n\",\n    \"plt.figure(figsize=(16,10))\\n\",\n    \"tsne_plot = sns.scatterplot(\\n\",\n    \"    x=\\\"tsne-2d-one\\\", y=\\\"tsne-2d-two\\\",\\n\",\n    \"    hue=\\\"y\\\",\\n\",\n    \"    palette=sns.color_palette(\\\"hls\\\", 10),\\n\",\n    \"    data=df,\\n\",\n    \"    legend=None,\\n\",\n    \"    alpha=0.3\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"tsne_plot.set(xticklabels=[])  # remove the tick labels\\n\",\n    \"tsne_plot.set(yticklabels=[])  # remove the tick labels\\n\",\n    \"tsne_plot.set(xlabel=None)  # remove the axis label\\n\",\n    \"tsne_plot.set(ylabel=None)  # remove the axis label\\n\",\n    \"tsne_plot.tick_params(bottom=False,left=False)\\n\",\n    \"fig = tsne_plot.get_figure()\\n\",\n    \"\\n\",\n    \"fig.savefig('tsne_random.svg',transparent=True)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 37,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"=> loading checkpoint '/mnt/e/doctoral/weights/SSL4EO-S12/B3_moco_rn18_ep200_ckpt.pth.tar'\\n\",\n      \"=> loaded pre-trained model '/mnt/e/doctoral/weights/SSL4EO-S12/B3_moco_rn18_ep200_ckpt.pth.tar'\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# load from pre-trained, before DistributedDataParallel constructor\\n\",\n    \"pretrained_model = '/mnt/e/doctoral/weights/SSL4EO-S12/B3_moco_rn18_ep200_ckpt.pth.tar'\\n\",\n    \"if os.path.isfile(pretrained_model):\\n\",\n    \"    print(\\\"=> loading checkpoint '{}'\\\".format(pretrained_model))\\n\",\n    \"    checkpoint = torch.load(pretrained_model, map_location=\\\"cpu\\\")\\n\",\n    \"\\n\",\n    \"    # rename moco pre-trained keys\\n\",\n    \"    state_dict = checkpoint['state_dict']\\n\",\n    \"    \\n\",\n    \"    for k in list(state_dict.keys()):\\n\",\n    \"        # retain only encoder up to before the embedding layer\\n\",\n    \"        if k.startswith('module.encoder_q') and not k.startswith('module.encoder_q.fc'):\\n\",\n    \"            # remove prefix\\n\",\n    \"            state_dict[k[len(\\\"module.encoder_q.\\\"):]] = state_dict[k]\\n\",\n    \"        # delete renamed or unused k\\n\",\n    \"        del state_dict[k]\\n\",\n    \"    '''\\n\",\n    \"    # remove prefix\\n\",\n    \"    state_dict = {k.replace(\\\"module.\\\", \\\"\\\"): v for k,v in state_dict.items()}\\n\",\n    \"    '''\\n\",\n    \"    msg = net.load_state_dict(state_dict, strict=False)\\n\",\n    \"    assert set(msg.missing_keys) == {\\\"fc.weight\\\", \\\"fc.bias\\\"}\\n\",\n    \"\\n\",\n    \"    print(\\\"=> loaded pre-trained model '{}'\\\".format(pretrained_model))\\n\",\n    \"else:\\n\",\n    \"    print(\\\"=> no checkpoint found at '{}'\\\".format(pretrained_model))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 44,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Feature extracting: 100%|██████████| 95/95 [00:57<00:00,  1.65it/s]\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"[t-SNE] Computing 121 nearest neighbors...\\n\",\n      \"[t-SNE] Indexed 24300 samples in 0.001s...\\n\",\n      \"[t-SNE] Computed neighbors for 24300 samples in 5.868s...\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 1000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 2000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 3000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 4000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 5000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 6000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 7000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 8000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 9000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 10000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 11000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 12000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 13000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 14000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 15000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 16000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 17000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 18000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 19000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 20000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 21000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 22000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 23000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 24000 / 24300\\n\",\n      \"[t-SNE] Computed conditional probabilities for sample 24300 / 24300\\n\",\n      \"[t-SNE] Mean sigma: 0.150672\\n\",\n      \"[t-SNE] Computed conditional probabilities in 0.725s\\n\",\n      \"[t-SNE] Iteration 50: error = 104.2441025, gradient norm = 0.0000410 (50 iterations in 2.796s)\\n\",\n      \"[t-SNE] Iteration 100: error = 93.8610764, gradient norm = 0.0013243 (50 iterations in 4.563s)\\n\",\n      \"[t-SNE] Iteration 150: error = 92.0576553, gradient norm = 0.0003275 (50 iterations in 2.213s)\\n\",\n      \"[t-SNE] Iteration 200: error = 91.7889175, gradient norm = 0.0000777 (50 iterations in 2.122s)\\n\",\n      \"[t-SNE] Iteration 250: error = 91.7347412, gradient norm = 0.0000231 (50 iterations in 2.175s)\\n\",\n      \"[t-SNE] KL divergence after 250 iterations with early exaggeration: 91.734741\\n\",\n      \"[t-SNE] Iteration 300: error = 3.9029982, gradient norm = 0.0012952 (50 iterations in 1.992s)\\n\",\n      \"[t-SNE] Iteration 350: error = 3.3327403, gradient norm = 0.0005962 (50 iterations in 1.997s)\\n\",\n      \"[t-SNE] Iteration 400: error = 3.0589499, gradient norm = 0.0003657 (50 iterations in 2.215s)\\n\",\n      \"[t-SNE] Iteration 450: error = 2.8941560, gradient norm = 0.0002550 (50 iterations in 1.946s)\\n\",\n      \"[t-SNE] Iteration 500: error = 2.7813408, gradient norm = 0.0001926 (50 iterations in 1.939s)\\n\",\n      \"[t-SNE] Iteration 550: error = 2.6985123, gradient norm = 0.0001524 (50 iterations in 1.966s)\\n\",\n      \"[t-SNE] Iteration 600: error = 2.6345620, gradient norm = 0.0001242 (50 iterations in 1.959s)\\n\",\n      \"[t-SNE] Iteration 650: error = 2.5834141, gradient norm = 0.0001046 (50 iterations in 1.928s)\\n\",\n      \"[t-SNE] Iteration 700: error = 2.5415025, gradient norm = 0.0000899 (50 iterations in 1.981s)\\n\",\n      \"[t-SNE] Iteration 750: error = 2.5064266, gradient norm = 0.0000789 (50 iterations in 1.936s)\\n\",\n      \"[t-SNE] Iteration 800: error = 2.4766457, gradient norm = 0.0000697 (50 iterations in 1.963s)\\n\",\n      \"[t-SNE] Iteration 850: error = 2.4509530, gradient norm = 0.0000620 (50 iterations in 1.958s)\\n\",\n      \"[t-SNE] Iteration 900: error = 2.4285412, gradient norm = 0.0000569 (50 iterations in 1.963s)\\n\",\n      \"[t-SNE] Iteration 950: error = 2.4090829, gradient norm = 0.0000512 (50 iterations in 1.935s)\\n\",\n      \"[t-SNE] Iteration 1000: error = 2.3918104, gradient norm = 0.0000468 (50 iterations in 1.960s)\\n\",\n      \"[t-SNE] KL divergence after 1000 iterations: 2.391810\\n\",\n      \"t-SNE done! Time elapsed: 50.109941720962524 seconds\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"net.eval()\\n\",\n    \"feature_bank = []\\n\",\n    \"targets = []\\n\",\n    \"with torch.no_grad():  \\n\",\n    \"    for data, target in tqdm(memory_loader, desc='Feature extracting'):\\n\",\n    \"        feature = net(data.cuda(non_blocking=True))\\n\",\n    \"        feature = F.normalize(feature, dim=1)\\n\",\n    \"        feature_bank.append(feature)\\n\",\n    \"        targets.append(target)\\n\",\n    \"    feature_data = torch.cat(feature_bank).cpu().reshape(len(memory_data),-1)\\n\",\n    \"    target_data = memory_data.targets\\n\",\n    \"    df = pd.DataFrame(feature_data)\\n\",\n    \"    df['y'] = target_data\\n\",\n    \"    pca = PCA(n_components=50)\\n\",\n    \"    pca_result = pca.fit_transform(feature_data)\\n\",\n    \"\\n\",\n    \"    time_start = time.time()\\n\",\n    \"    tsne = TSNE(n_components=2, verbose=2, perplexity=40, n_iter=1000, n_iter_without_progress=300)\\n\",\n    \"    tsne_results = tsne.fit_transform(pca_result)\\n\",\n    \"    tsne_time = time.time()-time_start\\n\",\n    \"    print('t-SNE done! Time elapsed: {} seconds'.format(tsne_time))\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 45,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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\",\n      \"text/plain\": [\n       \"<Figure size 1152x720 with 1 Axes>\"\n      ]\n     },\n     \"metadata\": {\n      \"needs_background\": \"light\"\n     },\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"df['tsne-2d-one'] = tsne_results[:,0]\\n\",\n    \"df['tsne-2d-two'] = tsne_results[:,1]\\n\",\n    \"plt.figure(figsize=(16,10))\\n\",\n    \"tsne_plot = sns.scatterplot(\\n\",\n    \"    x=\\\"tsne-2d-one\\\", y=\\\"tsne-2d-two\\\",\\n\",\n    \"    hue=\\\"y\\\",\\n\",\n    \"    palette=sns.color_palette(\\\"hls\\\", 10),\\n\",\n    \"    data=df,\\n\",\n    \"    legend=None,\\n\",\n    \"    alpha=0.3\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"tsne_plot.set(xticklabels=[])  # remove the tick labels\\n\",\n    \"tsne_plot.set(yticklabels=[])  # remove the tick labels\\n\",\n    \"tsne_plot.set(xlabel=None)  # remove the axis label\\n\",\n    \"tsne_plot.set(ylabel=None)  # remove the axis label\\n\",\n    \"tsne_plot.tick_params(bottom=False,left=False)\\n\",\n    \"fig = tsne_plot.get_figure()\\n\",\n    \"\\n\",\n    \"fig.savefig('tsne_pretrain.svg',transparent=True)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"interpreter\": {\n   \"hash\": \"1a231a5a3b33975212a7b8f2691b72c251678163b7a1032fd083fd9adb77faab\"\n  },\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.8.8 ('base')\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.8.8\"\n  },\n  \"orig_nbformat\": 4\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "src/download_data/convert_rgb.py",
    "content": "import os\nimport rasterio\nimport cv2\nimport numpy as np\nimport random\nfrom PIL import Image\n\nALL_BANDS_S2_L2A = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B9', 'B11', 'B12']\nALL_BANDS_S2_L1C = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B9', 'B10', 'B11', 'B12']\nRGB_BANDS = ['B4', 'B3', 'B2']\nALL_BANDS_S1_GRD = ['VV','VH']\n\nS2C_MEAN = {\n        'B1': 1612.9,\n        'B2': 1397.6,\n        'B3': 1322.3,\n        'B4': 1373.1,\n        'B5': 1561.0,\n        'B6': 2108.4,\n        'B7': 2390.7,\n        'B8': 2318.7,\n        'B8A': 2581.0,\n        'B9': 837.7,\n        'B10': 22.0,\n        'B11': 2195.2,\n        'B12': 1537.4}\nS2C_STD = {\n        'B1': 791.0,\n        'B2': 854.3,\n        'B3': 878.7,\n        'B4': 1144.9,\n        'B5': 1127.5,\n        'B6': 1164.2,\n        'B7': 1276.0,\n        'B8': 1249.5,\n        'B8A': 1345.9,\n        'B9': 577.5,\n        'B10': 47.5,\n        'B11': 1340.0,\n        'B12': 1142.9}\n\nS2A_MEAN = {\n        'B1': 756.4,\n        'B2': 889.6,\n        'B3': 1151.7,\n        'B4': 1307.6,\n        'B5': 1637.6,\n        'B6': 2212.6,\n        'B7': 2442.0,\n        'B8': 2538.9,\n        'B8A': 2602.9,\n        'B9': 2666.8,\n        'B11': 2388.8,\n        'B12': 1821.5}\nS2A_STD = {\n        'B1': 1111.4,\n        'B2': 1159.1,\n        'B3': 1188.1,\n        'B4': 1375.2,\n        'B5': 1376.6,\n        'B6': 1358.6,\n        'B7': 1418.4,\n        'B8': 1476.4,\n        'B8A': 1439.9,\n        'B9': 1582.1,\n        'B11': 1460.7,\n        'B12': 1352.2}\n\nS1_MEAN = {'VV': -12.59, 'VH': -20.26}\nS1_STD = {'VV': 5.26, 'VH': 5.91}\n\n\ndef normalize(img,mean,std):\n    min_value = mean - 2 * std\n    max_value = mean + 2 * std\n    img = (img - min_value) / (max_value - min_value) * 255.0\n    img = np.clip(img, 0, 255).astype(np.uint8)\n    return img\n\n\n\ndef get_array(patch_id, mode, RGB=False, norm=False):\n    data_root_patch = os.path.join(root_dir, mode, patch_id)\n    patch_seasons = os.listdir(data_root_patch)\n    seasons = {}\n\n    if mode=='s1':\n        bands = ALL_BANDS_S1_GRD\n        MEAN = S1_MEAN\n        STD = S1_STD\n    elif mode=='s2a':\n        bands = ALL_BANDS_S2_L2A if RGB==False else RGB_BANDS\n        MEAN = S2A_MEAN\n        STD = S2A_STD       \n    elif mode=='s2c':\n        bands = ALL_BANDS_S2_L1C if RGB==False else RGB_BANDS\n        MEAN = S2C_MEAN\n        STD = S2C_STD\n    \n    for patch_id_season in patch_seasons:\n        chs = []\n        for i,band in enumerate(bands):\n            patch_path = os.path.join(data_root_patch,patch_id_season,f'{band}.tif')\n            with rasterio.open(patch_path) as dataset:\n                ch = dataset.read(1)\n                ch = cv2.resize(ch, dsize=(264, 264), interpolation=cv2.INTER_LINEAR_EXACT) # [264,264]\n                \n                if norm:\n                    ch = normalize(ch,mean=MEAN[band],std=STD[band]) # uint8\n\n                #coord = dataset.xy(0,0) # up left                    \n            chs.append(ch)\n        img = np.stack(chs, axis=-1) # [264,264,C]\n        seasons[patch_id_season] = img\n\n    return seasons\n\n\n\nroot_dir = './'\nrandom.seed(42)\nsample_ids = random.sample(range(0, 100), 10)\n\nsample_inames = []\nfor id in sample_ids:\n    iname = f'{id:07d}'\n    sample_inames.append(iname)\n\nprint(sample_inames)\n\nfor index in sample_inames:\n    #img_s1_4s = get_array(index, 's1')\n    #img_s2a_4s = get_array(index, 's2a')\n    img_s2c_4s = get_array(index, 's2c', RGB=True, norm=True)\n\n    fdir = os.path.join('rgb_subset','s2c',index)\n    if not os.path.isdir(fdir):\n        os.makedirs(fdir,exist_ok=True)\n        \n    for t in img_s2c_4s.keys():\n        img_t = img_s2c_4s[t]\n        img_t = Image.fromarray(img_t,mode='RGB')\n\n        img_t.save(os.path.join('rgb_subset','s2c',index,t+'.png'))\n\n    #with h5py.File('ssl4eo-s12_h5/'+'s1/'+index+'.h5','w') as hf1:\n    #    h5_s1 = hf1.create_dataset('array',data=img_s1_4s,shape=img_s1_4s.shape,chunks=True)\n    #with h5py.File('ssl4eo-s12_h5/'+'s2a/'+index+'.h5','w') as hf2:\n    #    h5_s2a = hf2.create_dataset('array',data=img_s2a_4s,shape=img_s2a_4s.shape,chunks=True)\n    #with h5py.File('ssl4eo-s12_h5/'+'s2c/'+index+'.h5','w') as hf3:\n    #    h5_s2c = hf3.create_dataset('array',data=img_s2c_4s,shape=img_s2c_4s.shape,chunks=True)    \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/download_data/readme.md",
    "content": "## Data collection\nWe use Google Earth Engine to automatically process and download data. The data collection code is modified from [SeCo](https://github.com/ServiceNow/seasonal-contrast).\n\n### Update\nv2 (`ssl4eo_downloader.py`):\n- [x] extend sentinel-1/2 to other GEE available products\n\nv1 (`ssl4eo_s12_downloader.py`):\n- [x] speed up metadata collection\n- [x] reorganize for better resuming\n- [x] add support for overlap checking with rtree\n- [x] add support to match existing locations (e.g. reproduce the locations of ssl4eo-s12)\n\n### Usage\n`ssl4eo_s12_downloader.py`: follow the comments at the beginning of the script.\n\n`ssl4eo_downloader.py`: follow the comments at the beginning of the script.\n\n- Example 1: Sample and download sentinel-2 L1C images with rtree/grid overlap search.\n```\npython ssl4eo_downloader.py \\\n    --save_path ./data \\\n    --collection COPERNICUS/S2 \\\n    --meta_cloud_name CLOUDY_PIXEL_PERCENTAGE \\\n    --cloud_pct 20 \\\n    --dates 2021-12-21 2021-09-22 2021-06-21 2021-03-20 \\\n    --radius 1320 \\\n    --bands B1 B2 B3 B4 B5 B6 B7 B8 B8A B9 B10 B11 B12 \\\n    --crops 44 264 264 264 132 132 132 264 132 44 44 132 132 \\\n    --dtype uint16 \\\n    --num_workers 8 \\\n    --log_freq 100 \\\n    --overlap_check rtree \\\n    --indices_range 0 250000\n```\n- Example2: Download Landsat-8 images, match SSL4EO-S12 locations but keep same patch size.\n```\npython ssl4eo_downloader.py \\\n    --save_path ./data \\\n    --collection LANDSAT/LC08/C02/T1_TOA \\\n    --meta_cloud_name CLOUD_COVER \\\n    --cloud_pct 20 \\\n    --dates 2021-12-21 2021-09-22 2021-06-21 2021-03-20 \\\n    --radius 1980 \\\n    --bands B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 \\\n    --crops 132 132 132 132 132 132 132 264 264 132 132 \\\n    --dtype float32 \\\n    --num_workers 8 \\\n    --log_freq 100 \\\n    --match_file ./data/ssl4eo-s12_center_coords.csv \\\n    --indices_range 0 250000\n```\n\n"
  },
  {
    "path": "src/download_data/ssl4eo_downloader.py",
    "content": "\"\"\" Sample and download Satellite tiles with Google Earth Engine\n\n### run the script:\n\n## Install and authenticate Google Earth Engine (https://developers.google.com/earth-engine/guides/python_install) # noqa: E501\n\n## match and download pre-sampled locations\npython ssl4eo_downloader.py \\\n    --save_path ./data \\\n    --collection COPERNICUS/S2 \\\n    --meta_cloud_name CLOUDY_PIXEL_PERCENTAGE \\\n    --cloud_pct 20 \\\n    --dates 2021-12-21 2021-09-22 2021-06-21 2021-03-20 \\\n    --radius 1320 \\\n    --bands B1 B2 B3 B4 B5 B6 B7 B8 B8A B9 B10 B11 B12 \\\n    --crops 44 264 264 264 132 132 132 264 132 44 44 132 132 \\\n    --dtype uint16 \\\n    --num_workers 8 \\\n    --log_freq 100 \\\n    --match_file ./data/sampled_locations.csv \\\n    --indices_range 0 250000\n\n## resample and download new locations with rtree/grid overlap search\npython ssl4eo_downloader.py \\\n    --save_path ./data \\\n    --collection COPERNICUS/S2 \\\n    --meta_cloud_name CLOUDY_PIXEL_PERCENTAGE \\\n    --cloud_pct 20 \\\n    --dates 2021-12-21 2021-09-22 2021-06-21 2021-03-20 \\\n    --radius 1320 \\\n    --bands B1 B2 B3 B4 B5 B6 B7 B8 B8A B9 B10 B11 B12 \\\n    --crops 44 264 264 264 132 132 132 264 132 44 44 132 132 \\\n    --dtype uint16 \\\n    --num_workers 8 \\\n    --log_freq 100 \\\n    --overlap_check rtree \\\n    --indices_range 0 250000\n\n## resume from interruption (e.g. 20 ids processed)\npython ssl4eo_downloader.py \\\n    -- ... \\\n    --resume ./data/checked_locations.csv \\\n    --indices_range 20 250000\n\n\n## Example: download Landsat-8, match SSL4EO-S12 locations but keep same patch size\npython ssl4eo_downloader.py \\\n    --save_path ./data \\\n    --collection LANDSAT/LC08/C02/T1_TOA \\\n    --meta_cloud_name CLOUD_COVER \\\n    --cloud_pct 20 \\\n    --dates 2021-12-21 2021-09-22 2021-06-21 2021-03-20 \\\n    --radius 1980 \\\n    --bands B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 \\\n    --crops 132 132 132 132 132 132 132 264 264 132 132 \\\n    --dtype float32 \\\n    --num_workers 8 \\\n    --log_freq 100 \\\n    --match_file ./data/ssl4eo-s12_center_coords.csv \\\n    --indices_range 0 250000\n\n### Notes\n# By default, the script will sample and download Sentinel-2 L1C tiles (13 bands) with cloud cover less than 20%. # noqa: E501\n# The script will download 250k little-overlap locations, 4 tiles for each location, one for each season (in a two-year buffer). # noqa: E501\n# You may want to extend the buffer to more years by modifying the `get_period()` and `filter_collection()` functions. # noqa: E501\n\n\"\"\"\n\nimport argparse\nimport csv\nimport json\nimport math\nimport os\nimport time\nimport warnings\nfrom collections import OrderedDict\nfrom datetime import date, datetime, timedelta\nfrom multiprocessing.dummy import Lock, Pool\nfrom typing import Any, Dict, List, Optional, Tuple\n\nimport ee\nimport numpy as np\nimport rasterio\nimport shapefile\nimport urllib3\nfrom rasterio.transform import Affine\nfrom rtree import index\nfrom shapely.geometry import Point, shape\nfrom torchvision.datasets.utils import download_and_extract_archive\nfrom tqdm import tqdm\n\nwarnings.simplefilter(\"ignore\", UserWarning)\n\n\n\"\"\" samplers to get locations of interest points\"\"\"\n\n\nclass UniformSampler:\n    def sample_point(self) -> List[float]:\n        lon = np.random.uniform(-180, 180)\n        lat = np.random.uniform(-90, 90)\n        return [lon, lat]\n\n\nclass GaussianSampler:\n    def __init__(\n        self,\n        interest_points: Optional[List[List[float]]] = None,\n        num_cities: int = 1000,\n        std: float = 20,\n    ) -> None:\n        if interest_points is None:\n            cities = self.get_world_cities()\n            self.interest_points = self.get_interest_points(cities, size=num_cities)\n        else:\n            self.interest_points = interest_points\n        self.std = std\n\n    def sample_point(self) -> List[float]:\n        rng = np.random.default_rng()\n        point = rng.choice(self.interest_points)\n        std = self.km2deg(self.std)\n        lon, lat = np.random.normal(loc=point, scale=[std, std])\n        return [lon, lat]\n\n    @staticmethod\n    def get_world_cities(download_root: str = \"world_cities\") -> List[Dict[str, Any]]:\n        url = \"https://simplemaps.com/static/data/world-cities/basic/simplemaps_worldcities_basicv1.71.zip\"  # noqa: E501\n        filename = \"worldcities.csv\"\n        if not os.path.exists(os.path.join(download_root, os.path.basename(url))):\n            download_and_extract_archive(url, download_root)\n        with open(os.path.join(download_root, filename), encoding=\"UTF-8\") as csvfile:\n            reader = csv.DictReader(csvfile, delimiter=\",\", quotechar='\"')\n            cities = []\n            for row in reader:\n                row[\"population\"] = (\n                    row[\"population\"].replace(\".\", \"\") if row[\"population\"] else \"0\"\n                )\n                cities.append(row)\n        return cities\n\n    @staticmethod\n    def get_interest_points(\n        cities: List[Dict[str, str]], size: int = 10000\n    ) -> List[List[float]]:\n        cities = sorted(cities, key=lambda c: int(c[\"population\"]), reverse=True)[:size]\n        points = [[float(c[\"lng\"]), float(c[\"lat\"])] for c in cities]\n        return points\n\n    @staticmethod\n    def km2deg(kms: float, radius: float = 6371) -> float:\n        return kms / (2.0 * radius * np.pi / 360.0)\n\n    @staticmethod\n    def deg2km(deg: float, radius: float = 6371) -> float:\n        return deg * (2.0 * radius * np.pi / 360.0)\n\n\nclass BoundedUniformSampler:\n    def __init__(self, boundaries: shape = None) -> None:\n        if boundaries is None:\n            self.boundaries = self.get_country_boundaries()\n        else:\n            self.boundaries = boundaries\n\n    def sample_point(self) -> List[float]:\n        minx, miny, maxx, maxy = self.boundaries.bounds\n        lon = np.random.uniform(minx, maxx)\n        lat = np.random.uniform(miny, maxy)\n        p = Point(lon, lat)\n        if self.boundaries.contains(p):\n            return [p.x, p.y]\n        else:\n            return self.sample_point()\n\n    @staticmethod\n    def get_country_boundaries(\n        download_root: str = os.path.expanduser(\"~/.cache/naturalearth\"),\n    ) -> shape:\n        url = \"https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/cultural/ne_110m_admin_0_countries.zip\"  # noqa: E501\n        filename = \"ne_110m_admin_0_countries.shp\"\n        if not os.path.exists(os.path.join(download_root, os.path.basename(url))):\n            download_and_extract_archive(url, download_root)\n        sf = shapefile.Reader(os.path.join(download_root, filename))\n        return shape(sf.shapes().__geo_interface__)\n\n\nclass OverlapError(Exception):\n    pass\n\n\ndef date2str(date: datetime) -> str:\n    return date.strftime(\"%Y-%m-%d\")\n\n\ndef get_period(date: datetime, days: int = 5) -> Tuple[str, str, str, str]:\n    date1 = date - timedelta(days=days / 2)\n    date2 = date + timedelta(days=days / 2)\n    date3 = date1 - timedelta(days=365)\n    date4 = date2 - timedelta(days=365)\n    return (\n        date2str(date1),\n        date2str(date2),\n        date2str(date3),\n        date2str(date4),\n    )  # two-years buffer\n\n\n\"\"\"get collection and remove clouds from ee\"\"\"\n\n\ndef maskS2clouds(args: Any, image: ee.Image) -> ee.Image:\n    qa = image.select(args.qa_band)\n    cloudBitMask = 1 << args.qa_cloud_bit\n    # Both flags should be set to zero, indicating clear conditions.\n    mask = qa.bitwiseAnd(cloudBitMask).eq(0)\n    return image.updateMask(mask)\n\n\ndef get_collection(\n    collection_name: str, meta_cloud_name: str, cloud_pct: float\n) -> ee.ImageCollection:\n    collection = ee.ImageCollection(collection_name)\n    collection = collection.filter(ee.Filter.lt(meta_cloud_name, cloud_pct))\n    # Uncomment the following line if you want to apply cloud masking.\n    # collection = collection.map(maskS2clouds, args)\n    return collection\n\n\ndef filter_collection(\n    collection: ee.ImageCollection,\n    coords: List[float],\n    period: Tuple[str, str, str, str],\n) -> ee.ImageCollection:\n    filtered = collection\n    if period is not None:\n        # filtered = filtered.filterDate(*period)  # filter time, if there's one period\n        filtered = filtered.filter(\n            ee.Filter.Or(\n                ee.Filter.date(period[0], period[1]),\n                ee.Filter.date(period[2], period[3]),\n            )\n        )  # filter time, if there're two periods\n\n    filtered = filtered.filterBounds(ee.Geometry.Point(coords))  # filter region\n\n    if filtered.size().getInfo() == 0:\n        raise ee.EEException(\n            f\"ImageCollection.filter: No suitable images found in ({coords[1]:.4f}, {coords[0]:.4f}) between {period[0]} and {period[1]}.\"  # noqa: E501\n        )\n    return filtered\n\n\ndef center_crop(\n    img: np.ndarray[Any, np.dtype[Any]], out_size: Tuple[int, int]\n) -> np.ndarray[Any, np.dtype[Any]]:\n    image_height, image_width = img.shape[:2]\n    crop_height, crop_width = out_size\n    crop_top = (image_height - crop_height + 1) // 2\n    crop_left = (image_width - crop_width + 1) // 2\n    return img[crop_top : crop_top + crop_height, crop_left : crop_left + crop_width]\n\n\ndef adjust_coords(\n    coords: List[List[float]], old_size: Tuple[int, int], new_size: Tuple[int, int]\n) -> List[List[float]]:\n    xres = (coords[1][0] - coords[0][0]) / old_size[1]\n    yres = (coords[0][1] - coords[1][1]) / old_size[0]\n    xoff = int((old_size[1] - new_size[1] + 1) * 0.5)\n    yoff = int((old_size[0] - new_size[0] + 1) * 0.5)\n    return [\n        [coords[0][0] + (xoff * xres), coords[0][1] - (yoff * yres)],\n        [\n            coords[0][0] + ((xoff + new_size[1]) * xres),\n            coords[0][1] - ((yoff + new_size[0]) * yres),\n        ],\n    ]\n\n\ndef get_properties(image: ee.Image) -> Any:\n    return image.getInfo()\n\n\ndef get_patch(\n    collection: ee.ImageCollection,\n    center_coord: List[float],\n    radius: float,\n    bands: List[str],\n    crop: Optional[Dict[str, Any]] = None,\n    dtype: str = \"float32\",\n) -> Dict[str, Any]:\n    image = collection.sort(\"system:time_start\", False).first()  # get most recent\n    region = (\n        ee.Geometry.Point(center_coord).buffer(radius).bounds()\n    )  # sample region bound\n    patch = image.select(*bands).sampleRectangle(region, defaultValue=0)\n\n    features = patch.getInfo()  # the actual download\n\n    raster = OrderedDict()\n    for band in bands:\n        img = np.atleast_3d(features[\"properties\"][band])\n        if crop is not None:\n            img = center_crop(img, out_size=crop[band])\n        raster[band] = img.astype(dtype)\n\n    coords0 = np.array(features[\"geometry\"][\"coordinates\"][0])\n    coords = [\n        [coords0[:, 0].min(), coords0[:, 1].max()],\n        [coords0[:, 0].max(), coords0[:, 1].min()],\n    ]\n    if crop is not None:\n        band = bands[0]\n        old_size = (\n            len(features[\"properties\"][band]),\n            len(features[\"properties\"][band][0]),\n        )\n        new_size = raster[band].shape[:2]\n        coords = adjust_coords(coords, old_size, new_size)\n\n    return OrderedDict(\n        {\"raster\": raster, \"coords\": coords, \"metadata\": get_properties(image)}\n    )\n\n\n\"\"\" get data --- match from pre-sampled locations \"\"\"\n\n\ndef get_random_patches_match(\n    idx: int,\n    collection: ee.ImageCollection,\n    bands: List[str],\n    crops: Dict[str, Any],\n    dtype: str,\n    dates: List[Any],\n    radius: float,\n    debug: bool = False,\n    match_coords: Dict[str, Any] = {},\n) -> Tuple[Optional[List[Dict[str, Any]]], List[float]]:\n    # (lon,lat) of idx patch\n    coords = match_coords[str(idx)]\n\n    # random +- 30 days of random days within 1 year from the reference dates\n    periods = [get_period(date, days=60) for date in dates]\n\n    try:\n        filtered_collections = [\n            filter_collection(collection, coords, p) for p in periods\n        ]\n        patches = [\n            get_patch(c, coords, radius, bands=bands, crop=crops, dtype=dtype)\n            for c in filtered_collections\n        ]\n\n    except (ee.EEException, urllib3.exceptions.HTTPError) as e:\n        if debug:\n            print(e)\n        return None, coords\n\n    return patches, coords\n\n\n\"\"\" sample new coord, check overlap, and get data --- rtree \"\"\"\n\n\ndef get_random_patches_rtree(\n    idx: int,\n    collection: ee.ImageCollection,\n    bands: List[str],\n    crops: Dict[str, Any],\n    dtype: str,\n    sampler: GaussianSampler,\n    dates: List[Any],\n    radius: float,\n    debug: bool = False,\n    rtree_obj: index.Index = None,\n) -> Tuple[List[Dict[str, Any]], List[float]]:\n    # (lon,lat) of top-10000 cities\n    coords = sampler.sample_point()\n\n    # use rtree to avoid strong overlap\n    try:\n        new_coord = (coords[0], coords[1])\n        for i in rtree_obj.nearest(new_coord, num_results=1, objects=True):\n            distance = np.sqrt(\n                sampler.deg2km(abs(new_coord[0] - i.bbox[2])) ** 2\n                + sampler.deg2km(abs(new_coord[1] - i.bbox[3])) ** 2\n            )\n            if distance < (1.5 * radius / 1000):\n                raise OverlapError\n        rtree_obj.insert(\n            len(rtree_obj) - 1, (new_coord[0], new_coord[1], new_coord[0], new_coord[1])\n        )\n\n    except OverlapError:\n        patches, center_coord = get_random_patches_rtree(\n            idx,\n            collection,\n            bands,\n            crops,\n            dtype,\n            sampler,\n            dates,\n            radius,\n            debug,\n            rtree_obj,\n        )\n\n    # random +- 30 days of random days within 1 year from the reference dates\n    periods = [get_period(date, days=60) for date in dates]\n\n    try:\n        filtered_collections = [\n            filter_collection(collection, coords, p) for p in periods\n        ]\n        patches = [\n            get_patch(c, coords, radius, bands=bands, crop=crops, dtype=dtype)\n            for c in filtered_collections\n        ]\n        center_coord = coords\n\n    except (ee.EEException, urllib3.exceptions.HTTPError) as e:\n        if debug:\n            print(e)\n        rtree_obj.insert(\n            len(rtree_obj) - 1, (new_coord[0], new_coord[1], new_coord[0], new_coord[1])\n        )  # prevent from sampling an old coord that doesn't fit the collection\n        patches, center_coord = get_random_patches_rtree(\n            idx,\n            collection,\n            bands,\n            crops,\n            dtype,\n            sampler,\n            dates,\n            radius,\n            debug,\n            rtree_obj,\n        )\n\n    return patches, center_coord\n\n\n\"\"\" sample new coord, check overlap, and get data --- grid \"\"\"\n\n\ndef get_random_patches_grid(\n    idx: int,\n    collection: ee.ImageCollection,\n    bands: List[str],\n    crops: Dict[str, Any],\n    dtype: str,\n    sampler: GaussianSampler,\n    dates: List[Any],\n    radius: float,\n    debug: bool = False,\n    grid_dict: Dict[Tuple[int, int], Any] = {},\n) -> Tuple[List[Dict[str, Any]], List[float]]:\n    # (lon,lat) of top-10000 cities\n    coords = sampler.sample_point()\n\n    # avoid strong overlap\n    try:\n        new_coord = (coords[0], coords[1])\n        gridIndex = (math.floor(new_coord[0] + 180), math.floor(new_coord[1] + 90))\n\n        if gridIndex not in grid_dict.keys():\n            grid_dict[gridIndex] = {new_coord}\n        else:\n            for coord in grid_dict[gridIndex]:\n                distance = np.sqrt(\n                    sampler.deg2km(abs(new_coord[0] - coord[0])) ** 2\n                    + sampler.deg2km(abs(new_coord[1] - coord[1])) ** 2\n                )\n                if distance < (1.5 * radius / 1000):\n                    raise OverlapError\n            grid_dict[gridIndex].add(new_coord)\n\n    except OverlapError:\n        patches, center_coord = get_random_patches_grid(\n            idx,\n            collection,\n            bands,\n            crops,\n            dtype,\n            sampler,\n            dates,\n            radius,\n            debug,\n            grid_dict=grid_dict,\n        )\n\n    # random +- 15 days of random days within 1 year from the reference dates\n    periods = [get_period(date, days=30) for date in dates]\n\n    try:\n        filtered_collections = [\n            filter_collection(collection, coords, p) for p in periods\n        ]\n        patches = [\n            get_patch(c, coords, radius, bands=bands, crop=crops, dtype=dtype)\n            for c in filtered_collections\n        ]\n\n        center_coord = coords\n\n    except (ee.EEException, urllib3.exceptions.HTTPError) as e:\n        if debug:\n            print(e)\n        patches, center_coord = get_random_patches_grid(\n            idx,\n            collection,\n            bands,\n            crops,\n            dtype,\n            sampler,\n            dates,\n            radius,\n            debug,\n            grid_dict=grid_dict,\n        )\n\n    return patches, center_coord\n\n\ndef save_geotiff(\n    img: np.ndarray[Any, np.dtype[Any]], coords: List[List[float]], filename: str\n) -> None:\n    height, width, channels = img.shape\n    xres = (coords[1][0] - coords[0][0]) / width\n    yres = (coords[0][1] - coords[1][1]) / height\n    transform = Affine.translation(\n        coords[0][0] - xres / 2, coords[0][1] + yres / 2\n    ) * Affine.scale(xres, -yres)\n    profile = {\n        \"driver\": \"GTiff\",\n        \"width\": width,\n        \"height\": height,\n        \"count\": channels,\n        \"crs\": \"+proj=latlong\",\n        \"transform\": transform,\n        \"dtype\": img.dtype,\n        \"compress\": \"lzw\",\n        \"predictor\": 2,\n    }\n    with rasterio.open(filename, \"w\", **profile) as f:\n        f.write(img.transpose(2, 0, 1))\n\n\ndef save_patch(\n    raster: Dict[str, Any],\n    coords: List[List[float]],\n    metadata: Dict[str, Any],\n    path: str,\n) -> None:\n    patch_id = metadata[\"properties\"][\"system:index\"]\n    patch_path = os.path.join(path, patch_id)\n    os.makedirs(patch_path, exist_ok=True)\n\n    for band, img in raster.items():\n        save_geotiff(img, coords, os.path.join(patch_path, f\"{band}.tif\"))\n\n    with open(os.path.join(patch_path, \"metadata.json\"), \"w\") as f:\n        json.dump(metadata, f)\n\n\nclass Counter:\n    def __init__(self, start: int = 0) -> None:\n        self.value = start\n        self.lock = Lock()\n\n    def update(self, delta: int = 1) -> int:\n        with self.lock:\n            self.value += delta\n            return self.value\n\n\ndef fix_random_seeds(seed: int = 42) -> None:\n    np.random.seed(seed)\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\n        \"--save_path\", type=str, default=\"./data/\", help=\"dir to save data\"\n    )\n    # collection properties\n    parser.add_argument(\n        \"--collection\", type=str, default=\"COPERNICUS/S2\", help=\"GEE collection name\"\n    )\n    parser.add_argument(\n        \"--qa_band\", type=str, default=\"QA60\", help=\"qa band name (optional)\"\n    )  # optional\n    parser.add_argument(\n        \"--qa_cloud_bit\", type=int, default=10, help=\"qa band cloud bit (optional)\"\n    )  # optional\n    parser.add_argument(\n        \"--meta_cloud_name\",\n        type=str,\n        default=\"CLOUDY_PIXEL_PERCENTAGE\",\n        help=\"meta data cloud percentage name\",\n    )\n    parser.add_argument(\n        \"--cloud_pct\", type=int, default=20, help=\"cloud percentage threshold\"\n    )\n    # patch properties\n    parser.add_argument(\n        \"--dates\",\n        type=str,\n        nargs=\"+\",\n        default=[\"2021-12-21\", \"2021-09-22\", \"2021-06-21\", \"2021-03-20\"],\n        help=\"reference dates\",\n    )\n    parser.add_argument(\n        \"--radius\", type=int, default=1320, help=\"patch radius in meters\"\n    )\n    parser.add_argument(\n        \"--bands\",\n        type=str,\n        nargs=\"+\",\n        default=[\n            \"B1\",\n            \"B2\",\n            \"B3\",\n            \"B4\",\n            \"B5\",\n            \"B6\",\n            \"B7\",\n            \"B8\",\n            \"B8A\",\n            \"B9\",\n            \"B10\",\n            \"B11\",\n            \"B12\",\n        ],\n        help=\"bands to download\",\n    )\n    parser.add_argument(\n        \"--crops\",\n        type=int,\n        nargs=\"+\",\n        default=[44, 264, 264, 264, 132, 132, 132, 264, 132, 44, 44, 132, 132],\n        help=\"crop size for each band\",\n    )\n    parser.add_argument(\"--dtype\", type=str, default=\"float32\", help=\"data type\")\n    # sampler properties\n    parser.add_argument(\n        \"--num_cities\", type=int, default=10000, help=\"number of cities to sample\"\n    )\n    parser.add_argument(\n        \"--std\", type=int, default=50, help=\"std of gaussian distribution\"\n    )\n    # download settings\n    parser.add_argument(\"--num_workers\", type=int, default=8, help=\"number of workers\")\n    parser.add_argument(\"--log_freq\", type=int, default=10, help=\"print frequency\")\n    parser.add_argument(\n        \"--resume\", type=str, default=None, help=\"resume from a previous run\"\n    )\n    # sampler options\n    # op1: match pre-sampled coordinates and indexes\n    parser.add_argument(\n        \"--match_file\",\n        type=str,\n        default=None,\n        help=\"match pre-sampled coordinates and indexes\",\n    )\n    # op2-3: resample from scratch, grid or rtree based overlap check\n    parser.add_argument(\n        \"--overlap_check\",\n        type=str,\n        default=\"rtree\",\n        choices=[\"grid\", \"rtree\", None],\n        help=\"overlap check method\",\n    )\n    # number of locations to download\n    parser.add_argument(\n        \"--indices_range\",\n        type=int,\n        nargs=2,\n        default=[0, 250000],\n        help=\"indices to download\",\n    )\n    # debug\n    parser.add_argument(\"--debug\", action=\"store_true\", help=\"debug mode\")\n\n    args = parser.parse_args()\n\n    fix_random_seeds(seed=42)\n\n    # initialize ee\n    ee.Initialize()\n\n    # get data collection (remove clouds)\n    collection = get_collection(args.collection, args.meta_cloud_name, args.cloud_pct)\n\n    # initialize sampler\n    sampler = GaussianSampler(num_cities=args.num_cities, std=args.std)\n\n    dates = []\n    for d in args.dates:\n        dates.append(date.fromisoformat(d))\n\n    bands = args.bands\n    crops = {}\n    for i, band in enumerate(bands):\n        crops[band] = (args.crops[i], args.crops[i])\n    dtype = args.dtype\n\n    # if resume\n    ext_coords = {}\n    ext_flags = {}\n    if args.resume:\n        ext_path = args.resume\n        with open(ext_path) as csv_file:\n            reader = csv.reader(csv_file)\n            for row in reader:\n                key = row[0]\n                val1 = float(row[1])\n                val2 = float(row[2])\n                ext_coords[key] = (val1, val2)  # lon, lat\n                ext_flags[key] = int(row[3])  # success or not\n    else:\n        ext_path = os.path.join(args.save_path, \"checked_locations.csv\")\n\n    # if match from pre-sampled coords (e.g. SSL4EO-S12)\n    if args.match_file:\n        match_coords = {}\n        with open(args.match_file) as csv_file:\n            reader = csv.reader(csv_file)\n            for row in reader:\n                key = row[0]\n                val1 = float(row[1])\n                val2 = float(row[2])\n                match_coords[key] = (val1, val2)  # lon, lat\n    # else need to check overlap\n    # build grid or rtree from existing coordinates\n    elif args.overlap_check is not None:\n        grid_dict: Dict[Any, Any] = {}\n        rtree_coords = index.Index()\n        if args.resume:\n            print(\"Load existing locations.\")\n            for i, key in enumerate(tqdm(ext_coords.keys())):\n                c = ext_coords[key]\n                rtree_coords.insert(i, (c[0], c[1], c[0], c[1]))\n                gridIndex = (math.floor(c[0] + 180), math.floor(c[1] + 90))\n                if gridIndex not in grid_dict.keys():\n                    grid_dict[gridIndex] = {c}\n                else:\n                    grid_dict[gridIndex].add(c)\n    else:\n        raise NotImplementedError\n\n    start_time = time.time()\n    counter = Counter()\n\n    def worker(idx: int) -> None:\n        if str(idx) in ext_coords.keys():\n            if args.match_file:  # skip all processed ids\n                return\n            else:\n                if ext_flags[str(idx)] != 0:  # only skip downloaded ids\n                    return\n\n        if args.match_file:\n            patches, center_coord = get_random_patches_match(\n                idx,\n                collection,\n                bands,\n                crops,\n                dtype,\n                dates,\n                radius=args.radius,\n                debug=args.debug,\n                match_coords=match_coords,\n            )\n        elif args.overlap_check == \"rtree\":\n            patches, center_coord = get_random_patches_rtree(\n                idx,\n                collection,\n                bands,\n                crops,\n                dtype,\n                sampler,\n                dates,\n                radius=args.radius,\n                debug=args.debug,\n                rtree_obj=rtree_coords,\n            )\n        elif args.overlap_check == \"grid\":\n            patches, center_coord = get_random_patches_grid(\n                idx,\n                collection,\n                bands,\n                crops,\n                dtype,\n                sampler,\n                dates,\n                radius=args.radius,\n                debug=args.debug,\n                grid_dict=grid_dict,\n            )\n        else:\n            raise NotImplementedError\n\n        if patches is not None:\n            if args.save_path is not None:\n                # s2c\n                location_path = os.path.join(args.save_path, \"imgs\", f\"{idx:06d}\")\n                os.makedirs(location_path, exist_ok=True)\n                for patch in patches:\n                    save_patch(\n                        raster=patch[\"raster\"],\n                        coords=patch[\"coords\"],\n                        metadata=patch[\"metadata\"],\n                        path=location_path,\n                    )\n\n            count = counter.update(1)\n            if count % args.log_freq == 0:\n                print(f\"Downloaded {count} images in {time.time() - start_time:.3f}s.\")\n        else:\n            print(\"no suitable image for location %d.\" % (idx))\n\n        # add to existing checked locations\n        with open(ext_path, \"a\") as f:\n            writer = csv.writer(f)\n            if patches is not None:\n                if args.match_file:\n                    success = 2\n                else:\n                    success = 1\n            else:\n                success = 0\n            data = [idx, center_coord[0], center_coord[1], success]\n            writer.writerow(data)\n\n        return\n\n    # set indices\n    if args.match_file is not None:\n        indices = []\n        for key in match_coords.keys():\n            indices.append(int(key))\n        indices = indices[args.indices_range[0] : args.indices_range[1]]\n    elif args.indices_range is not None:\n        indices = list(range(args.indices_range[0], args.indices_range[1]))\n    else:\n        print(\"Please set up indices.\")\n        raise NotImplementedError\n\n    if args.num_workers == 0:\n        for i in indices:\n            worker(i)\n    else:\n        # parallelism data\n        with Pool(processes=args.num_workers) as p:\n            p.map(worker, indices)\n"
  },
  {
    "path": "src/download_data/ssl4eo_s12_downloader.py",
    "content": "\n''' Sample and download Sentinel-1/2 tiles with Google Earth Engine\n\n#### run the script:\n### option 1: match ssl4eo-s12, and fill unmatched locations with newly sampled locations\n# match ssl4eo-s12 ids, unavailable ids skip\n!python ssl4eo_s12_downloader.py --save_path ./data --num_workers 8 --cloud_pct 20 --log_freq 100 --match_file ssl4eo-s12_coords_v1.csv --indices_range 0 250000\n\n# fill unmatched ids with rtree overlap search\n!python ssl4eo_s12_downloader.py --save_path ./data --num_workers 8 --cloud_pct 20 --log_freq 100 --resume ./data/checked_locations.csv --overlap_check rtree --indices_range 0 250000\n\n### option 2: resample new locations\n# (op1) resample new ids with rtree overlap search\n!python ssl4eo_s12_downloader.py --save_path ./data --num_workers 8 --cloud_pct 20 --log_freq 100 --overlap_check rtree --indices_range 0 250000\n\n# (op2) resample new ids with grid overlap search\n!python ssl4eo_s12_downloader.py --save_path ./data --num_workers 8 --cloud_pct 20 --log_freq 100 --overlap_check grid --indices_range 0 250000\n\n### (optional) resume from interruption\n!python ssl4eo_s12_downloader.py --save_path ./data --num_workers 8 --cloud_pct 20 --log_freq 100 --resume ./data/checked_locations.csv --overlap_check rtree --indices_range 0 250000\n\n\n\n'''\n\nimport argparse\nimport csv\nimport json\nfrom multiprocessing.dummy import Pool, Lock\nimport os\nfrom collections import OrderedDict\nimport time\nfrom datetime import datetime, timedelta, date\nimport warnings\nwarnings.simplefilter('ignore', UserWarning)\n\nimport ee\nimport numpy as np\nimport rasterio\nimport urllib3\nfrom rasterio.transform import Affine\n# from skimage.exposure import rescale_intensity\nfrom torchvision.datasets.utils import download_and_extract_archive\nimport shapefile\nfrom shapely.geometry import shape, Point\n\nimport pickle\nimport pdb\nimport math\nfrom rtree import index\n\nALL_BANDS_L2A = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B9', 'B11', 'B12']\nALL_BANDS_L1C = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B9', 'B10', 'B11', 'B12']\nRGB_BANDS = ['B4', 'B3', 'B2']\nALL_BANDS_GRD = ['VV','VH']\n\n\n''' samplers to get locations of interest points'''\nclass GeoSampler:\n\n    def sample_point(self):\n        raise NotImplementedError()\n\n\nclass UniformSampler(GeoSampler):\n\n    def sample_point(self):\n        #fix_random_seeds()\n        lon = np.random.uniform(-180, 180)\n        lat = np.random.uniform(-90, 90)\n        return [lon, lat]\n\n\nclass GaussianSampler(GeoSampler):\n\n    def __init__(self, interest_points=None, num_cities=1000, std=20):\n        if interest_points is None:\n            cities = self.get_world_cities()\n            self.interest_points = self.get_interest_points(cities,size=num_cities)\n        else:\n            self.interest_points = interest_points\n        self.std = std\n\n    def sample_point(self,idx):\n        #pdb.set_trace()\n        \n        #rng = np.random.default_rng(seed=idx)\n        rng = np.random.default_rng()\n        point = rng.choice(self.interest_points)\n        std = self.km2deg(self.std)\n        #fix_random_seeds(idx)\n        lon, lat = np.random.normal(loc=point, scale=[std, std])\n        return [lon, lat]\n\n    @staticmethod\n    def get_world_cities(download_root=os.path.expanduser('./world_cities/')):\n        url = 'https://simplemaps.com/static/data/world-cities/basic/simplemaps_worldcities_basicv1.71.zip'\n        filename = 'worldcities.csv'\n        if not os.path.exists(os.path.join(download_root, os.path.basename(url))):\n            download_and_extract_archive(url, download_root)\n        with open(os.path.join(download_root, filename),encoding='UTF-8') as csvfile:\n            reader = csv.DictReader(csvfile, delimiter=',', quotechar='\"')\n            cities = []\n            for row in reader:\n                row['population'] = row['population'].replace('.', '') if row['population'] else '0'\n                cities.append(row)\n        return cities\n\n    @staticmethod\n    def get_interest_points(cities, size=10000):\n        cities = sorted(cities, key=lambda c: int(c['population']), reverse=True)[:size]\n        points = [[float(c['lng']), float(c['lat'])] for c in cities]\n        return points\n\n    @staticmethod\n    def km2deg(kms, radius=6371):\n        return kms / (2.0 * radius * np.pi / 360.0)\n    @staticmethod    \n    def deg2km(deg, radius=6371):\n        return deg * (2.0 * radius * np.pi / 360.0)\n\n\nclass BoundedUniformSampler(GeoSampler):\n\n    def __init__(self, boundaries=None):\n        if boundaries is None:\n            self.boundaries = self.get_country_boundaries()\n        else:\n            self.boundaries = boundaries\n\n    def sample_point(self):\n        minx, miny, maxx, maxy = self.boundaries.bounds\n        #fix_random_seeds()\n        lon = np.random.uniform(minx, maxx)\n        lat = np.random.uniform(miny, maxy)\n        p = Point(lon, lat)\n        if self.boundaries.contains(p):\n            return [p.x, p.y]\n        else:\n            return self.sample_point()\n\n    @staticmethod\n    def get_country_boundaries(download_root=os.path.expanduser('~/.cache/naturalearth')):\n        url = 'https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/cultural/ne_110m_admin_0_countries.zip'\n        filename = 'ne_110m_admin_0_countries.shp'\n        if not os.path.exists(os.path.join(download_root, os.path.basename(url))):\n            download_and_extract_archive(url, download_root)\n        sf = shapefile.Reader(os.path.join(download_root, filename))\n        return shape(sf.shapes().__geo_interface__)\n\n\nclass OverlapError(Exception):\n    pass\n\n\ndef date2str(date):\n    return date.strftime('%Y-%m-%d')\n\n\ndef get_period(date, days=5):\n    date1 = date - timedelta(days=days / 2)\n    date2 = date + timedelta(days=days / 2)\n    return date2str(date1), date2str(date2)\n\n\n'''get collection and remove clouds from ee'''\n\ndef maskS2clouds(image):\n    qa = image.select('QA60')\n    # Bits 10 and 11 are clouds and cirrus, respectively.\n    cloudBitMask = 1 << 10\n    cirrusBitMask = 1 << 11\n    # Both flags should be set to zero, indicating clear conditions.\n    mask = qa.bitwiseAnd(cloudBitMask).eq(0)\n    mask = mask.bitwiseAnd(cirrusBitMask).eq(0)\n    return image.updateMask(mask)\n\n\ndef get_collection_s2a(cloud_pct=20):\n    collection = ee.ImageCollection('COPERNICUS/S2_SR')\n    collection = collection.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', cloud_pct))\n    #collection = collection.map(maskS2clouds)\n    return collection\n\ndef get_collection_s2c(cloud_pct=20):\n    collection = ee.ImageCollection('COPERNICUS/S2')\n    collection = collection.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', cloud_pct))\n    #collection = collection.map(maskS2clouds)\n    return collection\n\ndef get_collection_s1():\n    collection = ee.ImageCollection('COPERNICUS/S1_GRD')\n    return collection\n\ndef filter_collection(collection, coords, period=None):\n    #pdb.set_trace()\n    filtered = collection\n    if period is not None:\n        filtered = filtered.filterDate(*period)  # filter time\n    filtered = filtered.filterBounds(ee.Geometry.Point(coords))  # filter region\n\n    if filtered.size().getInfo() == 0:\n        #pdb.set_trace()\n        raise ee.EEException(\n            f'ImageCollection.filter: No suitable images found in ({coords[1]:.4f}, {coords[0]:.4f}) between {period[0]} and {period[1]}.')\n    return filtered\n\ndef filter_collection_s1(collection, coords, period=None):\n    #pdb.set_trace()\n    filtered = collection\n    if period is not None:\n        filtered = filtered.filterDate(*period)  # filter time\n    filtered = filtered.filterBounds(ee.Geometry.Point(coords))  # filter region\n\n    filtered = filtered.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV')).filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))\n    filtered = filtered.filter(ee.Filter.eq('instrumentMode', 'IW'))\n    #filtered = filtered.filter(ee.Filter.eq('orbitProperties_pass', 'ASCENDING'))\n    #filtered = filtered.filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))\n\n    if filtered.size().getInfo() == 0:\n        raise ee.EEException(\n            f'ImageCollection.filter: No suitable images found in ({coords[1]:.4f}, {coords[0]:.4f}) between {period[0]} and {period[1]}.')\n    return filtered\n\n\ndef center_crop(img, out_size):\n    image_height, image_width = img.shape[:2]\n    crop_height, crop_width = out_size\n    crop_top = int((image_height - crop_height + 1) * 0.5)\n    crop_left = int((image_width - crop_width + 1) * 0.5)\n    return img[crop_top:crop_top+crop_height, crop_left:crop_left+crop_width]\n\n\ndef adjust_coords(coords, old_size, new_size):\n    xres = (coords[1][0] - coords[0][0]) / old_size[1]\n    yres = (coords[0][1] - coords[1][1]) / old_size[0]\n    xoff = int((old_size[1] - new_size[1] + 1) * 0.5)\n    yoff = int((old_size[0] - new_size[0] + 1) * 0.5)\n    return [\n        [coords[0][0] + (xoff * xres), coords[0][1] - (yoff * yres)],\n        [coords[0][0] + ((xoff + new_size[1]) * xres), coords[0][1] - ((yoff + new_size[0]) * yres)]\n    ]\n\n\ndef get_properties(image):\n    #properties = {}\n    #for property in image.propertyNames().getInfo():\n    #    properties[property] = image.get(property)\n    #return ee.Dictionary(properties).getInfo()\n    return image.getInfo()\n\ndef get_patch_s1(collection, coords, radius, bands=None, crop=None):\n\n    image = collection.sort('system:time_start', False).first()  # get most recent\n    region = ee.Geometry.Point(coords).buffer(radius).bounds() # sample region bound\n\n    patch = image.select(*bands).sampleRectangle(region,defaultValue=0)\n    features = patch.getInfo()  # the actual download\n\n    raster = OrderedDict()\n    for band in bands:\n        img = np.atleast_3d(features['properties'][band])\n        if crop is not None:\n            img = center_crop(img, out_size=crop[band])\n        #img = rescale_intensity(img, in_range=(0, 1), out_range=np.uint8)\n        raster[band] = img.astype('float32')\n\n    coords = np.array(features['geometry']['coordinates'][0])\n    coords = [\n        [coords[:, 0].min(), coords[:, 1].max()],\n        [coords[:, 0].max(), coords[:, 1].min()]\n    ]\n    if crop is not None:\n        band = bands[0]\n        old_size = (len(features['properties'][band]), len(features['properties'][band][0]))\n        new_size = raster[band].shape[:2]\n        coords = adjust_coords(coords, old_size, new_size)\n\n    return OrderedDict({\n        'raster': raster,\n        'coords': coords,\n        'metadata': get_properties(image)\n    })\n\n\ndef get_patch_s2(collection, coords, radius, bands=None, crop=None):\n    #pdb.set_trace()\n    if bands is None:\n        bands = RGB_BANDS\n\n    image = collection.sort('system:time_start', False).first()  # get most recent\n    region = ee.Geometry.Point(coords).buffer(radius).bounds() # sample region bound\n    #pdb.set_trace()\n    patch = image.select(*bands).sampleRectangle(region,defaultValue=0)\n\n    features = patch.getInfo()  # the actual download\n\n    raster = OrderedDict()\n    for band in bands:\n        img = np.atleast_3d(features['properties'][band])\n        if crop is not None:\n            img = center_crop(img, out_size=crop[band])\n        #img = rescale_intensity(img, in_range=(0, 1), out_range=np.uint8)\n        raster[band] = img.astype('uint16')\n\n    coords = np.array(features['geometry']['coordinates'][0])\n    coords = [\n        [coords[:, 0].min(), coords[:, 1].max()],\n        [coords[:, 0].max(), coords[:, 1].min()]\n    ]\n    if crop is not None:\n        band = bands[0]\n        old_size = (len(features['properties'][band]), len(features['properties'][band][0]))\n        new_size = raster[band].shape[:2]\n        coords = adjust_coords(coords, old_size, new_size)\n\n    return OrderedDict({\n        'raster': raster,\n        'coords': coords,\n        'metadata': get_properties(image)\n    })\n\n\ndef get_random_patches_grid(idx, collections, bands, crops, sampler, dates, radius, debug=False, grid_dict={}):\n    ## (lon,lat) of top-10000 cities\n    coords = sampler.sample_point(idx)\n    \n    # avoid strong overlap\n    try:\n        new_coord = (coords[0],coords[1])\n        gridIndex = (math.floor(new_coord[0]+180),math.floor(new_coord[1]+90))\n        \n        if not gridIndex in grid_dict.keys():\n            grid_dict[gridIndex] = {new_coord}\n        else:\n            for coord in grid_dict[gridIndex]:\n                distance = np.sqrt(sampler.deg2km(abs(new_coord[0]-coord[0]))**2 + sampler.deg2km(abs(new_coord[1]-coord[1]))**2)\n                if distance < (1.5 * radius/1000):\n                    raise OverlapError\n            grid_dict[gridIndex].add(new_coord)\n            \n    except OverlapError:\n        patches_s1, patches_s2c, patches_s2a, center_coord = get_random_patches_grid(idx, collections, bands, crops, sampler, dates, radius, debug, grid_dict)\n    \n    \n    ## random +- 15 days of random days within 1 year from the reference dates\n    #fix_random_seeds(idx)\n    delta = timedelta(days=np.random.randint(365))\n    periods = [get_period(date - delta, days=30) for date in dates]\n\n    collection_s1 = collections['s1_grd']\n    collection_s2c = collections['s2_l1c']\n    collection_s2a = collections['s2_l2a']\n\n    bands_s1 = bands['s1_grd']\n    bands_s2c = bands['s2_l1c']\n    bands_s2a = bands['s2_l2a']\n\n    crop_s1 = crops['s1_grd']\n    crop_s2c = crops['s2_l1c']\n    crop_s2a = crops['s2_l2a']\n\n    try:\n        \n        filtered_collections_s2c = [filter_collection(collection_s2c, coords, p) for p in periods]\n        patches_s2c = [get_patch_s2(c, coords, radius, bands=bands_s2c, crop=crop_s2c) for c in filtered_collections_s2c]\n        filtered_collections_s2a = [filter_collection(collection_s2a, coords, p) for p in periods]\n        patches_s2a = [get_patch_s2(c, coords, radius, bands=bands_s2a, crop=crop_s2a) for c in filtered_collections_s2a]        \n        filtered_collections_s1 = [filter_collection_s1(collection_s1, coords, p) for p in periods]\n        patches_s1 = [get_patch_s1(c, coords, radius, bands=bands_s1, crop=crop_s1) for c in filtered_collections_s1]\n        \n        center_coord = coords\n\n    except (ee.EEException, urllib3.exceptions.HTTPError) as e:\n        if debug:\n            print(e)\n        patches_s1, patches_s2c, patches_s2a, center_coord = get_random_patches_grid(idx, collections, bands, crops, sampler, dates, radius, debug, grid_dict)\n\n    return patches_s1, patches_s2c, patches_s2a, center_coord\n\n\ndef get_random_patches_rtree(idx, collections, bands, crops, sampler, dates, radius, debug=False, rtree_obj=None):\n    ## (lon,lat) of top-10000 cities\n    coords = sampler.sample_point(idx)\n    \n    # use rtree to avoid strong overlap\n    try:\n        new_coord = (coords[0],coords[1])\n        for i in rtree_obj.nearest(new_coord, objects=True):\n            distance = np.sqrt(sampler.deg2km(abs(new_coord[0]-i.bbox[2]))**2 + sampler.deg2km(abs(new_coord[1]-i.bbox[3]))**2)\n            if distance < (1.5 * radius/1000):\n                raise OverlapError\n        rtree_obj.insert(len(rtree_obj)-1, (new_coord[0], new_coord[1], new_coord[0], new_coord[1]))\n\n    except OverlapError:\n        patches_s1, patches_s2c, patches_s2a, center_coord = get_random_patches_rtree(idx, collections, bands, crops, sampler, dates, radius, debug, rtree_obj)\n    \n    ## random +- 30 days of random days within 1 year from the reference dates\n    #fix_random_seeds(idx)\n    delta = timedelta(days=np.random.randint(365))\n    periods = [get_period(date-delta, days=30) for date in dates]\n\n    collection_s1 = collections['s1_grd']\n    collection_s2c = collections['s2_l1c']\n    collection_s2a = collections['s2_l2a']\n\n    bands_s1 = bands['s1_grd']\n    bands_s2c = bands['s2_l1c']\n    bands_s2a = bands['s2_l2a']\n\n    crop_s1 = crops['s1_grd']\n    crop_s2c = crops['s2_l1c']\n    crop_s2a = crops['s2_l2a']\n\n    try:        \n        filtered_collections_s2c = [filter_collection(collection_s2c, coords, p) for p in periods]\n        patches_s2c = [get_patch_s2(c, coords, radius, bands=bands_s2c, crop=crop_s2c) for c in filtered_collections_s2c]\n        filtered_collections_s2a = [filter_collection(collection_s2a, coords, p) for p in periods]\n        patches_s2a = [get_patch_s2(c, coords, radius, bands=bands_s2a, crop=crop_s2a) for c in filtered_collections_s2a]        \n        filtered_collections_s1 = [filter_collection_s1(collection_s1, coords, p) for p in periods]\n        patches_s1 = [get_patch_s1(c, coords, radius, bands=bands_s1, crop=crop_s1) for c in filtered_collections_s1]       \n        center_coord = coords\n\n    except (ee.EEException, urllib3.exceptions.HTTPError) as e:\n        if debug:\n            print(e)\n        rtree_obj.insert(len(rtree_obj)-1, (new_coord[0], new_coord[1], new_coord[0], new_coord[1])) # prevent from sampling an old coord that doesn't fit the collection        \n        patches_s1, patches_s2c, patches_s2a, center_coord = get_random_patches_rtree(idx, collections, bands, crops, sampler, dates, radius, debug, rtree_obj)\n   \n    return patches_s1, patches_s2c, patches_s2a, center_coord\n\n''' match from existing coords (option3) '''\ndef get_random_patches_match(idx, collections, bands, crops, sampler, dates, radius, debug=False, match_coords={}):\n    ## (lon,lat) of idx patch\n    coords = match_coords[str(idx)]\n        \n    ## random +- 30 days of random days within 1 year from the reference dates\n    #fix_random_seeds(idx)\n    delta = timedelta(days=np.random.randint(365))\n    periods = [get_period(date-delta, days=30) for date in dates]\n\n    collection_s1 = collections['s1_grd']\n    collection_s2c = collections['s2_l1c']\n    collection_s2a = collections['s2_l2a']\n\n    bands_s1 = bands['s1_grd']\n    bands_s2c = bands['s2_l1c']\n    bands_s2a = bands['s2_l2a']\n\n    crop_s1 = crops['s1_grd']\n    crop_s2c = crops['s2_l1c']\n    crop_s2a = crops['s2_l2a']\n\n    try:\n        filtered_collections_s2c = [filter_collection(collection_s2c, coords, p) for p in periods]\n        patches_s2c = [get_patch_s2(c, coords, radius, bands=bands_s2c, crop=crop_s2c) for c in filtered_collections_s2c]\n        filtered_collections_s2a = [filter_collection(collection_s2a, coords, p) for p in periods]\n        patches_s2a = [get_patch_s2(c, coords, radius, bands=bands_s2a, crop=crop_s2a) for c in filtered_collections_s2a]        \n        filtered_collections_s1 = [filter_collection_s1(collection_s1, coords, p) for p in periods]\n        patches_s1 = [get_patch_s1(c, coords, radius, bands=bands_s1, crop=crop_s1) for c in filtered_collections_s1]       \n        center_coord = coords              \n\n    except (ee.EEException, urllib3.exceptions.HTTPError) as e:\n        if debug:\n            print(e)\n        return None, None, None, coords\n\n    return patches_s1, patches_s2c, patches_s2a, center_coord\n\n\ndef save_geotiff(img, coords, filename):\n    #pdb.set_trace()\n    height, width, channels = img.shape\n    xres = (coords[1][0] - coords[0][0]) / width\n    yres = (coords[0][1] - coords[1][1]) / height\n    transform = Affine.translation(coords[0][0] - xres / 2, coords[0][1] + yres / 2) * Affine.scale(xres, -yres)\n    profile = {\n        'driver': 'GTiff',\n        'width': width,\n        'height': height,\n        'count': channels,\n        'crs': '+proj=latlong',\n        'transform': transform,\n        'dtype': img.dtype,\n        'compress': 'None'\n    }\n    with rasterio.open(filename, 'w', **profile) as f:\n        f.write(img.transpose(2, 0, 1))\n\n\ndef save_patch(raster, coords, metadata, path, preview=False):\n    #pdb.set_trace()\n    patch_id = metadata['properties']['system:index']\n    patch_path = os.path.join(path, patch_id)\n    os.makedirs(patch_path, exist_ok=True)\n\n    for band, img in raster.items():\n        save_geotiff(img, coords, os.path.join(patch_path, f'{band}.tif'))\n\n    if preview:\n        rgb = np.dstack([raster[band] for band in RGB_BANDS])\n        rgb = rescale_intensity(rgb, in_range=(0, 255 * 0.3), out_range=(0, 255)).astype(np.uint8)\n        save_geotiff(rgb, coords, os.path.join(path, f'{patch_id}.tif'))\n\n    with open(os.path.join(patch_path, 'metadata.json'), 'w') as f:\n        json.dump(metadata, f)\n\n\nclass Counter:\n\n    def __init__(self, start=0):\n        self.value = start\n        self.lock = Lock()\n\n    def update(self, delta=1):\n        with self.lock:\n            self.value += delta\n            return self.value\n\n\ndef fix_random_seeds(seed=42):\n    \"\"\"\n    Fix random seeds.\n    \"\"\"\n    #torch.manual_seed(seed)\n    #torch.cuda.manual_seed_all(seed)\n    np.random.seed(seed)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--save_path', type=str, default='./data/') # dir to save data\n    parser.add_argument('--num_cities', type=int, default=10000)\n    parser.add_argument('--std', type=int, default=50)\n    parser.add_argument('--debug', action='store_true')\n    parser.add_argument('--cloud_pct', type=int, default=20)\n    parser.add_argument('--num_workers', type=int, default=8)\n    parser.add_argument('--log_freq', type=int, default=10) # print frequency\n    parser.add_argument('--preview', action='store_true')\n\n    parser.add_argument('--resume', type=str, default=None) # resume from existing coordinates\n    # op1: match ssl4eo coordinates and indexes\n    parser.add_argument('--match_file', type=str, default=None)\n    # op2-3: resample, grid or rtree based overlap check. grid is faster but allows boundary overlap; rtree is slower but completely avoid overlap\n    parser.add_argument('--overlap_check', type=str, default='rtree',choices=['grid','rtree',None])\n    parser.add_argument('--indices_range', type=int, nargs=2, default=[0,250000]) # range of download indices --> number of locations\n    args = parser.parse_args()\n\n    fix_random_seeds(seed=42)\n\n    ## initialize ee\n    ee.Initialize()\n    ## get data collection (remove clouds)\n\n    collection_s2a = get_collection_s2a(cloud_pct=args.cloud_pct)\n    collection_s2c = get_collection_s2c(cloud_pct=args.cloud_pct)\n    collection_s1 = get_collection_s1()\n\n    collections = {'s1_grd': collection_s1, 's2_l2a': collection_s2a, 's2_l1c': collection_s2c}\n\n    ## initialize sampler\n    sampler = GaussianSampler(num_cities=args.num_cities, std=args.std)\n\n    reference = date.fromisoformat('2021-09-22')\n    date1 = date.fromisoformat('2021-06-21')\n    date2 = date.fromisoformat('2021-03-20')\n    date3 = date.fromisoformat('2020-12-21')\n    \n    dates = [reference, date1, date2, date3]\n\n    radius = 1320\n    crop10 = (264, 264)\n    crop20 = (132, 132)\n    crop60 = (44, 44)\n    # s2 l2a\n    crop_s2a = {'B1': crop60, 'B2': crop10, 'B3': crop10, 'B4': crop10, 'B5': crop20, 'B6': crop20, 'B7': crop20,\n            'B8': crop10, 'B8A': crop20, 'B9': crop60, 'B11': crop20, 'B12': crop20}\n    # s2 l1c\n    crop_s2c = {'B1': crop60, 'B2': crop10, 'B3': crop10, 'B4': crop10, 'B5': crop20, 'B6': crop20, 'B7': crop20,\n            'B8': crop10, 'B8A': crop20, 'B9': crop60, 'B10': crop60, 'B11': crop20, 'B12': crop20}\n    # s1 grd\n    crop_s1 = {'VV': crop10, 'VH': crop10}\n\n    crops = {'s1_grd': crop_s1, 's2_l2a': crop_s2a, 's2_l1c': crop_s2c}\n\n    bands = {'s1_grd': ALL_BANDS_GRD, 's2_l2a': ALL_BANDS_L2A, 's2_l1c': ALL_BANDS_L1C}\n\n\n    ### if resume\n    ext_coords = {}\n    ext_flags = {}\n    if args.resume:\n        ext_path = args.resume   \n        with open(ext_path, 'r') as csv_file:\n            reader = csv.reader(csv_file)\n            for row in reader:\n                key = row[0]\n                val1 = float(row[1])\n                val2 = float(row[2])\n                ext_coords[key] = (val1, val2) # lon, lat\n                ext_flags[key] = int(row[3]) # success or not\n    else:\n        ext_path = os.path.join(args.save_path,'checked_locations.csv')\n    \n    ### if match from exisiting coords (e.g. SSL4EO-S12)\n    if args.match_file:\n        match_coords = {}\n        with open(args.match_file, 'r') as csv_file:\n            reader = csv.reader(csv_file)\n            for row in reader:\n                key = row[0]\n                val1 = float(row[1])\n                val2 = float(row[2])\n                match_coords[key] = (val1, val2) # lon, lat\n    ### else need to check overlap, build the grid or rtree from existing coordinates\n    elif args.overlap_check is not None:\n        grid_dict = {}\n        rtree_coords = index.Index()\n        if args.resume:\n            print('Load existing locations.')\n            for i, key in enumerate(tqdm(ext_coords.keys())):\n                c = ext_coords[key]\n                rtree_coords.insert(i, (c[0], c[1], c[0], c[1]))\n                gridIndex = (math.floor(c[0]+180),math.floor(c[1]+90))\n                if not gridIndex in grid_dict.keys():\n                    grid_dict[gridIndex] = {c}\n                else:\n                    grid_dict[gridIndex].add(c)\n    else:\n        raise NotImplementedError\n\n\n\n\n    start_time = time.time()\n    counter = Counter()\n\n\n    def worker(idx):\n\n        if str(idx) in ext_coords.keys():\n            if args.match_file: # skip all processed ids\n                #print('Already processed:',idx)\n                return\n            else:\n                if ext_flags[str(idx)]!=0: # only skip downloaded ids\n                    return\n\n        if args.match_file:\n            patches_s1, patches_s2c, patches_s2a, center_coord = get_random_patches_match(idx,collections, bands, crops, sampler, dates, radius=radius, debug=args.debug, match_coords=match_coords)\n        elif args.overlap_check=='rtree':\n            patches_s1, patches_s2c, patches_s2a, center_coord = get_random_patches_rtree(idx,collections, bands, crops, sampler, dates, radius=radius, debug=args.debug, rtree_obj=rtree_coords)\n        elif args.overlap_check=='grid':\n            patches_s1, patches_s2c, patches_s2a, center_coord = get_random_patches_grid(idx,collections, bands, crops, sampler, dates, radius=radius, debug=args.debug, grid_dict=grid_dict)\n        else:\n            raise NotImplementedError\n\n        if patches_s2c is not None:\n            if args.save_path is not None:\n                # s2c\n                location_path_s2c = os.path.join(args.save_path, 's2c', f'{idx:06d}')\n                os.makedirs(location_path_s2c, exist_ok=True)\n                for patch in patches_s2c:\n                    save_patch(\n                        raster=patch['raster'],\n                        coords=patch['coords'],\n                        metadata=patch['metadata'],\n                        path=location_path_s2c,\n                        preview=args.preview\n                    )\n                # s2a\n                location_path_s2a = os.path.join(args.save_path, 's2a', f'{idx:06d}')\n                os.makedirs(location_path_s2a, exist_ok=True)\n                for patch in patches_s2a:\n                    save_patch(\n                        raster=patch['raster'],\n                        coords=patch['coords'],\n                        metadata=patch['metadata'],\n                        path=location_path_s2a,\n                        preview=args.preview\n                    )\n                # s1\n                location_path_s1 = os.path.join(args.save_path, 's1', f'{idx:06d}')\n                os.makedirs(location_path_s1, exist_ok=True)                    \n                for patch in patches_s1:\n                    save_patch(\n                        raster=patch['raster'],\n                        coords=patch['coords'],\n                        metadata=patch['metadata'],\n                        path=location_path_s1,\n                        preview=args.preview\n                    )            \n                \n            count = counter.update(1)\n            if count % args.log_freq == 0:\n                print(f'Downloaded {count} images in {time.time() - start_time:.3f}s.')\n        else:\n            print('no suitable image for location %d.' % (idx))\n            \n        ## add to existing checked locations            \n        with open(ext_path, 'a') as f:\n            writer = csv.writer(f)\n            if patches_s2c is not None:\n                if args.match_file:\n                    success = 2\n                else:\n                    success = 1\n            else:\n                success = 0\n            data = [idx, center_coord[0], center_coord[1], success]\n            writer.writerow(data)\n                       \n        return\n\n    ### set indices\n    if args.match_file is not None:\n        indices = []\n        for key in match_coords.keys():\n            indices.append(int(key))\n        indices = indices[args.indices_range[0]:args.indices_range[1]]\n    elif args.indices_range is not None:\n        indices = range(args.indices_range[0], args.indices_range[1])\n    else:\n        print('Please set up indices.')\n        raise NotImplementedError\n\n    if args.num_workers == 0:\n        for i in indices:\n            worker(i)\n    else:\n        ## parallelism data\n        with Pool(processes=args.num_workers) as p:\n            p.map(worker, indices)\n           \n"
  }
]