Showing preview only (1,065K chars total). Download the full file or copy to clipboard to get everything.
Repository: VlSomers/bpbreid
Branch: main
Commit: a2dc43042847
Files: 171
Total size: 1009.1 KB
Directory structure:
gitextract_fsax4gel/
├── .flake8
├── .gitignore
├── .isort.cfg
├── .style.yapf
├── LICENSE
├── README.md
├── Torchreid_original_README.rst
├── configs/
│ └── bpbreid/
│ ├── bpbreid_dukemtmc_test.yaml
│ ├── bpbreid_dukemtmc_train.yaml
│ ├── bpbreid_market1501_test.yaml
│ ├── bpbreid_market1501_train.yaml
│ ├── bpbreid_occ_duke_test.yaml
│ ├── bpbreid_occ_duke_train.yaml
│ ├── bpbreid_occ_reid_test.yaml
│ ├── bpbreid_occ_reid_train.yaml
│ ├── bpbreid_p_dukemtmc_test.yaml
│ ├── bpbreid_p_dukemtmc_train.yaml
│ ├── pcb_market1501_train.yaml
│ └── pcb_occ_duke_train.yaml
├── docs/
│ ├── AWESOME_REID.md
│ ├── MODEL_ZOO.md
│ ├── Makefile
│ ├── conf.py
│ ├── datasets.rst
│ ├── evaluation.rst
│ ├── index.rst
│ ├── pkg/
│ │ ├── data.rst
│ │ ├── engine.rst
│ │ ├── losses.rst
│ │ ├── metrics.rst
│ │ ├── models.rst
│ │ ├── optim.rst
│ │ └── utils.rst
│ ├── requirements.txt
│ └── user_guide.rst
├── linter.sh
├── pyproject.toml
├── requirements.txt
├── requirements_labels.txt
├── setup.py
└── torchreid/
├── __init__.py
├── data/
│ ├── __init__.py
│ ├── data_augmentation/
│ │ ├── __init__.py
│ │ └── random_occlusion.py
│ ├── datamanager.py
│ ├── datasets/
│ │ ├── __init__.py
│ │ ├── dataset.py
│ │ ├── image/
│ │ │ ├── __init__.py
│ │ │ ├── cuhk01.py
│ │ │ ├── cuhk02.py
│ │ │ ├── cuhk03.py
│ │ │ ├── dukemtmcreid.py
│ │ │ ├── grid.py
│ │ │ ├── ilids.py
│ │ │ ├── market1501.py
│ │ │ ├── msmt17.py
│ │ │ ├── occluded_dukemtmc.py
│ │ │ ├── occluded_reid.py
│ │ │ ├── p_ETHZ.py
│ │ │ ├── p_dukemtmc_reid.py
│ │ │ ├── partial_ilids.py
│ │ │ ├── partial_reid.py
│ │ │ ├── prid.py
│ │ │ ├── sensereid.py
│ │ │ └── viper.py
│ │ └── video/
│ │ ├── __init__.py
│ │ ├── dukemtmcvidreid.py
│ │ ├── ilidsvid.py
│ │ ├── mars.py
│ │ └── prid2011.py
│ ├── masks_transforms/
│ │ ├── __init__.py
│ │ ├── coco_keypoints_transforms.py
│ │ ├── mask_transform.py
│ │ ├── pcb_transforms.py
│ │ └── pifpaf_mask_transform.py
│ ├── sampler.py
│ └── transforms.py
├── engine/
│ ├── __init__.py
│ ├── engine.py
│ ├── image/
│ │ ├── __init__.py
│ │ ├── part_based_engine.py
│ │ ├── softmax.py
│ │ └── triplet.py
│ └── video/
│ ├── __init__.py
│ ├── softmax.py
│ └── triplet.py
├── hyperparameter/
│ ├── custom_hyperparameter_optimizer.py
│ ├── hyperparameter_optimizer.py
│ └── optuna_hyperparameter_optimizer.py
├── losses/
│ ├── GiLt_loss.py
│ ├── __init__.py
│ ├── body_part_attention_loss.py
│ ├── cross_entropy_loss.py
│ ├── hard_mine_triplet_loss.py
│ ├── inter_parts_triplet_loss.py
│ ├── part_averaged_triplet_loss.py
│ ├── part_individual_triplet_loss.py
│ ├── part_max_min_triplet_loss.py
│ ├── part_max_triplet_loss.py
│ ├── part_min_triplet_loss.py
│ └── part_random_max_min_triplet_loss.py
├── metrics/
│ ├── __init__.py
│ ├── accuracy.py
│ ├── distance.py
│ ├── rank.py
│ └── rank_cylib/
│ ├── Makefile
│ ├── __init__.py
│ ├── rank_cy.pyx
│ ├── setup.py
│ └── test_cython.py
├── models/
│ ├── __init__.py
│ ├── bpbreid.py
│ ├── compact_bilinear_pooling.py
│ ├── densenet.py
│ ├── hacnn.py
│ ├── hrnet.py
│ ├── inceptionresnetv2.py
│ ├── inceptionv4.py
│ ├── mlfn.py
│ ├── mobilenetv2.py
│ ├── mudeep.py
│ ├── nasnet.py
│ ├── osnet.py
│ ├── osnet_ain.py
│ ├── pcb.py
│ ├── pvpm.py
│ ├── resnet.py
│ ├── resnet_fastreid.py
│ ├── resnet_ibn_a.py
│ ├── resnet_ibn_b.py
│ ├── resnetmid.py
│ ├── senet.py
│ ├── shufflenet.py
│ ├── shufflenetv2.py
│ ├── squeezenet.py
│ └── xception.py
├── optim/
│ ├── __init__.py
│ ├── lr_scheduler.py
│ ├── optimizer.py
│ └── radam.py
├── scripts/
│ ├── __init__.py
│ ├── default_config.py
│ ├── get_labels.py
│ └── main.py
├── tools/
│ ├── __init__.py
│ ├── compute_mean_std.py
│ ├── extract_part_based_features.py
│ └── feature_extractor.py
└── utils/
├── __init__.py
├── avgmeter.py
├── constants.py
├── distribution.py
├── engine_state.py
├── imagetools.py
├── logging/
│ ├── __init__.py
│ ├── deprecated_loggers.py
│ └── logger.py
├── model_complexity.py
├── reidtools.py
├── rerank.py
├── tensortools.py
├── tools.py
├── torch_receptive_field/
│ ├── __init__.py
│ └── receptive_field.py
├── torchtools.py
├── visualization/
│ ├── __init__.py
│ ├── display_batch_triplets.py
│ ├── embeddings_projection.py
│ ├── feature_map_visualization.py
│ └── visualize_query_gallery_rankings.py
└── writer.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .flake8
================================================
[flake8]
ignore =
# At least two spaces before inline comment
E261,
# Line lengths are recommended to be no greater than 79 characters
E501,
# Missing whitespace around arithmetic operator
E226,
# Blank line contains whitespace
W293,
# Do not use bare 'except'
E722,
# Line break after binary operator
W504,
# isort found an import in the wrong position
I001
max-line-length = 79
exclude = __init__.py, build, torchreid/metrics/rank_cylib/
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/f
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# Cython eval code
*.c
*.html
# OS X
.DS_Store
.Spotlight-V100
.Trashes
._*
# ReID
reid-data/
log/
saved-models/
model-zoo/
pretrained_models/
debug*
/.idea/
/configs_user/
================================================
FILE: .isort.cfg
================================================
[isort]
line_length=79
multi_line_output=3
length_sort=true
known_standard_library=numpy,setuptools
known_myself=torchreid
known_third_party=matplotlib,cv2,torch,torchvision,PIL,yacs
no_lines_before=STDLIB,THIRDPARTY
sections=FUTURE,STDLIB,THIRDPARTY,myself,FIRSTPARTY,LOCALFOLDER
default_section=FIRSTPARTY
================================================
FILE: .style.yapf
================================================
[style]
BASED_ON_STYLE = pep8
BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF = true
SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN = true
DEDENT_CLOSING_BRACKETS = true
SPACES_BEFORE_COMMENT = 1
ARITHMETIC_PRECEDENCE_INDICATION = true
================================================
FILE: LICENSE
================================================
**HIPPOCRATIC LICENSE**
**Version 3.0, October 2021**
<https://firstdonoharm.dev/version/3/0/law-media-mil-soc-sv.md>
**TERMS AND CONDITIONS**
TERMS AND CONDITIONS FOR USE, COPY, MODIFICATION, PREPARATION OF DERIVATIVE WORK, REPRODUCTION, AND DISTRIBUTION:
**[1.](#1) DEFINITIONS:**
_This section defines certain terms used throughout this license agreement._
[1.1.](#1.1) “License” means the terms and conditions, as stated herein, for use, copy, modification, preparation of derivative work, reproduction, and distribution of Software (as defined below).
[1.2.](#1.2) “Licensor” means the copyright and/or patent owner or entity authorized by the copyright and/or patent owner that is granting the License.
[1.3.](#1.3) “Licensee” means the individual or entity exercising permissions granted by this License, including the use, copy, modification, preparation of derivative work, reproduction, and distribution of Software (as defined below).
[1.4.](#1.4) “Software” means any copyrighted work, including but not limited to software code, authored by Licensor and made available under this License.
[1.5.](#1.5) “Supply Chain” means the sequence of processes involved in the production and/or distribution of a commodity, good, or service offered by the Licensee.
[1.6.](#1.6) “Supply Chain Impacted Party” or “Supply Chain Impacted Parties” means any person(s) directly impacted by any of Licensee’s Supply Chain, including the practices of all persons or entities within the Supply Chain prior to a good or service reaching the Licensee.
[1.7.](#1.7) “Duty of Care” is defined by its use in tort law, delict law, and/or similar bodies of law closely related to tort and/or delict law, including without limitation, a requirement to act with the watchfulness, attention, caution, and prudence that a reasonable person in the same or similar circumstances would use towards any Supply Chain Impacted Party.
[1.8.](#1.8) “Worker” is defined to include any and all permanent, temporary, and agency workers, as well as piece-rate, salaried, hourly paid, legal young (minors), part-time, night, and migrant workers.
**[2.](#2) INTELLECTUAL PROPERTY GRANTS:**
_This section identifies intellectual property rights granted to a Licensee_.
[2.1.](#2.1) _Grant of Copyright License_: Subject to the terms and conditions of this License, Licensor hereby grants to Licensee a worldwide, non-exclusive, no-charge, royalty-free copyright license to use, copy, modify, prepare derivative work, reproduce, or distribute the Software, Licensor authored modified software, or other work derived from the Software.
[2.2.](#2.2) _Grant of Patent License_: Subject to the terms and conditions of this License, Licensor hereby grants Licensee a worldwide, non-exclusive, no-charge, royalty-free patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer Software.
**[3.](#3) ETHICAL STANDARDS:**
_This section lists conditions the Licensee must comply with in order to have rights under this License._
The rights granted to the Licensee by this License are expressly made subject to the Licensee’s ongoing compliance with the following conditions:
* [3.1.](#3.1) The Licensee SHALL NOT, whether directly or indirectly, through agents or assigns:
* [3.1.1.](#3.1.1) Infringe upon any person’s right to life or security of person, engage in extrajudicial killings, or commit murder, without lawful cause (See Article 3, _United Nations Universal Declaration of Human Rights_; Article 6, _International Covenant on Civil and Political Rights_)
* [3.1.2.](#3.1.2) Hold any person in slavery, servitude, or forced labor (See Article 4, _United Nations Universal Declaration of Human Rights_; Article 8, _International Covenant on Civil and Political Rights_);
* [3.1.3.](#3.1.3) Contribute to the institution of slavery, slave trading, forced labor, or unlawful child labor (See Article 4, _United Nations Universal Declaration of Human Rights_; Article 8, _International Covenant on Civil and Political Rights_);
* [3.1.4.](#3.1.4) Torture or subject any person to cruel, inhumane, or degrading treatment or punishment (See Article 5, _United Nations Universal Declaration of Human Rights_; Article 7, _International Covenant on Civil and Political Rights_);
* [3.1.5.](#3.1.5) Discriminate on the basis of sex, gender, sexual orientation, race, ethnicity, nationality, religion, caste, age, medical disability or impairment, and/or any other like circumstances (See Article 7, _United Nations Universal Declaration of Human Rights_; Article 2, _International Covenant on Economic, Social and Cultural Rights_; Article 26, _International Covenant on Civil and Political Rights_);
* [3.1.6.](#3.1.6) Prevent any person from exercising his/her/their right to seek an effective remedy by a competent court or national tribunal (including domestic judicial systems, international courts, arbitration bodies, and other adjudicating bodies) for actions violating the fundamental rights granted to him/her/them by applicable constitutions, applicable laws, or by this License (See Article 8, _United Nations Universal Declaration of Human Rights_; Articles 9 and 14, _International Covenant on Civil and Political Rights_);
* [3.1.7.](#3.1.7) Subject any person to arbitrary arrest, detention, or exile (See Article 9, _United Nations Universal Declaration of Human Rights_; Article 9, _International Covenant on Civil and Political Rights_);
* [3.1.8.](#3.1.8) Subject any person to arbitrary interference with a person’s privacy, family, home, or correspondence without the express written consent of the person (See Article 12, _United Nations Universal Declaration of Human Rights_; Article 17, _International Covenant on Civil and Political Rights_);
* [3.1.9.](#3.1.9) Arbitrarily deprive any person of his/her/their property (See Article 17, _United Nations Universal Declaration of Human Rights_);
* [3.1.10.](#3.1.10) Forcibly remove indigenous peoples from their lands or territories or take any action with the aim or effect of dispossessing indigenous peoples from their lands, territories, or resources, including without limitation the intellectual property or traditional knowledge of indigenous peoples, without the free, prior, and informed consent of indigenous peoples concerned (See Articles 8 and 10, _United Nations Declaration on the Rights of Indigenous Peoples_);
* [3.1.11.](#3.1.11) _Mass Surveillance_: Be a government agency or multinational corporation, or a representative, agent, affiliate, successor, attorney, or assign of a government or multinational corporation, which participates in mass surveillance programs;
* [3.1.12.](#3.1.12) _Military Activities_: Be an entity or a representative, agent, affiliate, successor, attorney, or assign of an entity which conducts military activities;
* [3.1.13.](#3.1.13) _Law Enforcement_: Be an individual or entity, or a or a representative, agent, affiliate, successor, attorney, or assign of an individual or entity, that provides good or services to, or otherwise enters into any commercial contracts with, any local, state, or federal law enforcement agency;
* [3.1.14.](#3.1.14) _Media_: Be an individual or entity, or a or a representative, agent, affiliate, successor, attorney, or assign of an individual or entity, that broadcasts messages promoting killing, torture, or other forms of extreme violence;
* [3.1.15.](#3.1.15) Interfere with Workers' free exercise of the right to organize and associate (See Article 20, United Nations Universal Declaration of Human Rights; C087 - Freedom of Association and Protection of the Right to Organise Convention, 1948 (No. 87), International Labour Organization; Article 8, International Covenant on Economic, Social and Cultural Rights); and
* [3.1.16.](#3.1.16) Harm the environment in a manner inconsistent with local, state, national, or international law.
* [3.2.](#3.2) The Licensee SHALL:
* [3.2.1.](#3.2.1) _Social Auditing_: Only use social auditing mechanisms that adhere to Worker-Driven Social Responsibility Network’s Statement of Principles (<https://wsr-network.org/what-is-wsr/statement-of-principles/>) over traditional social auditing mechanisms, to the extent the Licensee uses any social auditing mechanisms at all;
* [3.2.2.](#3.2.2) Provide equal pay for equal work where the performance of such work requires equal skill, effort, and responsibility, and which are performed under similar working conditions, except where such payment is made pursuant to:
* [3.2.2.1.](#3.2.2.1) A seniority system;
* [3.2.2.2.](#3.2.2.2) A merit system;
* [3.2.2.3.](#3.2.2.3) A system which measures earnings by quantity or quality of production; or
* [3.2.2.4.](#3.2.2.4) A differential based on any other factor other than sex, gender, sexual orientation, race, ethnicity, nationality, religion, caste, age, medical disability or impairment, and/or any other like circumstances (See 29 U.S.C.A. § 206(d)(1); Article 23, _United Nations Universal Declaration of Human Rights_; Article 7, _International Covenant on Economic, Social and Cultural Rights_; Article 26, _International Covenant on Civil and Political Rights_); and
* [3.2.3.](#3.2.3) Allow for reasonable limitation of working hours and periodic holidays with pay (See Article 24, _United Nations Universal Declaration of Human Rights_; Article 7, _International Covenant on Economic, Social and Cultural Rights_).
**[4.](#4) SUPPLY CHAIN IMPACTED PARTIES:**
_This section identifies additional individuals or entities that a Licensee could harm as a result of violating the Ethical Standards section, the condition that the Licensee must voluntarily accept a Duty of Care for those individuals or entities, and the right to a private right of action that those individuals or entities possess as a result of violations of the Ethical Standards section._
[4.1.](#4.1) In addition to the above Ethical Standards, Licensee voluntarily accepts a Duty of Care for Supply Chain Impacted Parties of this License, including individuals and communities impacted by violations of the Ethical Standards. The Duty of Care is breached when a provision within the Ethical Standards section is violated by a Licensee, one of its successors or assigns, or by an individual or entity that exists within the Supply Chain prior to a good or service reaching the Licensee.
[4.2.](#4.2) Breaches of the Duty of Care, as stated within this section, shall create a private right of action, allowing any Supply Chain Impacted Party harmed by the Licensee to take legal action against the Licensee in accordance with applicable negligence laws, whether they be in tort law, delict law, and/or similar bodies of law closely related to tort and/or delict law, regardless if Licensee is directly responsible for the harms suffered by a Supply Chain Impacted Party. Nothing in this section shall be interpreted to include acts committed by individuals outside of the scope of his/her/their employment.
[5.](#5) **NOTICE:** _This section explains when a Licensee must notify others of the License._
[5.1.](#5.1) _Distribution of Notice_: Licensee must ensure that everyone who receives a copy of or uses any part of Software from Licensee, with or without changes, also receives the License and the copyright notice included with Software (and if included by the Licensor, patent, trademark, and attribution notice). Licensee must ensure that License is prominently displayed so that any individual or entity seeking to download, copy, use, or otherwise receive any part of Software from Licensee is notified of this License and its terms and conditions. Licensee must cause any modified versions of the Software to carry prominent notices stating that Licensee changed the Software.
[5.2.](#5.2) _Modified Software_: Licensee is free to create modifications of the Software and distribute only the modified portion created by Licensee, however, any derivative work stemming from the Software or its code must be distributed pursuant to this License, including this Notice provision.
[5.3.](#5.3) _Recipients as Licensees_: Any individual or entity that uses, copies, modifies, reproduces, distributes, or prepares derivative work based upon the Software, all or part of the Software’s code, or a derivative work developed by using the Software, including a portion of its code, is a Licensee as defined above and is subject to the terms and conditions of this License.
**[6.](#6) REPRESENTATIONS AND WARRANTIES:**
[6.1.](#6.1) _Disclaimer of Warranty_: TO THE FULL EXTENT ALLOWED BY LAW, THIS SOFTWARE COMES “AS IS,” WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED, AND LICENSOR SHALL NOT BE LIABLE TO ANY PERSON OR ENTITY FOR ANY DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THIS LICENSE, UNDER ANY LEGAL CLAIM.
[6.2.](#6.2) _Limitation of Liability_: LICENSEE SHALL HOLD LICENSOR HARMLESS AGAINST ANY AND ALL CLAIMS, DEBTS, DUES, LIABILITIES, LIENS, CAUSES OF ACTION, DEMANDS, OBLIGATIONS, DISPUTES, DAMAGES, LOSSES, EXPENSES, ATTORNEYS' FEES, COSTS, LIABILITIES, AND ALL OTHER CLAIMS OF EVERY KIND AND NATURE WHATSOEVER, WHETHER KNOWN OR UNKNOWN, ANTICIPATED OR UNANTICIPATED, FORESEEN OR UNFORESEEN, ACCRUED OR UNACCRUED, DISCLOSED OR UNDISCLOSED, ARISING OUT OF OR RELATING TO LICENSEE’S USE OF THE SOFTWARE. NOTHING IN THIS SECTION SHOULD BE INTERPRETED TO REQUIRE LICENSEE TO INDEMNIFY LICENSOR, NOR REQUIRE LICENSOR TO INDEMNIFY LICENSEE.
**[7.](#7) TERMINATION**
[7.1.](#7.1) _Violations of Ethical Standards or Breaching Duty of Care_: If Licensee violates the Ethical Standards section or Licensee, or any other person or entity within the Supply Chain prior to a good or service reaching the Licensee, breaches its Duty of Care to Supply Chain Impacted Parties, Licensee must remedy the violation or harm caused by Licensee within 30 days of being notified of the violation or harm. If Licensee fails to remedy the violation or harm within 30 days, all rights in the Software granted to Licensee by License will be null and void as between Licensor and Licensee.
[7.2.](#7.2) _Failure of Notice_: If any person or entity notifies Licensee in writing that Licensee has not complied with the Notice section of this License, Licensee can keep this License by taking all practical steps to comply within 30 days after the notice of noncompliance. If Licensee does not do so, Licensee’s License (and all rights licensed hereunder) will end immediately.
[7.3.](#7.3) _Judicial Findings_: In the event Licensee is found by a civil, criminal, administrative, or other court of competent jurisdiction, or some other adjudicating body with legal authority, to have committed actions which are in violation of the Ethical Standards or Supply Chain Impacted Party sections of this License, all rights granted to Licensee by this License will terminate immediately.
[7.4.](#7.4) _Patent Litigation_: If Licensee institutes patent litigation against any entity (including a cross-claim or counterclaim in a suit) alleging that the Software, all or part of the Software’s code, or a derivative work developed using the Software, including a portion of its code, constitutes direct or contributory patent infringement, then any patent license, along with all other rights, granted to Licensee under this License will terminate as of the date such litigation is filed.
[7.5.](#7.5) _Additional Remedies_: Termination of the License by failing to remedy harms in no way prevents Licensor or Supply Chain Impacted Party from seeking appropriate remedies at law or in equity.
**[8.](#8) MISCELLANEOUS:**
[8.1.](#8.1) _Conditions_: Sections 3, 4.1, 5.1, 5.2, 7.1, 7.2, 7.3, and 7.4 are conditions of the rights granted to Licensee in the License.
[8.2.](#8.2) _Equitable Relief_: Licensor and any Supply Chain Impacted Party shall be entitled to equitable relief, including injunctive relief or specific performance of the terms hereof, in addition to any other remedy to which they are entitled at law or in equity.
[8.3.](#8.3) _Severability_: If any term or provision of this License is determined to be invalid, illegal, or unenforceable by a court of competent jurisdiction, any such determination of invalidity, illegality, or unenforceability shall not affect any other term or provision of this License or invalidate or render unenforceable such term or provision in any other jurisdiction. If the determination of invalidity, illegality, or unenforceability by a court of competent jurisdiction pertains to the terms or provisions contained in the Ethical Standards section of this License, all rights in the Software granted to Licensee shall be deemed null and void as between Licensor and Licensee.
[8.4.](#8.4) _Section Titles_: Section titles are solely written for organizational purposes and should not be used to interpret the language within each section.
[8.5.](#8.5) _Citations_: Citations are solely written to provide context for the source of the provisions in the Ethical Standards.
[8.6.](#8.6) _Section Summaries_: Some sections have a brief _italicized description_ which is provided for the sole purpose of briefly describing the section and should not be used to interpret the terms of the License.
[8.7.](#8.7) _Entire License_: This is the entire License between the Licensor and Licensee with respect to the claims released herein and that the consideration stated herein is the only consideration or compensation to be paid or exchanged between them for this License. This License cannot be modified or amended except in a writing signed by Licensor and Licensee.
[8.8.](#8.8) _Successors and Assigns_: This License shall be binding upon and inure to the benefit of the Licensor’s and Licensee’s respective heirs, successors, and assigns.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<!-- TODO
-->
# BPBReID: Body Part-based (Occluded) Re-Identification
**A strong baseline for body part-based person re-identification**
🔥 *Our new work on [Keypoint Promptable ReID](https://github.com/VlSomers/keypoint_promptable_reidentification) was accepted at ECCV24* 🔥
[[Paper](https://arxiv.org/abs/2211.03679)] [[Video](https://www.youtube.com/watch?v=4NQump-vg_A&ab_channel=VladimirSomers)] [[Poster](docs/figures/bpbreid/wacv23_poster_bpbreid.pdf)]
[](https://arxiv.org/abs/2211.03679) [](https://firstdonoharm.dev/version/3/0/law-media-mil-soc-sv.html)
>**[Body Part-Based Representation Learning for Occluded Person Re-Identification, WACV23](https://arxiv.org/abs/2211.03679)**
>
>Vladimir Somers, Christophe De Vleeschouwer, Alexandre Alahi
>
>[*arxiv 2211.03679*](https://arxiv.org/abs/2211.03679)
>
### State-of-the-art performance on 5 datasets:
Occluded-Duke: [](https://paperswithcode.com/sota/person-re-identification-on-occluded-dukemtmc?p=body-part-based-representation-learning-for)
Occluded ReID: [](https://paperswithcode.com/sota/person-re-identification-on-occluded-reid-1?p=body-part-based-representation-learning-for)
P-DukeMTMC: [](https://paperswithcode.com/sota/person-re-identification-on-p-dukemtmc-reid?p=body-part-based-representation-learning-for)
DukeMTMC-ReID: [](https://paperswithcode.com/sota/person-re-identification-on-dukemtmc-reid?p=body-part-based-representation-learning-for)
Market1501: [](https://paperswithcode.com/sota/person-re-identification-on-market-1501?p=body-part-based-representation-learning-for)
<p align="center"><img src="/docs/figures/bpbreid/part_based_reid_methods.png" width="860"></p>
## News
- [2025.10.25] Added a discussion on the Theoretical Limitations of Global Embeddings in ReID Under Partial Observations
- [2024.08.23] 🚀🔥 Our new work on [Keypoint Promptable ReID](https://arxiv.org/abs/2407.18112) was accepted to ECCV24, full codebase available [here](https://github.com/VlSomers/keypoint_promptable_reidentification).
- [2023.09.20] New paper and big update coming soon 🚀 ...
- [2023.07.26] The Python script from @samihormi to generate human parsing labels based on PifPaf and MaskRCNN has been released, have a look at the "Generate human parsing labels" section below. This script is different from the one used by the authors (especially when facing multiple pedestrians in a single image): resulting human parsing labels will not be exactly the same.
- [2023.06.28] Please find a non-official script to generate human parsing labels from PifPaf and MaskRCNN in this [Pull Request](https://github.com/VlSomers/bpbreid/pull/18). The PR will be merged soon.
- [2022.12.02] We release the first version of our codebase. Please update frequently as we will add more documentation during the next few weeks.
## What's next
We plan on extending BPBReID in the near future, put a star and stay updated for future changes:
- part-based video/tracklet reid
- part-based reid for multi-object tracking
- ...
<!--
Table of content tool:
https://ecotrust-canada.github.io/markdown-toc/
-->
## Table of content
- [BPBReID: Body Part-based Re-Identification](#bpbreid--body-part-based-re-identification)
* [News](#news)
* [What's next](#what-s-next)
* [Table of content](#table-of-content)
* [Introduction](#introduction)
* [What to find in this repository](#what-to-find-in-this-repository)
* [Discussion on the Theoretical Limitations of Global Embeddings in ReID Under Partial Observations](#discussion-on-the-theoretical-limitations-of-global-embeddings-in-reid-under-partial-observationsRetry)
* [Instructions](#instructions)
+ [Installation](#installation)
+ [Download human parsing labels](#download-human-parsing-labels)
+ [Generate human parsing labels](#generate-human-parsing-labels)
+ [Download the pre-trained models](#download-the-pre-trained-models)
+ [Inference](#inference)
+ [Training](#training)
+ [Visualization tools](#visualization-tools)
* [Other works](#other-works)
* [Questions and suggestions](#questions-and-suggestions)
* [Citation](#citation)
* [Acknowledgement](#acknowledgement)
## Introduction
Welcome to the official repository for our WACV23 paper "_Body Part-Based Representation Learning for Occluded Person Re-Identification_".
In this work, we propose BPBReID, a part-based method for person re-identification using body part feature representations to compute to similarity between two samples.
As illustrated in the figure below, **part-based** ReID methods output multiple features per input sample, i.e. one for each part, whereas standard global methods only output a single feature.
Compared to global methods, part-based ones come with some advantages:
1. They achieve explicit appearance feature alignement for better ReID accuracy.
2. They are robust to occlusions, since only mutually visible parts are used when comparing two samples.
Our model BPBreID uses pseudo human parsing labels at training time to learn an attention mechanism. This attention mechanism has K branches to pool the global spatial feature map into K body part-based embeddings. Based on the attention maps activations, visibility scores are computed for each part.
At test time, no human parsing labels is required.
The final similarity score between two samples is computed using the average distance of all mutually visible part-based embeddings.
Please refer to [our paper](https://arxiv.org/abs/2211.03679) for more information.
<!--
<p align="center"><img src="docs/figures/bpbreid/model_trained_attention.jpg" width="860"></p>
<p align="center"><img src="docs/figures/bpbreid/WACV23_pull_figure_page.jpg" width="560"></p>
-->
## What to find in this repository
In this repository, we propose a framework and a strong baseline to support further research on part-based ReID methods.
Our code is based on the popular [Torchreid](https://github.com/KaiyangZhou/deep-person-reid) framework for person re-identification.
In this codebase, we provide several adaptations to the original framework to support part-based ReID methods:
- The [ImagePartBasedEngine](torchreid/engine/image/part_based_engine.py) to train/test part-based models, compute query-gallery distance matrix using multiple features per test sample with support for visibility scores.
- The fully configurable [GiLt loss](/torchreid/losses/GiLt_loss.py) to selectively apply id/triplet loss on holistics (global) and part-based features.
- The [BodyPartAttentionLoss](torchreid/losses/body_part_attention_loss.py) to train the attention mechanism.
- The [BPBreID](torchreid/models/bpbreid.py) part-based model to compute part-based features with support for body-part learnable attention, fixed attention heatmaps from an external model, PCB-like horizontal stripes, etc.
- The [Albumentation](https://albumentations.ai/) data augmentation library used for data augmentation, with support for external heatmaps/masks transforms.
- Support for [Weights & Biases](https://wandb.ai/site) and other logging tools in the [Logger](torchreid/utils/logging/logger.py) class.
- An [EngineState](torchreid/utils/engine_state.py) class to keep track of training epoch, etc.
- A new [ranking visualization](torchreid/utils/visualization/visualize_query_gallery_rankings.py) tool to display part heatmaps, local distance for each part and other metrics.
- For more information about all available configuration and parameters, please have a look at the [default config file](torchreid/scripts/default_config.py).
You can also have a look at the original [Torchreid README](Torchreid_original_README.rst) for additional information, such as documentation, how-to instructions, etc.
Be aware that some of the original Torchreid functionnality and models might be broken (for example, we don't support video re-id yet).
## Discussion on the Theoretical Limitations of Global Embeddings in ReID Under Partial Observations (Occlusions)
Current ReID models aim to learn a single global embedding where images of the same person cluster together.
However, this paradigm faces an inherent paradox when dealing with partial observations.
Consider three images of the same person: a full-body image (A) and two occluded variations - an upper-body-only image (B) and a lower-body-only image (C).
This becomes particularly problematic when comparing B with C - they share no common visible features despite representing the same person.
The global embedding approach implicitly assumes transitivity (if A=B and B=C, then A=C), but this property breaks down under partial observations, revealing a fundamental flaw in the single embedding space paradigm.
This observation suggests that the traditional approach of mapping all images to a unified embedding space may be fundamentally flawed. ReID models do not learn truly identity-centric representations, but rather appearance-centric representations that serve as a proxy to model identity. These appearance-centric representations are learned to be invariant to pose, lighting, and viewpoint changes, but when faced with partial observations, expecting such models to produce consistent embeddings becomes theoretically questionable.
This theoretical limitation is reflected in practice, where part-based representation learning, which compares only mutually visible regions, offer a more principled solution to this ambiguity.
Rather than being a technical hack to improve image retrieval performance, they may represent a fundamental requirement for representation learning under partial observation constraints.
Nevertheless, this apparent limitation of deep metric learning deserves further investigation. We identify two promising research directions. First, developing generic part-based architectures for representation learning that extend beyond human ReID and dynamically align comparable features while discarding missing information across object pairs. Such generic part-based methods would learn to build representations under partial observability without priors on the input object type, making them truly universal solutions.
Second, moving beyond representation learning entirely by designing ReID models that directly process image pairs to compute similarity scores, thus avoiding the ambiguity of intermediate representation in an embedding space under partial observations.
In this paradigm, the network would inherently learn to compare only mutually visible parts of the input image pair.
This approach faces however two key limitations compared to the first one: the need to run the neural network for every possible image pair, leading to quadratic computational complexity with gallery size (versus running the network once per image in representation learning), and the challenge of quantifying the confidence in the output similarity score when comparing partially visible objects.
## Instructions
### Installation
Make sure [conda](https://www.anaconda.com/distribution/) is installed.
# clone this repository
git clone https://github.com/VlSomers/bpbreid
# create conda environment
cd bpbreid/ # enter project folder
conda create --name bpbreid python=3.10
conda activate bpbreid
# install dependencies
# make sure `which python` and `which pip` point to the correct path
pip install -r requirements.txt
# install torch and torchvision (select the proper cuda version to suit your machine)
conda install pytorch torchvision cudatoolkit=9.0 -c pytorch
# install torchreid (don't need to re-build it if you modify the source code)
python setup.py develop
### Download human parsing labels
You can download the human parsing labels on [GDrive](https://drive.google.com/drive/folders/1IbCAbjj3XtV3_tFOsCuqBi79ZiDqNc1H?usp=sharing).
These labels were generated using the [PifPaf](https://github.com/openpifpaf/openpifpaf) pose estimation model and then filtered using segmentation masks from [Mask-RCNN](https://github.com/facebookresearch/detectron2).
We provide the labels for five datasets: **Market-1501**, **DukeMTMC-reID**, **Occluded-Duke**, **Occluded-ReID** and **P-DukeMTMC**.
After downloading, unzip the file and put the `masks` folder under the corresponding dataset directory.
For instance, Market-1501 should look like this:
Market-1501-v15.09.15
├── bounding_box_test
├── bounding_box_train
├── masks
│ └── pifpaf_maskrcnn_filtering
│ ├── bounding_box_test
│ ├── bounding_box_train
│ └── query
└── query
Make also sure to set `data.root` config to your dataset root directory path, i.e., all your datasets folders (`Market-1501-v15.09.15`, `DukeMTMC-reID`, `Occluded_Duke`, `P-DukeMTMC-reID`, `Occluded_REID`) should be under this path.
### Generate human parsing labels
You can create human parsing labels for your own dataset using the following command:
conda activate bpbreid
python torchreid/scripts/get_labels --source [Dataset Path]
The labels will be saved under the source directory in the *masks* folder as per the code convention.
### Download the pre-trained models
We also provide some [state-of-the-art pre-trained models](https://drive.google.com/drive/folders/1aUjpSXXVGtAh2nzV0RVsCq0tTXuDZWoH?usp=sharing) based on the HRNet-W32 backbone.
You can put the downloaded weights under a 'pretrained_models/' directory or specify the path to the pre-trained weights using the `model.load_weights` parameter in the `yaml` config.
The configuration used to obtain the pre-trained weights is also saved within the `.pth` file: make sure to set `model.load_config` to `True` so that the parameters under the `model.bpbreid` part of the configuration tree will be loaded from this file.
### Inference
You can test the above downloaded models using the following command:
conda activate bpbreid
python torchreid/scripts/main.py --config-file configs/bpbreid/bpbreid_<target_dataset>_test.yaml
For instance, for the Market-1501 dataset:
conda activate bpbreid
python torchreid/scripts/main.py --config-file configs/bpbreid/bpbreid_market1501_test.yaml
Configuration files for other datasets are available under `configs/bpbreid/`.
Make sure the `model.load_weights` in these `yaml` config files points to the pre-trained weights you just downloaded.
### Training
Training configs for five datasets (Market-1501, DukeMTMC-reID, Occluded-Duke, Occluded-ReID and P-DukeMTMC) are provided in the `configs/bpbreid/` folder.
A training procedure can be launched with:
conda activate bpbreid
python ./torchreid/scripts/main.py --config-file configs/bpbreid/bpbreid_<target_dataset>_train.yaml
For instance, for the Occluded-Duke dataset:
conda activate bpbreid
python torchreid/scripts/main.py --config-file configs/bpbreid/bpbreid_occ_duke_train.yaml
Make sure to download and install the human parsing labels for your training dataset before runing this command.
### Visualization tools
The ranking visualization tool can be activated by setting the `test.visrank` config to `True`.
As illustrated below, this tool displays the Top-K ranked samples as rows (K can be set via `test.visrank_topk`). The first row with blue background is the query, and the following green/red rows indicated correct/incorrect matches.
The attention maps for each test embedding (foreground, parts, etc) are displayed in the row.
An attention map has a green/red border when it is visible/unvisible.
The first number under each attention map indicate the visibility score and the second number indicate the distance of the embedding to the corresponding query embedding.
The distances under the images in the first column on the left are the global distances of that sample to the query, which is usually computed as the average of all other distances weighted by the visibility score.
If you need more information about the visualization tool, fell free to open an issue.
<p align="center"><img src="docs/figures/bpbreid/visualization_tool.jpg" width="860"></p>
## Other works
If you are looking for datasets to evaluate your re-identification models, please have a look at our other works on player re-identification for team sport events:
- [CAMELTrack: Context-Aware Multi-cue ExpLoitation for Online Multi-Object Tracking](https://github.com/TrackingLaboratory/CAMELTrack)
- The [SoccerNet Player Re-Identification](https://github.com/SoccerNet/sn-reid) dataset
- The [DeepSportRadar Player Re-Identification](https://github.com/DeepSportRadar/player-reidentification-challenge) dataset
<p align="center">
<img src="docs/figures/bpbreid/deepsportradar_reid.jpg" width="400" />
<img src="docs/figures/bpbreid/soccernet_reid.jpg" width="400" />
</p>
## Questions and suggestions
If you have any question/suggestion, or find any bug/issue with the code, please raise a GitHub issue in this repository, I'll be glab to help you as much as I can!
I'll try to update the documentation regularly based on your questions.
## Citation
If you use this repository for your research or wish to refer to our method [BPBReID](https://arxiv.org/abs/2211.03679), please use the following BibTeX entry:
```
@article{bpbreid,
archivePrefix = {arXiv},
arxivId = {2211.03679},
author = {Somers, Vladimir and {De Vleeschouwer}, Christophe and Alahi, Alexandre},
doi = {10.48550/arxiv.2211.03679},
eprint = {2211.03679},
isbn = {2211.03679v1},
journal = {Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision (WACV23)},
month = {nov},
title = {{Body Part-Based Representation Learning for Occluded Person Re-Identification}},
url = {https://arxiv.org/abs/2211.03679v1 http://arxiv.org/abs/2211.03679},
year = {2023}
}
```
## Acknowledgement
This codebase is a fork from [Torchreid](https://github.com/KaiyangZhou/deep-person-reid)
================================================
FILE: Torchreid_original_README.rst
================================================
Torchreid
===========
Torchreid is a library for deep-learning person re-identification, written in `PyTorch <https://pytorch.org/>`_.
It features:
- multi-GPU training
- support both image- and video-reid
- end-to-end training and evaluation
- incredibly easy preparation of reid datasets
- multi-dataset training
- cross-dataset evaluation
- standard protocol used by most research papers
- highly extensible (easy to add models, datasets, training methods, etc.)
- implementations of state-of-the-art deep reid models
- access to pretrained reid models
- advanced training techniques
- visualization tools (tensorboard, ranks, etc.)
Code: https://github.com/KaiyangZhou/deep-person-reid.
Documentation: https://kaiyangzhou.github.io/deep-person-reid/.
How-to instructions: https://kaiyangzhou.github.io/deep-person-reid/user_guide.
Model zoo: https://kaiyangzhou.github.io/deep-person-reid/MODEL_ZOO.
Tech report: https://arxiv.org/abs/1910.10093.
You can find some research projects that are built on top of Torchreid `here <https://github.com/KaiyangZhou/deep-person-reid/tree/master/projects>`_.
What's new
------------
- [May 2020] Added the person attribute recognition code used in [Omni-Scale Feature Learning for Person Re-Identification (ICCV'19)](https://arxiv.org/abs/1905.00953).
- [May 2020] ``1.2.1``: Added a simple API for feature extraction (``torchreid/utils/feature_extractor.py``). See the `documentation <https://kaiyangzhou.github.io/deep-person-reid/user_guide.html>`_ for the instruction.
- [Apr 2020] Code for reproducing the experiments of `deep mutual learning <https://zpascal.net/cvpr2018/Zhang_Deep_Mutual_Learning_CVPR_2018_paper.pdf>`_ in the `OSNet paper <https://arxiv.org/pdf/1905.00953v6.pdf>`__ (Supp. B) has been released at ``projects/DML``.
- [Apr 2020] Upgraded to ``1.2.0``. The engine class has been made more model-agnostic to improve extensibility. See `Engine <torchreid/engine/engine.py>`_ and `ImageSoftmaxEngine <torchreid/engine/image/softmax.py>`_ for more details. Credit to `Dassl.pytorch <https://github.com/KaiyangZhou/Dassl.pytorch>`_.
- [Dec 2019] Our `OSNet paper <https://arxiv.org/pdf/1905.00953v6.pdf>`_ has been updated, with additional experiments (in section B of the supplementary) showing some useful techniques for improving OSNet's performance in practice.
- [Nov 2019] ``ImageDataManager`` can load training data from target datasets by setting ``load_train_targets=True``, and the train-loader can be accessed with ``train_loader_t = datamanager.train_loader_t``. This feature is useful for domain adaptation research.
Installation
---------------
Make sure `conda <https://www.anaconda.com/distribution/>`_ is installed.
.. code-block:: bash
# cd to your preferred directory and clone this repo
git clone https://github.com/KaiyangZhou/deep-person-reid.git
# create environment
cd deep-person-reid/
conda create --name torchreid python=3.7
conda activate torchreid
# install dependencies
# make sure `which python` and `which pip` point to the correct path
pip install -r requirements.txt
# install torch and torchvision (select the proper cuda version to suit your machine)
conda install pytorch torchvision cudatoolkit=9.0 -c pytorch
# install torchreid (don't need to re-build it if you modify the source code)
python setup.py develop
Get started: 30 seconds to Torchreid
-------------------------------------
1. Import ``torchreid``
.. code-block:: python
import torchreid
2. Load data manager
.. code-block:: python
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources='market1501',
targets='market1501',
height=256,
width=128,
batch_size_train=32,
batch_size_test=100,
transforms=['random_flip', 'random_crop']
)
3 Build model, optimizer and lr_scheduler
.. code-block:: python
model = torchreid.models.build_model(
name='resnet50',
num_classes=datamanager.num_train_pids,
loss='softmax',
pretrained=True
)
model = model.cuda()
optimizer = torchreid.optim.build_optimizer(
model,
optim='adam',
lr=0.0003
)
scheduler = torchreid.optim.build_lr_scheduler(
optimizer,
lr_scheduler='single_step',
stepsize=20
)
4. Build engine
.. code-block:: python
engine = torchreid.engine.ImageSoftmaxEngine(
datamanager,
model,
optimizer=optimizer,
scheduler=scheduler,
label_smooth=True
)
5. Run training and test
.. code-block:: python
engine.run(
save_dir='log/resnet50',
max_epoch=60,
eval_freq=10,
test_only=False
)
A unified interface
-----------------------
In "deep-person-reid/scripts/", we provide a unified interface to train and test a model. See "scripts/main.py" and "scripts/default_config.py" for more details. The folder "configs/" contains some predefined configs which you can use as a starting point.
Below we provide an example to train and test `OSNet (Zhou et al. ICCV'19) <https://arxiv.org/abs/1905.00953>`_. Assume :code:`PATH_TO_DATA` is the directory containing reid datasets. The environmental variable :code:`CUDA_VISIBLE_DEVICES` is omitted, which you need to specify if you have a pool of gpus and want to use a specific set of them.
Conventional setting
^^^^^^^^^^^^^^^^^^^^^
To train OSNet on Market1501, do
.. code-block:: bash
python scripts/main.py \
--config-file configs/im_osnet_x1_0_softmax_256x128_amsgrad_cosine.yaml \
--transforms random_flip random_erase \
--root $PATH_TO_DATA
The config file sets Market1501 as the default dataset. If you wanna use DukeMTMC-reID, do
.. code-block:: bash
python scripts/main.py \
--config-file configs/im_osnet_x1_0_softmax_256x128_amsgrad_cosine.yaml \
-s dukemtmcreid \
-t dukemtmcreid \
--transforms random_flip random_erase \
--root $PATH_TO_DATA \
data.save_dir log/osnet_x1_0_dukemtmcreid_softmax_cosinelr
The code will automatically (download and) load the ImageNet pretrained weights. After the training is done, the model will be saved as "log/osnet_x1_0_market1501_softmax_cosinelr/model.pth.tar-250". Under the same folder, you can find the `tensorboard <https://pytorch.org/docs/stable/tensorboard.html>`_ file. To visualize the learning curves using tensorboard, you can run :code:`tensorboard --logdir=log/osnet_x1_0_market1501_softmax_cosinelr` in the terminal and visit :code:`http://localhost:6006/` in your web browser.
Evaluation is automatically performed at the end of training. To run the test again using the trained model, do
.. code-block:: bash
python scripts/main.py \
--config-file configs/im_osnet_x1_0_softmax_256x128_amsgrad_cosine.yaml \
--root $PATH_TO_DATA \
model.load_weights log/osnet_x1_0_market1501_softmax_cosinelr/model.pth.tar-250 \
test.evaluate True
Cross-domain setting
^^^^^^^^^^^^^^^^^^^^^
Suppose you wanna train OSNet on DukeMTMC-reID and test its performance on Market1501, you can do
.. code-block:: bash
python scripts/main.py \
--config-file configs/im_osnet_x1_0_softmax_256x128_amsgrad.yaml \
-s dukemtmcreid \
-t market1501 \
--transforms random_flip color_jitter \
--root $PATH_TO_DATA
Here we only test the cross-domain performance. However, if you also want to test the performance on the source dataset, i.e. DukeMTMC-reID, you can set :code:`-t dukemtmcreid market1501`, which will evaluate the model on the two datasets separately.
Different from the same-domain setting, here we replace :code:`random_erase` with :code:`color_jitter`. This can improve the generalization performance on the unseen target dataset.
Pretrained models are available in the `Model Zoo <https://kaiyangzhou.github.io/deep-person-reid/MODEL_ZOO.html>`_.
Datasets
--------
Image-reid datasets
^^^^^^^^^^^^^^^^^^^^^
- `Market1501 <https://www.cv-foundation.org/openaccess/content_iccv_2015/papers/Zheng_Scalable_Person_Re-Identification_ICCV_2015_paper.pdf>`_
- `CUHK03 <https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Li_DeepReID_Deep_Filter_2014_CVPR_paper.pdf>`_
- `DukeMTMC-reID <https://arxiv.org/abs/1701.07717>`_
- `MSMT17 <https://arxiv.org/abs/1711.08565>`_
- `VIPeR <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.331.7285&rep=rep1&type=pdf>`_
- `GRID <http://www.eecs.qmul.ac.uk/~txiang/publications/LoyXiangGong_cvpr_2009.pdf>`_
- `CUHK01 <http://www.ee.cuhk.edu.hk/~xgwang/papers/liZWaccv12.pdf>`_
- `SenseReID <http://openaccess.thecvf.com/content_cvpr_2017/papers/Zhao_Spindle_Net_Person_CVPR_2017_paper.pdf>`_
- `QMUL-iLIDS <http://www.eecs.qmul.ac.uk/~sgg/papers/ZhengGongXiang_BMVC09.pdf>`_
- `PRID <https://pdfs.semanticscholar.org/4c1b/f0592be3e535faf256c95e27982db9b3d3d3.pdf>`_
Video-reid datasets
^^^^^^^^^^^^^^^^^^^^^^^
- `MARS <http://www.liangzheng.org/1320.pdf>`_
- `iLIDS-VID <https://www.eecs.qmul.ac.uk/~sgg/papers/WangEtAl_ECCV14.pdf>`_
- `PRID2011 <https://pdfs.semanticscholar.org/4c1b/f0592be3e535faf256c95e27982db9b3d3d3.pdf>`_
- `DukeMTMC-VideoReID <http://openaccess.thecvf.com/content_cvpr_2018/papers/Wu_Exploit_the_Unknown_CVPR_2018_paper.pdf>`_
Models
-------
ImageNet classification models
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- `ResNet <https://arxiv.org/abs/1512.03385>`_
- `ResNeXt <https://arxiv.org/abs/1611.05431>`_
- `SENet <https://arxiv.org/abs/1709.01507>`_
- `DenseNet <https://arxiv.org/abs/1608.06993>`_
- `Inception-ResNet-V2 <https://arxiv.org/abs/1602.07261>`_
- `Inception-V4 <https://arxiv.org/abs/1602.07261>`_
- `Xception <https://arxiv.org/abs/1610.02357>`_
- `IBN-Net <https://arxiv.org/abs/1807.09441>`_
Lightweight models
^^^^^^^^^^^^^^^^^^^
- `NASNet <https://arxiv.org/abs/1707.07012>`_
- `MobileNetV2 <https://arxiv.org/abs/1801.04381>`_
- `ShuffleNet <https://arxiv.org/abs/1707.01083>`_
- `ShuffleNetV2 <https://arxiv.org/abs/1807.11164>`_
- `SqueezeNet <https://arxiv.org/abs/1602.07360>`_
ReID-specific models
^^^^^^^^^^^^^^^^^^^^^^
- `MuDeep <https://arxiv.org/abs/1709.05165>`_
- `ResNet-mid <https://arxiv.org/abs/1711.08106>`_
- `HACNN <https://arxiv.org/abs/1802.08122>`_
- `PCB <https://arxiv.org/abs/1711.09349>`_
- `MLFN <https://arxiv.org/abs/1803.09132>`_
- `OSNet <https://arxiv.org/abs/1905.00953>`_
- `OSNet-AIN <https://arxiv.org/abs/1910.06827>`_
Useful links
-------------
- `OSNet-IBN1-Lite (test-only code with lite docker container) <https://github.com/RodMech/OSNet-IBN1-Lite>`_
- `Deep Learning for Person Re-identification: A Survey and Outlook <https://github.com/mangye16/ReID-Survey>`_
Citation
---------
If you find this code useful to your research, please cite the following papers.
.. code-block:: bash
@article{torchreid,
title={Torchreid: A Library for Deep Learning Person Re-Identification in Pytorch},
author={Zhou, Kaiyang and Xiang, Tao},
journal={arXiv preprint arXiv:1910.10093},
year={2019}
}
@inproceedings{zhou2019osnet,
title={Omni-Scale Feature Learning for Person Re-Identification},
author={Zhou, Kaiyang and Yang, Yongxin and Cavallaro, Andrea and Xiang, Tao},
booktitle={ICCV},
year={2019}
}
@article{zhou2019learning,
title={Learning Generalisable Omni-Scale Representations for Person Re-Identification},
author={Zhou, Kaiyang and Yang, Yongxin and Cavallaro, Andrea and Xiang, Tao},
journal={arXiv preprint arXiv:1910.06827},
year={2019}
}
================================================
FILE: configs/bpbreid/bpbreid_dukemtmc_test.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['dukemtmcreid']
targets: ['dukemtmcreid']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
load_weights: 'pretrained_models/bpbreid_dukemtmcreid_hrnet32_10669.pth'
load_config: True
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'five_v'
test:
evaluate: True
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_dukemtmc_train.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['dukemtmcreid']
targets: ['dukemtmcreid']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'five_v'
loss:
name: 'part_based'
part_based:
name: 'part_averaged_triplet_loss'
ppl: 'cl'
weights: # SOTA weights for GiLt loss
globl:
id: 1.
tr: 0.
foreg:
id: 1.
tr: 1.
conct:
id: 1.
tr: 0.
parts:
id: 0.
tr: 1.
pixls:
ce: 0.35
train:
batch_size: 64
test:
evaluate: False
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_market1501_test.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['market1501']
targets: ['market1501']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
load_weights: 'pretrained_models/bpbreid_market1501_hrnet32_10642.pth'
load_config: True
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'five_v'
test:
evaluate: True
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_market1501_train.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['market1501']
targets: ['market1501']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'five_v'
loss:
name: 'part_based'
part_based:
name: 'part_averaged_triplet_loss'
ppl: 'cl'
weights: # SOTA weights for GiLt loss
globl:
id: 1.
tr: 0.
foreg:
id: 1.
tr: 1.
conct:
id: 1.
tr: 0.
parts:
id: 0.
tr: 1.
pixls:
ce: 0.35
train:
batch_size: 64
test:
evaluate: False
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_occ_duke_test.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['occluded_duke']
targets: ['occluded_duke']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
load_weights: 'pretrained_models/bpbreid_occluded_duke_hrnet32_10670.pth'
load_config: True
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'five_v'
test:
evaluate: True
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_occ_duke_train.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['occluded_duke']
targets: ['occluded_duke']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'eight'
loss:
name: 'part_based'
part_based:
name: 'part_averaged_triplet_loss'
ppl: 'cl'
weights: # SOTA weights for GiLt loss
globl:
id: 1.
tr: 0.
foreg:
id: 1.
tr: 0.
conct:
id: 1.
tr: 0.
parts:
id: 0.
tr: 1.
pixls:
ce: 0.35
train:
batch_size: 64
test:
evaluate: False
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_occ_reid_test.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['market1501']
targets: ['occluded_reid']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
load_weights: 'pretrained_models/'
load_config: True
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'five_v'
test:
evaluate: True
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_occ_reid_train.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['market1501']
targets: ['market1501', 'occluded_reid']
height: 384
width: 128
transforms: ['rc', 're', 'rf', 'cj']
model:
name: 'bpbreid'
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'eight'
loss:
name: 'part_based'
part_based:
name: 'part_averaged_triplet_loss'
ppl: 'cl'
weights: # SOTA weights for GiLt loss
globl:
id: 1.
tr: 0.
foreg:
id: 1.
tr: 1.
conct:
id: 1.
tr: 0.
parts:
id: 0.
tr: 1.
pixls:
ce: 0.7
train:
batch_size: 64
test:
evaluate: False
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_p_dukemtmc_test.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['p_dukemtmc_reid']
targets: ['p_dukemtmc_reid']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
load_weights: 'pretrained_models/bpbreid_p_dukemtmc_hrnet32_10672.pth'
load_config: True
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'five_v'
test:
evaluate: True
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/bpbreid_p_dukemtmc_train.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['p_dukemtmc_reid']
targets: ['p_dukemtmc_reid']
height: 384
width: 128
transforms: ['rc', 're']
model:
name: 'bpbreid'
bpbreid:
mask_filtering_training: False
mask_filtering_testing: True
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['bn_foreg', 'parts']
masks:
dir: 'pifpaf_maskrcnn_filtering'
preprocess: 'eight'
loss:
name: 'part_based'
part_based:
name: 'part_averaged_triplet_loss'
ppl: 'cl'
weights: # SOTA weights for GiLt loss
globl:
id: 1.
tr: 0.
foreg:
id: 1.
tr: 0.
conct:
id: 1.
tr: 0.
parts:
id: 0.
tr: 1.
pixls:
ce: 0.35
train:
batch_size: 64
test:
evaluate: False
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/pcb_market1501_train.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['market1501']
targets: ['market1501']
height: 384
width: 128
transforms: ['rc', 'rf', 're']
model:
name: 'bpbreid'
bpbreid:
mask_filtering_training: False
mask_filtering_testing: False # no visibility scores used at training for PCB
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['conct'] # the holistic concatenated embedding alone is used to compute query-gallery distances
masks:
type: 'stripes' # PCB uses horizontal stripes
parts_num: 6 # we use 6 horizontal stripes here
loss:
name: 'part_based'
part_based:
name: 'part_averaged_triplet_loss'
ppl: 'cl'
weights:
globl:
id: 0.
tr: 0.
foreg:
id: 0.
tr: 0.
conct:
id: 0.
tr: 0.
parts:
id: 1. # For PCB, we use the cross-entropy (identity) loss on each of the 6 horizontal stripes
tr: 0.
pixls:
ce: 0. # no body part prediction loss for PCB
train:
batch_size: 64
test:
evaluate: False
batch_size: 64
visrank: True
================================================
FILE: configs/bpbreid/pcb_occ_duke_train.yaml
================================================
data:
root: '~/datasets/reid'
sources: ['occluded_duke']
targets: ['occluded_duke']
height: 384
width: 128
transforms: ['rc', 'rf', 're']
model:
name: 'bpbreid'
bpbreid:
mask_filtering_training: False
mask_filtering_testing: False # no visibility scores used at training for PCB
learnable_attention_enabled: True
backbone: 'hrnet32'
test_embeddings: ['conct'] # the holistic concatenated embedding alone is used to compute query-gallery distances
masks:
type: 'stripes' # PCB uses horizontal stripes
parts_num: 6 # we use 6 horizontal stripes here
loss:
name: 'part_based'
part_based:
name: 'part_averaged_triplet_loss'
ppl: 'cl'
weights:
globl:
id: 0.
tr: 0.
foreg:
id: 0.
tr: 0.
conct:
id: 0.
tr: 0.
parts:
id: 1. # For PCB, we use the cross-entropy (identity) loss on each of the 6 horizontal stripes
tr: 0.
pixls:
ce: 0. # no body part prediction loss for PCB
train:
batch_size: 64
test:
evaluate: False
batch_size: 64
visrank: True
================================================
FILE: docs/AWESOME_REID.md
================================================
# Awesome-ReID
Here is a collection of ReID-related research with links to papers and code. You are welcome to submit [PR](https://help.github.com/articles/creating-a-pull-request/)s if you find something missing.
- [ArXiv20] Deep Learning for Person Re-identification: A Survey and Outlook [[paper](https://arxiv.org/abs/2001.04193)] [[code](https://github.com/mangye16/ReID-Survey)]
- [ArXiv19] Learning Generalisable Omni-Scale Representations for Person Re-Identification [[paper](https://arxiv.org/abs/1910.06827)][[code](https://github.com/KaiyangZhou/deep-person-reid)]
- [ICCV19] RGB-Infrared Cross-Modality Person Re-Identification via Joint Pixel and Feature Alignment. [[paper](http://openaccess.thecvf.com/content_ICCV_2019/papers/Wang_RGB-Infrared_Cross-Modality_Person_Re-Identification_via_Joint_Pixel_and_Feature_Alignment_ICCV_2019_paper.pdf)] [[code](https://github.com/wangguanan/AlignGAN)]
- [ICCV19] Unsupervised Graph Association for Person Re-identification. [[paper](https://github.com/yichuan9527/Unsupervised-Graph-Association-for-Person-Re-identification)] [[code](https://github.com/yichuan9527/Unsupervised-Graph-Association-for-Person-Re-identification)]
- [ICCV19] Self-similarity Grouping: A Simple Unsupervised Cross Domain Adaptation Approach for Person Re-identification. [[paper](http://openaccess.thecvf.com/content_ICCV_2019/papers/Fu_Self-Similarity_Grouping_A_Simple_Unsupervised_Cross_Domain_Adaptation_Approach_for_ICCV_2019_paper.pdf)] [[code](https://github.com/OasisYang/SSG)]
- [ICCV19] Spectral Feature Transformation for Person Re-Identification. [[paper](http://openaccess.thecvf.com/content_ICCV_2019/papers/Luo_Spectral_Feature_Transformation_for_Person_Re-Identification_ICCV_2019_paper.pdf)] [[code](https://github.com/LuckyDC/SFT_REID)]
- [ICCV19] Beyond Human Parts: Dual Part-Aligned Representations for Person Re-Identification. [[paper](http://openaccess.thecvf.com/content_ICCV_2019/papers/Guo_Beyond_Human_Parts_Dual_Part-Aligned_Representations_for_Person_Re-Identification_ICCV_2019_paper.pdf)] [[code](https://github.com/ggjy/P2Net.pytorch)]
- [ICCV19] Co-segmentation Inspired Attention Networks for Video-based Person Re-identification. [[paper](http://openaccess.thecvf.com/content_ICCV_2019/papers/Subramaniam_Co-Segmentation_Inspired_Attention_Networks_for_Video-Based_Person_Re-Identification_ICCV_2019_paper.pdf)][[code](https://github.com/InnovArul/vidreid_cosegmentation)]
- [ICCV19] Mixed High-Order Attention Network for Person Re-Identification. [[paper](https://arxiv.org/abs/1908.05819)][[code](https://github.com/chenbinghui1/MHN)]
- [ICCV19] ABD-Net: Attentive but Diverse Person Re-Identification. [[paper](https://arxiv.org/abs/1908.01114)] [[code](https://github.com/TAMU-VITA/ABD-Net)]
- [ICCV19] Omni-Scale Feature Learning for Person Re-Identification. [[paper](https://arxiv.org/abs/1905.00953)] [[code](https://github.com/KaiyangZhou/deep-person-reid)]
- [CVPR19] Joint Discriminative and Generative Learning for Person Re-identification. [[paper](https://arxiv.org/abs/1904.07223)][[code](https://github.com/NVlabs/DG-Net)]
- [CVPR19] Invariance Matters: Exemplar Memory for Domain Adaptive Person Re-identification. [[paper](https://arxiv.org/abs/1904.01990)][[code](https://github.com/zhunzhong07/ECN)]
- [CVPR19] Dissecting Person Re-identification from the Viewpoint of Viewpoint. [[paper](https://arxiv.org/abs/1812.02162)][[code](https://github.com/sxzrt/Dissecting-Person-Re-ID-from-the-Viewpoint-of-Viewpoint)]
- [CVPR19] Unsupervised Person Re-identification by Soft Multilabel Learning. [[paper](https://arxiv.org/abs/1903.06325)][[code](https://github.com/KovenYu/MAR)]
- [CVPR19] Patch-based Discriminative Feature Learning for Unsupervised Person Re-identification. [[paper](https://kovenyu.com/publication/2019-cvpr-pedal/)][[code](https://github.com/QizeYang/PAUL)]
- [AAAI19] Spatial and Temporal Mutual Promotion for Video-based Person Re-identification. [[paper](https://arxiv.org/abs/1812.10305)][[code](https://github.com/yolomax/person-reid-lib)]
- [AAAI19] Spatial-Temporal Person Re-identification. [[paper](https://arxiv.org/abs/1812.03282)][[code](https://github.com/Wanggcong/Spatial-Temporal-Re-identification)]
- [AAAI19] Horizontal Pyramid Matching for Person Re-identification. [[paper](https://arxiv.org/abs/1804.05275)][[code](https://github.com/OasisYang/HPM)]
- [AAAI19] Backbone Can Not be Trained at Once: Rolling Back to Pre-trained Network for Person Re-identification. [[paper](https://arxiv.org/abs/1901.06140)][[code](https://github.com/youngminPIL/rollback)]
- [AAAI19] A Bottom-Up Clustering Approach to Unsupervised Person Re-identification. [[paper](https://vana77.github.io/vana77.github.io/images/AAAI19.pdf)][[code](https://github.com/vana77/Bottom-up-Clustering-Person-Re-identification)]
- [NIPS18] FD-GAN: Pose-guided Feature Distilling GAN for Robust Person Re-identification. [[paper](https://arxiv.org/abs/1810.02936)][[code](https://github.com/yxgeee/FD-GAN)]
- [ECCV18] Generalizing A Person Retrieval Model Hetero- and Homogeneously. [[paper](http://openaccess.thecvf.com/content_ECCV_2018/papers/Zhun_Zhong_Generalizing_A_Person_ECCV_2018_paper.pdf)][[code](https://github.com/zhunzhong07/HHL)]
- [ECCV18] Pose-Normalized Image Generation for Person Re-identification. [[paper](https://arxiv.org/abs/1712.02225)][[code](https://github.com/naiq/PN_GAN)]
- [CVPR18] Camera Style Adaptation for Person Re-Identification. [[paper](https://arxiv.org/abs/1711.10295)][[code](https://github.com/zhunzhong07/CamStyle)]
- [CVPR18] Deep Group-Shuffling Random Walk for Person Re-Identification. [[paper](https://arxiv.org/abs/1807.11178)][[code](https://github.com/YantaoShen/kpm_rw_person_reid)]
- [CVPR18] End-to-End Deep Kronecker-Product Matching for Person Re-identification. [[paper](https://arxiv.org/abs/1807.11182)][[code](https://github.com/YantaoShen/kpm_rw_person_reid)]
- [CVPR18] Features for Multi-Target Multi-Camera Tracking and Re-Identification. [[paper](https://arxiv.org/abs/1803.10859)][[code](https://github.com/ergysr/DeepCC)]
- [CVPR18] Group Consistent Similarity Learning via Deep CRF for Person Re-Identification. [[paper](http://openaccess.thecvf.com/content_cvpr_2018/papers/Chen_Group_Consistent_Similarity_CVPR_2018_paper.pdf)][[code](https://github.com/dapengchen123/crf_affinity)]
- [CVPR18] Harmonious Attention Network for Person Re-Identification. [[paper](https://arxiv.org/abs/1802.08122)][[code](https://github.com/KaiyangZhou/deep-person-reid)]
- [CVPR18] Human Semantic Parsing for Person Re-Identification. [[paper](https://arxiv.org/abs/1804.00216)][[code](https://github.com/emrahbasaran/SPReID)]
- [CVPR18] Multi-Level Factorisation Net for Person Re-Identification. [[paper](https://arxiv.org/abs/1803.09132)][[code](https://github.com/KaiyangZhou/deep-person-reid)]
- [CVPR18] Resource Aware Person Re-identification across Multiple Resolutions. [[paper](https://arxiv.org/abs/1805.08805)][[code](https://github.com/mileyan/DARENet)]
- [CVPR18] Exploit the Unknown Gradually: One-Shot Video-Based Person Re-Identification by Stepwise Learning. [[paper](https://yu-wu.net/pdf/CVPR2018_Exploit-Unknown-Gradually.pdf)][[code](https://github.com/Yu-Wu/Exploit-Unknown-Gradually)]
- [ArXiv18] Revisiting Temporal Modeling for Video-based Person ReID. [[paper](https://arxiv.org/abs/1805.02104)][[code](https://github.com/jiyanggao/Video-Person-ReID)]
================================================
FILE: docs/MODEL_ZOO.md
================================================
# Model Zoo
- Results are presented in the format of *<Rank-1 (mAP)>*.
- When computing model size and FLOPs, only layers that are used at test time are considered (see `torchreid.utils.compute_model_complexity`).
- Asterisk (\*) means the model is trained from scratch.
- `combineall=True` means all images in the dataset are used for model training.
## ImageNet pretrained models
| Model | Download |
| :--- | :---: |
| shufflenet | [model](https://mega.nz/#!RDpUlQCY!tr_5xBEkelzDjveIYBBcGcovNCOrgfiJO9kiidz9fZM) |
| mobilenetv2_x1_0 | [model](https://mega.nz/#!NKp2wAIA!1NH1pbNzY_M2hVk_hdsxNM1NUOWvvGPHhaNr-fASF6c) |
| mobilenetv2_x1_4 | [model](https://mega.nz/#!RGhgEIwS!xN2s2ZdyqI6vQ3EwgmRXLEW3khr9tpXg96G9SUJugGk) |
| mlfn | [model](https://mega.nz/#!YHxAhaxC!yu9E6zWl0x5zscSouTdbZu8gdFFytDdl-RAdD2DEfpk) |
| osnet_x1_0 | [model](https://mega.nz/#!YK5GRARL!F90NsNB2XHjXGZFC3Lrw1GMic0oMw4fnfuDUnSrPAYM) |
| osnet_x0_75 | [model](https://mega.nz/#!NPxilYBA!Se414Wtts__7eY6J5FIrowynvjUUG7a8Z5zUPfJN33s) |
| osnet_x0_5 | [model](https://mega.nz/#!NO4ihQSJ!oMIRSZ0HlJF_8FKUbXT8Ei0vzH0xUYs5tWaf_KLrODg) |
| osnet_x0_25 | [model](https://mega.nz/#!IDwQwaxT!TbQ_33gPK-ZchPFTf43UMc45rlNKWiWMqH4rTXB1T7k) |
| osnet_ibn_x1_0 | [model](https://mega.nz/#!8Wo2kSDR!bNvgu4V0VkCQp_L2ZUDaudYKYRCkkSNdzcA1CcZGZTE) |
| osnet_ain_x1_0 | [model](https://drive.google.com/open?id=1-CaioD9NaqbHK_kzSMW8VE4_3KcsRjEo) |
## Same-domain ReID
| Model | # Param (10^6) | GFLOPs | Loss | Input | Transforms | Distance | market1501 | dukemtmcreid | msmt17 |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| resnet50 | 23.5 | 2.7 | softmax | (256, 128) | `random_flip`, `random_crop` | `euclidean` | [87.9 (70.4)](https://mega.nz/#!FKZjVKaZ!4v_FR8pTvuHoMQIKdstJ_YCsRrtZW2hwWxc-T0JIlHE) | [78.3 (58.9)](https://mega.nz/#!JPZjCYhK!YVJbE_4vTc8DX19Rt_FB77YY4BaEA1P6Xb5sNJGep2M) | [63.2 (33.9)](https://mega.nz/#!APAxDY4Z!Iou9x8s3ATdYS2SlK2oiJbHrhvlzH7F1gE2qjM-GJGw) |
| resnet50_fc512 | 24.6 | 4.1 | softmax | (256, 128) | `random_flip`, `random_crop` | `euclidean` | [90.8 (75.3)](https://mega.nz/#!EaZjhKyS!lBvD3vAJ4DOmElZkNa7gyPM1RE661GUd2v9kK84gSZE) | [81.0 (64.0)](https://mega.nz/#!lXYDSKZa!lumiXkY2H5Sm8gEgTWPBdWKv3ujy4zjrffjERaXkc9I) | [69.6 (38.4)](https://mega.nz/#!9PQTXIpL!iI5wgieTCn0Jm-pyg9RCu0RkH43pV3ntHhr1PeqSyT4) |
| mlfn | 32.5 | 2.8 | softmax | (256, 128) | `random_flip`, `random_crop` | `euclidean` | [90.1 (74.3)](https://mega.nz/#!kHQ3ESLT!NoGc8eHEBZOJZM19THh3DFfRBXIPXzM-sdLmF1mvTXA) | [81.1 (63.2)](https://mega.nz/#!8PQXUCaI!mJO1vD9tI739hkNBj2QWUt0VPcZ-s89fSMMGPPP1msc) | [66.4 (37.2)](https://mega.nz/#!paIXFQCS!W3ZGkxyF1idwvQzTRDE2p0DhNDki2SBJRfp7S_Cwphk) |
| hacnn<sup>*</sup> | 4.5 | 0.5 | softmax | (160, 64) | `random_flip`, `random_crop` | `euclidean` | [90.9 (75.6)](https://mega.nz/#!ULQXUQBK!S-8v_pR2xBD3ZpuY0I7Bqift-eX_V84gajHMDG6zUac) | [80.1 (63.2)](https://mega.nz/#!wPJTkAQR!XkKd39lsmBZMrCh3JjF6vnNafBZkouVIVdeBqQKdSzA) | [64.7 (37.2)](https://mega.nz/#!AXAziKjL!JtMwHz2UYy58gDMQLGakSmF3JOr72o8zmkqlQA-LIpQ) |
| mobilenetv2_x1_0 | 2.2 | 0.2 | softmax | (256, 128) | `random_flip`, `random_crop` | `euclidean` | [85.6 (67.3)](https://mega.nz/#!8KYTFAIB!3dL35WQLxSoTSClDTv0kxa81k3fh5hXmAWA4_a3qiOI) | [74.2 (54.7)](https://mega.nz/#!hbRXDSCL!YYgqJ6PVUf4clgtUuK2s5FRhYJdU3yTibLscwOTNnDk) | [57.4 (29.3)](https://mega.nz/#!5SJTmCYb!ZQ8O2MN9JF4-WDAeX04Xex1KyuBYQ_o2aoMIsTgQ748) |
| mobilenetv2_x1_4 | 4.3 | 0.4 | softmax | (256, 128) | `random_flip`, `random_crop` | `euclidean` | [87.0 (68.5)](https://mega.nz/#!4XZhEKCS!6lTuTRbHIWU5nzJzTPDGykA7sPME8_1ISGsUYFJXZWA) | [76.2 (55.8)](https://mega.nz/#!JbQVDIYQ!-7pnjIfpIDt1EoQOvpvuIEcTj3Qg8SE6o_3ZPGWrIcw) | [60.1 (31.5)](https://mega.nz/#!gOYDAQrK!sMJO7c_X4iIxoVfV_tXYdzeDJByPo5XkUjEN7Z2JTmM) |
| osnet_x1_0 | 2.2 | 0.98 | softmax | (256, 128) | `random_flip` | `euclidean` | [94.2 (82.6)](https://mega.nz/#!hLoyTSba!fqt7GcKrHJhwe9BtuK0ozgVAQcrlMG8Pm6JsSfr5HEI) | [87.0 (70.2)](https://mega.nz/#!ETwGhQYB!h2gHN-H3J4X4WqcJXy2b0pPKl28paydkiS-PDHsEgPM) | [74.9 (43.8)](https://mega.nz/#!hWxE2aJA!NGcxu5uYH1qI6DfBTu0KFoi_NfoA0TJcBFW-g43pC0I) |
| osnet_x0_75 | 1.3 | 0.57 | softmax | (256, 128) | `random_flip` | `euclidean` | [93.7 (81.2)](https://mega.nz/#!JO4WAaJa!nQuoqZnYfy0xu7vs2mp28AFceya-ZhrXTry837jvoDQ) | [85.8 (69.8)](https://mega.nz/#!lOgkEIoI!fQ5vuYIABIOcRxF-OK-6YxtEufWhyVkYkGB4qPoRYJ4) | [72.8 (41.4)](https://mega.nz/#!0exGXI5a!rxtzBayyRK0on0HFq9XO0UtWEBhbV86dFitljhjeWcs) |
| osnet_x0_5 | 0.6 | 0.27 | softmax | (256, 128) | `random_flip` | `euclidean` | [92.5 (79.8)](https://mega.nz/#!QCx0RArD!hqz3Mh0Iif5d8PpQW0frxa-Tepn2a2g24aei7du4MFs) | [85.1 (67.4)](https://mega.nz/#!QTxCDIbT!eOZxj4dHl0uFnjKEB-J3YBY98blXZvppgWGA3CGa-tk) | [69.7 (37.5)](https://mega.nz/#!ETpiECDa!CCkq4JryztHqgw7spL5zDw0usJpAfEsSd5gPlkMufCc) |
| osnet_x0_25 | 0.2 | 0.08 | softmax | (256, 128) | `random_flip` | `euclidean` | [91.2 (75.0)](https://mega.nz/#!VWxCgSqY!Q4WaQ3j9D7HMhK3jsbvMuwaZ7yBY80T2Zj5V8JAlAKU) | [82.0 (61.4)](https://mega.nz/#!5TpwnATK!UvU_Asdy_aJ9SNzuvqhEFoemxSSB8vm_Gm8Xe03jqiA) | [61.4 (29.5)](https://mega.nz/#!AWgE3SzD!DngUaNyA7VIqOd2gq10Aty_-ER0CmG0xTJLHLj6_36g) |
## Cross-domain ReID
#### Market1501 -> DukeMTMC-reID
| Model | # Param (10^6) | GFLOPs | Loss | Input | Transforms | Distance | Rank-1 | Rank-5 | Rank-10 | mAP | Download |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| osnet_ibn_x1_0 | 2.2 | 0.98 | softmax | (256, 128) | `random_flip`, `color_jitter` | `euclidean` | 48.5 | 62.3 | 67.4 | 26.7 | [model](https://mega.nz/#!wXwGxKxK!f8EMk8hBt6AjxU3JIPGMFSMvX7j-Nt5Lp1Gpbqso1Ts) |
| osnet_ain_x1_0 | 2.2 | 0.98 | softmax | (256, 128) | `random_flip`, `color_jitter` | `cosine` | 52.4 | 66.1 | 71.2 | 30.5 | [model](https://mega.nz/#!QLJE2CRI!FXYc3Vm6Y5Scwx0xvRwBJxId56kf06fIXNLwA_b_1FE) |
#### DukeMTMC-reID -> Market1501
| Model | # Param (10^6) | GFLOPs | Loss | Input | Transforms | Distance | Rank-1 | Rank-5 | Rank-10 | mAP | Download |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| osnet_ibn_x1_0 | 2.2 | 0.98 | softmax | (256, 128) | `random_flip`, `color_jitter` | `euclidean` | 57.7 | 73.7 | 80.0 | 26.1 | [model](https://mega.nz/#!FD4WEKJS!ZGgI-2IwVuX6re09xylChR03o6Dkjpi6KSebrbS0fAA) |
| osnet_ain_x1_0 | 2.2 | 0.98 | softmax | (256, 128) | `random_flip`, `color_jitter` | `cosine` | 61.0 | 77.0 | 82.5 | 30.6 | [model](https://mega.nz/#!4PBQlCCL!9yMHu1WyyBVxqssubLAEyoEfHUiNP4Ggg5On0nCX2S4) |
#### MSMT17 (`combineall=True`) -> Market1501 & DukeMTMC-reID
| Model | # Param (10^6) | GFLOPs | Loss | Input | Transforms | Distance | msmt17 -> market1501 | msmt17 -> dukemtmcreid | Download |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| resnet50 | 23.5 | 2.7 | softmax | (256, 128) | `random_flip`, `color_jitter` | `euclidean` | 46.3 (22.8) | 52.3 (32.1) | [model](https://mega.nz/#!VTpkWSbS!Y8gDnmg7u-sPwnZDhWXrtZNYOj7UYL4QzZkhDf1qWW4) |
| osnet_x1_0 | 2.2 | 0.98 | softmax | (256, 128) | `random_flip`, `color_jitter` | `euclidean` | 66.6 (37.5) | 66.0 (45.3) | [model](https://mega.nz/#!MepG3QRC!Lb-C9d7rdS_YJjGSoJ5cRlzjYcP28P_1Cm5S5WSslW0) |
| osnet_x0_75 | 1.3 | 0.57 | softmax | (256, 128) | `random_flip`, `color_jitter` | `euclidean` | 63.6 (35.5) | 65.3 (44.5) | [model](https://mega.nz/#!tO4WDagL!8Tl6kdJWRXRHQb16GeUHR008tJqW3N7_3fyVMu-LcKM) |
| osnet_x0_5 | 0.6 | 0.27 | softmax | (256, 128) | `random_flip`, `color_jitter` | `euclidean` | 64.3 (34.9) | 65.2 (43.3) | [model](https://mega.nz/#!papSWQhY!IId-QfcHj7nXQ_muUubgv9_n0SsnZzarmb5mQgcMv74) |
| osnet_x0_25 | 0.2 | 0.08 | softmax | (256, 128) | `random_flip`, `color_jitter` | `euclidean` | 59.9 (31.0) | 61.5 (39.6) | [model](https://mega.nz/#!QCoE0Kpa!BITLANumgjiR68TUFteL__N_RIoDKkL0M5Bl3Q8LC3U) |
| osnet_ibn_x1_0 | 2.2 | 0.98 | softmax | (256, 128) | `random_flip`, `color_jitter` | `euclidean` | 66.5 (37.2) | 67.4 (45.6) | [model](https://mega.nz/#!dL4Q2K5B!ZdHQ_X_rs2T-xmggigM5YvzJhmT1orkr6aQ1_fHgunM) |
| osnet_ain_x1_0 | 2.2 | 0.98 | softmax | (256, 128) | `random_flip`, `color_jitter` | `cosine` | 70.1 (43.3) | 71.1 (52.7) | [model](https://mega.nz/#!YTZFnSJY!wlbo_5oa2TpDAGyWCTKTX1hh4d6DvJhh_RUA2z6i_so) |
================================================
FILE: docs/Makefile
================================================
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
================================================
FILE: docs/conf.py
================================================
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
# -- Project information -----------------------------------------------------
project = u'torchreid'
copyright = u'2019, Kaiyang Zhou'
author = u'Kaiyang Zhou'
version_file = '../torchreid/__init__.py'
with open(version_file, 'r') as f:
exec(compile(f.read(), version_file, 'exec'))
__version__ = locals()['__version__']
# The short X.Y version
version = __version__
# The full version, including alpha/beta/rc tags
release = __version__
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinxcontrib.napoleon',
'sphinx.ext.viewcode',
'sphinx.ext.githubpages',
'sphinx_markdown_tables',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
source_suffix = ['.rst', '.md']
# source_suffix = '.rst'
source_parsers = {'.md': 'recommonmark.parser.CommonMarkParser'}
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'torchreiddoc'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(
master_doc, 'torchreid.tex', u'torchreid Documentation',
u'Kaiyang Zhou', 'manual'
),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'torchreid', u'torchreid Documentation', [author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc, 'torchreid', u'torchreid Documentation', author,
'torchreid', 'One line description of project.', 'Miscellaneous'
),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Extension configuration -------------------------------------------------
================================================
FILE: docs/datasets.rst
================================================
.. _datasets:
Datasets
=========
Here we provide a guide on how to prepare datasets.
Suppose you wanna store the reid data in a directory called "path/to/reid-data/", you need to specify the ``root`` as *root='path/to/reid-data/'* when initializing ``DataManager``. Below we use ``$REID`` to denote "path/to/reid-data".
Please refer to :ref:`torchreid_data` for details regarding the arguments.
.. note::
Dataset with a :math:`\dagger` superscript means that the process is automated, so you can directly call the dataset in ``DataManager`` (which automatically downloads the dataset and organizes the data structure). However, we also provide a way below to help the manual setup in case the automation fails.
.. note::
The keys to use specific datasets are enclosed in the parantheses beside the datasets.
.. note::
You are suggested to use the provided names for dataset folders such as "market1501" for Market1501 and "dukemtmcreid" for DukeMTMC-reID when doing the manual setup, otherwise you need to modify the source code accordingly (i.e. the ``dataset_dir`` attribute).
.. contents::
:local:
Image Datasets
--------------
Market1501 :math:`^\dagger` (``market1501``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Create a directory named "market1501" under ``$REID``.
- Download the dataset to "market1501" from http://www.liangzheng.org/Project/project_reid.html and extract the files.
- The data structure should look like
.. code-block:: none
market1501/
Market-1501-v15.09.15/
query/
bounding_box_train/
bounding_box_test/
- To use the extra 500K distractors (i.e. Market1501 + 500K), go to the **Market-1501+500k Dataset** section at http://www.liangzheng.org/Project/project_reid.html, download the zip file "distractors_500k.zip" and extract it under "market1501/Market-1501-v15.09.15". The argument to use these 500K distrctors is ``market1501_500k`` in ``ImageDataManager``.
CUHK03 (``cuhk03``)
^^^^^^^^^^^^^^^^^^^^^
- Create a folder named "cuhk03" under ``$REID``.
- Download the dataset to "cuhk03/" from http://www.ee.cuhk.edu.hk/~xgwang/CUHK_identification.html and extract "cuhk03_release.zip", resulting in "cuhk03/cuhk03_release/".
- Download the new split (767/700) from `person-re-ranking <https://github.com/zhunzhong07/person-re-ranking/tree/master/evaluation/data/CUHK03>`_. What you need are "cuhk03_new_protocol_config_detected.mat" and "cuhk03_new_protocol_config_labeled.mat". Put these two mat files under "cuhk03/".
- The data structure should look like
.. code-block:: none
cuhk03/
cuhk03_release/
cuhk03_new_protocol_config_detected.mat
cuhk03_new_protocol_config_labeled.mat
- In the default mode, we load data using the new split (767/700). If you wanna use the original (20) splits (1367/100), please set ``cuhk03_classic_split`` to True in ``ImageDataManager``. As the CMC is computed differently from Market1501 for the 1367/100 split (see `here <http://www.ee.cuhk.edu.hk/~xgwang/CUHK_identification.html>`_), you need to enable ``use_metric_cuhk03`` in ``ImageDataManager`` to activate the *single-gallery-shot* metric for fair comparison with some methods that adopt the old splits (*do not need to report mAP*). In addition, we support both *labeled* and *detected* modes. The default mode loads *detected* images. Enable ``cuhk03_labeled`` in ``ImageDataManager`` if you wanna train and test on *labeled* images.
.. note::
The code will extract images in "cuhk-03.mat" and save them under "cuhk03/images_detected" and "cuhk03/images_labeled". Also, four json files will be automatically generated, i.e. "splits_classic_detected.json", "splits_classic_labeled.json", "splits_new_detected.json" and "splits_new_labeled.json". If the parent path of ``$REID`` is changed, these json files should be manually deleted. The code can automatically generate new json files to match the new path.
DukeMTMC-reID :math:`^\dagger` (``dukemtmcreid``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Create a directory called "dukemtmc-reid" under ``$REID``.
- Download "DukeMTMC-reID" from http://vision.cs.duke.edu/DukeMTMC/ and extract it under "dukemtmc-reid".
- The data structure should look like
.. code-block:: none
dukemtmc-reid/
DukeMTMC-reID/
query/
bounding_box_train/
bounding_box_test/
...
MSMT17 (``msmt17``)
^^^^^^^^^^^^^^^^^^^^^
- Create a directory called "msmt17" under ``$REID``.
- Download the dataset from http://www.pkuvmc.com/publications/msmt17.html to "msmt17" and extract the files.
- The data structure should look like
.. code-block:: none
msmt17/
MSMT17_V1/ # or MSMT17_V2
train/
test/
list_train.txt
list_query.txt
list_gallery.txt
list_val.txt
VIPeR :math:`^\dagger` (``viper``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The download link is http://users.soe.ucsc.edu/~manduchi/VIPeR.v1.0.zip.
- Organize the dataset in a folder named "viper" as follows
.. code-block:: none
viper/
VIPeR/
cam_a/
cam_b/
GRID :math:`^\dagger` (``grid``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The download link is http://personal.ie.cuhk.edu.hk/~ccloy/files/datasets/underground_reid.zip.
- Organize the dataset in a folder named "grid" as follows
.. code-block:: none
grid/
underground_reid/
probe/
gallery/
...
CUHK01 (``cuhk01``)
^^^^^^^^^^^^^^^^^^^^^^^^
- Create a folder named "cuhk01" under ``$REID``.
- Download "CUHK01.zip" from http://www.ee.cuhk.edu.hk/~xgwang/CUHK_identification.html and place it under "cuhk01/".
- The code can automatically extract the files, or you can do it yourself.
- The data structure should look like
.. code-block:: none
cuhk01/
campus/
SenseReID (``sensereid``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Create "sensereid" under ``$REID``.
- Download the dataset from this `link <https://drive.google.com/file/d/0B56OfSrVI8hubVJLTzkwV2VaOWM/view>`_ and extract it to "sensereid".
- Organize the data to be like
.. code-block:: none
sensereid/
SenseReID/
test_probe/
test_gallery/
QMUL-iLIDS :math:`^\dagger` (``ilids``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Create a folder named "ilids" under ``$REID``.
- Download the dataset from http://www.eecs.qmul.ac.uk/~jason/data/i-LIDS_Pedestrian.tgz and organize it to look like
.. code-block:: none
ilids/
i-LIDS_Pedestrian/
Persons/
PRID (``prid``)
^^^^^^^^^^^^^^^^^^^
- Create a directory named "prid2011" under ``$REID``.
- Download the dataset from https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/PRID11/ and extract it under "prid2011".
- The data structure should end up with
.. code-block:: none
prid2011/
prid_2011/
single_shot/
multi_shot/
CUHK02 (``cuhk02``)
^^^^^^^^^^^^^^^^^^^^^
- Create a folder named "cuhk02" under ``$REID``.
- Download the data from http://www.ee.cuhk.edu.hk/~xgwang/CUHK_identification.html and put it under "cuhk02/".
- Extract the file so the data structure looks like
.. code-block:: none
cuhk02/
Dataset/
P1/
P2/
P3/
P4/
P5/
Video Datasets
--------------
MARS (``mars``)
^^^^^^^^^^^^^^^^^
- Create "mars/" under ``$REID``.
- Download the dataset from http://www.liangzheng.com.cn/Project/project_mars.html and place it in "mars/".
- Extract "bbox_train.zip" and "bbox_test.zip".
- Download the split metadata from https://github.com/liangzheng06/MARS-evaluation/tree/master/info and put "info/" in "mars/".
- The data structure should end up with
.. code-block:: none
mars/
bbox_test/
bbox_train/
info/
iLIDS-VID :math:`^\dagger` (``ilidsvid``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Create "ilids-vid" under ``$REID``.
- Download the dataset from http://www.eecs.qmul.ac.uk/~xiatian/downloads_qmul_iLIDS-VID_ReID_dataset.html to "ilids-vid".
- Organize the data structure to match
.. code-block:: none
ilids-vid/
i-LIDS-VID/
train-test people splits/
PRID2011 (``prid2011``)
^^^^^^^^^^^^^^^^^^^^^^^^^
- Create a directory named "prid2011" under ``$REID``.
- Download the dataset from https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/PRID11/ and extract it under "prid2011".
- Download the split created by *iLIDS-VID* from `this google drive <https://drive.google.com/open?id=1qw7SI7YdIgfHetIQO7LLW4SHpL_qkieT>`_ and put it under "prid2011/". Following the standard protocol, only 178 persons whose sequences are more than a threshold are used.
- The data structure should end up with
.. code-block:: none
prid2011/
splits_prid2011.json
prid_2011/
single_shot/
multi_shot/
DukeMTMC-VideoReID :math:`^\dagger` (``dukemtmcvidreid``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Create "dukemtmc-vidreid" under ``$REID``.
- Download "DukeMTMC-VideoReID" from http://vision.cs.duke.edu/DukeMTMC/ and unzip the file to "dukemtmc-vidreid/".
- The data structure should look like
.. code-block:: none
dukemtmc-vidreid/
DukeMTMC-VideoReID/
train/
query/
gallery/
================================================
FILE: docs/evaluation.rst
================================================
Evaluation
==========
Image ReID
-----------
- **Market1501**, **DukeMTMC-reID**, **CUHK03 (767/700 split)** and **MSMT17** have fixed split so keeping ``split_id=0`` is fine.
- **CUHK03 (classic split)** has 20 fixed splits, so do ``split_id=0~19``.
- **VIPeR** contains 632 identities each with 2 images under two camera views. Evaluation should be done for 10 random splits. Each split randomly divides 632 identities to 316 train ids (632 images) and the other 316 test ids (632 images). Note that, in each random split, there are two sub-splits, one using camera-A as query and camera-B as gallery while the other one using camera-B as query and camera-A as gallery. Thus, there are totally 20 splits generated with ``split_id`` starting from 0 to 19. Models can be trained on ``split_id=[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]`` (because ``split_id=0`` and ``split_id=1`` share the same train set, and so on and so forth.). At test time, models trained on ``split_id=0`` can be directly evaluated on ``split_id=1``, models trained on ``split_id=2`` can be directly evaluated on ``split_id=3``, and so on and so forth.
- **CUHK01** is similar to VIPeR in the split generation.
- **GRID** , **iLIDS** and **PRID** have 10 random splits, so evaluation should be done by varying ``split_id`` from 0 to 9.
- **SenseReID** has no training images and is used for evaluation only.
.. note::
The ``split_id`` argument is defined in ``ImageDataManager`` and ``VideoDataManager``. Please refer to :ref:`torchreid_data`.
Video ReID
-----------
- **MARS** and **DukeMTMC-VideoReID** have fixed single split so using ``split_id=0`` is ok.
- **iLIDS-VID** and **PRID2011** have 10 predefined splits so evaluation should be done by varying ``split_id`` from 0 to 9.
================================================
FILE: docs/index.rst
================================================
.. include:: ../README.rst
.. toctree::
:hidden:
user_guide
datasets
evaluation
.. toctree::
:caption: Package Reference
:hidden:
pkg/data
pkg/engine
pkg/losses
pkg/metrics
pkg/models
pkg/optim
pkg/utils
.. toctree::
:caption: Resources
:hidden:
AWESOME_REID.md
MODEL_ZOO.md
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
================================================
FILE: docs/pkg/data.rst
================================================
.. _torchreid_data:
torchreid.data
==============
Data Manager
---------------------------
.. automodule:: torchreid.data.datamanager
:members:
Sampler
-----------------------
.. automodule:: torchreid.data.sampler
:members:
Transforms
---------------------------
.. automodule:: torchreid.data.transforms
:members:
Dataset
---------------------------
.. automodule:: torchreid.data.datasets.dataset
:members:
.. automodule:: torchreid.data.datasets.__init__
:members:
Image Datasets
------------------------------
.. automodule:: torchreid.data.datasets.image.market1501
:members:
.. automodule:: torchreid.data.datasets.image.cuhk03
:members:
.. automodule:: torchreid.data.datasets.image.dukemtmcreid
:members:
.. automodule:: torchreid.data.datasets.image.msmt17
:members:
.. automodule:: torchreid.data.datasets.image.viper
:members:
.. automodule:: torchreid.data.datasets.image.grid
:members:
.. automodule:: torchreid.data.datasets.image.cuhk01
:members:
.. automodule:: torchreid.data.datasets.image.ilids
:members:
.. automodule:: torchreid.data.datasets.image.sensereid
:members:
.. automodule:: torchreid.data.datasets.image.prid
:members:
Video Datasets
------------------------------
.. automodule:: torchreid.data.datasets.video.mars
:members:
.. automodule:: torchreid.data.datasets.video.ilidsvid
:members:
.. automodule:: torchreid.data.datasets.video.prid2011
:members:
.. automodule:: torchreid.data.datasets.video.dukemtmcvidreid
:members:
================================================
FILE: docs/pkg/engine.rst
================================================
.. _torchreid_engine:
torchreid.engine
==================
Base Engine
------------
.. autoclass:: torchreid.engine.engine.Engine
:members:
Image Engines
-------------
.. autoclass:: torchreid.engine.image.softmax.ImageSoftmaxEngine
:members:
.. autoclass:: torchreid.engine.image.triplet.ImageTripletEngine
:members:
Video Engines
-------------
.. autoclass:: torchreid.engine.video.softmax.VideoSoftmaxEngine
.. autoclass:: torchreid.engine.video.triplet.VideoTripletEngine
================================================
FILE: docs/pkg/losses.rst
================================================
.. _torchreid_losses:
torchreid.losses
=================
Softmax
--------
.. automodule:: torchreid.losses.cross_entropy_loss
:members:
Triplet
-------
.. automodule:: torchreid.losses.hard_mine_triplet_loss
:members:
================================================
FILE: docs/pkg/metrics.rst
================================================
.. _torchreid_metrics:
torchreid.metrics
=================
Distance
---------
.. automodule:: torchreid.metrics.distance
:members:
Accuracy
--------
.. automodule:: torchreid.metrics.accuracy
:members:
Rank
-----
.. automodule:: torchreid.metrics.rank
:members: evaluate_rank
================================================
FILE: docs/pkg/models.rst
================================================
.. _torchreid_models:
torchreid.models
=================
Interface
---------
.. automodule:: torchreid.models.__init__
:members:
ImageNet Classification Models
-------------------------------
.. autoclass:: torchreid.models.resnet.ResNet
.. autoclass:: torchreid.models.senet.SENet
.. autoclass:: torchreid.models.densenet.DenseNet
.. autoclass:: torchreid.models.inceptionresnetv2.InceptionResNetV2
.. autoclass:: torchreid.models.inceptionv4.InceptionV4
.. autoclass:: torchreid.models.xception.Xception
Lightweight Models
------------------
.. autoclass:: torchreid.models.nasnet.NASNetAMobile
.. autoclass:: torchreid.models.mobilenetv2.MobileNetV2
.. autoclass:: torchreid.models.shufflenet.ShuffleNet
.. autoclass:: torchreid.models.squeezenet.SqueezeNet
.. autoclass:: torchreid.models.shufflenetv2.ShuffleNetV2
ReID-specific Models
--------------------
.. autoclass:: torchreid.models.mudeep.MuDeep
.. autoclass:: torchreid.models.resnetmid.ResNetMid
.. autoclass:: torchreid.models.hacnn.HACNN
.. autoclass:: torchreid.models.pcb.PCB
.. autoclass:: torchreid.models.mlfn.MLFN
.. autoclass:: torchreid.models.osnet.OSNet
.. autoclass:: torchreid.models.osnet_ain.OSNet
================================================
FILE: docs/pkg/optim.rst
================================================
.. _torchreid_optim:
torchreid.optim
=================
Optimizer
----------
.. automodule:: torchreid.optim.optimizer
:members: build_optimizer
LR Scheduler
-------------
.. automodule:: torchreid.optim.lr_scheduler
:members: build_lr_scheduler
================================================
FILE: docs/pkg/utils.rst
================================================
.. _torchreid_utils:
torchreid.utils
=================
Average Meter
--------------
.. automodule:: torchreid.utils.avgmeter
:members:
Loggers
-------
.. automodule:: torchreid.utils.loggers
:members:
Generic Tools
---------------
.. automodule:: torchreid.utils.tools
:members:
ReID Tools
----------
.. automodule:: torchreid.utils.reidtools
:members:
Torch Tools
------------
.. automodule:: torchreid.utils.torchtools
:members:
.. automodule:: torchreid.utils.model_complexity
:members:
================================================
FILE: docs/requirements.txt
================================================
sphinx
sphinx-markdown-tables
sphinx-rtd-theme
sphinxcontrib-napoleon
sphinxcontrib-websupport
recommonmark
================================================
FILE: docs/user_guide.rst
================================================
How-to
============
.. contents::
:local:
Prepare datasets
-----------------
See :ref:`datasets`.
Find model keys
-----------------
Keys are listed under the *Public keys* section within each model class in :ref:`torchreid_models`.
Show available models
----------------------
.. code-block:: python
import torchreid
torchreid.models.show_avai_models()
Change the training sampler
-----------------------------
The default ``train_sampler`` is "RandomSampler". You can give the specific sampler name as input to ``train_sampler``, e.g. ``train_sampler='RandomIdentitySampler'`` for triplet loss.
Choose an optimizer/lr_scheduler
----------------------------------
Please refer to the source code of ``build_optimizer``/``build_lr_scheduler`` in :ref:`torchreid_optim` for details.
Resume training
----------------
Suppose the checkpoint is saved in "log/resnet50/model.pth.tar-30", you can do
.. code-block:: python
start_epoch = torchreid.utils.resume_from_checkpoint(
'log/resnet50/model.pth.tar-30',
model,
optimizer
)
engine.run(
save_dir='log/resnet50',
max_epoch=60,
start_epoch=start_epoch
)
Compute model complexity
--------------------------
We provide a tool in ``torchreid.utils.model_complexity.py`` to automatically compute the model complexity, i.e. number of parameters and FLOPs.
.. code-block:: python
from torchreid import models, utils
model = models.build_model(name='resnet50', num_classes=1000)
num_params, flops = utils.compute_model_complexity(model, (1, 3, 256, 128))
# show detailed complexity for each module
utils.compute_model_complexity(model, (1, 3, 256, 128), verbose=True)
# count flops for all layers including ReLU and BatchNorm
utils.compute_model_complexity(model, (1, 3, 256, 128), verbose=True, only_conv_linear=False)
Note that (1) this function only provides an estimate of the theoretical time complexity rather than the actual running time which depends on implementations and hardware; (2) the FLOPs is only counted for layers that are used at test time. This means that redundant layers such as person ID classification layer will be ignored. The inference graph depends on how you define the computations in ``forward()``.
Combine multiple datasets
---------------------------
Easy. Just give whatever datasets (keys) you want to the ``sources`` argument when instantiating a data manager. For example,
.. code-block:: python
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources=['market1501', 'dukemtmcreid', 'cuhk03', 'msmt17'],
height=256,
width=128,
batch_size=32
)
In this example, the target datasets are Market1501, DukeMTMC-reID, CUHK03 and MSMT17 as the ``targets`` argument is not specified. Please refer to ``Engine.test()`` in :ref:`torchreid_engine` for details regarding how evaluation is performed.
Do cross-dataset evaluation
-----------------------------
Easy. Just give whatever datasets (keys) you want to the argument ``targets``, like
.. code-block:: python
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources='market1501',
targets='dukemtmcreid', # or targets='cuhk03' or targets=['dukemtmcreid', 'cuhk03']
height=256,
width=128,
batch_size=32
)
Combine train, query and gallery
---------------------------------
This can be easily done by setting ``combineall=True`` when instantiating a data manager. Below is an example of using Market1501,
.. code-block:: python
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources='market1501',
height=256,
width=128,
batch_size=32,
market1501_500k=False,
combineall=True # it's me, here
)
More specifically, with ``combineall=False``, you will get
.. code-block:: none
=> Loaded Market1501
----------------------------------------
subset | # ids | # images | # cameras
----------------------------------------
train | 751 | 12936 | 6
query | 750 | 3368 | 6
gallery | 751 | 15913 | 6
---------------------------------------
with ``combineall=True``, you will get
.. code-block:: none
=> Loaded Market1501
----------------------------------------
subset | # ids | # images | # cameras
----------------------------------------
train | 1501 | 29419 | 6
query | 750 | 3368 | 6
gallery | 751 | 15913 | 6
---------------------------------------
Optimize layers with different learning rates
-----------------------------------------------
A common practice for fine-tuning pretrained models is to use a smaller learning rate for base layers and a large learning rate for randomly initialized layers (referred to as ``new_layers``). ``torchreid.optim.optimizer`` has implemented such feature. What you need to do is to set ``staged_lr=True`` and give the names of ``new_layers`` such as "classifier".
Below is an example of setting different learning rates for base layers and new layers in ResNet50,
.. code-block:: python
# New layer "classifier" has a learning rate of 0.01
# The base layers have a learning rate of 0.001
optimizer = torchreid.optim.build_optimizer(
model,
optim='sgd',
lr=0.01,
staged_lr=True,
new_layers='classifier',
base_lr_mult=0.1
)
Please refer to :ref:`torchreid_optim` for more details.
Do two-stepped transfer learning
-------------------------------------
To prevent the pretrained layers from being damaged by harmful gradients back-propagated from randomly initialized layers, one can adopt the *two-stepped transfer learning strategy* presented in `Deep Transfer Learning for Person Re-identification <https://arxiv.org/abs/1611.05244>`_. The basic idea is to pretrain the randomly initialized layers for few epochs while keeping the base layers frozen before training all layers end-to-end.
This has been implemented in ``Engine.train()`` (see :ref:`torchreid_engine`). The arguments related to this feature are ``fixbase_epoch`` and ``open_layers``. Intuitively, ``fixbase_epoch`` denotes the number of epochs to keep the base layers frozen; ``open_layers`` means which layer is open for training.
For example, say you want to pretrain the classification layer named "classifier" in ResNet50 for 5 epochs before training all layers, you can do
.. code-block:: python
engine.run(
save_dir='log/resnet50',
max_epoch=60,
eval_freq=10,
test_only=False,
fixbase_epoch=5,
open_layers='classifier'
)
# or open_layers=['fc', 'classifier'] if there is another fc layer that
# is randomly initialized, like resnet50_fc512
Note that ``fixbase_epoch`` is counted into ``max_epoch``. In the above example, the base network will be fixed for 5 epochs and then open for training for 55 epochs. Thus, if you want to freeze some layers throughout the training, what you can do is to set ``fixbase_epoch`` equal to ``max_epoch`` and put the layer names in ``open_layers`` which you want to train.
Test a trained model
----------------------
You can load a trained model using :code:`torchreid.utils.load_pretrained_weights(model, weight_path)` and set ``test_only=True`` in ``engine.run()``.
Fine-tune a model pre-trained on reid datasets
-----------------------------------------------
Use :code:`torchreid.utils.load_pretrained_weights(model, weight_path)` to load the pre-trained weights and then fine-tune on the dataset you want.
Visualize learning curves with tensorboard
--------------------------------------------
The ``SummaryWriter()`` for tensorboard will be automatically initialized in ``engine.run()`` when you are training your model. Therefore, you do not need to do extra jobs. After the training is done, the ``*tf.events*`` file will be saved in ``save_dir``. Then, you just call ``tensorboard --logdir=your_save_dir`` in your terminal and visit ``http://localhost:6006/`` in a web browser. See `pytorch tensorboard <https://pytorch.org/docs/stable/tensorboard.html>`_ for further information.
Visualize ranking results
---------------------------
This can be achieved by setting ``visrank`` to true in ``engine.run()``. ``visrank_topk`` determines the top-k images to be visualized (Default is ``visrank_topk=10``). Note that ``visrank`` can only be used in test mode, i.e. ``test_only=True`` in ``engine.run()``. The output will be saved under ``save_dir/visrank_DATASETNAME`` where each plot contains the top-k similar gallery images given a query. An example is shown below where red and green denote incorrect and correct matches respectively.
.. image:: figures/ranking_results.jpg
:width: 800px
:align: center
Visualize activation maps
--------------------------
To understand where the CNN focuses on to extract features for ReID, you can visualize the activation maps as in `OSNet <https://arxiv.org/abs/1905.00953>`_. This is implemented in ``tools/visualize_actmap.py`` (check the code for more details). An example running command is
.. code-block:: shell
python tools/visualize_actmap.py \
--root $DATA/reid \
-d market1501 \
-m osnet_x1_0 \
--weights PATH_TO_PRETRAINED_WEIGHTS \
--save-dir log/visactmap_osnet_x1_0_market1501
The output will look like (from left to right: image, activation map, overlapped image)
.. image:: figures/actmap.jpg
:width: 300px
:align: center
.. note::
In order to visualize activation maps, the CNN needs to output the last convolutional feature maps at eval mode. See ``torchreid/models/osnet.py`` for example.
Use your own dataset
----------------------
1. Write your own dataset class. Below is a template for image dataset. However, it can also be applied to a video dataset class, for which you simply change ``ImageDataset`` to ``VideoDataset``.
.. code-block:: python
from __future__ import absolute_import
from __future__ import print_function
from __future__ import division
import sys
import os
import os.path as osp
from torchreid.data import ImageDataset
class NewDataset(ImageDataset):
dataset_dir = 'new_dataset'
def __init__(self, root='', **kwargs):
self.root = osp.abspath(osp.expanduser(root))
self.dataset_dir = osp.join(self.root, self.dataset_dir)
# All you need to do here is to generate three lists,
# which are train, query and gallery.
# Each list contains tuples of (img_path, pid, camid),
# where
# - img_path (str): absolute path to an image.
# - pid (int): person ID, e.g. 0, 1.
# - camid (int): camera ID, e.g. 0, 1.
# Note that
# - pid and camid should be 0-based.
# - query and gallery should share the same pid scope (e.g.
# pid=0 in query refers to the same person as pid=0 in gallery).
# - train, query and gallery share the same camid scope (e.g.
# camid=0 in train refers to the same camera as camid=0
# in query/gallery).
train = ...
query = ...
gallery = ...
super(NewDataset, self).__init__(train, query, gallery, **kwargs)
2. Register your dataset.
.. code-block:: python
import torchreid
torchreid.data.register_image_dataset('new_dataset', NewDataset)
3. Initialize a data manager with your dataset.
.. code-block:: python
# use your own dataset only
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources='new_dataset'
)
# combine with other datasets
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources=['new_dataset', 'dukemtmcreid']
)
# cross-dataset evaluation
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources=['new_dataset', 'dukemtmcreid'],
targets='market1501' # or targets=['market1501', 'cuhk03']
)
Design your own Engine
------------------------
A new Engine should be designed if you have your own loss function. The base Engine class ``torchreid.engine.Engine`` has implemented some generic methods which you can inherit to avoid re-writing. Please refer to the source code for more details. You are suggested to see how ``ImageSoftmaxEngine`` and ``ImageTripletEngine`` are constructed (also ``VideoSoftmaxEngine`` and ``VideoTripletEngine``). All you need to implement might be just a ``forward_backward()`` function.
Use Torchreid as a feature extractor in your projects
-------------------------------------------------------
We have provided a simple API for feature extraction, which accepts input of various types such as a list of image paths or numpy arrays. More details can be found in the code at ``torchreid/utils/feature_extractor.py``. Here we show a simple example of how to extract features given a list of image paths.
.. code-block:: python
from torchreid.utils import FeatureExtractor
extractor = FeatureExtractor(
model_name='osnet_x1_0',
model_path='a/b/c/model.pth.tar',
device='cuda'
)
image_list = [
'a/b/c/image001.jpg',
'a/b/c/image002.jpg',
'a/b/c/image003.jpg',
'a/b/c/image004.jpg',
'a/b/c/image005.jpg'
]
features = extractor(image_list)
print(features.shape) # output (5, 512)
================================================
FILE: linter.sh
================================================
echo "Running isort"
isort -y -sp .
echo "Done"
echo "Running yapf"
yapf -i -r -vv -e build .
echo "Done"
echo "Running flake8"
flake8 .
echo "Done"
================================================
FILE: pyproject.toml
================================================
[project]
name = "torchreid"
authors = [{name="Vladimir Somers"}, {name="Kaiyang Zhou"}]
urls = {homepage = "https://github.com/VlSomers/bpbreid"}
dynamic = ["version", "description", "license", "dependencies", "keywords", "readme", "optional-dependencies"]
[tool.setuptools.dynamic]
version = {attr = "torchreid.__version__"}
[build-system]
requires = ["setuptools", "numpy", "cython"]
build-backend = "setuptools.build_meta"
================================================
FILE: requirements.txt
================================================
# pip install -r requirements.txt
# base torchreid ----------------------------------------
numpy
Cython
h5py
Pillow
six
scipy
opencv-python
matplotlib
tb-nightly
future
yacs
gdown
flake8
yapf
isort
# added for bpbreid
albumentations
pandas
tabulate
deepdiff
wandb
monai
torchmetrics==0.10.3
================================================
FILE: requirements_labels.txt
================================================
openpifpaf
detectron2 @ git+https://github.com/facebookresearch/detectron2.git
================================================
FILE: setup.py
================================================
import numpy as np
import os.path as osp
from setuptools import setup, find_packages
from distutils.extension import Extension
from Cython.Build import cythonize
def readme():
with open('README.md') as f:
content = f.read()
return content
def numpy_include():
try:
numpy_include = np.get_include()
except AttributeError:
numpy_include = np.get_numpy_include()
return numpy_include
ext_modules = [
Extension(
'torchreid.metrics.rank_cylib.rank_cy',
['torchreid/metrics/rank_cylib/rank_cy.pyx'],
include_dirs=[numpy_include()],
)
]
def get_requirements(filename='requirements.txt'):
here = osp.dirname(osp.realpath(__file__))
with open(osp.join(here, filename), 'r') as f:
requires = [line.replace('\n', '') for line in f.readlines()]
return requires
setup(
description='A library for deep learning person re-ID in PyTorch',
license='MIT',
long_description=readme(),
packages=find_packages(),
install_requires=get_requirements(),
extras_require={"labels": get_requirements("requirements_labels.txt")},
keywords=['Person Re-Identification', 'Deep Learning', 'Computer Vision'],
ext_modules=cythonize(ext_modules)
)
================================================
FILE: torchreid/__init__.py
================================================
from __future__ import print_function, absolute_import
from torchreid import data, optim, utils, engine, losses, models, metrics
__version__ = '1.2.4'
__author__ = 'Kaiyang Zhou'
__homepage__ = 'https://kaiyangzhou.github.io/'
__description__ = 'Deep learning person re-identification in PyTorch'
__url__ = 'https://github.com/KaiyangZhou/deep-person-reid'
================================================
FILE: torchreid/data/__init__.py
================================================
from __future__ import print_function, absolute_import
from .datasets import (
Dataset, ImageDataset, VideoDataset, register_image_dataset,
register_video_dataset, get_dataset_nickname
)
from .datamanager import ImageDataManager, VideoDataManager
================================================
FILE: torchreid/data/data_augmentation/__init__.py
================================================
from __future__ import print_function, absolute_import
from .random_occlusion import *
================================================
FILE: torchreid/data/data_augmentation/random_occlusion.py
================================================
# Source: https://github.com/isarandi/synthetic-occlusion/blob/master/augmentation.py
import math
import os.path
import random
import sys
import xml.etree.ElementTree
import numpy as np
import matplotlib.pyplot as plt
import skimage.data
import cv2
import PIL.Image
from albumentations import (
DualTransform, functional
)
def main():
"""Demo of how to use the code"""
# path = 'something/something/VOCtrainval_11-May-2012/VOCdevkit/VOC2012'
path = sys.argv[1]
print('Loading occluders from Pascal VOC dataset...')
occluders = load_occluders(pascal_voc_root_path=path)
print('Found {} suitable objects'.format(len(occluders)))
original_im = cv2.resize(skimage.data.astronaut(), (256, 256))
fig, axarr = plt.subplots(3, 3, figsize=(7, 7))
for ax in axarr.ravel():
occluded_im = occlude_with_objects(original_im, occluders)
ax.imshow(occluded_im, interpolation="none")
ax.axis('off')
fig.tight_layout(h_pad=0)
# plt.savefig('examples.jpg', dpi=150, bbox_inches='tight')
plt.show()
def load_occluders(
pascal_voc_root_path,
classes_filter=None,
):
occluders = []
structuring_element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8, 8))
if classes_filter is None:
# classes_filter = ["person", "bicycle", "boat", "bus", "car", "motorbike", "train", "chair", "dining", "table", "plant", "sofa"]
classes_filter = ["person", "bicycle", "boat", "bus", "car", "motorbike", "train"]
# classes_filter = ["person"]
annotation_paths = list_filepaths(os.path.join(pascal_voc_root_path, 'Annotations'))
for annotation_path in annotation_paths:
xml_root = xml.etree.ElementTree.parse(annotation_path).getroot()
is_segmented = (xml_root.find('segmented').text != '0')
if not is_segmented:
continue
boxes = []
for i_obj, obj in enumerate(xml_root.findall('object')):
is_authorized_class = (obj.find('name').text in classes_filter)
is_difficult = (obj.find('difficult').text != '0')
is_truncated = (obj.find('truncated').text != '0')
if is_authorized_class and not is_difficult and not is_truncated:
bndbox = obj.find('bndbox')
box = [int(bndbox.find(s).text) for s in ['xmin', 'ymin', 'xmax', 'ymax']]
boxes.append((i_obj, box))
if not boxes:
continue
im_filename = xml_root.find('filename').text
seg_filename = im_filename.replace('jpg', 'png')
im_path = os.path.join(pascal_voc_root_path, 'JPEGImages', im_filename)
seg_path = os.path.join(pascal_voc_root_path, 'SegmentationObject', seg_filename)
im = np.asarray(PIL.Image.open(im_path))
labels = np.asarray(PIL.Image.open(seg_path))
for i_obj, (xmin, ymin, xmax, ymax) in boxes:
object_mask = (labels[ymin:ymax, xmin:xmax] == i_obj + 1).astype(np.uint8) * 255
object_image = im[ymin:ymax, xmin:xmax]
if cv2.countNonZero(object_mask) < 500:
# Ignore small objects
continue
# Reduce the opacity of the mask along the border for smoother blending
eroded = cv2.erode(object_mask, structuring_element)
object_mask[eroded < object_mask] = 192
object_with_mask = np.concatenate([object_image, object_mask[..., np.newaxis]], axis=-1)
# Downscale for efficiency
object_with_mask = resize_by_factor(object_with_mask, 0.5)
occluders.append(object_with_mask)
return occluders
def occlude_with_objects(im, occluders, n=1, min_overlap=0.1, max_overlap=0.6):
"""Returns an augmented version of `im`, containing some occluders from the Pascal VOC dataset."""
result = im.copy()
width_height = np.asarray([im.shape[1], im.shape[0]])
im_area = im.shape[1] * im.shape[0]
count = np.random.randint(1, n+1)
for _ in range(count):
occluder = random.choice(occluders)
occluder_area = occluder.shape[1] * occluder.shape[0]
overlap = random.uniform(min_overlap, max_overlap)
scale_factor = math.sqrt(overlap * im_area / occluder_area)
occluder = resize_by_factor(occluder, scale_factor)
assert (occluder.shape[1] * occluder.shape[0]) / im_area == overlap
center = np.random.uniform([0, 0], width_height)
paste_over(im_src=occluder, im_dst=result, center=center)
return result
def paste_over(im_src, im_dst, center, is_mask=False):
"""Pastes `im_src` onto `im_dst` at a specified position, with alpha blending, in place.
Locations outside the bounds of `im_dst` are handled as expected (only a part or none of
`im_src` becomes visible).
Args:
im_src: The RGBA image to be pasted onto `im_dst`. Its size can be arbitrary.
im_dst: The target image.
alpha: A float (0.0-1.0) array of the same size as `im_src` controlling the alpha blending
at each pixel. Large values mean more visibility for `im_src`.
center: coordinates in `im_dst` where the center of `im_src` should be placed.
"""
width_height_src = np.asarray([im_src.shape[1], im_src.shape[0]])
width_height_dst = np.asarray([im_dst.shape[1], im_dst.shape[0]])
center = np.round(center).astype(np.int32)
raw_start_dst = center - width_height_src // 2
raw_end_dst = raw_start_dst + width_height_src
start_dst = np.clip(raw_start_dst, 0, width_height_dst)
end_dst = np.clip(raw_end_dst, 0, width_height_dst)
region_dst = im_dst[start_dst[1]:end_dst[1], start_dst[0]:end_dst[0]]
start_src = start_dst - raw_start_dst
end_src = width_height_src + (end_dst - raw_end_dst)
region_src = im_src[start_src[1]:end_src[1], start_src[0]:end_src[0]]
color_src = region_src[..., 0:3]
alpha = region_src[..., 3:].astype(np.float32) / 255
if is_mask: # if this is a segmentation mask, just apply alpha erasing
im_dst[start_dst[1]:end_dst[1], start_dst[0]:end_dst[0]] = (1 - alpha) * region_dst
else:
im_dst[start_dst[1]:end_dst[1], start_dst[0]:end_dst[0]] = (
alpha * color_src + (1 - alpha) * region_dst)
im_area = im_src.shape[1] * im_src.shape[0]
bbox_overlap = (color_src.shape[0] * color_src.shape[1]) / im_area
pxls_overlap = np.count_nonzero(alpha) / im_area
return bbox_overlap, pxls_overlap
def resize_by_factor(im, factor):
"""Returns a copy of `im` resized by `factor`, using bilinear interp for up and area interp
for downscaling.
"""
new_size = tuple(np.round(np.array([im.shape[1], im.shape[0]]) * factor).astype(int))
interp = cv2.INTER_LINEAR if factor > 1.0 else cv2.INTER_AREA
return cv2.resize(im, new_size, fx=factor, fy=factor, interpolation=interp)
def list_filepaths(dirpath):
names = os.listdir(dirpath)
paths = [os.path.join(dirpath, name) for name in names]
return sorted(filter(os.path.isfile, paths))
class RandomOcclusion(DualTransform):
def __init__(self,
path,
im_shape,
always_apply=False,
p=.5,
n=1,
min_overlap=0.5,
max_overlap=0.8,
):
super(RandomOcclusion, self).__init__(always_apply, p)
print('Loading occluders from Pascal VOC dataset...')
self.all_occluders = load_occluders(pascal_voc_root_path=path)
self.bbox_overlaps = []
self.pxls_overlaps = []
self.count = 0
self.n = n
self.min_overlap = min_overlap
self.max_overlap = max_overlap
self.im_shape = im_shape
def check_range(self, dimension):
if isinstance(dimension, float) and not 0 <= dimension < 1.0:
raise ValueError(
"Invalid value {}. If using floats, the value should be in the range [0.0, 1.0)".format(dimension)
)
def apply(self, image, occluders=(), centers=(), **params):
for occluder, center in zip(occluders, centers):
bbox_overlap, pxls_overlap = paste_over(im_src=occluder, im_dst=image, center=center)
self.bbox_overlaps.append(bbox_overlap)
self.pxls_overlaps.append(pxls_overlap)
self.count += 1
if self.count % 10000 == 0:
bbox_overlaps = np.array(self.bbox_overlaps)
pxls_overlaps = np.array(self.pxls_overlaps)
print("RandomOcclusion #{}: bbox_overlap=[{:.2f},{:.2f},{:.2f}], pxls_overlap=[{:.2f},{:.2f},{:.2f}]"
.format(self.count,
bbox_overlaps.min(),
bbox_overlaps.max(),
bbox_overlaps.mean(),
pxls_overlaps.min(),
pxls_overlaps.max(),
pxls_overlaps.mean()
)
)
return image
def apply_to_mask(self, image, occluders=(), centers=(), **params):
for occluder, center in zip(occluders, centers):
paste_over(im_src=occluder, im_dst=image, center=center, is_mask=True)
return image
def get_params_dependent_on_targets(self, params):
img = params["image"]
count = np.random.randint(1, self.n + 1)
width_height = np.asarray([img.shape[1], img.shape[0]])
im_area = self.im_shape[1] * self.im_shape[0]
occluders = []
centers = []
for _ in range(count):
occluder = random.choice(self.all_occluders)
occluder_area = occluder.shape[1] * occluder.shape[0]
overlap = random.uniform(self.min_overlap, self.max_overlap)
scale_factor = math.sqrt(overlap * im_area / occluder_area)
occluder = resize_by_factor(occluder, scale_factor)
# assert abs((occluder.shape[1] * occluder.shape[0]) / im_area - overlap) < 0.005
center = np.random.uniform([0, 0], width_height)
occluders.append(occluder)
centers.append(center)
return {"occluders": occluders,
"centers": centers}
@property
def targets_as_params(self):
return ["image"]
def get_transform_init_args_names(self):
return (
"max_holes",
"max_height",
"max_width",
"min_holes",
"min_height",
"min_width",
"fill_value",
"mask_fill_value",
)
if __name__ == '__main__':
main()
================================================
FILE: torchreid/data/datamanager.py
================================================
from __future__ import division, print_function, absolute_import
import torch
from torchreid.data.masks_transforms import masks_preprocess_transforms
from torchreid.data.sampler import build_train_sampler
from torchreid.data.datasets import init_image_dataset, init_video_dataset, get_image_dataset
from torchreid.data.transforms import build_transforms
class DataManager(object):
r"""Base data manager.
Args:
sources (str or list): source dataset(s).
targets (str or list, optional): target dataset(s). If not given,
it equals to ``sources``.
height (int, optional): target image height. Default is 256.
width (int, optional): target image width. Default is 128.
transforms (str or list of str, optional): transformations applied to model training.
Default is 'random_flip'.
norm_mean (list or None, optional): data mean. Default is None (use imagenet mean).
norm_std (list or None, optional): data std. Default is None (use imagenet std).
use_gpu (bool, optional): use gpu. Default is True.
"""
def __init__(
self,
config,
sources=None,
targets=None,
height=256,
width=128,
transforms='random_flip',
norm_mean=None,
norm_std=None,
use_gpu=False,
use_masks=False,
masks_dir='',
):
self.sources = sources
self.targets = targets
self.height = height
self.width = width
self.masks_dir = masks_dir
self.config = config
if self.sources is None:
raise ValueError('sources must not be None')
if isinstance(self.sources, str):
self.sources = [self.sources]
if self.targets is None:
self.targets = self.sources
if isinstance(self.targets, str):
self.targets = [self.targets]
masks_config = get_image_dataset(self.sources[0]).get_masks_config(self.masks_dir)
self.transform_tr, self.transform_te = build_transforms(
self.height,
self.width,
config,
transforms=transforms,
norm_mean=norm_mean,
norm_std=norm_std,
remove_background_mask=masks_config[1] if masks_config is not None else False,
masks_preprocess=config.model.bpbreid.masks.preprocess,
softmax_weight=config.model.bpbreid.masks.softmax_weight,
background_computation_strategy=config.model.bpbreid.masks.background_computation_strategy,
mask_filtering_threshold=config.model.bpbreid.masks.mask_filtering_threshold,
)
self.use_gpu = (torch.cuda.is_available() and use_gpu)
@property
def num_train_pids(self):
"""Returns the number of training person identities."""
return self._num_train_pids
@property
def num_train_cams(self):
"""Returns the number of training cameras."""
return self._num_train_cams
def fetch_test_loaders(self, name):
"""Returns query and gallery of a test dataset, each containing
tuples of (img_path(s), pid, camid).
Args:
name (str): dataset name.
"""
query_loader = self.test_dataset[name]['query']
gallery_loader = self.test_dataset[name]['gallery']
return query_loader, gallery_loader
def preprocess_pil_img(self, img):
"""Transforms a PIL image to torch tensor for testing."""
return self.transform_te(img)
class ImageDataManager(DataManager):
r"""Image data manager.
Args:
root (str): root path to datasets.
sources (str or list): source dataset(s).
targets (str or list, optional): target dataset(s). If not given,
it equals to ``sources``.
height (int, optional): target image height. Default is 256.
width (int, optional): target image width. Default is 128.
transforms (str or list of str, optional): transformations applied to model training.
Default is 'random_flip'.
norm_mean (list or None, optional): data mean. Default is None (use imagenet mean).
norm_std (list or None, optional): data std. Default is None (use imagenet std).
use_gpu (bool, optional): use gpu. Default is True.
split_id (int, optional): split id (*0-based*). Default is 0.
combineall (bool, optional): combine train, query and gallery in a dataset for
training. Default is False.
load_train_targets (bool, optional): construct train-loader for target datasets.
Default is False. This is useful for domain adaptation research.
batch_size_train (int, optional): number of images in a training batch. Default is 32.
batch_size_test (int, optional): number of images in a test batch. Default is 32.
workers (int, optional): number of workers. Default is 4.
num_instances (int, optional): number of instances per identity in a batch.
Default is 4.
train_sampler (str, optional): sampler. Default is RandomSampler.
train_sampler_t (str, optional): sampler for target train loader. Default is RandomSampler.
cuhk03_labeled (bool, optional): use cuhk03 labeled images.
Default is False (defaul is to use detected images).
cuhk03_classic_split (bool, optional): use the classic split in cuhk03.
Default is False.
market1501_500k (bool, optional): add 500K distractors to the gallery
set in market1501. Default is False.
Examples::
datamanager = torchreid.data.ImageDataManager(
root='path/to/reid-data',
sources='market1501',
height=256,
width=128,
batch_size_train=32,
batch_size_test=100
)
# return train loader of source data
train_loader = datamanager.train_loader
# return test loader of target data
test_loader = datamanager.test_loader
# return train loader of target data
train_loader_t = datamanager.train_loader_t
"""
data_type = 'image'
def __init__(
self,
config,
root='',
sources=None,
targets=None,
height=256,
width=128,
mask_scale=8,
transforms='random_flip',
norm_mean=None,
norm_std=None,
use_gpu=True,
split_id=0,
combineall=False,
load_train_targets=False,
batch_size_train=32,
batch_size_test=32,
workers=4,
num_instances=4,
train_sampler='RandomSampler',
train_sampler_t='RandomSampler',
cuhk03_labeled=False,
cuhk03_classic_split=False,
market1501_500k=False,
use_masks=False,
masks_dir=None,
):
super(ImageDataManager, self).__init__(
sources=sources,
targets=targets,
height=height,
width=width,
transforms=transforms,
norm_mean=norm_mean,
norm_std=norm_std,
use_gpu=use_gpu,
use_masks=use_masks,
masks_dir=masks_dir,
config=config
)
print('=> Loading train (source) dataset')
trainset = []
for name in self.sources:
trainset_ = init_image_dataset(
name,
config=config,
transform_tr=self.transform_tr,
transform_te=self.transform_te,
mode='train',
combineall=combineall,
root=root,
split_id=split_id,
cuhk03_labeled=cuhk03_labeled,
cuhk03_classic_split=cuhk03_classic_split,
market1501_500k=market1501_500k,
use_masks=use_masks,
masks_dir=masks_dir,
load_masks=self.config.model.bpbreid.masks.preprocess in masks_preprocess_transforms,
)
trainset.append(trainset_)
trainset = sum(trainset)
self._num_train_pids = trainset.num_train_pids
self._num_train_cams = trainset.num_train_cams
self.train_loader = torch.utils.data.DataLoader(
trainset,
sampler=build_train_sampler(
trainset.train,
train_sampler,
batch_size=batch_size_train,
num_instances=num_instances
),
batch_size=batch_size_train,
shuffle=False,
num_workers=workers,
pin_memory=self.use_gpu,
drop_last=True
)
self.train_loader_t = None
if load_train_targets:
# check if sources and targets are identical
assert len(set(self.sources) & set(self.targets)) == 0, \
'sources={} and targets={} must not have overlap'.format(self.sources, self.targets)
print('=> Loading train (target) dataset')
trainset_t = []
for name in self.targets:
trainset_t_ = init_image_dataset(
name,
config=config,
transform_tr=self.transform_tr,
transform_te=self.transform_te,
mode='train',
combineall=False, # only use the training data
root=root,
split_id=split_id,
cuhk03_labeled=cuhk03_labeled,
cuhk03_classic_split=cuhk03_classic_split,
market1501_500k=market1501_500k,
use_masks=use_masks,
masks_dir=masks_dir,
load_masks=self.config.model.bpbreid.masks.preprocess in masks_preprocess_transforms,
)
trainset_t.append(trainset_t_)
trainset_t = sum(trainset_t)
self.train_loader_t = torch.utils.data.DataLoader(
trainset_t,
sampler=build_train_sampler(
trainset_t.train,
train_sampler_t,
batch_size=batch_size_train,
num_instances=num_instances
),
batch_size=batch_size_train,
shuffle=False,
num_workers=workers,
pin_memory=self.use_gpu,
drop_last=True
)
print('=> Loading test (target) dataset')
self.test_loader = {
name: {
'query': None,
'gallery': None
}
for name in self.targets
}
self.test_dataset = {
name: {
'query': None,
'gallery': None
}
for name in self.targets
}
for name in self.targets:
# build query loader
queryset = init_image_dataset(
name,
config=config,
transform_tr=self.transform_tr,
transform_te=self.transform_te,
mode='query',
combineall=combineall,
root=root,
split_id=split_id,
cuhk03_labeled=cuhk03_labeled,
cuhk03_classic_split=cuhk03_classic_split,
market1501_500k=market1501_500k,
use_masks=use_masks,
masks_dir=masks_dir,
load_masks=self.config.model.bpbreid.masks.preprocess in masks_preprocess_transforms,
)
self.test_loader[name]['query'] = torch.utils.data.DataLoader(
queryset,
batch_size=batch_size_test,
shuffle=False,
num_workers=workers,
pin_memory=self.use_gpu,
drop_last=False
)
# build gallery loader
galleryset = init_image_dataset(
name,
config=config,
transform_tr=self.transform_tr,
transform_te=self.transform_te,
mode='gallery',
combineall=combineall,
verbose=False,
root=root,
split_id=split_id,
cuhk03_labeled=cuhk03_labeled,
cuhk03_classic_split=cuhk03_classic_split,
market1501_500k=market1501_500k,
use_masks=use_masks,
masks_dir=masks_dir,
load_masks=self.config.model.bpbreid.masks.preprocess in masks_preprocess_transforms,
)
self.test_loader[name]['gallery'] = torch.utils.data.DataLoader(
galleryset,
batch_size=batch_size_test,
shuffle=False,
num_workers=workers,
pin_memory=self.use_gpu,
drop_last=False
)
self.test_dataset[name]['query'] = queryset.query
self.test_dataset[name]['gallery'] = galleryset.gallery
print('\n')
print(' **************** Summary ****************')
print(' source : {}'.format(self.sources))
print(' # source datasets : {}'.format(len(self.sources)))
print(' # source ids : {}'.format(self.num_train_pids))
print(' # source images : {}'.format(len(trainset)))
print(' # source cameras : {}'.format(self.num_train_cams))
if load_train_targets:
print(
' # target images : {} (unlabeled)'.format(len(trainset_t))
)
print(' target : {}'.format(self.targets))
print(' *****************************************')
print('\n')
class VideoDataManager(DataManager):
r"""Video data manager.
Args:
root (str): root path to datasets.
sources (str or list): source dataset(s).
targets (str or list, optional): target dataset(s). If not given,
it equals to ``sources``.
height (int, optional): target image height. Default is 256.
width (int, optional): target image width. Default is 128.
transforms (str or list of str, optional): transformations applied to model training.
Default is 'random_flip'.
norm_mean (list or None, optional): data mean. Default is None (use imagenet mean).
norm_std (list or None, optional): data std. Default is None (use imagenet std).
use_gpu (bool, optional): use gpu. Default is True.
split_id (int, optional): split id (*0-based*). Default is 0.
combineall (bool, optional): combine train, query and gallery in a dataset for
training. Default is False.
batch_size_train (int, optional): number of tracklets in a training batch. Default is 3.
batch_size_test (int, optional): number of tracklets in a test batch. Default is 3.
workers (int, optional): number of workers. Default is 4.
num_instances (int, optional): number of instances per identity in a batch.
Default is 4.
train_sampler (str, optional): sampler. Default is RandomSampler.
seq_len (int, optional): how many images to sample in a tracklet. Default is 15.
sample_method (str, optional): how to sample images in a tracklet. Default is "evenly".
Choices are ["evenly", "random", "all"]. "evenly" and "random" will sample ``seq_len``
images in a tracklet while "all" samples all images in a tracklet, where the batch size
needs to be set to 1.
Examples::
datamanager = torchreid.data.VideoDataManager(
root='path/to/reid-data',
sources='mars',
height=256,
width=128,
batch_size_train=3,
batch_size_test=3,
seq_len=15,
sample_method='evenly'
)
# return train loader of source data
train_loader = datamanager.train_loader
# return test loader of target data
test_loader = datamanager.test_loader
.. note::
The current implementation only supports image-like training. Therefore, each image in a
sampled tracklet will undergo independent transformation functions. To achieve tracklet-aware
training, you need to modify the transformation functions for video reid such that each function
applies the same operation to all images in a tracklet to keep consistency.
"""
data_type = 'video'
def __init__(
self,
config,
root='',
sources=None,
targets=None,
height=256,
width=128,
transforms='random_flip',
norm_mean=None,
norm_std=None,
use_gpu=True,
split_id=0,
combineall=False,
batch_size_train=3,
batch_size_test=3,
workers=4,
num_instances=4,
train_sampler='RandomSampler',
seq_len=15,
sample_method='evenly'
):
super(VideoDataManager, self).__init__(
config=config,
sources=sources,
targets=targets,
height=height,
width=width,
transforms=transforms,
norm_mean=norm_mean,
norm_std=norm_std,
use_gpu=use_gpu
)
print('=> Loading train (source) dataset')
trainset = []
for name in self.sources:
trainset_ = init_video_dataset(
name,
transform=self.transform_tr,
mode='train',
combineall=combineall,
root=root,
split_id=split_id,
seq_len=seq_len,
sample_method=sample_method
)
trainset.append(trainset_)
trainset = sum(trainset)
self._num_train_pids = trainset.num_train_pids
self._num_train_cams = trainset.num_train_cams
train_sampler = build_train_sampler(
trainset.train,
train_sampler,
batch_size=batch_size_train,
num_instances=num_instances
)
self.train_loader = torch.utils.data.DataLoader(
trainset,
sampler=train_sampler,
batch_size=batch_size_train,
shuffle=False,
num_workers=workers,
pin_memory=self.use_gpu,
drop_last=True
)
print('=> Loading test (target) dataset')
self.test_loader = {
name: {
'query': None,
'gallery': None
}
for name in self.targets
}
self.test_dataset = {
name: {
'query': None,
'gallery': None
}
for name in self.targets
}
for name in self.targets:
# build query loader
queryset = init_video_dataset(
name,
transform=self.transform_te,
mode='query',
combineall=combineall,
root=root,
split_id=split_id,
seq_len=seq_len,
sample_method=sample_method
)
self.test_loader[name]['query'] = torch.utils.data.DataLoader(
queryset,
batch_size=batch_size_test,
shuffle=False,
num_workers=workers,
pin_memory=self.use_gpu,
drop_last=False
)
# build gallery loader
galleryset = init_video_dataset(
name,
transform=self.transform_te,
mode='gallery',
combineall=combineall,
verbose=False,
root=root,
split_id=split_id,
seq_len=seq_len,
sample_method=sample_method
)
self.test_loader[name]['gallery'] = torch.utils.data.DataLoader(
galleryset,
batch_size=batch_size_test,
shuffle=False,
num_workers=workers,
pin_memory=self.use_gpu,
drop_last=False
)
self.test_dataset[name]['query'] = queryset.query
self.test_dataset[name]['gallery'] = galleryset.gallery
print('\n')
print(' **************** Summary ****************')
print(' source : {}'.format(self.sources))
print(' # source datasets : {}'.format(len(self.sources)))
print(' # source ids : {}'.format(self.num_train_pids))
print(' # source tracklets : {}'.format(len(trainset)))
print(' # source cameras : {}'.format(self.num_train_cams))
print(' target : {}'.format(self.targets))
print(' *****************************************')
print('\n')
================================================
FILE: torchreid/data/datasets/__init__.py
================================================
from __future__ import print_function, absolute_import
import copy
from .image import (
GRID, PRID, CUHK01, CUHK02, CUHK03, MSMT17, VIPeR, SenseReID, Market1501,
DukeMTMCreID, iLIDS, OccludedDuke, OccludedReID, Partial_iLIDS, Partial_REID, PDukemtmcReid,
P_ETHZ
)
from .video import PRID2011, Mars, DukeMTMCVidReID, iLIDSVID
from .dataset import Dataset, ImageDataset, VideoDataset
__image_datasets = {
'market1501': Market1501,
'cuhk03': CUHK03,
'dukemtmcreid': DukeMTMCreID,
'msmt17': MSMT17,
'viper': VIPeR,
'grid': GRID,
'cuhk01': CUHK01,
'ilids': iLIDS,
'sensereid': SenseReID,
'prid': PRID,
'cuhk02': CUHK02,
'occluded_duke': OccludedDuke,
'occluded_reid': OccludedReID,
'partial_reid': Partial_REID,
'partial_ilids': Partial_iLIDS,
'p_ETHZ': P_ETHZ,
'p_dukemtmc_reid': PDukemtmcReid,
}
__datasets_nicknames = {
'market1501': 'mk',
'cuhk03': 'c03',
'dukemtmcreid': 'du',
'msmt17': 'ms',
'viper': 'vi',
'grid': 'gr',
'cuhk01': 'c01',
'ilids': 'il',
'sensereid': 'se',
'prid': 'pr',
'cuhk02': 'c02',
'occluded_duke': 'od',
'occluded_reid': 'or',
'partial_reid': 'pr',
'partial_ilids': 'pi',
'p_ETHZ': 'pz',
'p_dukemtmc_reid': 'pd',
}
__video_datasets = {
'mars': Mars,
'ilidsvid': iLIDSVID,
'prid2011': PRID2011,
'dukemtmcvidreid': DukeMTMCVidReID
}
__datasets_cache = {}
def configure_dataset_class(clazz, **ext_kwargs):
"""
Wrapper function to provide the class with args external to torchreid
"""
class ClazzWrapper(clazz):
def __init__(self, **kwargs):
self.__name__ = clazz.__name__
super(ClazzWrapper, self).__init__(**{**kwargs, **ext_kwargs})
ClazzWrapper.__name__ = clazz.__name__
return ClazzWrapper
def get_dataset_nickname(name):
return __datasets_nicknames.get(name, name)
def get_image_dataset(name):
avai_datasets = list(__image_datasets.keys())
if name not in avai_datasets:
raise ValueError(
'Invalid dataset name. Received "{}", '
'but expected to be one of {}'.format(name, avai_datasets)
)
return __image_datasets[name]
def init_image_dataset(name, mode='train', **kwargs):
"""
Initializes an image dataset.
The copy.copy() was introduced to fix Torchreid implementing multiple times the same dataset.
In Datamanager, each dataset was instantiated multiple times via 'init_image_dataset': one for train, one for query
and one for gallery. Each instance had its own 'data' field containing either train, query or gallery set, based on
the 'mode' field passed as argument, and its own transforms, to perform training time or test time data transformation.
However, instantiating the same dataset multiple times is not efficient, as it requires to load the dataset metadata from
disk multiple times. Moreover, other printing (such as dataset summary) are displayed multiple times.
To fix this, we copy the dataset class but not its contained objects (such as train/query/gallery) and set a new 'mode' on each copy.
Thanks to that hack, the data list is created only once, and only the Dataset class is instantiated multiple times
(for each 'mode'). Therefore, each Dataset uses the same data lists in the background, switching
between train, query and gallery based on the 'mode' field.
"""
if name in __datasets_cache:
print("Using cached dataset {}.".format(name))
dataset = __datasets_cache[name]
else:
print("Creating new dataset {} and add it to the datasets cache.".format(name))
dataset = get_image_dataset(name)(mode=mode, **kwargs)
__datasets_cache[name] = dataset
mode_dataset = copy.copy(dataset)
mode_dataset.mode = mode
return mode_dataset
def init_video_dataset(name, **kwargs):
"""Initializes a video dataset."""
avai_datasets = list(__video_datasets.keys())
if name not in avai_datasets:
raise ValueError(
'Invalid dataset name. Received "{}", '
'but expected to be one of {}'.format(name, avai_datasets)
)
return __video_datasets[name](**kwargs)
def register_image_dataset(name, dataset, nickname=None):
"""Registers a new image dataset.
Args:
name (str): key corresponding to the new dataset.
dataset (Dataset): the new dataset class.
Examples::
import torchreid
import NewDataset
torchreid.data.register_image_dataset('new_dataset', NewDataset)
# single dataset case
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources='new_dataset'
)
# multiple dataset case
datamanager = torchreid.data.ImageDataManager(
root='reid-data',
sources=['new_dataset', 'dukemtmcreid']
)
"""
global __image_datasets
curr_datasets = list(__image_datasets.keys())
if name in curr_datasets:
raise ValueError(
'The given name already exists, please choose '
'another name excluding {}'.format(curr_datasets)
)
__image_datasets[name] = dataset
__datasets_nicknames[name] = nickname if nickname is not None else name
def register_video_dataset(name, dataset):
"""Registers a new video dataset.
Args:
name (str): key corresponding to the new dataset.
dataset (Dataset): the new dataset class.
Examples::
import torchreid
import NewDataset
torchreid.data.register_video_dataset('new_dataset', NewDataset)
# single dataset case
datamanager = torchreid.data.VideoDataManager(
root='reid-data',
sources='new_dataset'
)
# multiple dataset case
datamanager = torchreid.data.VideoDataManager(
root='reid-data',
sources=['new_dataset', 'ilidsvid']
)
"""
global __video_datasets
curr_datasets = list(__video_datasets.keys())
if name in curr_datasets:
raise ValueError(
'The given name already exists, please choose '
'another name excluding {}'.format(curr_datasets)
)
__video_datasets[name] = dataset
================================================
FILE: torchreid/data/datasets/dataset.py
================================================
from __future__ import division, print_function, absolute_import
import copy
import os
import numpy as np
import os.path as osp
import tarfile
import zipfile
import torch
from torchreid.utils import read_masks, read_image, download_url, mkdir_if_missing
class Dataset(object):
"""An abstract class representing a Dataset.
This is the base class for ``ImageDataset`` and ``VideoDataset``.
Args:
train (list): contains tuples of (img_path(s), pid, camid).
query (list): contains tuples of (img_path(s), pid, camid).
gallery (list): contains tuples of (img_path(s), pid, camid).
transform: transform function.
mode (str): 'train', 'query' or 'gallery'.
combineall (bool): combines train, query and gallery in a
dataset for training.
verbose (bool): show information.
"""
_junk_pids = [
] # contains useless person IDs, e.g. background, false detections
masks_base_dir = None
eval_metric = 'default' # default to market101
def gallery_filter(self, q_pid, q_camid, q_ann, g_pids, g_camids, g_anns):
""" Remove gallery samples that have the same pid and camid as the query sample, since ReID is a cross-camera
person retrieval task for most datasets. However, we still keep samples from the same camera but of different
identity as distractors."""
remove = (g_camids == q_camid) & (g_pids == q_pid)
return remove
def infer_masks_path(self, img_path):
masks_path = os.path.join(self.dataset_dir, self.masks_base_dir, self.masks_dir, os.path.basename(os.path.dirname(img_path)), os.path.splitext(os.path.basename(img_path))[0] + self.masks_suffix)
return masks_path
def __init__(
self,
train,
query,
gallery,
config=None,
transform_tr=None,
transform_te=None,
mode='train',
combineall=False,
verbose=True,
use_masks=False,
masks_dir=None,
masks_base_dir=None,
load_masks=False,
**kwargs
):
self.train = train
self.query = query
self.gallery = gallery
self.transform_tr = transform_tr
self.transform_te = transform_te
self.cfg = config
self.mode = mode
self.combineall = combineall
self.verbose = verbose
self.use_masks = use_masks
self.masks_dir = masks_dir
self.load_masks = load_masks
if masks_base_dir is not None:
self.masks_base_dir = masks_base_dir
self.num_train_pids = self.get_num_pids(self.train)
self.num_train_cams = self.get_num_cams(self.train)
if self.combineall:
self.combine_all()
if self.verbose:
self.show_summary()
def transforms(self, mode):
"""Returns the transforms of a specific mode."""
if mode == 'train':
return self.transform_tr
elif mode == 'query':
return self.transform_te
elif mode == 'gallery':
return self.transform_te
else:
raise ValueError("Invalid mode. Got {}, but expected to be "
"'train', 'query' or 'gallery'".format(mode))
def data(self, mode):
"""Returns the data of a specific mode.
Args:
mode (str): 'train', 'query' or 'gallery'.
Returns:
list: contains tuples of (img_path(s), pid, camid).
"""
if mode == 'train':
return self.train
elif mode == 'query':
return self.query
elif mode == 'gallery':
return self.gallery
else:
raise ValueError("Invalid mode. Got {}, but expected to be "
"'train', 'query' or 'gallery'".format(mode))
def __getitem__(self, index):
raise NotImplementedError
def __len__(self): # kept for backward compatibility
return self.len(self.mode)
def len(self, mode):
return len(self.data(mode))
def __add__(self, other):
"""Adds two datasets together (only the train set)."""
train = copy.deepcopy(self.train)
for sample in other.train:
sample['pid'] += self.num_train_pids
train.append(sample)
###################################
# Things to do beforehand:
# 1. set verbose=False to avoid unnecessary print
# 2. set combineall=False because combineall would have been applied
# if it was True for a specific dataset, setting it to True will
# create new IDs that should have been included
###################################
# FIXME find better implementation for combining datasets and masks
assert self.use_masks == other.use_masks
if isinstance(self, ImageDataset):
return ImageDataset(
train,
self.query,
self.gallery,
transform=self.transform,
mode=self.mode,
combineall=False,
verbose=False,
use_masks=self.use_masks,
masks_base_dir=self.masks_base_dir,
)
else:
return VideoDataset(
train,
self.query,
self.gallery,
transform=self.transform,
mode=self.mode,
combineall=False,
verbose=False,
seq_len=self.seq_len,
sample_method=self.sample_method
)
def __radd__(self, other):
"""Supports sum([dataset1, dataset2, dataset3])."""
if other == 0:
return self
else:
return self.__add__(other)
def parse_data(self, data):
"""Parses data list and returns the number of person IDs
and the number of camera views.
Args:
data (list): contains tuples of (img_path(s), pid, camid)
"""
pids = set()
cams = set()
for i, sample in enumerate(data):
pids.add(sample['pid'])
cams.add(sample['camid'])
return len(pids), len(cams)
def get_num_pids(self, data):
"""Returns the number of training person identities."""
return self.parse_data(data)[0]
def get_num_cams(self, data):
"""Returns the number of training cameras."""
return self.parse_data(data)[1]
def show_summary(self):
"""Shows dataset statistics."""
pass
def combine_all(self):
"""Combines train, query and gallery in a dataset for training."""
combined = copy.deepcopy(self.train)
# relabel pids in gallery (query shares the same scope)
g_pids = set()
for sample in self.gallery:
pid = sample['pid']
if pid in self._junk_pids:
continue
g_pids.add(pid)
pid2label = {pid: i for i, pid in enumerate(g_pids)}
def _combine_data(data):
for sample in data:
pid = sample['pid']
if pid in self._junk_pids:
continue
sample['pid'] = pid2label[pid] + self.num_train_pids
combined.append(sample)
_combine_data(self.query)
_combine_data(self.gallery)
self.train = combined
self.num_train_pids = self.get_num_pids(self.train)
def download_dataset(self, dataset_dir, dataset_url):
"""Downloads and extracts dataset.
Args:
dataset_dir (str): dataset directory.
dataset_url (str): url to download dataset.
"""
if osp.exists(dataset_dir):
return
if dataset_url is None:
raise RuntimeError(
'{} dataset needs to be manually '
'prepared, please follow the '
'document to prepare this dataset'.format(
self.__class__.__name__
)
)
print('Creating directory "{}"'.format(dataset_dir))
mkdir_if_missing(dataset_dir)
fpath = osp.join(dataset_dir, osp.basename(dataset_url))
print(
'Downloading {} dataset to "{}"'.format(
self.__class__.__name__, dataset_dir
)
)
download_url(dataset_url, fpath)
print('Extracting "{}"'.format(fpath))
try:
tar = tarfile.open(fpath)
tar.extractall(path=dataset_dir)
tar.close()
except:
zip_ref = zipfile.ZipFile(fpath, 'r')
zip_ref.extractall(dataset_dir)
zip_ref.close()
print('{} dataset is ready'.format(self.__class__.__name__))
def check_before_run(self, required_files):
"""Checks if required files exist before going deeper.
Args:
required_files (str or list): string file name(s).
"""
if isinstance(required_files, str):
required_files = [required_files]
for fpath in required_files:
if not osp.exists(fpath):
raise RuntimeError('"{}" is not found'.format(fpath))
def __repr__(self):
num_train_pids, num_train_cams = self.parse_data(self.train)
num_query_pids, num_query_cams = self.parse_data(self.query)
num_gallery_pids, num_gallery_cams = self.parse_data(self.gallery)
msg = ' ----------------------------------------\n' \
' subset | # ids | # items | # cameras\n' \
' ----------------------------------------\n' \
' train | {:5d} | {:7d} | {:9d}\n' \
' query | {:5d} | {:7d} | {:9d}\n' \
' gallery | {:5d} | {:7d} | {:9d}\n' \
' ----------------------------------------\n' \
' items: images/tracklets for image/video dataset\n'.format(
num_train_pids, len(self.train), num_train_cams,
num_query_pids, len(self.query), num_query_cams,
num_gallery_pids, len(self.gallery), num_gallery_cams
)
return msg
class ImageDataset(Dataset):
"""A base class representing ImageDataset.
All other image datasets should subclass it.
``__getitem__`` returns an image given index.
It will return ``img``, ``pid``, ``camid`` and ``img_path``
where ``img`` has shape (channel, height, width). As a result,
data in each batch has shape (batch_size, channel, height, width).
"""
def __init__(self, train, query, gallery, **kwargs):
super(ImageDataset, self).__init__(train, query, gallery, **kwargs)
def __getitem__(self, index): # kept for backward compatibility
return self.getitem(index, self.mode)
def getitem(self, index, mode):
# BPBreID can work with None masks
# list all combination: source vs target, merged/joined vs not, cross domain or not, load from disk vs fixed for BoT/PBP transform vs None,
# need masks when available for pixel accuracy prediction
sample = self.data(mode)[index]
transf_args = {"image": read_image(sample['img_path'])}
if self.use_masks:
if self.load_masks and 'masks_path' in sample:
transf_args["mask"] = read_masks(sample['masks_path'])
elif not self.load_masks:
# hack for BoT and PCB masks that are generated in transform().
# FIXME BoT and PCB masks should not be generated here, but later in BPBreID model with a config
transf_args["mask"] = np.ones((1, 2, 2))
else:
pass
result = self.transforms(mode)(**transf_args)
sample.update(result)
return sample
def show_summary(self):
num_train_pids, num_train_cams = self.parse_data(self.train)
num_query_pids, num_query_cams = self.parse_data(self.query)
num_gallery_pids, num_gallery_cams = self.parse_data(self.gallery)
print('=> Loaded {}'.format(self.__class__.__name__))
print(' ----------------------------------------')
print(' subset | # ids | # images | # cameras')
print(' ----------------------------------------')
print(
' train | {:5d} | {:8d} | {:9d}'.format(
num_train_pids, len(self.train), num_train_cams
)
)
print(
' query | {:5d} | {:8d} | {:9d}'.format(
num_query_pids, len(self.query), num_query_cams
)
)
print(
' gallery | {:5d} | {:8d} | {:9d}'.format(
num_gallery_pids, len(self.gallery), num_gallery_cams
)
)
print(' ----------------------------------------')
class VideoDataset(Dataset):
"""A base class representing VideoDataset.
All other video datasets should subclass it.
``__getitem__`` returns an image given index.
It will return ``imgs``, ``pid`` and ``camid``
where ``imgs`` has shape (seq_len, channel, height, width). As a result,
data in each batch has shape (batch_size, seq_len, channel, height, width).
"""
def __init__(
self,
train,
query,
gallery,
seq_len=15,
sample_method='evenly',
**kwargs
):
super(VideoDataset, self).__init__(train, query, gallery, **kwargs)
self.seq_len = seq_len
self.sample_method = sample_method
if self.transform is None:
raise RuntimeError('transform must not be None')
def getitem(self, index, mode):
img_paths, pid, camid = self.data(mode)[index] # FIXME new format
num_imgs = len(img_paths)
if self.sample_method == 'random':
# Randomly samples seq_len images from a tracklet of length num_imgs,
# if num_imgs is smaller than seq_len, then replicates images
indices = np.arange(num_imgs)
replace = False if num_imgs >= self.seq_len else True
indices = np.random.choice(
indices, size=self.seq_len, replace=replace
)
# sort indices to keep temporal order (comment it to be order-agnostic)
indices = np.sort(indices)
elif self.sample_method == 'evenly':
# Evenly samples seq_len images from a tracklet
if num_imgs >= self.seq_len:
num_imgs -= num_imgs % self.seq_len
indices = np.arange(0, num_imgs, num_imgs / self.seq_len)
else:
# if num_imgs is smaller than seq_len, simply replicate the last image
# until the seq_len requirement is satisfied
indices = np.arange(0, num_imgs)
num_pads = self.seq_len - num_imgs
indices = np.concatenate(
[
indices,
np.ones(num_pads).astype(np.int32) * (num_imgs-1)
]
)
assert len(indices) == self.seq_len
elif self.sample_method == 'all':
# Samples all images in a tracklet. batch_size must be set to 1
indices = np.arange(num_imgs)
else:
raise ValueError(
'Unknown sample method: {}'.format(self.sample_method)
)
imgs = []
for index in indices:
img_path = img_paths[int(index)]
img = read_image(img_path)
if self.transform is not None:
img = self.transform(img)
img = img.unsqueeze(0) # img must be torch.Tensor
imgs.append(img)
imgs = torch.cat(imgs, dim=0)
return imgs, pid, camid
def show_summary(self):
num_train_pids, num_train_cams = self.parse_data(self.train)
num_query_pids, num_query_cams = self.parse_data(self.query)
num_gallery_pids, num_gallery_cams = self.parse_data(self.gallery)
print('=> Loaded {}'.format(self.__class__.__name__))
print(' -------------------------------------------')
print(' subset | # ids | # tracklets | # cameras')
print(' -------------------------------------------')
print(
' train | {:5d} | {:11d} | {:9d}'.format(
num_train_pids, len(self.train), num_train_cams
)
)
print(
' query | {:5d} | {:11d} | {:9d}'.format(
num_query_pids, len(self.query), num_query_cams
)
)
print(
' gallery | {:5d} | {:11d} | {:9d}'.format(
num_gallery_pids, len(self.gallery), num_gallery_cams
)
)
print(' -------------------------------------------')
================================================
FILE: torchreid/data/datasets/image/__init__.py
================================================
from __future__ import print_function, absolute_import
from .grid import GRID
from .prid import PRID
from .ilids import iLIDS
from .viper import VIPeR
from .cuhk01 import CUHK01
from .cuhk02 import CUHK02
from .cuhk03 import CUHK03
from .msmt17 import MSMT17
from .sensereid import SenseReID
from .market1501 import Market1501
from .dukemtmcreid import DukeMTMCreID
from .occluded_dukemtmc import OccludedDuke
from .occluded_reid import OccludedReID
from .partial_reid import Partial_REID
from .partial_ilids import Partial_iLIDS
from .p_ETHZ import P_ETHZ
from .p_dukemtmc_reid import PDukemtmcReid
================================================
FILE: torchreid/data/datasets/image/cuhk01.py
================================================
from __future__ import division, print_function, absolute_import
import glob
import numpy as np
import os.path as osp
import zipfile
from torchreid.utils import read_json, write_json
from ..dataset import ImageDataset
class CUHK01(ImageDataset):
"""CUHK01.
Reference:
Li et al. Human Reidentification with Transferred Metric Learning. ACCV 2012.
URL: `<http://www.ee.cuhk.edu.hk/~xgwang/CUHK_identification.html>`_
Dataset statistics:
- identities: 971.
- images: 3884.
- cameras: 4.
"""
dataset_dir = 'cuhk01'
dataset_url = None
eval_metric = 'default'
def __init__(self, root='', split_id=0, **kwargs):
self.root = osp.abspath(osp.expanduser(root))
self.dataset_dir = osp.join(self.root, self.dataset_dir)
self.download_dataset(self.dataset_dir, self.dataset_url)
self.zip_path = osp.join(self.dataset_dir, 'CUHK01.zip')
self.campus_dir = osp.join(self.dataset_dir, 'campus')
self.split_path = osp.join(self.dataset_dir, 'splits.json')
self.extract_file()
required_files = [self.dataset_dir, self.campus_dir]
self.check_before_run(required_files)
self.prepare_split()
splits = read_json(self.split_path)
if split_id >= len(splits):
raise ValueError(
'split_id exceeds range, received {}, but expected between 0 and {}'
.format(split_id,
len(splits) - 1)
)
split = splits[split_id]
train = split['train']
query = split['query']
gallery = split['gallery']
train = [tuple(item) for item in train]
query = [tuple(item) for item in query]
gallery = [tuple(item) for item in gallery]
super(CUHK01, self).__init__(train, query, gallery, **kwargs)
def extract_file(self):
if not osp.exists(self.campus_dir):
print('Extracting files')
zip_ref = zipfile.ZipFile(self.zip_path, 'r')
zip_ref.extractall(self.dataset_dir)
zip_ref.close()
def prepare_split(self):
"""
Image name format: 0001001.png, where first four digits represent identity
and last four digits represent cameras. Camera 1&2 are considered the same
view and camera 3&4 are considered the same view.
"""
if not osp.exists(self.split_path):
print('Creating 10 random splits of train ids and test ids')
img_paths = sorted(glob.glob(osp.join(self.campus_dir, '*.png')))
img_list = []
pid_container = set()
for img_path in img_paths:
img_name = osp.basename(img_path)
pid = int(img_name[:4]) - 1
camid = (int(img_name[4:7]) - 1) // 2 # result is either 0 or 1
img_list.append((img_path, pid, camid))
pid_container.add(pid)
num_pids = len(pid_container)
num_train_pids = num_pids // 2
splits = []
for _ in range(10):
order = np.arange(num_pids)
np.random.shuffle(order)
train_idxs = order[:num_train_pids]
train_idxs = np.sort(train_idxs)
idx2label = {
idx: label
for label, idx in enumerate(train_idxs)
}
train, test_a, test_b = [], [], []
for img_path, pid, camid in img_list:
if pid in train_idxs:
train.append((img_path, idx2label[pid], camid))
else:
if camid == 0:
test_a.append((img_path, pid, camid))
else:
test_b.append((img_path, pid, camid))
# use cameraA as query and cameraB as gallery
split = {
'train': train,
'query': test_a,
'gallery': test_b,
'num_train_pids': num_train_pids,
'num_query_pids': num_pids - num_train_pids,
'num_gallery_pids': num_pids - num_train_pids
}
splits.append(split)
# use cameraB as query and cameraA as gallery
split = {
'train': train,
'query': test_b,
'gallery': test_a,
'num_train_pids': num_train_pids,
'num_query_pids': num_pids - num_train_pids,
'num_gallery_pids': num_pids - num_train_pids
}
splits.append(split)
print('Totally {} splits are created'.format(len(splits)))
write_json(splits, self.split_path)
print('Split file saved to {}'.format(self.split_path))
================================================
FILE: torchreid/data/datasets/image/cuhk02.py
================================================
from __future__ import division, print_function, absolute_import
import glob
import os.path as osp
from ..dataset import ImageDataset
class CUHK02(ImageDataset):
"""CUHK02.
Reference:
Li and Wang. Locally Aligned Feature Transforms across Views. CVPR 2013.
URL: `<http://www.ee.cuhk.edu.hk/~xgwang/CUHK_identification.html>`_
Dataset statistics:
- 5 camera view pairs each with two cameras
- 971, 306, 107, 193 and 239 identities from P1 - P5
- totally 1,816 identities
- image format is png
Protocol: Use P1 - P4 for training and P5 for evaluation.
"""
dataset_dir = 'cuhk02'
cam_pairs = ['P1', 'P2', 'P3', 'P4', 'P5']
test_cam_pair = 'P5'
eval_metric = 'default'
def __init__(self, root='', **kwargs):
self.root = osp.abspath(osp.expanduser(root))
self.dataset_dir = osp.join(self.root, self.dataset_dir, 'Dataset')
required_files = [self.dataset_dir]
self.check_before_run(required_files)
train, query, gallery = self.get_data_list()
super(CUHK02, self).__init__(train, query, gallery, **kwargs)
def get_data_list(self):
num_train_pids, camid = 0, 0
train, query, gallery = [], [], []
for cam_pair in self.cam_pairs:
cam_pair_dir = osp.join(self.dataset_dir, cam_pair)
cam1_dir = osp.join(cam_pair_dir, 'cam1')
cam2_dir = osp.join(cam_pair_dir, 'cam2')
impaths1 = glob.glob(osp.join(cam1_dir, '*.png'))
impaths2 = glob.glob(osp.join(cam2_dir, '*.png'))
if cam_pair == self.test_cam_pair:
# add images to query
for impath in impaths1:
pid = osp.basename(impath).split('_')[0]
pid = int(pid)
query.append((impath, pid, camid))
camid += 1
# add images to gallery
for impath in impaths2:
pid = osp.basename(impath).split('_')[0]
pid = int(pid)
gallery.append((impath, pid, camid))
camid += 1
else:
pids1 = [
osp.basename(impath).split('_')[0] for impath in impaths1
]
pids2 = [
osp.basename(impath).split('_')[0] for impath in impaths2
]
pids = set(pids1 + pids2)
pid2label = {
pid: label + num_train_pids
for label, pid in enumerate(pids)
}
# add images to train from cam1
for impath in impaths1:
pid = osp.basename(impath).split('_')[0]
pid = pid2label[pid]
train.append((impath, pid, camid))
camid += 1
# add images to train from cam2
for impath in impaths2:
pid = osp.basename(impath).split('_')[0]
pid = pid2label[pid]
train.append((impath, pid, camid))
camid += 1
num_train_pids += len(pids)
return train, query, gallery
================================================
FILE: torchreid/data/datasets/image/cuhk03.py
================================================
from __future__ import division, print_function, absolute_import
import os.path as osp
from torchreid.utils import read_json, write_json, mkdir_if_missing
from ..dataset import ImageDataset
class CUHK03(ImageDataset):
"""CUHK03.
Reference:
Li et al. DeepReID: Deep Filter Pairing Neural Network for Person Re-identification. CVPR 2014.
URL: `<http://www.ee.cuhk.edu.hk/~xgwang/CUHK_identification.html#!>`_
Dataset statistics:
- identities: 1360.
- images: 13164.
- cameras: 6.
- splits: 20 (classic).
"""
dataset_dir = 'cuhk03'
dataset_url = None
eval_metric = 'default'
def __init__(
self,
root='',
split_id=0,
cuhk03_labeled=False,
cuhk03_classic_split=False,
**kwargs
):
self.root = osp.abspath(osp.expanduser(root))
self.dataset_dir = osp.join(self.root, self.dataset_dir)
self.download_dataset(self.dataset_dir, self.dataset_url)
self.data_dir = osp.join(self.dataset_dir, 'cuhk03_release')
self.raw_mat_path = osp.join(self.data_dir, 'cuhk-03.mat')
self.imgs_detected_dir = osp.join(self.dataset_dir, 'images_detected')
self.imgs_labeled_dir = osp.join(self.dataset_dir, 'images_labeled')
self.split_classic_det_json_path = osp.join(
self.dataset_dir, 'splits_classic_detected.json'
)
self.split_classic_lab_json_path = osp.join(
self.dataset_dir, 'splits_classic_labeled.json'
)
self.split_new_det_json_path = osp.join(
self.dataset_dir, 'splits_new_detected.json'
)
self.split_new_lab_json_path = osp.join(
self.dataset_dir, 'splits_new_labeled.json'
)
self.split_new_det_mat_path = osp.join(
self.dataset_dir, 'cuhk03_new_protocol_config_detected.mat'
)
self.split_new_lab_mat_path = osp.join(
self.dataset_dir, 'cuhk03_new_protocol_config_labeled.mat'
)
required_files = [
self.dataset_dir, self.data_dir, self.raw_mat_path,
self.split_new_det_mat_path, self.split_new_lab_mat_path
]
self.check_before_run(required_files)
self.preprocess_split()
if cuhk03_labeled:
split_path = self.split_classic_lab_json_path if cuhk03_classic_split else self.split_new_lab_json_path
else:
split_path = self.split_classic_det_json_path if cuhk03_classic_split else self.split_new_det_json_path
splits = read_json(split_path)
assert split_id < len(
splits
), 'Condition split_id ({}) < len(splits) ({}) is false'.format(
split_id, len(splits)
)
split = splits[split_id]
train = split['train']
query = split['query']
gallery = split['gallery']
super(CUHK03, self).__init__(train, query, gallery, **kwargs)
def preprocess_split(self):
# This function is a bit complex and ugly, what it does is
# 1. extract data from cuhk-03.mat and save as png images
# 2. create 20 classic splits (Li et al. CVPR'14)
# 3. create new split (Zhong et al. CVPR'17)
if osp.exists(self.imgs_labeled_dir) \
and osp.exists(self.imgs_detected_dir) \
and osp.exists(self.split_classic_det_json_path) \
and osp.exists(self.split_classic_lab_json_path) \
and osp.exists(self.split_new_det_json_path) \
and osp.exists(self.split_new_lab_json_path):
return
import h5py
from scipy.misc import imsave
from scipy.io import loadmat
mkdir_if_missing(self.imgs_detected_dir)
mkdir_if_missing(self.imgs_labeled_dir)
print(
'Extract image data from "{}" and save as png'.format(
self.raw_mat_path
)
)
mat = h5py.File(self.raw_mat_path, 'r')
def _deref(ref):
return mat[ref][:].T
def _process_images(img_refs, campid, pid, save_dir):
img_paths = [] # Note: some persons only have images for one view
for imgid, img_ref in enumerate(img_refs):
img = _deref(img_ref)
if img.size == 0 or img.ndim < 3:
continue # skip empty cell
# images are saved with the following format, index-1 (ensure uniqueness)
# campid: index of camera pair (1-5)
# pid: index of person in 'campid'-th camera pair
# viewid: index of view, {1, 2}
# imgid: index of image, (1-10)
viewid = 1 if imgid < 5 else 2
img_name = '{:01d}_{:03d}_{:01d}_{:02d}.png'.format(
campid + 1, pid + 1, viewid, imgid + 1
)
img_path = osp.join(save_dir, img_name)
if not osp.isfile(img_path):
imsave(img_path, img)
img_paths.append(img_path)
return img_paths
def _extract_img(image_type):
print('Processing {} images ...'.format(image_type))
meta_data = []
imgs_dir = self.imgs_detected_dir if image_type == 'detected' else self.imgs_labeled_dir
for campid, camp_ref in enumerate(mat[image_type][0]):
camp = _deref(camp_ref)
num_pids = camp.shape[0]
for pid in range(num_pids):
img_paths = _process_images(
camp[pid, :], campid, pid, imgs_dir
)
assert len(img_paths) > 0, \
'campid{}-pid{} has no images'.format(campid, pid)
meta_data.append((campid + 1, pid + 1, img_paths))
print(
'- done camera pair {} with {} identities'.format(
campid + 1, num_pids
)
)
return meta_data
meta_detected = _extract_img('detected')
meta_labeled = _extract_img('labeled')
def _extract_classic_split(meta_data, test_split):
train, test = [], []
num_train_pids, num_test_pids = 0, 0
num_train_imgs, num_test_imgs = 0, 0
for i, (campid, pid, img_paths) in enumerate(meta_data):
if [campid, pid] in test_split:
for img_path in img_paths:
camid = int(
osp.basename(img_path).split('_')[2]
) - 1 # make it 0-based
test.append((img_path, num_test_pids, camid))
num_test_pids += 1
num_test_imgs += len(img_paths)
else:
for img_path in img_paths:
camid = int(
osp.basename(img_path).split('_')[2]
) - 1 # make it 0-based
train.append((img_path, num_train_pids, camid))
num_train_pids += 1
num_train_imgs += len(img_paths)
return train, num_train_pids, num_train_imgs, test, num_test_pids, num_test_imgs
print('Creating classic splits (# = 20) ...')
splits_classic_det, splits_classic_lab = [], []
for split_ref in mat['testsets'][0]:
test_split = _deref(split_ref).tolist()
# create split for detected images
train, num_train_pids, num_train_imgs, test, num_test_pids, num_test_imgs = \
_extract_classic_split(meta_detected, test_split)
splits_classic_det.append(
{
'train': train,
'query': test,
'gallery': test,
'num_train_pids': num_train_pids,
'num_train_imgs': num_train_imgs,
'num_query_pids': num_test_pids,
'num_query_imgs': num_test_imgs,
'num_gallery_pids': num_test_pids,
'num_gallery_imgs': num_test_imgs
}
)
# create split for labeled images
train, num_train_pids, num_train_imgs, test, num_test_pids, num_test_imgs = \
_extract_classic_split(meta_labeled, test_split)
splits_classic_lab.append(
{
'train': train,
'query': test,
'gallery': test,
'num_train_pids': num_train_pids,
'num_train_imgs': num_train_imgs,
'num_query_pids': num_test_pids,
'num_query_imgs': num_test_imgs,
'num_gallery_pids': num_test_pids,
'num_gallery_imgs': num_test_imgs
}
)
write_json(splits_classic_det, self.split_classic_det_json_path)
write_json(splits_classic_lab, self.split_classic_lab_json_path)
def _extract_set(filelist, pids, pid2label, idxs, img_dir, relabel):
tmp_set = []
unique_pids = set()
for idx in idxs:
img_name = filelist[idx][0]
camid = int(img_name.split('_')[2]) - 1 # make it 0-based
pid = pids[idx]
if relabel:
pid = pid2label[pid]
img_path = osp.join(img_dir, img_name)
tmp_set.append((img_path, int(pid), camid))
unique_pids.add(pid)
return tmp_set, len(unique_pids), len(idxs)
def _extract_new_split(split_dict, img_dir):
train_idxs = split_dict['train_idx'].flatten() - 1 # index-0
pids = split_dict['labels'].flatten()
train_pids = set(pids[train_idxs])
pid2label = {pid: label for label, pid in enumerate(train_pids)}
query_idxs = split_dict['query_idx'].flatten() - 1
gallery_idxs = split_dict['gallery_idx'].flatten() - 1
filelist = split_dict['filelist'].flatten()
train_info = _extract_set(
filelist, pids, pid2label, train_idxs, img_dir, relabel=True
)
query_info = _extract_set(
filelist, pids, pid2label, query_idxs, img_dir, relabel=False
)
gallery_info = _extract_set(
filelist,
pids,
pid2label,
gallery_idxs,
img_dir,
relabel=False
)
return train_info, query_info, gallery_info
print('Creating new split for detected images (767/700) ...')
train_info, query_info, gallery_info = _extract_new_split(
loadmat(self.split_new_det_mat_path), self.imgs_detected_dir
)
split = [
{
'train': train_info[0],
'query': query_info[0],
'gallery': gallery_info[0],
'num_train_pids': train_info[1],
'num_train_imgs': train_info[2],
'num_query_pids': query_info[1],
'num_query_imgs': query_info[2],
'num_gallery_pids': gallery_info[1],
'num_gallery_imgs': gallery_info[2]
}
]
write_json(split, self.split_new_det_json_path)
print('Creating new split for labeled images (767/700) ...')
train_info, query_info, gallery_info = _extract_new_split(
loadmat(self.split_new_lab_mat_path), self.imgs_labeled_dir
)
split = [
{
'train': train_info[0],
'query': query_info[0],
'gallery': gallery_info[0],
'num_train_pids': train_info[1],
'num_train_imgs': train_info[2],
'num_query_pids': query_info[1],
'num_query_imgs': query_info[2],
'num_gallery_pids': gallery_info[1],
'num_gallery_imgs': gallery_info[2]
}
]
write_json(split, self.split_new_lab_json_path)
================================================
FILE: torchreid/data/datasets/image/dukemtmcreid.py
================================================
from __future__ import division, print_function, absolute_import
import re
import glob
import os.path as osp
from ..dataset import ImageDataset
class DukeMTMCreID(ImageDataset):
"""DukeMTMC-reID.
Reference:
- Ristani et al. Performance Measures and a Data Set for Multi-Target, Multi-Camera Tracking. ECCVW 2016.
- Zheng et al. Unlabeled Samples Generated by GAN Improve the Person Re-identification Baseline in vitro. ICCV 2017.
URL: `<https://github.com/layumi/DukeMTMC-reID_evaluation>`_
Dataset statistics:
- identities: 1404 (train + query).
- images:16522 (train) + 2228 (query) + 17661 (gallery).
- cameras: 8.
"""
dataset_dir = 'DukeMTMC-reID'
dataset_url = 'http://vision.cs.duke.edu/DukeMTMC/data/misc/DukeMTMC-reID.zip'
masks_base_dir = 'masks'
masks_dirs = {
# dir_name: (parts_num, masks_stack_size, contains_background_mask)
'pifpaf': (36, False,
gitextract_fsax4gel/
├── .flake8
├── .gitignore
├── .isort.cfg
├── .style.yapf
├── LICENSE
├── README.md
├── Torchreid_original_README.rst
├── configs/
│ └── bpbreid/
│ ├── bpbreid_dukemtmc_test.yaml
│ ├── bpbreid_dukemtmc_train.yaml
│ ├── bpbreid_market1501_test.yaml
│ ├── bpbreid_market1501_train.yaml
│ ├── bpbreid_occ_duke_test.yaml
│ ├── bpbreid_occ_duke_train.yaml
│ ├── bpbreid_occ_reid_test.yaml
│ ├── bpbreid_occ_reid_train.yaml
│ ├── bpbreid_p_dukemtmc_test.yaml
│ ├── bpbreid_p_dukemtmc_train.yaml
│ ├── pcb_market1501_train.yaml
│ └── pcb_occ_duke_train.yaml
├── docs/
│ ├── AWESOME_REID.md
│ ├── MODEL_ZOO.md
│ ├── Makefile
│ ├── conf.py
│ ├── datasets.rst
│ ├── evaluation.rst
│ ├── index.rst
│ ├── pkg/
│ │ ├── data.rst
│ │ ├── engine.rst
│ │ ├── losses.rst
│ │ ├── metrics.rst
│ │ ├── models.rst
│ │ ├── optim.rst
│ │ └── utils.rst
│ ├── requirements.txt
│ └── user_guide.rst
├── linter.sh
├── pyproject.toml
├── requirements.txt
├── requirements_labels.txt
├── setup.py
└── torchreid/
├── __init__.py
├── data/
│ ├── __init__.py
│ ├── data_augmentation/
│ │ ├── __init__.py
│ │ └── random_occlusion.py
│ ├── datamanager.py
│ ├── datasets/
│ │ ├── __init__.py
│ │ ├── dataset.py
│ │ ├── image/
│ │ │ ├── __init__.py
│ │ │ ├── cuhk01.py
│ │ │ ├── cuhk02.py
│ │ │ ├── cuhk03.py
│ │ │ ├── dukemtmcreid.py
│ │ │ ├── grid.py
│ │ │ ├── ilids.py
│ │ │ ├── market1501.py
│ │ │ ├── msmt17.py
│ │ │ ├── occluded_dukemtmc.py
│ │ │ ├── occluded_reid.py
│ │ │ ├── p_ETHZ.py
│ │ │ ├── p_dukemtmc_reid.py
│ │ │ ├── partial_ilids.py
│ │ │ ├── partial_reid.py
│ │ │ ├── prid.py
│ │ │ ├── sensereid.py
│ │ │ └── viper.py
│ │ └── video/
│ │ ├── __init__.py
│ │ ├── dukemtmcvidreid.py
│ │ ├── ilidsvid.py
│ │ ├── mars.py
│ │ └── prid2011.py
│ ├── masks_transforms/
│ │ ├── __init__.py
│ │ ├── coco_keypoints_transforms.py
│ │ ├── mask_transform.py
│ │ ├── pcb_transforms.py
│ │ └── pifpaf_mask_transform.py
│ ├── sampler.py
│ └── transforms.py
├── engine/
│ ├── __init__.py
│ ├── engine.py
│ ├── image/
│ │ ├── __init__.py
│ │ ├── part_based_engine.py
│ │ ├── softmax.py
│ │ └── triplet.py
│ └── video/
│ ├── __init__.py
│ ├── softmax.py
│ └── triplet.py
├── hyperparameter/
│ ├── custom_hyperparameter_optimizer.py
│ ├── hyperparameter_optimizer.py
│ └── optuna_hyperparameter_optimizer.py
├── losses/
│ ├── GiLt_loss.py
│ ├── __init__.py
│ ├── body_part_attention_loss.py
│ ├── cross_entropy_loss.py
│ ├── hard_mine_triplet_loss.py
│ ├── inter_parts_triplet_loss.py
│ ├── part_averaged_triplet_loss.py
│ ├── part_individual_triplet_loss.py
│ ├── part_max_min_triplet_loss.py
│ ├── part_max_triplet_loss.py
│ ├── part_min_triplet_loss.py
│ └── part_random_max_min_triplet_loss.py
├── metrics/
│ ├── __init__.py
│ ├── accuracy.py
│ ├── distance.py
│ ├── rank.py
│ └── rank_cylib/
│ ├── Makefile
│ ├── __init__.py
│ ├── rank_cy.pyx
│ ├── setup.py
│ └── test_cython.py
├── models/
│ ├── __init__.py
│ ├── bpbreid.py
│ ├── compact_bilinear_pooling.py
│ ├── densenet.py
│ ├── hacnn.py
│ ├── hrnet.py
│ ├── inceptionresnetv2.py
│ ├── inceptionv4.py
│ ├── mlfn.py
│ ├── mobilenetv2.py
│ ├── mudeep.py
│ ├── nasnet.py
│ ├── osnet.py
│ ├── osnet_ain.py
│ ├── pcb.py
│ ├── pvpm.py
│ ├── resnet.py
│ ├── resnet_fastreid.py
│ ├── resnet_ibn_a.py
│ ├── resnet_ibn_b.py
│ ├── resnetmid.py
│ ├── senet.py
│ ├── shufflenet.py
│ ├── shufflenetv2.py
│ ├── squeezenet.py
│ └── xception.py
├── optim/
│ ├── __init__.py
│ ├── lr_scheduler.py
│ ├── optimizer.py
│ └── radam.py
├── scripts/
│ ├── __init__.py
│ ├── default_config.py
│ ├── get_labels.py
│ └── main.py
├── tools/
│ ├── __init__.py
│ ├── compute_mean_std.py
│ ├── extract_part_based_features.py
│ └── feature_extractor.py
└── utils/
├── __init__.py
├── avgmeter.py
├── constants.py
├── distribution.py
├── engine_state.py
├── imagetools.py
├── logging/
│ ├── __init__.py
│ ├── deprecated_loggers.py
│ └── logger.py
├── model_complexity.py
├── reidtools.py
├── rerank.py
├── tensortools.py
├── tools.py
├── torch_receptive_field/
│ ├── __init__.py
│ └── receptive_field.py
├── torchtools.py
├── visualization/
│ ├── __init__.py
│ ├── display_batch_triplets.py
│ ├── embeddings_projection.py
│ ├── feature_map_visualization.py
│ └── visualize_query_gallery_rankings.py
└── writer.py
SYMBOL INDEX (1199 symbols across 111 files)
FILE: setup.py
function readme (line 7) | def readme():
function numpy_include (line 13) | def numpy_include():
function get_requirements (line 30) | def get_requirements(filename='requirements.txt'):
FILE: torchreid/data/data_augmentation/random_occlusion.py
function main (line 17) | def main():
function load_occluders (line 39) | def load_occluders(
function occlude_with_objects (line 98) | def occlude_with_objects(im, occluders, n=1, min_overlap=0.1, max_overla...
function paste_over (line 118) | def paste_over(im_src, im_dst, center, is_mask=False):
function resize_by_factor (line 160) | def resize_by_factor(im, factor):
function list_filepaths (line 169) | def list_filepaths(dirpath):
class RandomOcclusion (line 175) | class RandomOcclusion(DualTransform):
method __init__ (line 176) | def __init__(self,
method check_range (line 196) | def check_range(self, dimension):
method apply (line 202) | def apply(self, image, occluders=(), centers=(), **params):
method apply_to_mask (line 223) | def apply_to_mask(self, image, occluders=(), centers=(), **params):
method get_params_dependent_on_targets (line 228) | def get_params_dependent_on_targets(self, params):
method targets_as_params (line 250) | def targets_as_params(self):
method get_transform_init_args_names (line 253) | def get_transform_init_args_names(self):
FILE: torchreid/data/datamanager.py
class DataManager (line 10) | class DataManager(object):
method __init__ (line 26) | def __init__(
method num_train_pids (line 77) | def num_train_pids(self):
method num_train_cams (line 82) | def num_train_cams(self):
method fetch_test_loaders (line 86) | def fetch_test_loaders(self, name):
method preprocess_pil_img (line 97) | def preprocess_pil_img(self, img):
class ImageDataManager (line 102) | class ImageDataManager(DataManager):
method __init__ (line 158) | def __init__(
class VideoDataManager (line 374) | class VideoDataManager(DataManager):
method __init__ (line 431) | def __init__(
FILE: torchreid/data/datasets/__init__.py
function configure_dataset_class (line 63) | def configure_dataset_class(clazz, **ext_kwargs):
function get_dataset_nickname (line 77) | def get_dataset_nickname(name):
function get_image_dataset (line 81) | def get_image_dataset(name):
function init_image_dataset (line 91) | def init_image_dataset(name, mode='train', **kwargs):
function init_video_dataset (line 117) | def init_video_dataset(name, **kwargs):
function register_image_dataset (line 128) | def register_image_dataset(name, dataset, nickname=None):
function register_video_dataset (line 162) | def register_video_dataset(name, dataset):
FILE: torchreid/data/datasets/dataset.py
class Dataset (line 14) | class Dataset(object):
method gallery_filter (line 35) | def gallery_filter(self, q_pid, q_camid, q_ann, g_pids, g_camids, g_an...
method infer_masks_path (line 42) | def infer_masks_path(self, img_path):
method __init__ (line 46) | def __init__(
method transforms (line 87) | def transforms(self, mode):
method data (line 99) | def data(self, mode):
method __getitem__ (line 118) | def __getitem__(self, index):
method __len__ (line 121) | def __len__(self): # kept for backward compatibility
method len (line 124) | def len(self, mode):
method __add__ (line 127) | def __add__(self, other):
method __radd__ (line 172) | def __radd__(self, other):
method parse_data (line 179) | def parse_data(self, data):
method get_num_pids (line 193) | def get_num_pids(self, data):
method get_num_cams (line 197) | def get_num_cams(self, data):
method show_summary (line 201) | def show_summary(self):
method combine_all (line 205) | def combine_all(self):
method download_dataset (line 232) | def download_dataset(self, dataset_dir, dataset_url):
method check_before_run (line 274) | def check_before_run(self, required_files):
method __repr__ (line 287) | def __repr__(self):
class ImageDataset (line 308) | class ImageDataset(Dataset):
method __init__ (line 319) | def __init__(self, train, query, gallery, **kwargs):
method __getitem__ (line 322) | def __getitem__(self, index): # kept for backward compatibility
method getitem (line 325) | def getitem(self, index, mode):
method show_summary (line 344) | def show_summary(self):
class VideoDataset (line 371) | class VideoDataset(Dataset):
method __init__ (line 382) | def __init__(
method getitem (line 398) | def getitem(self, index, mode):
method show_summary (line 452) | def show_summary(self):
FILE: torchreid/data/datasets/image/cuhk01.py
class CUHK01 (line 12) | class CUHK01(ImageDataset):
method __init__ (line 29) | def __init__(self, root='', split_id=0, **kwargs):
method extract_file (line 63) | def extract_file(self):
method prepare_split (line 70) | def prepare_split(self):
FILE: torchreid/data/datasets/image/cuhk02.py
class CUHK02 (line 8) | class CUHK02(ImageDataset):
method __init__ (line 29) | def __init__(self, root='', **kwargs):
method get_data_list (line 40) | def get_data_list(self):
FILE: torchreid/data/datasets/image/cuhk03.py
class CUHK03 (line 9) | class CUHK03(ImageDataset):
method __init__ (line 27) | def __init__(
method preprocess_split (line 93) | def preprocess_split(self):
FILE: torchreid/data/datasets/image/dukemtmcreid.py
class DukeMTMCreID (line 10) | class DukeMTMCreID(ImageDataset):
method get_masks_config (line 35) | def get_masks_config(masks_dir):
method __init__ (line 41) | def __init__(self, root='', masks_dir=None, **kwargs):
method process_dir (line 65) | def process_dir(self, dir_path, relabel=False):
FILE: torchreid/data/datasets/image/grid.py
class GRID (line 11) | class GRID(ImageDataset):
method __init__ (line 27) | def __init__(self, root='', split_id=0, **kwargs):
method prepare_split (line 71) | def prepare_split(self):
FILE: torchreid/data/datasets/image/ilids.py
class iLIDS (line 13) | class iLIDS(ImageDataset):
method __init__ (line 27) | def __init__(self, root='', split_id=0, **kwargs):
method prepare_split (line 52) | def prepare_split(self):
method get_pid2label (line 109) | def get_pid2label(self, img_names):
method parse_img_names (line 117) | def parse_img_names(self, img_names, pid2label=None):
method process_split (line 130) | def process_split(self, split):
FILE: torchreid/data/datasets/image/market1501.py
class Market1501 (line 11) | class Market1501(ImageDataset):
method get_masks_config (line 35) | def get_masks_config(masks_dir):
method __init__ (line 41) | def __init__(self, root='', market1501_500k=False, masks_dir=None, **k...
method process_dir (line 79) | def process_dir(self, dir_path, relabel=False):
FILE: torchreid/data/datasets/image/msmt17.py
class MSMT17 (line 25) | class MSMT17(ImageDataset):
method get_masks_config (line 46) | def get_masks_config(masks_dir):
method __init__ (line 52) | def __init__(self, root='', masks_dir=None, **kwargs):
method process_dir (line 101) | def process_dir(self, dir_path, list_path):
FILE: torchreid/data/datasets/image/occluded_dukemtmc.py
class OccludedDuke (line 15) | class OccludedDuke(ImageDataset):
method get_masks_config (line 27) | def get_masks_config(masks_dir):
method __init__ (line 33) | def __init__(self, root='', masks_dir=None, **kwargs):
method process_dir (line 56) | def process_dir(self, dir_path, relabel=False):
FILE: torchreid/data/datasets/image/occluded_reid.py
class OccludedReID (line 16) | class OccludedReID(ImageDataset):
method get_masks_config (line 27) | def get_masks_config(masks_dir):
method infer_masks_path (line 33) | def infer_masks_path(self, img_path):
method __init__ (line 37) | def __init__(self, root='', masks_dir=None, **kwargs):
method process_dir (line 60) | def process_dir(self, dir_path, relabel=False, is_query=True):
FILE: torchreid/data/datasets/image/p_ETHZ.py
class P_ETHZ (line 16) | class P_ETHZ(ImageDataset):
method __init__ (line 19) | def __init__(self, root='', **kwargs):
method process_dir (line 35) | def process_dir(self, dir_path, relabel=False, is_query=True):
FILE: torchreid/data/datasets/image/p_dukemtmc_reid.py
class PDukemtmcReid (line 16) | class PDukemtmcReid(ImageDataset):
method get_masks_config (line 27) | def get_masks_config(masks_dir):
method infer_masks_path (line 33) | def infer_masks_path(self, img_path):
method __init__ (line 43) | def __init__(self, root='', masks_dir=None, **kwargs):
method process_train_dir (line 66) | def process_train_dir(self, dir_path, relabel=True):
method process_dir (line 100) | def process_dir(self, dir_path, relabel=False, is_query=True):
FILE: torchreid/data/datasets/image/partial_ilids.py
class Partial_iLIDS (line 15) | class Partial_iLIDS(ImageDataset):
method __init__ (line 18) | def __init__(self, root='', **kwargs):
method process_dir (line 42) | def process_dir(self, dir_path, is_query=True):
FILE: torchreid/data/datasets/image/partial_reid.py
class Partial_REID (line 16) | class Partial_REID(ImageDataset):
method __init__ (line 19) | def __init__(self, root='', **kwargs):
method process_dir (line 43) | def process_dir(self, dir_path, relabel=False, is_query=True):
FILE: torchreid/data/datasets/image/prid.py
class PRID (line 10) | class PRID(ImageDataset):
method __init__ (line 28) | def __init__(self, root='', split_id=0, **kwargs):
method prepare_split (line 58) | def prepare_split(self):
method process_split (line 77) | def process_split(self, split):
FILE: torchreid/data/datasets/image/sensereid.py
class SenseReID (line 9) | class SenseReID(ImageDataset):
method __init__ (line 27) | def __init__(self, root='', **kwargs):
method process_dir (line 60) | def process_dir(self, dir_path):
FILE: torchreid/data/datasets/image/viper.py
class VIPeR (line 11) | class VIPeR(ImageDataset):
method __init__ (line 27) | def __init__(self, root='', split_id=0, **kwargs):
method prepare_split (line 61) | def prepare_split(self):
FILE: torchreid/data/datasets/video/dukemtmcvidreid.py
class DukeMTMCVidReID (line 11) | class DukeMTMCVidReID(VideoDataset):
method __init__ (line 29) | def __init__(self, root='', min_seq_len=0, **kwargs):
method process_dir (line 67) | def process_dir(self, dir_path, json_path, relabel):
FILE: torchreid/data/datasets/video/ilidsvid.py
class iLIDSVID (line 11) | class iLIDSVID(VideoDataset):
method __init__ (line 27) | def __init__(self, root='', split_id=0, **kwargs):
method prepare_split (line 65) | def prepare_split(self):
method process_data (line 122) | def process_data(self, dirnames, cam1=True, cam2=True):
FILE: torchreid/data/datasets/video/mars.py
class Mars (line 9) | class Mars(VideoDataset):
method __init__ (line 25) | def __init__(self, root='', **kwargs):
method get_names (line 76) | def get_names(self, fpath):
method process_data (line 84) | def process_data(
method combine_all (line 129) | def combine_all(self):
FILE: torchreid/data/datasets/video/prid2011.py
class PRID2011 (line 10) | class PRID2011(VideoDataset):
method __init__ (line 27) | def __init__(self, root='', split_id=0, **kwargs):
method process_dir (line 59) | def process_dir(self, dirnames, cam1=True, cam2=True):
FILE: torchreid/data/masks_transforms/__init__.py
function compute_parts_num_and_names (line 55) | def compute_parts_num_and_names(cfg):
FILE: torchreid/data/masks_transforms/coco_keypoints_transforms.py
class CocoToSixBodyMasks (line 10) | class CocoToSixBodyMasks(MaskGroupingTransform):
method __init__ (line 20) | def __init__(self):
FILE: torchreid/data/masks_transforms/mask_transform.py
class MaskTransform (line 7) | class MaskTransform(DualTransform):
method __init__ (line 8) | def __init__(self):
method apply (line 11) | def apply(self, img, **params):
method apply_to_bbox (line 14) | def apply_to_bbox(self, bbox, **params):
method apply_to_keypoint (line 17) | def apply_to_keypoint(self, keypoint, **params):
class MaskGroupingTransform (line 21) | class MaskGroupingTransform(MaskTransform):
method __init__ (line 23) | def __init__(self, parts_grouping, parts_map, combine_mode='max'):
method apply_to_mask (line 31) | def apply_to_mask(self, masks, **params):
class PermuteMasksDim (line 41) | class PermuteMasksDim(MaskTransform):
method apply_to_mask (line 42) | def apply_to_mask(self, masks, **params):
class ResizeMasks (line 46) | class ResizeMasks(MaskTransform):
method __init__ (line 47) | def __init__(self, height, width, mask_scale):
method apply_to_mask (line 51) | def apply_to_mask(self, masks, **params):
class RemoveBackgroundMask (line 55) | class RemoveBackgroundMask(MaskTransform):
method apply_to_mask (line 56) | def apply_to_mask(self, masks, **params):
class AddBackgroundMask (line 60) | class AddBackgroundMask(MaskTransform):
method __init__ (line 61) | def __init__(self, background_computation_strategy='sum', softmax_weig...
method apply_to_mask (line 67) | def apply_to_mask(self, masks, **params):
class IdentityMask (line 88) | class IdentityMask(MaskTransform):
method apply_to_mask (line 91) | def apply_to_mask(self, masks, **params):
FILE: torchreid/data/masks_transforms/pcb_transforms.py
class PCBMasks (line 7) | class PCBMasks(MaskTransform):
method apply_to_mask (line 8) | def apply_to_mask(self, masks, **params):
class PCBMasks2 (line 21) | class PCBMasks2(PCBMasks):
class PCBMasks3 (line 26) | class PCBMasks3(PCBMasks):
class PCBMasks4 (line 31) | class PCBMasks4(PCBMasks):
class PCBMasks5 (line 36) | class PCBMasks5(PCBMasks):
class PCBMasks6 (line 41) | class PCBMasks6(PCBMasks):
class PCBMasks7 (line 46) | class PCBMasks7(PCBMasks):
class PCBMasks8 (line 51) | class PCBMasks8(PCBMasks):
FILE: torchreid/data/masks_transforms/pifpaf_mask_transform.py
class CombinePifPafIntoFullBodyMask (line 22) | class CombinePifPafIntoFullBodyMask(MaskGroupingTransform):
method __init__ (line 27) | def __init__(self):
class AddFullBodyMaskToBaseMasks (line 31) | class AddFullBodyMaskToBaseMasks(MaskGroupingTransform):
method __init__ (line 38) | def __init__(self):
class AddFullBodyMaskAndFullBoundingBoxToBaseMasks (line 42) | class AddFullBodyMaskAndFullBoundingBoxToBaseMasks(MaskGroupingTransform):
method apply_to_mask (line 46) | def apply_to_mask(self, masks, **params):
class CombinePifPafIntoMultiScaleBodyMasks (line 57) | class CombinePifPafIntoMultiScaleBodyMasks(MaskGroupingTransform):
method __init__ (line 82) | def __init__(self):
class CombinePifPafIntoOneBodyMasks (line 86) | class CombinePifPafIntoOneBodyMasks(MaskGroupingTransform):
method __init__ (line 91) | def __init__(self):
class CombinePifPafIntoTwoBodyMasks (line 95) | class CombinePifPafIntoTwoBodyMasks(MaskGroupingTransform):
method __init__ (line 111) | def __init__(self):
class CombinePifPafIntoThreeBodyMasks (line 115) | class CombinePifPafIntoThreeBodyMasks(MaskGroupingTransform):
method __init__ (line 132) | def __init__(self):
class CombinePifPafIntoFourBodyMasks (line 136) | class CombinePifPafIntoFourBodyMasks(MaskGroupingTransform):
method __init__ (line 153) | def __init__(self):
class CombinePifPafIntoFourBodyMasksNoOverlap (line 157) | class CombinePifPafIntoFourBodyMasksNoOverlap(MaskGroupingTransform):
method __init__ (line 174) | def __init__(self):
class CombinePifPafIntoFourVerticalParts (line 178) | class CombinePifPafIntoFourVerticalParts(MaskGroupingTransform):
method __init__ (line 195) | def __init__(self):
class CombinePifPafIntoFourVerticalPartsPif (line 199) | class CombinePifPafIntoFourVerticalPartsPif(MaskGroupingTransform):
method __init__ (line 207) | def __init__(self):
class CombinePifPafIntoFiveVerticalParts (line 211) | class CombinePifPafIntoFiveVerticalParts(MaskGroupingTransform):
method __init__ (line 231) | def __init__(self):
class CombinePifPafIntoFiveBodyMasks (line 235) | class CombinePifPafIntoFiveBodyMasks(MaskGroupingTransform):
method __init__ (line 257) | def __init__(self):
class CombinePifPafIntoSixVerticalParts (line 261) | class CombinePifPafIntoSixVerticalParts(MaskGroupingTransform):
method __init__ (line 279) | def __init__(self):
class CombinePifPafIntoSixBodyMasks (line 283) | class CombinePifPafIntoSixBodyMasks(MaskGroupingTransform):
method __init__ (line 302) | def __init__(self):
class CombinePifPafIntoSixBodyMasksSum (line 306) | class CombinePifPafIntoSixBodyMasksSum(MaskGroupingTransform):
method __init__ (line 325) | def __init__(self):
class CombinePifPafIntoSixBodyMasksSimilarToEight (line 329) | class CombinePifPafIntoSixBodyMasksSimilarToEight(MaskGroupingTransform):
method __init__ (line 348) | def __init__(self):
class CombinePifPafIntoEightBodyMasks (line 352) | class CombinePifPafIntoEightBodyMasks(MaskGroupingTransform):
method __init__ (line 373) | def __init__(self):
class CombinePifPafIntoEightVerticalBodyMasks (line 378) | class CombinePifPafIntoEightVerticalBodyMasks(MaskGroupingTransform):
method __init__ (line 399) | def __init__(self):
class CombinePifPafIntoTenMSBodyMasks (line 403) | class CombinePifPafIntoTenMSBodyMasks(MaskGroupingTransform):
method __init__ (line 442) | def __init__(self):
class CombinePifPafIntoSevenVerticalBodyMasks (line 446) | class CombinePifPafIntoSevenVerticalBodyMasks(MaskGroupingTransform):
method __init__ (line 460) | def __init__(self):
class CombinePifPafIntoSevenBodyMasksSimilarToEight (line 464) | class CombinePifPafIntoSevenBodyMasksSimilarToEight(MaskGroupingTransform):
method __init__ (line 483) | def __init__(self):
class CombinePifPafIntoElevenBodyMasks (line 488) | class CombinePifPafIntoElevenBodyMasks(MaskGroupingTransform):
method __init__ (line 509) | def __init__(self):
class CombinePifPafIntoFourteenBodyMasks (line 513) | class CombinePifPafIntoFourteenBodyMasks(MaskGroupingTransform):
method __init__ (line 533) | def __init__(self):
FILE: torchreid/data/sampler.py
class RandomIdentitySampler (line 11) | class RandomIdentitySampler(Sampler):
method __init__ (line 20) | def __init__(self, data_source, batch_size, num_instances):
method __iter__ (line 45) | def __iter__(self):
method __len__ (line 75) | def __len__(self):
function build_train_sampler (line 79) | def build_train_sampler(
FILE: torchreid/data/transforms.py
class NpToTensor (line 15) | class NpToTensor(object):
method __call__ (line 16) | def __call__(self, masks):
method __repr__ (line 20) | def __repr__(self):
function build_transforms (line 24) | def build_transforms(
FILE: torchreid/engine/engine.py
class Engine (line 19) | class Engine(object):
method __init__ (line 31) | def __init__(self, config, datamanager, writer, engine_state, use_gpu=...
method register_model (line 52) | def register_model(self, name='model', model=None, optim=None, sched=N...
method get_model_names (line 72) | def get_model_names(self, names=None):
method save_model (line 83) | def save_model(self, epoch, cmc, mAP, ssmd, save_dir, is_best=False):
method set_model_mode (line 104) | def set_model_mode(self, mode='train', names=None):
method get_current_lr (line 114) | def get_current_lr(self, names=None):
method update_lr (line 119) | def update_lr(self, names=None):
method run (line 127) | def run(
method train (line 255) | def train(self, fixbase_epoch=0, open_layers=None):
method forward_backward (line 279) | def forward_backward(self, data):
method test (line 282) | def test(
method _evaluate (line 389) | def _evaluate(
method _feature_extraction (line 491) | def _feature_extraction(self, data_loader):
method compute_loss (line 512) | def compute_loss(self, criterion, outputs, targets, **kwargs):
method extract_features (line 519) | def extract_features(self, input):
method parse_data_for_train (line 522) | def parse_data_for_train(self, data):
method parse_data_for_eval (line 527) | def parse_data_for_eval(self, data):
method two_stepped_transfer_learning (line 533) | def two_stepped_transfer_learning(
method normalize (line 558) | def normalize(self, features):
FILE: torchreid/engine/image/part_based_engine.py
class ImagePartBasedEngine (line 22) | class ImagePartBasedEngine(Engine):
method __init__ (line 25) | def __init__(
method forward_backward (line 77) | def forward_backward(self, data):
method combine_losses (line 107) | def combine_losses(self, visibility_scores_dict, embeddings_dict, id_c...
method _feature_extraction (line 132) | def _feature_extraction(self, data_loader):
method _evaluate (line 169) | def _evaluate(
method compute_pixels_cls_accuracy (line 297) | def compute_pixels_cls_accuracy(self, target_masks, pixels_cls_scores):
method display_individual_parts_ranking_performances (line 308) | def display_individual_parts_ranking_performances(self, body_parts_dis...
method parse_data_for_train (line 341) | def parse_data_for_train(self, data):
method parse_data_for_eval (line 358) | def parse_data_for_eval(self, data):
method extract_test_embeddings (line 365) | def extract_test_embeddings(self, model_output):
FILE: torchreid/engine/image/softmax.py
class ImageSoftmaxEngine (line 9) | class ImageSoftmaxEngine(Engine):
method __init__ (line 55) | def __init__(
method forward_backward (line 78) | def forward_backward(self, data):
FILE: torchreid/engine/image/triplet.py
class ImageTripletEngine (line 9) | class ImageTripletEngine(Engine):
method __init__ (line 61) | def __init__(
method forward_backward (line 91) | def forward_backward(self, data):
FILE: torchreid/engine/video/softmax.py
class VideoSoftmaxEngine (line 7) | class VideoSoftmaxEngine(ImageSoftmaxEngine):
method __init__ (line 59) | def __init__(
method parse_data_for_train (line 83) | def parse_data_for_train(self, data):
method extract_features (line 98) | def extract_features(self, input):
FILE: torchreid/engine/video/triplet.py
class VideoTripletEngine (line 7) | class VideoTripletEngine(ImageTripletEngine, VideoSoftmaxEngine):
method __init__ (line 66) | def __init__(
FILE: torchreid/hyperparameter/custom_hyperparameter_optimizer.py
function build_datamanager (line 21) | def build_datamanager(cfg):
function build_engine (line 28) | def build_engine(cfg, datamanager, model, optimizer, scheduler, writer):
function reset_config (line 108) | def reset_config(cfg, args):
function main (line 119) | def main():
FILE: torchreid/hyperparameter/hyperparameter_optimizer.py
function job_complete_callback (line 8) | def job_complete_callback(
FILE: torchreid/losses/GiLt_loss.py
class GiLtLoss (line 11) | class GiLtLoss(nn.Module):
method __init__ (line 27) | def __init__(self,
method forward (line 45) | def forward(self, embeddings_dict, visibility_scores_dict, id_cls_scor...
method compute_triplet_loss (line 95) | def compute_triplet_loss(self, embeddings, visibility_scores, pids):
method compute_id_cls_loss (line 105) | def compute_id_cls_loss(self, id_cls_scores, visibility_scores, pids):
FILE: torchreid/losses/__init__.py
function init_part_based_triplet_loss (line 24) | def init_part_based_triplet_loss(name, **kwargs):
function deep_supervision (line 35) | def deep_supervision(criterion, xs, y):
FILE: torchreid/losses/body_part_attention_loss.py
class BodyPartAttentionLoss (line 11) | class BodyPartAttentionLoss(nn.Module):
method __init__ (line 17) | def __init__(self, loss_type='cl', label_smoothing=0.1, use_gpu=False):
method forward (line 31) | def forward(self, pixels_cls_scores, targets):
method compute_pixels_cls_loss (line 45) | def compute_pixels_cls_loss(self, pixels_cls_scores, targets):
FILE: torchreid/losses/cross_entropy_loss.py
class CrossEntropyLoss (line 6) | class CrossEntropyLoss(nn.Module):
method __init__ (line 29) | def __init__(self, eps=0.1, label_smooth=True):
method forward (line 34) | def forward(self, inputs, targets, weights=None):
FILE: torchreid/losses/hard_mine_triplet_loss.py
class TripletLoss (line 6) | class TripletLoss(nn.Module):
method __init__ (line 18) | def __init__(self, margin=0.3):
method forward (line 23) | def forward(self, inputs, targets):
method compute_hard_mine_triplet_loss (line 36) | def compute_hard_mine_triplet_loss(self, dist, inputs, targets):
method compute_dist_matrix (line 49) | def compute_dist_matrix(self, inputs):
FILE: torchreid/losses/inter_parts_triplet_loss.py
class InterPartsTripletLoss (line 6) | class InterPartsTripletLoss(PartAveragedTripletLoss):
method __init__ (line 8) | def __init__(self, **kwargs):
method forward (line 11) | def forward(self, body_parts_features, targets, n_iter=0, parts_visibi...
method compute_mixed_body_parts_dist_matrices (line 16) | def compute_mixed_body_parts_dist_matrices(self, body_parts_features):
method hard_mine_triplet_loss (line 21) | def hard_mine_triplet_loss(self, dist, targets): # TODO extract code f...
FILE: torchreid/losses/part_averaged_triplet_loss.py
class PartAveragedTripletLoss (line 10) | class PartAveragedTripletLoss(nn.Module):
method __init__ (line 26) | def __init__(self, margin=0.3, epsilon=1e-16, writer=None):
method forward (line 35) | def forward(self, part_based_embeddings, labels, parts_visibility=None):
method _combine_part_based_dist_matrices (line 67) | def _combine_part_based_dist_matrices(self, part_based_pairwise_dist, ...
method _part_based_pairwise_distance_matrix (line 77) | def _part_based_pairwise_distance_matrix(self, embeddings, squared=Fal...
method _hard_mine_triplet_loss (line 95) | def _hard_mine_triplet_loss(self, batch_pairwise_dist, labels, margin):
method hard_margin_triplet_loss (line 175) | def hard_margin_triplet_loss(self, margin, valid_hardest_dist, valid_t...
method soft_margin_triplet_loss (line 182) | def soft_margin_triplet_loss(self, margin, valid_hardest_dist, valid_t...
method _get_anchor_positive_mask (line 198) | def _get_anchor_positive_mask(labels):
method _get_anchor_negative_mask (line 215) | def _get_anchor_negative_mask(labels):
FILE: torchreid/losses/part_individual_triplet_loss.py
class PartIndividualTripletLoss (line 7) | class PartIndividualTripletLoss(PartAveragedTripletLoss):
method __init__ (line 20) | def __init__(self, **kwargs):
method _combine_part_based_dist_matrices (line 23) | def _combine_part_based_dist_matrices(self, part_based_pairwise_dist, ...
FILE: torchreid/losses/part_max_min_triplet_loss.py
class PartMaxMinTripletLoss (line 9) | class PartMaxMinTripletLoss(PartAveragedTripletLoss):
method __init__ (line 11) | def __init__(self, **kwargs):
method _combine_part_based_dist_matrices (line 14) | def _combine_part_based_dist_matrices(self, part_based_pairwise_dist, ...
FILE: torchreid/losses/part_max_triplet_loss.py
class PartMaxTripletLoss (line 7) | class PartMaxTripletLoss(PartAveragedTripletLoss):
method __init__ (line 9) | def __init__(self, **kwargs):
method _combine_part_based_dist_matrices (line 12) | def _combine_part_based_dist_matrices(self, part_based_pairwise_dist, ...
FILE: torchreid/losses/part_min_triplet_loss.py
class PartMinTripletLoss (line 9) | class PartMinTripletLoss(PartAveragedTripletLoss):
method __init__ (line 11) | def __init__(self, **kwargs):
method _combine_part_based_dist_matrices (line 14) | def _combine_part_based_dist_matrices(self, part_based_pairwise_dist, ...
FILE: torchreid/losses/part_random_max_min_triplet_loss.py
class PartRandomMaxMinTripletLoss (line 9) | class PartRandomMaxMinTripletLoss(PartAveragedTripletLoss):
method __init__ (line 11) | def __init__(self, **kwargs):
method _combine_part_based_dist_matrices (line 14) | def _combine_part_based_dist_matrices(self, part_based_pairwise_dist, ...
FILE: torchreid/metrics/accuracy.py
function accuracy (line 4) | def accuracy(output, target, topk=(1, )):
FILE: torchreid/metrics/distance.py
function compute_distance_matrix (line 9) | def compute_distance_matrix(input1, input2, metric='euclidean'):
function euclidean_squared_distance (line 52) | def euclidean_squared_distance(input1, input2):
function cosine_distance (line 71) | def cosine_distance(input1, input2):
function compute_distance_matrix_using_bp_features (line 87) | def compute_distance_matrix_using_bp_features(qf, gf, qf_parts_visibilit...
function _compute_distance_matrix_using_bp_features (line 102) | def _compute_distance_matrix_using_bp_features(qf, gf, dist_combine_stra...
function _compute_distance_matrix_using_bp_features_and_masks (line 131) | def _compute_distance_matrix_using_bp_features_and_masks(qf, gf, qf_part...
function _compute_distance_matrix_using_bp_features_and_visibility_scores (line 181) | def _compute_distance_matrix_using_bp_features_and_visibility_scores(qf,...
function _compute_body_parts_dist_matrices (line 222) | def _compute_body_parts_dist_matrices(qf, gf, metric='euclidean'):
FILE: torchreid/metrics/rank.py
function eval_cuhk03 (line 17) | def eval_cuhk03(distmat, q_pids, g_pids, q_camids, g_camids, max_rank):
function eval_market1501 (line 97) | def eval_market1501(distmat, q_pids, g_pids, q_camids, g_camids, max_rank):
function evaluate_py (line 162) | def evaluate_py(
function evaluate_rank (line 173) | def evaluate_rank(
FILE: torchreid/metrics/rank_cylib/setup.py
function numpy_include (line 7) | def numpy_include():
FILE: torchreid/models/__init__.py
function show_avai_models (line 92) | def show_avai_models():
function build_model (line 102) | def build_model(
FILE: torchreid/models/bpbreid.py
class BPBreID (line 15) | class BPBreID(nn.Module):
method __init__ (line 18) | def __init__(self, num_classes, pretrained, loss, model_cfg, horizonta...
method init_dim_reduce_layers (line 84) | def init_dim_reduce_layers(self, dim_reduce_mode, spatial_feature_size...
method forward (line 116) | def forward(self, images, external_parts_masks=None):
method parts_identity_classification (line 261) | def parts_identity_classification(self, D, N, parts_embeddings):
class BeforePoolingDimReduceLayer (line 286) | class BeforePoolingDimReduceLayer(nn.Module):
method __init__ (line 287) | def __init__(self, input_dim, output_dim):
method forward (line 301) | def forward(self, x):
method _init_params (line 304) | def _init_params(self):
class AfterPoolingDimReduceLayer (line 324) | class AfterPoolingDimReduceLayer(nn.Module):
method __init__ (line 325) | def __init__(self, input_dim, output_dim, dropout_p=None):
method forward (line 342) | def forward(self, x):
method _init_params (line 352) | def _init_params(self):
class PixelToPartClassifier (line 376) | class PixelToPartClassifier(nn.Module):
method __init__ (line 377) | def __init__(self, dim_reduce_output, parts_num):
method forward (line 383) | def forward(self, x):
method _init_params (line 387) | def _init_params(self):
class BNClassifier (line 398) | class BNClassifier(nn.Module):
method __init__ (line 400) | def __init__(self, in_dim, class_num):
method forward (line 412) | def forward(self, x):
method _init_params (line 417) | def _init_params(self):
function init_part_attention_pooling_head (line 432) | def init_part_attention_pooling_head(normalization, pooling, dim_reduce_...
class GlobalMaskWeightedPoolingHead (line 444) | class GlobalMaskWeightedPoolingHead(nn.Module):
method __init__ (line 445) | def __init__(self, depth, normalization='identity'):
method forward (line 458) | def forward(self, features, part_masks):
method _init_params (line 470) | def _init_params(self):
class GlobalMaxPoolingHead (line 481) | class GlobalMaxPoolingHead(GlobalMaskWeightedPoolingHead):
class GlobalAveragePoolingHead (line 485) | class GlobalAveragePoolingHead(GlobalMaskWeightedPoolingHead):
class GlobalWeightedAveragePoolingHead (line 489) | class GlobalWeightedAveragePoolingHead(GlobalMaskWeightedPoolingHead):
method forward (line 490) | def forward(self, features, part_masks):
function bpbreid (line 510) | def bpbreid(num_classes, loss='part_based', pretrained=True, config=None...
function pcb (line 521) | def pcb(num_classes, loss='part_based', pretrained=True, config=None, **...
function bot (line 535) | def bot(num_classes, loss='part_based', pretrained=True, config=None, **...
FILE: torchreid/models/compact_bilinear_pooling.py
function CountSketchFn_forward (line 7) | def CountSketchFn_forward(h, s, output_size, x, force_cpu_scatter_add=Fa...
function CountSketchFn_backward (line 30) | def CountSketchFn_backward(h, s, x_size, grad_output):
class CountSketchFn (line 41) | class CountSketchFn(Function):
method forward (line 44) | def forward(ctx, h, s, output_size, x, force_cpu_scatter_add=False):
method backward (line 53) | def backward(ctx, grad_output):
class CountSketch (line 60) | class CountSketch(nn.Module):
method __init__ (line 86) | def __init__(self, input_size, output_size, h=None, s=None):
method forward (line 110) | def forward(self, x):
function ComplexMultiply_forward (line 118) | def ComplexMultiply_forward(X_re, X_im, Y_re, Y_im):
function ComplexMultiply_backward (line 124) | def ComplexMultiply_backward(X_re, X_im, Y_re, Y_im, grad_Z_re, grad_Z_im):
class ComplexMultiply (line 132) | class ComplexMultiply(torch.autograd.Function):
method forward (line 135) | def forward(ctx, X_re, X_im, Y_re, Y_im):
method backward (line 140) | def backward(ctx, grad_Z_re, grad_Z_im):
class CompactBilinearPoolingFn (line 145) | class CompactBilinearPoolingFn(Function):
method forward (line 148) | def forward(ctx, h1, s1, h2, s2, output_size, x, y, force_cpu_scatter_...
method backward (line 180) | def backward(ctx, grad_output):
class CompactBilinearPooling (line 229) | class CompactBilinearPooling(nn.Module):
method __init__ (line 260) | def __init__(self, input1_size, input2_size, output_size, h1=None, s1=...
method forward (line 268) | def forward(self, x, y=None):
FILE: torchreid/models/densenet.py
class _DenseLayer (line 29) | class _DenseLayer(nn.Sequential):
method __init__ (line 31) | def __init__(self, num_input_features, growth_rate, bn_size, drop_rate):
method forward (line 60) | def forward(self, x):
class _DenseBlock (line 69) | class _DenseBlock(nn.Sequential):
method __init__ (line 71) | def __init__(
class _Transition (line 83) | class _Transition(nn.Sequential):
method __init__ (line 85) | def __init__(self, num_input_features, num_output_features):
class DenseNet (line 102) | class DenseNet(nn.Module):
method __init__ (line 116) | def __init__(
method _construct_fc_layer (line 190) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method _init_params (line 221) | def _init_params(self):
method forward (line 240) | def forward(self, x):
function init_pretrained_weights (line 262) | def init_pretrained_weights(model, model_url):
function densenet121 (line 303) | def densenet121(num_classes, loss='softmax', pretrained=True, **kwargs):
function densenet169 (line 319) | def densenet169(num_classes, loss='softmax', pretrained=True, **kwargs):
function densenet201 (line 335) | def densenet201(num_classes, loss='softmax', pretrained=True, **kwargs):
function densenet161 (line 351) | def densenet161(num_classes, loss='softmax', pretrained=True, **kwargs):
function densenet121_fc512 (line 367) | def densenet121_fc512(num_classes, loss='softmax', pretrained=True, **kw...
FILE: torchreid/models/hacnn.py
class ConvBlock (line 9) | class ConvBlock(nn.Module):
method __init__ (line 22) | def __init__(self, in_c, out_c, k, s=1, p=0):
method forward (line 27) | def forward(self, x):
class InceptionA (line 31) | class InceptionA(nn.Module):
method __init__ (line 33) | def __init__(self, in_channels, out_channels):
method forward (line 54) | def forward(self, x):
class InceptionB (line 63) | class InceptionB(nn.Module):
method __init__ (line 65) | def __init__(self, in_channels, out_channels):
method forward (line 83) | def forward(self, x):
class SpatialAttn (line 91) | class SpatialAttn(nn.Module):
method __init__ (line 94) | def __init__(self):
method forward (line 99) | def forward(self, x):
class ChannelAttn (line 115) | class ChannelAttn(nn.Module):
method __init__ (line 118) | def __init__(self, in_channels, reduction_rate=16):
method forward (line 124) | def forward(self, x):
class SoftAttn (line 133) | class SoftAttn(nn.Module):
method __init__ (line 141) | def __init__(self, in_channels):
method forward (line 147) | def forward(self, x):
class HardAttn (line 155) | class HardAttn(nn.Module):
method __init__ (line 158) | def __init__(self, in_channels):
method init_params (line 163) | def init_params(self):
method forward (line 171) | def forward(self, x):
class HarmAttn (line 180) | class HarmAttn(nn.Module):
method __init__ (line 183) | def __init__(self, in_channels):
method forward (line 188) | def forward(self, x):
class HACNN (line 194) | class HACNN(nn.Module):
method __init__ (line 210) | def __init__(
method init_scale_factors (line 271) | def init_scale_factors(self):
method stn (line 287) | def stn(self, x, theta):
method transform_theta (line 297) | def transform_theta(self, theta_i, region_idx):
method forward (line 307) | def forward(self, x):
FILE: torchreid/models/hrnet.py
function get_hrnet_config (line 26) | def get_hrnet_config():
function conv3x3 (line 61) | def conv3x3(in_planes, out_planes, stride=1):
class BasicBlock (line 67) | class BasicBlock(nn.Module):
method __init__ (line 70) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 80) | def forward(self, x):
class Bottleneck (line 99) | class Bottleneck(nn.Module):
method __init__ (line 102) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 117) | def forward(self, x):
class HighResolutionModule (line 140) | class HighResolutionModule(nn.Module):
method __init__ (line 141) | def __init__(self, num_branches, blocks, num_blocks, num_inchannels,
method _check_branches (line 158) | def _check_branches(self, num_branches, blocks, num_blocks,
method _make_one_branch (line 178) | def _make_one_branch(self, branch_index, block, num_blocks, num_channels,
method _make_branches (line 202) | def _make_branches(self, num_branches, block, num_blocks, num_channels):
method _make_fuse_layers (line 211) | def _make_fuse_layers(self):
method get_num_inchannels (line 259) | def get_num_inchannels(self):
method forward (line 262) | def forward(self, x):
class ConvBlock (line 288) | class ConvBlock(nn.Module):
method __init__ (line 289) | def __init__(self, in_c, out_c, k, s=1, p=0):
method forward (line 295) | def forward(self, x):
function weights_init_kaiming (line 299) | def weights_init_kaiming(m):
class HighResolutionNet (line 314) | class HighResolutionNet(nn.Module):
method __init__ (line 316) | def __init__(self, cfg, enable_dim_reduction, dim_reduction_channels, ...
method _make_incre_channel_nin (line 382) | def _make_incre_channel_nin(self):
method _make_head (line 400) | def _make_head(self, pre_stage_channels):
method _make_transition_layer (line 449) | def _make_transition_layer(
method _make_layer (line 485) | def _make_layer(self, block, inplanes, planes, blocks, stride=1):
method _make_stage (line 502) | def _make_stage(self, layer_config, num_inchannels,
method forward (line 532) | def forward(self, x):
method random_init (line 578) | def random_init(self):
method load_param (line 588) | def load_param(self, pretrained_path):
function init_pretrained_weights (line 605) | def init_pretrained_weights(model, pretrain_path, model_key):
function hrnet32 (line 611) | def hrnet32(num_classes, loss='part_based', pretrained=True, enable_dim_...
FILE: torchreid/models/inceptionresnetv2.py
class BasicConv2d (line 37) | class BasicConv2d(nn.Module):
method __init__ (line 39) | def __init__(self, in_planes, out_planes, kernel_size, stride, padding...
method forward (line 57) | def forward(self, x):
class Mixed_5b (line 64) | class Mixed_5b(nn.Module):
method __init__ (line 66) | def __init__(self):
method forward (line 87) | def forward(self, x):
class Block35 (line 96) | class Block35(nn.Module):
method __init__ (line 98) | def __init__(self, scale=1.0):
method forward (line 119) | def forward(self, x):
class Mixed_6a (line 130) | class Mixed_6a(nn.Module):
method __init__ (line 132) | def __init__(self):
method forward (line 145) | def forward(self, x):
class Block17 (line 153) | class Block17(nn.Module):
method __init__ (line 155) | def __init__(self, scale=1.0):
method forward (line 175) | def forward(self, x):
class Mixed_7a (line 185) | class Mixed_7a(nn.Module):
method __init__ (line 187) | def __init__(self):
method forward (line 208) | def forward(self, x):
class Block8 (line 217) | class Block8(nn.Module):
method __init__ (line 219) | def __init__(self, scale=1.0, noReLU=False):
method forward (line 241) | def forward(self, x):
class InceptionResNetV2 (line 255) | class InceptionResNetV2(nn.Module):
method __init__ (line 266) | def __init__(self, num_classes, loss='softmax', **kwargs):
method load_imagenet_weights (line 309) | def load_imagenet_weights(self):
method featuremaps (line 321) | def featuremaps(self, x):
method forward (line 339) | def forward(self, x):
function inceptionresnetv2 (line 357) | def inceptionresnetv2(num_classes, loss='softmax', pretrained=True, **kw...
FILE: torchreid/models/inceptionv4.py
class BasicConv2d (line 37) | class BasicConv2d(nn.Module):
method __init__ (line 39) | def __init__(self, in_planes, out_planes, kernel_size, stride, padding...
method forward (line 57) | def forward(self, x):
class Mixed_3a (line 64) | class Mixed_3a(nn.Module):
method __init__ (line 66) | def __init__(self):
method forward (line 71) | def forward(self, x):
class Mixed_4a (line 78) | class Mixed_4a(nn.Module):
method __init__ (line 80) | def __init__(self):
method forward (line 95) | def forward(self, x):
class Mixed_5a (line 102) | class Mixed_5a(nn.Module):
method __init__ (line 104) | def __init__(self):
method forward (line 109) | def forward(self, x):
class Inception_A (line 116) | class Inception_A(nn.Module):
method __init__ (line 118) | def __init__(self):
method forward (line 138) | def forward(self, x):
class Reduction_A (line 147) | class Reduction_A(nn.Module):
method __init__ (line 149) | def __init__(self):
method forward (line 161) | def forward(self, x):
class Inception_B (line 169) | class Inception_B(nn.Module):
method __init__ (line 171) | def __init__(self):
method forward (line 206) | def forward(self, x):
class Reduction_B (line 215) | class Reduction_B(nn.Module):
method __init__ (line 217) | def __init__(self):
method forward (line 237) | def forward(self, x):
class Inception_C (line 245) | class Inception_C(nn.Module):
method __init__ (line 247) | def __init__(self):
method forward (line 279) | def forward(self, x):
class InceptionV4 (line 300) | class InceptionV4(nn.Module):
method __init__ (line 311) | def __init__(self, num_classes, loss, **kwargs):
method forward (line 342) | def forward(self, x):
function init_pretrained_weights (line 360) | def init_pretrained_weights(model, model_url):
function inceptionv4 (line 376) | def inceptionv4(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/models/mlfn.py
class MLFNBlock (line 16) | class MLFNBlock(nn.Module):
method __init__ (line 18) | def __init__(
method forward (line 64) | def forward(self, x):
class MLFN (line 98) | class MLFN(nn.Module):
method __init__ (line 109) | def __init__(
method init_params (line 196) | def init_params(self):
method forward (line 212) | def forward(self, x):
function init_pretrained_weights (line 244) | def init_pretrained_weights(model, model_url):
function mlfn (line 260) | def mlfn(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/models/mobilenetv2.py
class ConvBlock (line 18) | class ConvBlock(nn.Module):
method __init__ (line 33) | def __init__(self, in_c, out_c, k, s=1, p=0, g=1):
method forward (line 40) | def forward(self, x):
class Bottleneck (line 44) | class Bottleneck(nn.Module):
method __init__ (line 46) | def __init__(self, in_channels, out_channels, expansion_factor, stride...
method forward (line 59) | def forward(self, x):
class MobileNetV2 (line 69) | class MobileNetV2(nn.Module):
method __init__ (line 81) | def __init__(
method _make_layer (line 128) | def _make_layer(self, block, t, c, n, s):
method _construct_fc_layer (line 140) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method _init_params (line 171) | def _init_params(self):
method featuremaps (line 190) | def featuremaps(self, x):
method forward (line 202) | def forward(self, x):
function init_pretrained_weights (line 223) | def init_pretrained_weights(model, model_url):
function mobilenetv2_x1_0 (line 239) | def mobilenetv2_x1_0(num_classes, loss, pretrained=True, **kwargs):
function mobilenetv2_x1_4 (line 258) | def mobilenetv2_x1_4(num_classes, loss, pretrained=True, **kwargs):
FILE: torchreid/models/mudeep.py
class ConvBlock (line 9) | class ConvBlock(nn.Module):
method __init__ (line 22) | def __init__(self, in_c, out_c, k, s, p):
method forward (line 27) | def forward(self, x):
class ConvLayers (line 31) | class ConvLayers(nn.Module):
method __init__ (line 34) | def __init__(self):
method forward (line 40) | def forward(self, x):
class MultiScaleA (line 47) | class MultiScaleA(nn.Module):
method __init__ (line 50) | def __init__(self):
method forward (line 67) | def forward(self, x):
class Reduction (line 76) | class Reduction(nn.Module):
method __init__ (line 79) | def __init__(self):
method forward (line 89) | def forward(self, x):
class MultiScaleB (line 97) | class MultiScaleB(nn.Module):
method __init__ (line 100) | def __init__(self):
method forward (line 120) | def forward(self, x):
class Fusion (line 128) | class Fusion(nn.Module):
method __init__ (line 131) | def __init__(self):
method forward (line 142) | def forward(self, x1, x2, x3, x4):
class MuDeep (line 151) | class MuDeep(nn.Module):
method __init__ (line 162) | def __init__(self, num_classes, loss='softmax', **kwargs):
method featuremaps (line 184) | def featuremaps(self, x):
method forward (line 192) | def forward(self, x):
FILE: torchreid/models/nasnet.py
class MaxPoolPad (line 52) | class MaxPoolPad(nn.Module):
method __init__ (line 54) | def __init__(self):
method forward (line 59) | def forward(self, x):
class AvgPoolPad (line 66) | class AvgPoolPad(nn.Module):
method __init__ (line 68) | def __init__(self, stride=2, padding=1):
method forward (line 75) | def forward(self, x):
class SeparableConv2d (line 82) | class SeparableConv2d(nn.Module):
method __init__ (line 84) | def __init__(
method forward (line 107) | def forward(self, x):
class BranchSeparables (line 113) | class BranchSeparables(nn.Module):
method __init__ (line 115) | def __init__(
method forward (line 142) | def forward(self, x):
class BranchSeparablesStem (line 157) | class BranchSeparablesStem(nn.Module):
method __init__ (line 159) | def __init__(
method forward (line 184) | def forward(self, x):
class BranchSeparablesReduction (line 194) | class BranchSeparablesReduction(BranchSeparables):
method __init__ (line 196) | def __init__(
method forward (line 211) | def forward(self, x):
class CellStem0 (line 223) | class CellStem0(nn.Module):
method __init__ (line 225) | def __init__(self, stem_filters, num_filters=42):
method forward (line 272) | def forward(self, x):
class CellStem1 (line 300) | class CellStem1(nn.Module):
method __init__ (line 302) | def __init__(self, stem_filters, num_filters):
method forward (line 419) | def forward(self, x_conv0, x_stem_0):
class FirstCell (line 458) | class FirstCell(nn.Module):
method __init__ (line 460) | def __init__(
method forward (line 536) | def forward(self, x, x_prev):
class NormalCell (line 577) | class NormalCell(nn.Module):
method __init__ (line 579) | def __init__(
method forward (line 643) | def forward(self, x, x_prev):
class ReductionCell0 (line 674) | class ReductionCell0(nn.Module):
method __init__ (line 676) | def __init__(
method forward (line 737) | def forward(self, x, x_prev):
class ReductionCell1 (line 766) | class ReductionCell1(nn.Module):
method __init__ (line 768) | def __init__(
method forward (line 862) | def forward(self, x, x_prev):
class NASNetAMobile (line 891) | class NASNetAMobile(nn.Module):
method __init__ (line 902) | def __init__(
method _init_params (line 1041) | def _init_params(self):
method features (line 1060) | def features(self, input):
method forward (line 1094) | def forward(self, input):
function init_pretrained_weights (line 1110) | def init_pretrained_weights(model, model_url):
function nasnetamobile (line 1126) | def nasnetamobile(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/models/osnet.py
class ConvLayer (line 28) | class ConvLayer(nn.Module):
method __init__ (line 31) | def __init__(
method forward (line 57) | def forward(self, x):
class Conv1x1 (line 64) | class Conv1x1(nn.Module):
method __init__ (line 67) | def __init__(self, in_channels, out_channels, stride=1, groups=1):
method forward (line 81) | def forward(self, x):
class Conv1x1Linear (line 88) | class Conv1x1Linear(nn.Module):
method __init__ (line 91) | def __init__(self, in_channels, out_channels, stride=1):
method forward (line 98) | def forward(self, x):
class Conv3x3 (line 104) | class Conv3x3(nn.Module):
method __init__ (line 107) | def __init__(self, in_channels, out_channels, stride=1, groups=1):
method forward (line 121) | def forward(self, x):
class LightConv3x3 (line 128) | class LightConv3x3(nn.Module):
method __init__ (line 134) | def __init__(self, in_channels, out_channels):
method forward (line 151) | def forward(self, x):
class ChannelGate (line 162) | class ChannelGate(nn.Module):
method __init__ (line 165) | def __init__(
method forward (line 208) | def forward(self, x):
class OSBlock (line 223) | class OSBlock(nn.Module):
method __init__ (line 226) | def __init__(
method forward (line 262) | def forward(self, x):
class OSNet (line 282) | class OSNet(nn.Module):
method __init__ (line 291) | def __init__(
method _make_layer (line 344) | def _make_layer(
method _construct_fc_layer (line 369) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method _init_params (line 390) | def _init_params(self):
method featuremaps (line 412) | def featuremaps(self, x):
method forward (line 421) | def forward(self, x, return_featuremaps=False):
function init_pretrained_weights (line 440) | def init_pretrained_weights(model, key=''):
function osnet_x1_0 (line 521) | def osnet_x1_0(num_classes=1000, pretrained=True, loss='softmax', **kwar...
function osnet_x0_75 (line 536) | def osnet_x0_75(num_classes=1000, pretrained=True, loss='softmax', **kwa...
function osnet_x0_5 (line 551) | def osnet_x0_5(num_classes=1000, pretrained=True, loss='softmax', **kwar...
function osnet_x0_25 (line 566) | def osnet_x0_25(num_classes=1000, pretrained=True, loss='softmax', **kwa...
function osnet_ibn_x1_0 (line 581) | def osnet_ibn_x1_0(
FILE: torchreid/models/osnet_ain.py
class ConvLayer (line 18) | class ConvLayer(nn.Module):
method __init__ (line 21) | def __init__(
method forward (line 47) | def forward(self, x):
class Conv1x1 (line 53) | class Conv1x1(nn.Module):
method __init__ (line 56) | def __init__(self, in_channels, out_channels, stride=1, groups=1):
method forward (line 70) | def forward(self, x):
class Conv1x1Linear (line 76) | class Conv1x1Linear(nn.Module):
method __init__ (line 79) | def __init__(self, in_channels, out_channels, stride=1, bn=True):
method forward (line 88) | def forward(self, x):
class Conv3x3 (line 95) | class Conv3x3(nn.Module):
method __init__ (line 98) | def __init__(self, in_channels, out_channels, stride=1, groups=1):
method forward (line 112) | def forward(self, x):
class LightConv3x3 (line 118) | class LightConv3x3(nn.Module):
method __init__ (line 124) | def __init__(self, in_channels, out_channels):
method forward (line 141) | def forward(self, x):
class LightConvStream (line 148) | class LightConvStream(nn.Module):
method __init__ (line 151) | def __init__(self, in_channels, out_channels, depth):
method forward (line 162) | def forward(self, x):
class ChannelGate (line 169) | class ChannelGate(nn.Module):
method __init__ (line 172) | def __init__(
method forward (line 215) | def forward(self, x):
class OSBlock (line 230) | class OSBlock(nn.Module):
method __init__ (line 233) | def __init__(self, in_channels, out_channels, reduction=4, T=4, **kwar...
method forward (line 249) | def forward(self, x):
class OSBlockINin (line 263) | class OSBlockINin(nn.Module):
method __init__ (line 266) | def __init__(self, in_channels, out_channels, reduction=4, T=4, **kwar...
method forward (line 283) | def forward(self, x):
class OSNet (line 301) | class OSNet(nn.Module):
method __init__ (line 310) | def __init__(
method _make_layer (line 359) | def _make_layer(self, blocks, layer, in_channels, out_channels):
method _construct_fc_layer (line 366) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method _init_params (line 387) | def _init_params(self):
method featuremaps (line 413) | def featuremaps(self, x):
method forward (line 424) | def forward(self, x, return_featuremaps=False):
function init_pretrained_weights (line 443) | def init_pretrained_weights(model, key=''):
function osnet_ain_x1_0 (line 524) | def osnet_ain_x1_0(
FILE: torchreid/models/pcb.py
function conv3x3 (line 17) | def conv3x3(in_planes, out_planes, stride=1):
class BasicBlock (line 29) | class BasicBlock(nn.Module):
method __init__ (line 32) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 42) | def forward(self, x):
class Bottleneck (line 61) | class Bottleneck(nn.Module):
method __init__ (line 64) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 85) | def forward(self, x):
class DimReduceLayer (line 108) | class DimReduceLayer(nn.Module):
method __init__ (line 110) | def __init__(self, in_channels, out_channels, nonlinear):
method forward (line 127) | def forward(self, x):
class PCB (line 131) | class PCB(nn.Module):
method __init__ (line 143) | def __init__(
method _make_layer (line 188) | def _make_layer(self, block, planes, blocks, stride=1):
method _init_params (line 210) | def _init_params(self):
method featuremaps (line 229) | def featuremaps(self, x):
method forward (line 240) | def forward(self, x):
function init_pretrained_weights (line 267) | def init_pretrained_weights(model, model_url):
function pcb_p6 (line 283) | def pcb_p6(num_classes, loss='softmax', pretrained=True, **kwargs):
function pcb_p4 (line 300) | def pcb_p4(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/models/pvpm.py
function conv3x3 (line 25) | def conv3x3(in_planes, out_planes, stride=1):
class BasicBlock (line 31) | class BasicBlock(nn.Module):
method __init__ (line 34) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 44) | def forward(self, x):
class Bottleneck (line 63) | class Bottleneck(nn.Module):
method __init__ (line 66) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 79) | def forward(self, x):
class DimReduceLayer (line 102) | class DimReduceLayer(nn.Module):
method __init__ (line 104) | def __init__(self, in_channels, out_channels, nonlinear):
method forward (line 117) | def forward(self, x):
class PCB (line 121) | class PCB(nn.Module):
method __init__ (line 133) | def __init__(self, num_classes, loss, block, layers,
method _construct_em_layer (line 165) | def _construct_em_layer(self, fc_dims, input_dim, dropout_p=0.5): # TO...
method _make_layer (line 190) | def _make_layer(self, block, planes, blocks, stride=1):
method _init_params (line 207) | def _init_params(self):
method featuremaps (line 224) | def featuremaps(self, x):
method forward (line 235) | def forward(self, x):
function init_pretrained_weights (line 268) | def init_pretrained_weights(model, model_url):
function pcb_p6 (line 280) | def pcb_p6(num_classes, loss='softmax', pretrained=True, **kwargs):
function pcb_p4 (line 297) | def pcb_p4(num_classes, loss='softmax', pretrained=True, **kwargs):
class Conv1x1_att (line 314) | class Conv1x1_att(nn.Module):
method __init__ (line 317) | def __init__(self, in_channels, out_channels, stride=1, groups=1):
method forward (line 324) | def forward(self, x):
class score_embedding (line 331) | class score_embedding(nn.Module):
method __init__ (line 334) | def __init__(self, in_channels, out_channels):
method forward (line 341) | def forward(self, x):
class Pose_Subnet (line 350) | class Pose_Subnet(nn.Module): # TODO
method __init__ (line 354) | def __init__(self, blocks, in_channels, channels, att_num=1, IN=False,...
method _make_layer (line 371) | def _make_layer(self, block, layer, in_channels, out_channels, reduce_...
method forward (line 386) | def forward(self, x):
method _init_params (line 401) | def _init_params(self):
class pose_guide_att_Resnet (line 422) | class pose_guide_att_Resnet(PCB):
method __init__ (line 423) | def __init__(self, num_classes, loss, block, layers, last_stride=2, pa...
method forward (line 435) | def forward(self, x, pose_map):
function pose_resnet50_256_p4 (line 479) | def pose_resnet50_256_p4(num_classes, loss='softmax', pretrained=True, *...
function pose_resnet50_256_p6 (line 495) | def pose_resnet50_256_p6(num_classes, loss='softmax', pretrained=True, *...
function pose_resnet50_256_p6_pscore_reg (line 511) | def pose_resnet50_256_p6_pscore_reg(num_classes, loss='softmax', pretrai...
function pose_resnet50_256_p4_pscore_reg (line 528) | def pose_resnet50_256_p4_pscore_reg(num_classes, loss='softmax', pretrai...
FILE: torchreid/models/resnet.py
function conv3x3 (line 31) | def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
function conv1x1 (line 45) | def conv1x1(in_planes, out_planes, stride=1):
class BasicBlock (line 52) | class BasicBlock(nn.Module):
method __init__ (line 55) | def __init__(
method forward (line 86) | def forward(self, x):
class Bottleneck (line 105) | class Bottleneck(nn.Module):
method __init__ (line 108) | def __init__(
method forward (line 134) | def forward(self, x):
class ResNet (line 157) | class ResNet(nn.Module):
method __init__ (line 175) | def __init__(
method _make_layer (line 257) | def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
method _construct_fc_layer (line 292) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method _init_params (line 323) | def _init_params(self):
method featuremaps (line 342) | def featuremaps(self, x):
method forward (line 354) | def forward(self, x):
function init_pretrained_weights (line 379) | def init_pretrained_weights(model, model_url):
function resnet18 (line 398) | def resnet18(num_classes, loss='softmax', pretrained=True, **kwargs):
function resnet34 (line 414) | def resnet34(num_classes, loss='softmax', pretrained=True, **kwargs):
function resnet50 (line 430) | def resnet50(num_classes, loss='softmax', pretrained=True, **kwargs):
function resnet101 (line 445) | def resnet101(num_classes, loss='softmax', pretrained=True, **kwargs):
function resnet152 (line 461) | def resnet152(num_classes, loss='softmax', pretrained=True, **kwargs):
function resnext50_32x4d (line 480) | def resnext50_32x4d(num_classes, loss='softmax', pretrained=True, **kwar...
function resnext101_32x8d (line 498) | def resnext101_32x8d(num_classes, loss='softmax', pretrained=True, **kwa...
function resnet50_fc512 (line 521) | def resnet50_fc512(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/models/resnet_fastreid.py
function get_norm (line 36) | def get_norm(norm, out_channels, **kwargs):
class Non_local (line 60) | class Non_local(nn.Module):
method __init__ (line 61) | def __init__(self, in_channels, bn_norm, reduc_ratio=2):
method forward (line 84) | def forward(self, x):
class IBN (line 108) | class IBN(nn.Module):
method __init__ (line 109) | def __init__(self, planes, bn_norm, **kwargs):
method forward (line 117) | def forward(self, x):
class BatchNorm (line 125) | class BatchNorm(nn.BatchNorm2d):
method __init__ (line 126) | def __init__(self, num_features, eps=1e-05, momentum=0.1, weight_freez...
class SELayer (line 135) | class SELayer(nn.Module):
method __init__ (line 136) | def __init__(self, channel, reduction=16):
method forward (line 146) | def forward(self, x):
class BasicBlock (line 153) | class BasicBlock(nn.Module):
method __init__ (line 156) | def __init__(self, inplanes, planes, bn_norm, with_ibn=False, with_se=...
method forward (line 174) | def forward(self, x):
class Bottleneck (line 194) | class Bottleneck(nn.Module):
method __init__ (line 197) | def __init__(self, inplanes, planes, bn_norm, with_ibn=False, with_se=...
method forward (line 218) | def forward(self, x):
class ResNet (line 242) | class ResNet(nn.Module):
method __init__ (line 243) | def __init__(self, last_stride, bn_norm, with_ibn, with_se, with_nl, b...
method _make_layer (line 265) | def _make_layer(self, block, planes, blocks, stride=1, bn_norm="BN", w...
method _build_nonlocal (line 282) | def _build_nonlocal(self, layers, non_layers, bn_norm):
method forward (line 296) | def forward(self, x):
method random_init (line 347) | def random_init(self):
function init_pretrained_weights (line 357) | def init_pretrained_weights(key):
function fastreid_resnet (line 405) | def fastreid_resnet(pretrained=True, **kwargs):
function fastreid_resnet_ibn (line 408) | def fastreid_resnet_ibn(pretrained=True, **kwargs):
function fastreid_resnet_nl (line 411) | def fastreid_resnet_nl(pretrained=True, **kwargs):
function fastreid_resnet_ibn_nl (line 414) | def fastreid_resnet_ibn_nl(pretrained=True, **kwargs):
function build_resnet_backbone (line 417) | def build_resnet_backbone(pretrained=True, with_ibn=False, with_nl=False...
FILE: torchreid/models/resnet_ibn_a.py
function conv3x3 (line 19) | def conv3x3(in_planes, out_planes, stride=1):
class BasicBlock (line 31) | class BasicBlock(nn.Module):
method __init__ (line 34) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 44) | def forward(self, x):
class IBN (line 63) | class IBN(nn.Module):
method __init__ (line 65) | def __init__(self, planes):
method forward (line 73) | def forward(self, x):
class Bottleneck (line 81) | class Bottleneck(nn.Module):
method __init__ (line 84) | def __init__(self, inplanes, planes, ibn=False, stride=1, downsample=N...
method forward (line 108) | def forward(self, x):
class ResNet (line 131) | class ResNet(nn.Module):
method __init__ (line 140) | def __init__(
method _make_layer (line 183) | def _make_layer(self, block, planes, blocks, stride=1):
method _construct_fc_layer (line 208) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method featuremaps (line 239) | def featuremaps(self, x):
method forward (line 250) | def forward(self, x):
function init_pretrained_weights (line 267) | def init_pretrained_weights(model, model_url):
function resnet50_ibn_a (line 283) | def resnet50_ibn_a(num_classes, loss='softmax', pretrained=False, **kwar...
FILE: torchreid/models/resnet_ibn_b.py
function conv3x3 (line 18) | def conv3x3(in_planes, out_planes, stride=1):
class BasicBlock (line 30) | class BasicBlock(nn.Module):
method __init__ (line 33) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 43) | def forward(self, x):
class Bottleneck (line 62) | class Bottleneck(nn.Module):
method __init__ (line 65) | def __init__(self, inplanes, planes, stride=1, downsample=None, IN=Fal...
method forward (line 89) | def forward(self, x):
class ResNet (line 114) | class ResNet(nn.Module):
method __init__ (line 123) | def __init__(
method _make_layer (line 170) | def _make_layer(self, block, planes, blocks, stride=1, IN=False):
method _construct_fc_layer (line 193) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method featuremaps (line 224) | def featuremaps(self, x):
method forward (line 235) | def forward(self, x):
function init_pretrained_weights (line 252) | def init_pretrained_weights(model, model_url):
function resnet50_ibn_b (line 268) | def resnet50_ibn_b(num_classes, loss='softmax', pretrained=False, **kwar...
FILE: torchreid/models/resnetmid.py
function conv3x3 (line 17) | def conv3x3(in_planes, out_planes, stride=1):
class BasicBlock (line 29) | class BasicBlock(nn.Module):
method __init__ (line 32) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 42) | def forward(self, x):
class Bottleneck (line 61) | class Bottleneck(nn.Module):
method __init__ (line 64) | def __init__(self, inplanes, planes, stride=1, downsample=None):
method forward (line 85) | def forward(self, x):
class ResNetMid (line 108) | class ResNetMid(nn.Module):
method __init__ (line 119) | def __init__(
method _make_layer (line 158) | def _make_layer(self, block, planes, blocks, stride=1):
method _construct_fc_layer (line 180) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method _init_params (line 211) | def _init_params(self):
method featuremaps (line 230) | def featuremaps(self, x):
method forward (line 243) | def forward(self, x):
function init_pretrained_weights (line 268) | def init_pretrained_weights(model, model_url):
function resnet50mid (line 295) | def resnet50mid(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/models/senet.py
class SEModule (line 91) | class SEModule(nn.Module):
method __init__ (line 93) | def __init__(self, channels, reduction):
method forward (line 105) | def forward(self, x):
class Bottleneck (line 115) | class Bottleneck(nn.Module):
method forward (line 120) | def forward(self, x):
class SEBottleneck (line 143) | class SEBottleneck(Bottleneck):
method __init__ (line 149) | def __init__(
class SEResNetBottleneck (line 175) | class SEResNetBottleneck(Bottleneck):
method __init__ (line 183) | def __init__(
class SEResNeXtBottleneck (line 208) | class SEResNeXtBottleneck(Bottleneck):
method __init__ (line 212) | def __init__(
class SENet (line 246) | class SENet(nn.Module):
method __init__ (line 262) | def __init__(
method _make_layer (line 416) | def _make_layer(
method _construct_fc_layer (line 453) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method featuremaps (line 485) | def featuremaps(self, x):
method forward (line 493) | def forward(self, x):
function init_pretrained_weights (line 514) | def init_pretrained_weights(model, model_url):
function senet154 (line 530) | def senet154(num_classes, loss='softmax', pretrained=True, **kwargs):
function se_resnet50 (line 549) | def se_resnet50(num_classes, loss='softmax', pretrained=True, **kwargs):
function se_resnet50_fc512 (line 572) | def se_resnet50_fc512(num_classes, loss='softmax', pretrained=True, **kw...
function se_resnet101 (line 595) | def se_resnet101(num_classes, loss='softmax', pretrained=True, **kwargs):
function se_resnet152 (line 618) | def se_resnet152(num_classes, loss='softmax', pretrained=True, **kwargs):
function se_resnext50_32x4d (line 641) | def se_resnext50_32x4d(num_classes, loss='softmax', pretrained=True, **k...
function se_resnext101_32x4d (line 665) | def se_resnext101_32x4d(
FILE: torchreid/models/shufflenet.py
class ChannelShuffle (line 16) | class ChannelShuffle(nn.Module):
method __init__ (line 18) | def __init__(self, num_groups):
method forward (line 22) | def forward(self, x):
class Bottleneck (line 34) | class Bottleneck(nn.Module):
method __init__ (line 36) | def __init__(
method forward (line 78) | def forward(self, x):
class ShuffleNet (line 101) | class ShuffleNet(nn.Module):
method __init__ (line 112) | def __init__(self, num_classes, loss='softmax', num_groups=3, **kwargs):
method forward (line 153) | def forward(self, x):
function init_pretrained_weights (line 173) | def init_pretrained_weights(model, model_url):
function shufflenet (line 189) | def shufflenet(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/models/shufflenetv2.py
function channel_shuffle (line 24) | def channel_shuffle(x, groups):
class InvertedResidual (line 39) | class InvertedResidual(nn.Module):
method __init__ (line 41) | def __init__(self, inp, oup, stride):
method depthwise_conv (line 101) | def depthwise_conv(i, o, kernel_size, stride=1, padding=0, bias=False):
method forward (line 106) | def forward(self, x):
class ShuffleNetV2 (line 118) | class ShuffleNetV2(nn.Module):
method __init__ (line 131) | def __init__(
method featuremaps (line 180) | def featuremaps(self, x):
method forward (line 189) | def forward(self, x):
function init_pretrained_weights (line 207) | def init_pretrained_weights(model, model_url):
function shufflenet_v2_x0_5 (line 229) | def shufflenet_v2_x0_5(num_classes, loss='softmax', pretrained=True, **k...
function shufflenet_v2_x1_0 (line 238) | def shufflenet_v2_x1_0(num_classes, loss='softmax', pretrained=True, **k...
function shufflenet_v2_x1_5 (line 247) | def shufflenet_v2_x1_5(num_classes, loss='softmax', pretrained=True, **k...
function shufflenet_v2_x2_0 (line 256) | def shufflenet_v2_x2_0(num_classes, loss='softmax', pretrained=True, **k...
FILE: torchreid/models/squeezenet.py
class Fire (line 19) | class Fire(nn.Module):
method __init__ (line 21) | def __init__(
method forward (line 37) | def forward(self, x):
class SqueezeNet (line 47) | class SqueezeNet(nn.Module):
method __init__ (line 60) | def __init__(
method _construct_fc_layer (line 118) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method _init_params (line 149) | def _init_params(self):
method forward (line 168) | def forward(self, x):
function init_pretrained_weights (line 189) | def init_pretrained_weights(model, model_url):
function squeezenet1_0 (line 205) | def squeezenet1_0(num_classes, loss='softmax', pretrained=True, **kwargs):
function squeezenet1_0_fc512 (line 214) | def squeezenet1_0_fc512(
function squeezenet1_1 (line 230) | def squeezenet1_1(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/models/xception.py
class SeparableConv2d (line 26) | class SeparableConv2d(nn.Module):
method __init__ (line 28) | def __init__(
method forward (line 54) | def forward(self, x):
class Block (line 60) | class Block(nn.Module):
method __init__ (line 62) | def __init__(
method forward (line 132) | def forward(self, inp):
class Xception (line 145) | class Xception(nn.Module):
method __init__ (line 156) | def __init__(
method _construct_fc_layer (line 221) | def _construct_fc_layer(self, fc_dims, input_dim, dropout_p=None):
method _init_params (line 252) | def _init_params(self):
method featuremaps (line 271) | def featuremaps(self, input):
method forward (line 302) | def forward(self, x):
function init_pretrained_weights (line 323) | def init_pretrained_weights(model, model_url):
function xception (line 339) | def xception(num_classes, loss='softmax', pretrained=True, **kwargs):
FILE: torchreid/optim/lr_scheduler.py
function build_lr_scheduler (line 8) | def build_lr_scheduler(
class WarmupMultiStepLR (line 88) | class WarmupMultiStepLR(torch.optim.lr_scheduler._LRScheduler):
method __init__ (line 90) | def __init__(
method get_lr (line 118) | def get_lr(self):
FILE: torchreid/optim/optimizer.py
function build_optimizer (line 11) | def build_optimizer(
FILE: torchreid/optim/radam.py
class RAdam (line 19) | class RAdam(Optimizer):
method __init__ (line 21) | def __init__(
method __setstate__ (line 48) | def __setstate__(self, state):
method step (line 51) | def step(self, closure=None):
class PlainRAdam (line 134) | class PlainRAdam(Optimizer):
method __init__ (line 136) | def __init__(
method __setstate__ (line 163) | def __setstate__(self, state):
method step (line 166) | def step(self, closure=None):
class AdamW (line 233) | class AdamW(Optimizer):
method __init__ (line 235) | def __init__(
method __setstate__ (line 266) | def __setstate__(self, state):
method step (line 269) | def step(self, closure=None):
FILE: torchreid/scripts/default_config.py
function get_default_config (line 11) | def get_default_config():
function imagedata_kwargs (line 254) | def imagedata_kwargs(cfg):
function videodata_kwargs (line 284) | def videodata_kwargs(cfg):
function optimizer_kwargs (line 308) | def optimizer_kwargs(cfg):
function lr_scheduler_kwargs (line 325) | def lr_scheduler_kwargs(cfg):
function engine_run_kwargs (line 334) | def engine_run_kwargs(cfg):
function display_config_diff (line 353) | def display_config_diff(cfg, default_cfg_copy):
FILE: torchreid/scripts/get_labels.py
function build_config_maskrcnn (line 21) | def build_config_maskrcnn(model_config_name):
function compare_arrays (line 29) | def compare_arrays(array1, array2):
function get_image_paths (line 51) | def get_image_paths(source, path_format=False):
function format_path (line 72) | def format_path(img_path, dataset_dir):
function get_label_paths (line 91) | def get_label_paths(is_mask, img_paths, dataset_dir):
function skip_existing (line 116) | def skip_existing(is_mask, imagery, dataset_dir):
function save_files (line 136) | def save_files(files, files_path, verbose=True):
class ImageDataset (line 152) | class ImageDataset(Dataset):
method __init__ (line 163) | def __init__(self, imagery: List[Path]):
method __getitem__ (line 166) | def __getitem__(self, index):
method __len__ (line 169) | def __len__(self):
class BatchPifPaf (line 173) | class BatchPifPaf:
method __init__ (line 174) | def __init__(self, model_name: str = "shufflenetv2k16", batch_size: in...
method __call__ (line 197) | def __call__(self, imagery: List[Path] or List[str], dataset_dir: List...
method __get_pifpaf_conf (line 254) | def __get_pifpaf_conf(self, processed_image_batch: Instances):
class BatchMask (line 282) | class BatchMask:
method __init__ (line 283) | def __init__(self, cfg: CfgNode or str, batch_size: int = None, worker...
method __collate (line 322) | def __collate(self, batch):
method __call__ (line 348) | def __call__(self, imagery: List[Path] or List[str], dataset_dir: List...
method __filter_pifpaf_with_mask (line 404) | def __filter_pifpaf_with_mask(self, batch,
function main (line 487) | def main():
FILE: torchreid/scripts/main.py
function build_datamanager (line 20) | def build_datamanager(cfg):
function build_engine (line 27) | def build_engine(cfg, datamanager, model, optimizer, scheduler, writer, ...
function reset_config (line 111) | def reset_config(cfg, args):
function main (line 128) | def main():
function build_config (line 192) | def build_config(args=None, config_file=None, config=None):
function build_torchreid_model_engine (line 226) | def build_torchreid_model_engine(cfg):
FILE: torchreid/tools/compute_mean_std.py
function main (line 19) | def main():
FILE: torchreid/tools/extract_part_based_features.py
function extract_part_based_features (line 10) | def extract_part_based_features(extractor, image_list, batch_size=400):
function extract_det_idx (line 44) | def extract_det_idx(img_path):
function extract_reid_features (line 48) | def extract_reid_features(cfg, base_folder, out_path, model=None, model_...
FILE: torchreid/tools/feature_extractor.py
class FeatureExtractor (line 14) | class FeatureExtractor(object):
method __init__ (line 60) | def __init__(
method __call__ (line 125) | def __call__(self, input, external_parts_masks=None):
FILE: torchreid/utils/avgmeter.py
class AverageMeter (line 15) | class AverageMeter(object):
method __init__ (line 25) | def __init__(self):
method reset (line 28) | def reset(self):
method update (line 34) | def update(self, val, n=1):
class BatchMeter (line 41) | class BatchMeter(object):
method __init__ (line 42) | def __init__(self, epoch_count, batch_count):
method reset (line 47) | def reset(self):
method update (line 51) | def update(self, epoch, batch, val):
method total_for_epoch (line 55) | def total_for_epoch(self, epoch):
method avg_for_epoch (line 58) | def avg_for_epoch(self, epoch):
method batch_avg (line 61) | def batch_avg(self):
method epoch_avg (line 64) | def epoch_avg(self):
method total (line 67) | def total(self):
class SingleMeter (line 71) | class SingleMeter(EngineStateListener):
method __init__ (line 72) | def __init__(self, engine_state):
method reset (line 78) | def reset(self):
method update (line 82) | def update(self, val, total):
method ratio (line 92) | def ratio(self):
class EpochMeter (line 98) | class EpochMeter(EngineStateListener):
method __init__ (line 100) | def __init__(self, engine_state):
method update (line 113) | def update(self, val, total=1.):
method epoch_completed (line 124) | def epoch_completed(self):
method last_val (line 142) | def last_val(self):
method epoch_ratio (line 145) | def epoch_ratio(self, epoch):
method total_ratio (line 148) | def total_ratio(self):
class EpochArrayMeter (line 152) | class EpochArrayMeter(EngineStateListener):
method __init__ (line 154) | def __init__(self, engine_state, array_size):
method update (line 167) | def update(self, val, total):
method epoch_completed (line 183) | def epoch_completed(self):
method epoch_ratio (line 200) | def epoch_ratio(self, epoch):
method total_ratio (line 203) | def total_ratio(self):
class TimeMeter (line 207) | class TimeMeter(AverageMeter):
method __init__ (line 211) | def __init__(self, name):
method _format_time (line 216) | def _format_time(self, time):
method total_time (line 219) | def total_time(self):
method average_time (line 222) | def average_time(self):
method start (line 225) | def start(self):
method stop (line 228) | def stop(self):
method _current_time_ms (line 238) | def _current_time_ms():
class TorchTimeMeter (line 242) | class TorchTimeMeter(TimeMeter):
method __init__ (line 246) | def __init__(self, name, plot=True):
method start (line 253) | def start(self):
method _start_cuda (line 259) | def _start_cuda(self):
method stop (line 264) | def stop(self):
method _stop_cuda (line 270) | def _stop_cuda(self):
class EpochMetricsMeter (line 284) | class EpochMetricsMeter(object):
method __init__ (line 299) | def __init__(self, engine_state, delimiter='\t'):
method update (line 304) | def update(self, input_dict):
method summary (line 320) | def summary(self, epoch):
class LossEpochMetricsMeter (line 328) | class LossEpochMetricsMeter(object):
method __init__ (line 329) | def __init__(self, engine_state, delimiter='\t'):
method update (line 334) | def update(self, input_dict):
method summary (line 353) | def summary(self, epoch):
class MetricMeter (line 366) | class MetricMeter(object):
method __init__ (line 381) | def __init__(self, delimiter='\t'):
method update (line 385) | def update(self, input_dict):
method __str__ (line 399) | def __str__(self):
FILE: torchreid/utils/constants.py
function get_test_embeddings_names (line 21) | def get_test_embeddings_names(parts_names, test_embeddings):
FILE: torchreid/utils/distribution.py
function plot_body_parts_pairs_distance_distribution (line 10) | def plot_body_parts_pairs_distance_distribution(body_part_pairwise_dist,...
function plot_pairs_distance_distribution (line 28) | def plot_pairs_distance_distribution(distmat, q_pids, g_pids, tag):
function compute_distance_distribution (line 35) | def compute_distance_distribution(ax, distmat, q_pids, g_pids, title):
function compute_ssmd (line 47) | def compute_ssmd(neg_p, pos_p):
function plot_distributions (line 57) | def plot_distributions(ax, neg_p, pos_p, pos_p_mean, pos_p_std, neg_p_me...
FILE: torchreid/utils/engine_state.py
class EngineStateListener (line 5) | class EngineStateListener:
method batch_completed (line 6) | def batch_completed(self):
method epoch_started (line 9) | def epoch_started(self):
method epoch_completed (line 12) | def epoch_completed(self):
method training_started (line 15) | def training_started(self):
method training_completed (line 18) | def training_completed(self):
method test_completed (line 21) | def test_completed(self):
method run_completed (line 24) | def run_completed(self):
class EngineState (line 28) | class EngineState(EngineStateListener):
method current_engine_state (line 32) | def current_engine_state(cls):
method __init__ (line 36) | def __init__(self, start_epoch, max_epoch):
method add_listener (line 50) | def add_listener(self, listener, last=False):
method batch_completed (line 57) | def batch_completed(self):
method epoch_started (line 63) | def epoch_started(self):
method epoch_completed (line 68) | def epoch_completed(self):
method training_started (line 74) | def training_started(self):
method training_completed (line 79) | def training_completed(self):
method test_completed (line 84) | def test_completed(self):
method run_completed (line 88) | def run_completed(self):
method update_lr (line 92) | def update_lr(self, lr):
FILE: torchreid/utils/imagetools.py
function gkern (line 5) | def gkern(kernlen=21, std=None):
function build_gaussian_heatmaps (line 14) | def build_gaussian_heatmaps(kp_xyc, w, h, gaussian=None):
FILE: torchreid/utils/logging/deprecated_loggers.py
class StdoutLogger (line 11) | class StdoutLogger(object):
method __init__ (line 29) | def __init__(self, fpath=None):
method __del__ (line 36) | def __del__(self):
method __enter__ (line 39) | def __enter__(self):
method __exit__ (line 42) | def __exit__(self, *args):
method write (line 45) | def write(self, msg):
method flush (line 50) | def flush(self):
method close (line 56) | def close(self):
class RankLogger (line 62) | class RankLogger(object):
method __init__ (line 108) | def __init__(self, sources, targets):
method write (line 126) | def write(self, name, epoch, rank1):
method show_summary (line 137) | def show_summary(self):
FILE: torchreid/utils/logging/logger.py
class Logger (line 10) | class Logger:
method current_logger (line 17) | def current_logger(cls):
method __init__ (line 21) | def __init__(self, cfg):
method add_model (line 55) | def add_model(self, model):
method add_text (line 59) | def add_text(self, tag, value):
method add_scalar (line 63) | def add_scalar(self, tag, scalar_value, step):
method add_figure (line 69) | def add_figure(self, tag, figure, step):
method add_image (line 84) | def add_image(self, group, name, image, step):
method add_embeddings (line 96) | def add_embeddings(self, tag, embeddings, labels, imgs, step):
method close (line 105) | def close(self):
FILE: torchreid/utils/model_complexity.py
function _ntuple (line 17) | def _ntuple(n):
function hook_convNd (line 35) | def hook_convNd(m, x, y):
function hook_maxpool1d (line 50) | def hook_maxpool1d(m, x, y):
function hook_maxpool2d (line 56) | def hook_maxpool2d(m, x, y):
function hook_maxpool3d (line 65) | def hook_maxpool3d(m, x, y):
function hook_avgpool1d (line 73) | def hook_avgpool1d(m, x, y):
function hook_avgpool2d (line 79) | def hook_avgpool2d(m, x, y):
function hook_avgpool3d (line 87) | def hook_avgpool3d(m, x, y):
function hook_adapmaxpool1d (line 95) | def hook_adapmaxpool1d(m, x, y):
function hook_adapmaxpool2d (line 104) | def hook_adapmaxpool2d(m, x, y):
function hook_adapmaxpool3d (line 114) | def hook_adapmaxpool3d(m, x, y):
function hook_adapavgpool1d (line 124) | def hook_adapavgpool1d(m, x, y):
function hook_adapavgpool2d (line 133) | def hook_adapavgpool2d(m, x, y):
function hook_adapavgpool3d (line 143) | def hook_adapavgpool3d(m, x, y):
function hook_relu (line 158) | def hook_relu(m, x, y):
function hook_leakyrelu (line 164) | def hook_leakyrelu(m, x, y):
function hook_batchnormNd (line 176) | def hook_batchnormNd(m, x, y):
function hook_instancenormNd (line 184) | def hook_instancenormNd(m, x, y):
function hook_groupnorm (line 188) | def hook_groupnorm(m, x, y):
function hook_layernorm (line 192) | def hook_layernorm(m, x, y):
function hook_linear (line 205) | def hook_linear(m, x, y):
function _get_flops_counter (line 258) | def _get_flops_counter(only_conv_linear):
function compute_model_complexity (line 264) | def compute_model_complexity(
FILE: torchreid/utils/reidtools.py
function visualize_ranked_results (line 19) | def visualize_ranked_results(
FILE: torchreid/utils/rerank.py
function re_ranking (line 31) | def re_ranking(q_g_dist, q_q_dist, g_g_dist, k1=20, k2=6, lambda_value=0...
FILE: torchreid/utils/tensortools.py
function replace_values (line 3) | def replace_values(input, mask, value):
function masked_mean (line 12) | def masked_mean(input, mask):
FILE: torchreid/utils/tools.py
function mkdir_if_missing (line 23) | def mkdir_if_missing(dirname):
function check_isfile (line 33) | def check_isfile(fpath):
function read_json (line 48) | def read_json(fpath):
function write_json (line 55) | def write_json(obj, fpath):
function set_random_seed (line 62) | def set_random_seed(seed):
function download_url (line 69) | def download_url(url, dst):
function read_image (line 99) | def read_image(path):
function read_masks (line 124) | def read_masks(masks_path):
function collect_env_info (line 150) | def collect_env_info():
function perc (line 161) | def perc(val, decimals=2):
function extract_test_embeddings (line 164) | def extract_test_embeddings(model_output, test_embeddings):
FILE: torchreid/utils/torch_receptive_field/receptive_field.py
function check_same (line 10) | def check_same(stride):
function receptive_field (line 16) | def receptive_field(model, input_size, batch_size=-1, device="cuda"):
function receptive_field_for_unit (line 154) | def receptive_field_for_unit(receptive_field_dict, layer, unit_position):
FILE: torchreid/utils/torchtools.py
function save_checkpoint (line 24) | def save_checkpoint(
function load_checkpoint (line 65) | def load_checkpoint(fpath):
function resume_from_checkpoint (line 101) | def resume_from_checkpoint(fpath, model, optimizer=None, scheduler=None):
function adjust_learning_rate (line 140) | def adjust_learning_rate(
function set_bn_to_eval (line 166) | def set_bn_to_eval(m):
function open_all_layers (line 175) | def open_all_layers(model):
function open_specified_layers (line 187) | def open_specified_layers(model, open_layers):
function count_num_param (line 228) | def count_num_param(model):
function load_pretrained_weights (line 260) | def load_pretrained_weights(model, weight_path):
function collate (line 323) | def collate(batch):
FILE: torchreid/utils/visualization/display_batch_triplets.py
function show_triplet_grid (line 20) | def show_triplet_grid(triplets):
function show_triplet (line 50) | def show_triplet(anc, pos, neg, pos_dist, neg_dist):
function add_border (line 61) | def add_border(img, color):
function show_instance (line 67) | def show_instance(ax, instance, dist, color):
FILE: torchreid/utils/visualization/embeddings_projection.py
function visualize_embeddings (line 9) | def visualize_embeddings(qf, gf, q_pids, g_pids, test_loader, dataset_na...
function extract_samples (line 26) | def extract_samples(features, dataset, sample_size):
FILE: torchreid/utils/visualization/feature_map_visualization.py
function flatten (line 26) | def flatten(maps):
function organize (line 31) | def organize(flattened, num_map, feat_dim, h, w):
function feat_to_color (line 37) | def feat_to_color(maps):
function normalize_01 (line 45) | def normalize_01(m):
function mapwise_normalize (line 53) | def mapwise_normalize(map1, feats):
function visualize_pca_multi (line 68) | def visualize_pca_multi(maps_all, feats, pids, tag):
function display_feature_maps (line 128) | def display_feature_maps(embeddings_dict, spatial_features, body_part_ma...
FILE: torchreid/utils/visualization/visualize_query_gallery_rankings.py
function visualize_ranking_grid (line 34) | def visualize_ranking_grid(distmat, body_parts_distmat, test_loader, dat...
function show_ranking_grid (line 104) | def show_ranking_grid(query_sample, gallery_topk_samples, mAP, rank1, da...
function insert_background_line (line 166) | def insert_background_line(grid_img, match_color, row, height, padding_t...
function display_sample_on_row (line 178) | def display_sample_on_row(grid_img, sample, row, img_shape, mask_filteri...
function mask_overlay (line 255) | def mask_overlay(img, mask, clip=True, interpolation=cv2.INTER_NEAREST):
function align_top_text (line 268) | def align_top_text(img, text, pos, fontScale=1.0, thickness=1, padding=4):
function align_top_multi_text (line 276) | def align_top_multi_text(img, text, pos, fontScale=1.0, thickness=1, pad...
function align_bottom_text (line 296) | def align_bottom_text(img, text, pos, fontScale=1.0, thickness=1, paddin...
function align_right_text (line 304) | def align_right_text(img, text, pos, fontScale=1.0, thickness=1, padding...
function align_left_multitext (line 312) | def align_left_multitext(img, text, pos, fontScale=1.0, thickness=1, pad...
function centered_text (line 332) | def centered_text(img, text, pos, fontScale=1, thickness=1):
function insert_img_into_grid (line 340) | def insert_img_into_grid(grid_img, img, row, col):
function make_border (line 351) | def make_border(img, border_color, bw):
FILE: torchreid/utils/writer.py
class Writer (line 17) | class Writer(EngineStateListener):
method current_writer (line 24) | def current_writer(cls):
method __init__ (line 28) | def __init__(self, cfg):
method init_engine_state (line 56) | def init_engine_state(self, engine_state, parts_num):
method report_performance (line 75) | def report_performance(self, cmc, mAP, ssmd, pxl_acc_avg, name=""):
method report_global_performance (line 84) | def report_global_performance(self,
method intermediate_evaluate (line 97) | def intermediate_evaluate(self):
method update_invalid_pairwise_distances_count (line 101) | def update_invalid_pairwise_distances_count(self, batch_pairwise_dist):
method update_invalid_part_based_pairwise_distances_count (line 104) | def update_invalid_part_based_pairwise_distances_count(self, valid_bod...
method used_parts_statistics (line 108) | def used_parts_statistics(self, M, body_part_id):
method visualize_triplets (line 134) | def visualize_triplets(self, images, masks, mask, dist):
method qg_pairwise_dist_statistics (line 172) | def qg_pairwise_dist_statistics(self, pairwise_dist, body_part_pairwis...
method qg_body_part_distances_boxplot (line 188) | def qg_body_part_distances_boxplot(self, body_part_pairwise_dist):
method qg_body_part_pairs_availability_barplot (line 202) | def qg_body_part_pairs_availability_barplot(self, body_part_pairwise_d...
method qg_body_part_availability_barplot (line 233) | def qg_body_part_availability_barplot(self, qf_parts_visibility, gf_pa...
method qg_distribution_of_body_part_availability_histogram (line 267) | def qg_distribution_of_body_part_availability_histogram(self, qf_parts...
method visualize_embeddings (line 293) | def visualize_embeddings(self, qf, gf, q_pids, g_pids, test_loader, da...
method visualize_rank (line 298) | def visualize_rank(self, test_loader, dataset_name, distmat, save_dir,...
method training_started (line 320) | def training_started(self):
method epoch_started (line 323) | def epoch_started(self):
method epoch_completed (line 328) | def epoch_completed(self):
method training_completed (line 358) | def training_completed(self):
method test_completed (line 366) | def test_completed(self):
method run_completed (line 373) | def run_completed(self):
method display_used_body_parts (line 397) | def display_used_body_parts(self):
Condensed preview — 171 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,077K chars).
[
{
"path": ".flake8",
"chars": 496,
"preview": "[flake8]\nignore =\n # At least two spaces before inline comment\n E261,\n # Line lengths are recommended to be no "
},
{
"path": ".gitignore",
"chars": 1871,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packagi"
},
{
"path": ".isort.cfg",
"chars": 307,
"preview": "[isort]\nline_length=79\nmulti_line_output=3\nlength_sort=true\nknown_standard_library=numpy,setuptools\nknown_myself=torchre"
},
{
"path": ".style.yapf",
"chars": 222,
"preview": "[style]\nBASED_ON_STYLE = pep8\nBLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF = true\nSPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN ="
},
{
"path": "LICENSE",
"chars": 18377,
"preview": "**HIPPOCRATIC LICENSE**\n\n**Version 3.0, October 2021**\n\n<https://firstdonoharm.dev/version/3/0/law-media-mil-soc-sv.md>\n"
},
{
"path": "README.md",
"chars": 19040,
"preview": "<!-- TODO\n\n-->\n\n# BPBReID: Body Part-based (Occluded) Re-Identification\n\n**A strong baseline for body part-based person "
},
{
"path": "Torchreid_original_README.rst",
"chars": 11600,
"preview": "Torchreid\n===========\nTorchreid is a library for deep-learning person re-identification, written in `PyTorch <https://py"
},
{
"path": "configs/bpbreid/bpbreid_dukemtmc_test.yaml",
"chars": 581,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['dukemtmcreid']\n targets: ['dukemtmcreid']\n height: 384\n width: 128\n tra"
},
{
"path": "configs/bpbreid/bpbreid_dukemtmc_train.yaml",
"chars": 852,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['dukemtmcreid']\n targets: ['dukemtmcreid']\n height: 384\n width: 128\n tra"
},
{
"path": "configs/bpbreid/bpbreid_market1501_test.yaml",
"chars": 575,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['market1501']\n targets: ['market1501']\n height: 384\n width: 128\n transfo"
},
{
"path": "configs/bpbreid/bpbreid_market1501_train.yaml",
"chars": 848,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['market1501']\n targets: ['market1501']\n height: 384\n width: 128\n transfo"
},
{
"path": "configs/bpbreid/bpbreid_occ_duke_test.yaml",
"chars": 584,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['occluded_duke']\n targets: ['occluded_duke']\n height: 384\n width: 128\n t"
},
{
"path": "configs/bpbreid/bpbreid_occ_duke_train.yaml",
"chars": 853,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['occluded_duke']\n targets: ['occluded_duke']\n height: 384\n width: 128\n t"
},
{
"path": "configs/bpbreid/bpbreid_occ_reid_test.yaml",
"chars": 542,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['market1501']\n targets: ['occluded_reid']\n height: 384\n width: 128\n tran"
},
{
"path": "configs/bpbreid/bpbreid_occ_reid_train.yaml",
"chars": 875,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['market1501']\n targets: ['market1501', 'occluded_reid']\n height: 384\n wid"
},
{
"path": "configs/bpbreid/bpbreid_p_dukemtmc_test.yaml",
"chars": 585,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['p_dukemtmc_reid']\n targets: ['p_dukemtmc_reid']\n height: 384\n width: 128"
},
{
"path": "configs/bpbreid/bpbreid_p_dukemtmc_train.yaml",
"chars": 857,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['p_dukemtmc_reid']\n targets: ['p_dukemtmc_reid']\n height: 384\n width: 128"
},
{
"path": "configs/bpbreid/pcb_market1501_train.yaml",
"chars": 1119,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['market1501']\n targets: ['market1501']\n height: 384\n width: 128\n transfo"
},
{
"path": "configs/bpbreid/pcb_occ_duke_train.yaml",
"chars": 1125,
"preview": "data:\n root: '~/datasets/reid'\n sources: ['occluded_duke']\n targets: ['occluded_duke']\n height: 384\n width: 128\n t"
},
{
"path": "docs/AWESOME_REID.md",
"chars": 7462,
"preview": "# Awesome-ReID\nHere is a collection of ReID-related research with links to papers and code. You are welcome to submit [P"
},
{
"path": "docs/MODEL_ZOO.md",
"chars": 8290,
"preview": "# Model Zoo\n\n- Results are presented in the format of *<Rank-1 (mAP)>*.\n- When computing model size and FLOPs, only laye"
},
{
"path": "docs/Makefile",
"chars": 580,
"preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHI"
},
{
"path": "docs/conf.py",
"chars": 5646,
"preview": "# -*- coding: utf-8 -*-\n#\n# Configuration file for the Sphinx documentation builder.\n#\n# This file does only contain a s"
},
{
"path": "docs/datasets.rst",
"chars": 9465,
"preview": ".. _datasets:\n\nDatasets\n=========\n\nHere we provide a guide on how to prepare datasets.\n\nSuppose you wanna store the reid"
},
{
"path": "docs/evaluation.rst",
"chars": 1760,
"preview": "Evaluation\n==========\n\nImage ReID\n-----------\n- **Market1501**, **DukeMTMC-reID**, **CUHK03 (767/700 split)** and **MSMT"
},
{
"path": "docs/index.rst",
"chars": 426,
"preview": ".. include:: ../README.rst\n\n\n.. toctree::\n :hidden:\n\n user_guide\n datasets\n evaluation\n\n.. toctree::\n :ca"
},
{
"path": "docs/pkg/data.rst",
"chars": 1569,
"preview": ".. _torchreid_data:\n\ntorchreid.data\n==============\n\n\nData Manager\n---------------------------\n\n.. automodule:: torchreid"
},
{
"path": "docs/pkg/engine.rst",
"chars": 500,
"preview": ".. _torchreid_engine:\n\ntorchreid.engine\n==================\n\n\nBase Engine\n------------\n\n.. autoclass:: torchreid.engine.e"
},
{
"path": "docs/pkg/losses.rst",
"chars": 232,
"preview": ".. _torchreid_losses:\n\ntorchreid.losses\n=================\n\n\nSoftmax\n--------\n\n.. automodule:: torchreid.losses.cross_ent"
},
{
"path": "docs/pkg/metrics.rst",
"chars": 297,
"preview": ".. _torchreid_metrics:\n\ntorchreid.metrics\n=================\n\n\nDistance\n---------\n\n.. automodule:: torchreid.metrics.dist"
},
{
"path": "docs/pkg/models.rst",
"chars": 1192,
"preview": ".. _torchreid_models:\n\ntorchreid.models\n=================\n\nInterface\n---------\n\n.. automodule:: torchreid.models.__init_"
},
{
"path": "docs/pkg/optim.rst",
"chars": 259,
"preview": ".. _torchreid_optim:\n\ntorchreid.optim\n=================\n\n\nOptimizer\n----------\n\n.. automodule:: torchreid.optim.optimize"
},
{
"path": "docs/pkg/utils.rst",
"chars": 530,
"preview": ".. _torchreid_utils:\n\ntorchreid.utils\n=================\n\nAverage Meter\n--------------\n\n.. automodule:: torchreid.utils.a"
},
{
"path": "docs/requirements.txt",
"chars": 107,
"preview": "sphinx\nsphinx-markdown-tables\nsphinx-rtd-theme\nsphinxcontrib-napoleon\nsphinxcontrib-websupport\nrecommonmark"
},
{
"path": "docs/user_guide.rst",
"chars": 13754,
"preview": "How-to\n============\n\n.. contents::\n :local:\n\n\nPrepare datasets\n-----------------\nSee :ref:`datasets`.\n\n\nFind model key"
},
{
"path": "linter.sh",
"chars": 150,
"preview": "echo \"Running isort\"\nisort -y -sp .\necho \"Done\"\n\necho \"Running yapf\"\nyapf -i -r -vv -e build .\necho \"Done\"\n\necho \"Runnin"
},
{
"path": "pyproject.toml",
"chars": 429,
"preview": "[project]\nname = \"torchreid\"\nauthors = [{name=\"Vladimir Somers\"}, {name=\"Kaiyang Zhou\"}]\nurls = {homepage = \"https://git"
},
{
"path": "requirements.txt",
"chars": 295,
"preview": "# pip install -r requirements.txt\n\n# base torchreid ----------------------------------------\nnumpy\nCython\nh5py\nPillow\nsi"
},
{
"path": "requirements_labels.txt",
"chars": 79,
"preview": "openpifpaf\ndetectron2 @ git+https://github.com/facebookresearch/detectron2.git\n"
},
{
"path": "setup.py",
"chars": 1248,
"preview": "import numpy as np\nimport os.path as osp\nfrom setuptools import setup, find_packages\nfrom distutils.extension import Ext"
},
{
"path": "torchreid/__init__.py",
"chars": 359,
"preview": "from __future__ import print_function, absolute_import\n\nfrom torchreid import data, optim, utils, engine, losses, models"
},
{
"path": "torchreid/data/__init__.py",
"chars": 256,
"preview": "from __future__ import print_function, absolute_import\n\nfrom .datasets import (\n Dataset, ImageDataset, VideoDataset,"
},
{
"path": "torchreid/data/data_augmentation/__init__.py",
"chars": 88,
"preview": "from __future__ import print_function, absolute_import\n\nfrom .random_occlusion import *\n"
},
{
"path": "torchreid/data/data_augmentation/random_occlusion.py",
"chars": 10606,
"preview": "# Source: https://github.com/isarandi/synthetic-occlusion/blob/master/augmentation.py\nimport math\nimport os.path\nimport "
},
{
"path": "torchreid/data/datamanager.py",
"chars": 20991,
"preview": "from __future__ import division, print_function, absolute_import\nimport torch\n\nfrom torchreid.data.masks_transforms impo"
},
{
"path": "torchreid/data/datasets/__init__.py",
"chars": 6333,
"preview": "from __future__ import print_function, absolute_import\n\nimport copy\n\nfrom .image import (\n GRID, PRID, CUHK01, CUHK02"
},
{
"path": "torchreid/data/datasets/dataset.py",
"chars": 16873,
"preview": "from __future__ import division, print_function, absolute_import\nimport copy\nimport os\n\nimport numpy as np\nimport os.pat"
},
{
"path": "torchreid/data/datasets/image/__init__.py",
"chars": 601,
"preview": "from __future__ import print_function, absolute_import\n\nfrom .grid import GRID\nfrom .prid import PRID\nfrom .ilids import"
},
{
"path": "torchreid/data/datasets/image/cuhk01.py",
"chars": 4941,
"preview": "from __future__ import division, print_function, absolute_import\nimport glob\nimport numpy as np\nimport os.path as osp\nim"
},
{
"path": "torchreid/data/datasets/image/cuhk02.py",
"chars": 3243,
"preview": "from __future__ import division, print_function, absolute_import\nimport glob\nimport os.path as osp\n\nfrom ..dataset impor"
},
{
"path": "torchreid/data/datasets/image/cuhk03.py",
"chars": 12211,
"preview": "from __future__ import division, print_function, absolute_import\nimport os.path as osp\n\nfrom torchreid.utils import read"
},
{
"path": "torchreid/data/datasets/image/dukemtmcreid.py",
"chars": 3375,
"preview": "from __future__ import division, print_function, absolute_import\n\nimport re\nimport glob\nimport os.path as osp\n\nfrom ..da"
},
{
"path": "torchreid/data/datasets/image/grid.py",
"chars": 4654,
"preview": "from __future__ import division, print_function, absolute_import\nimport glob\nimport os.path as osp\nfrom scipy.io import "
},
{
"path": "torchreid/data/datasets/image/ilids.py",
"chars": 5019,
"preview": "from __future__ import division, print_function, absolute_import\nimport copy\nimport glob\nimport random\nimport os.path as"
},
{
"path": "torchreid/data/datasets/image/market1501.py",
"chars": 4155,
"preview": "from __future__ import division, print_function, absolute_import\n\nimport re\nimport glob\nimport os.path as osp\nimport war"
},
{
"path": "torchreid/data/datasets/image/msmt17.py",
"chars": 4087,
"preview": "from __future__ import division, print_function, absolute_import\nimport os.path as osp\n\nfrom ..dataset import ImageDatas"
},
{
"path": "torchreid/data/datasets/image/occluded_dukemtmc.py",
"chars": 3126,
"preview": "from __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport os."
},
{
"path": "torchreid/data/datasets/image/occluded_reid.py",
"chars": 3279,
"preview": "from __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport os\n"
},
{
"path": "torchreid/data/datasets/image/p_ETHZ.py",
"chars": 1932,
"preview": "from __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport os."
},
{
"path": "torchreid/data/datasets/image/p_dukemtmc_reid.py",
"chars": 5124,
"preview": "from __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport os\n"
},
{
"path": "torchreid/data/datasets/image/partial_ilids.py",
"chars": 1982,
"preview": "from __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport os."
},
{
"path": "torchreid/data/datasets/image/partial_reid.py",
"chars": 2312,
"preview": "from __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport os."
},
{
"path": "torchreid/data/datasets/image/prid.py",
"chars": 3887,
"preview": "from __future__ import division, print_function, absolute_import\nimport random\nimport os.path as osp\n\nfrom torchreid.uti"
},
{
"path": "torchreid/data/datasets/image/sensereid.py",
"chars": 2247,
"preview": "from __future__ import division, print_function, absolute_import\nimport copy\nimport glob\nimport os.path as osp\n\nfrom ..d"
},
{
"path": "torchreid/data/datasets/image/viper.py",
"chars": 5021,
"preview": "from __future__ import division, print_function, absolute_import\nimport glob\nimport numpy as np\nimport os.path as osp\n\nf"
},
{
"path": "torchreid/data/datasets/video/__init__.py",
"chars": 186,
"preview": "from __future__ import print_function, absolute_import\n\nfrom .mars import Mars\nfrom .ilidsvid import iLIDSVID\nfrom .prid"
},
{
"path": "torchreid/data/datasets/video/dukemtmcvidreid.py",
"chars": 4725,
"preview": "from __future__ import division, print_function, absolute_import\nimport glob\nimport os.path as osp\nimport warnings\n\nfrom"
},
{
"path": "torchreid/data/datasets/video/ilidsvid.py",
"chars": 5368,
"preview": "from __future__ import division, print_function, absolute_import\nimport glob\nimport os.path as osp\nfrom scipy.io import "
},
{
"path": "torchreid/data/datasets/video/mars.py",
"chars": 4887,
"preview": "from __future__ import division, print_function, absolute_import\nimport os.path as osp\nimport warnings\nfrom scipy.io imp"
},
{
"path": "torchreid/data/datasets/video/prid2011.py",
"chars": 2824,
"preview": "from __future__ import division, print_function, absolute_import\nimport glob\nimport os.path as osp\n\nfrom torchreid.utils"
},
{
"path": "torchreid/data/masks_transforms/__init__.py",
"chars": 2743,
"preview": "from __future__ import print_function, absolute_import\n\nfrom .mask_transform import *\nfrom .pcb_transforms import *\nfrom"
},
{
"path": "torchreid/data/masks_transforms/coco_keypoints_transforms.py",
"chars": 1023,
"preview": "from torchreid.data.masks_transforms.mask_transform import MaskGroupingTransform\n\nCOCO_KEYPOINTS = [\"nose\", \"left_eye\", "
},
{
"path": "torchreid/data/masks_transforms/mask_transform.py",
"chars": 3747,
"preview": "import torch\nfrom torch import nn\nfrom albumentations import DualTransform\nimport torch.nn.functional as F\n\n\nclass MaskT"
},
{
"path": "torchreid/data/masks_transforms/pcb_transforms.py",
"chars": 1434,
"preview": "import numpy as np\nimport torch\n\nfrom torchreid.data.masks_transforms.mask_transform import MaskTransform\n\n\nclass PCBMas"
},
{
"path": "torchreid/data/masks_transforms/pifpaf_mask_transform.py",
"chars": 32322,
"preview": "from __future__ import division, print_function, absolute_import\n\nimport torch\nfrom torchreid.data.masks_transforms.mask"
},
{
"path": "torchreid/data/sampler.py",
"chars": 3692,
"preview": "from __future__ import division, absolute_import\nimport copy\nimport numpy as np\nimport random\nfrom collections import de"
},
{
"path": "torchreid/data/transforms.py",
"chars": 6429,
"preview": "from __future__ import division, print_function, absolute_import\n\nimport cv2\nimport torch\nimport numpy as np\nfrom albume"
},
{
"path": "torchreid/engine/__init__.py",
"chars": 221,
"preview": "from __future__ import print_function, absolute_import\n\nfrom .image import ImageSoftmaxEngine, ImageTripletEngine, Image"
},
{
"path": "torchreid/engine/engine.py",
"chars": 22353,
"preview": "from __future__ import division, print_function, absolute_import\n\nimport os.path as osp\nfrom collections import OrderedD"
},
{
"path": "torchreid/engine/image/__init__.py",
"chars": 172,
"preview": "from __future__ import absolute_import\n\nfrom .softmax import ImageSoftmaxEngine\nfrom .triplet import ImageTripletEngine\n"
},
{
"path": "torchreid/engine/image/part_based_engine.py",
"chars": 19072,
"preview": "from __future__ import division, print_function, absolute_import\n\nimport os.path as osp\nimport torch\nimport numpy as np\n"
},
{
"path": "torchreid/engine/image/softmax.py",
"chars": 2868,
"preview": "from __future__ import division, print_function, absolute_import\n\nfrom torchreid import metrics\nfrom torchreid.losses im"
},
{
"path": "torchreid/engine/image/triplet.py",
"chars": 3626,
"preview": "from __future__ import division, print_function, absolute_import\n\nfrom torchreid import metrics\nfrom torchreid.losses im"
},
{
"path": "torchreid/engine/video/__init__.py",
"chars": 120,
"preview": "from __future__ import absolute_import\n\nfrom .softmax import VideoSoftmaxEngine\nfrom .triplet import VideoTripletEngine\n"
},
{
"path": "torchreid/engine/video/softmax.py",
"chars": 3556,
"preview": "from __future__ import division, print_function, absolute_import\nimport torch\n\nfrom torchreid.engine.image import ImageS"
},
{
"path": "torchreid/engine/video/triplet.py",
"chars": 3218,
"preview": "from __future__ import division, print_function, absolute_import\n\nfrom torchreid.engine.image import ImageTripletEngine\n"
},
{
"path": "torchreid/hyperparameter/custom_hyperparameter_optimizer.py",
"chars": 8781,
"preview": "import os\nimport sys\nimport time\nimport os.path as osp\nimport argparse\nimport torch\nimport torch.nn as nn\n\nimport torchr"
},
{
"path": "torchreid/hyperparameter/hyperparameter_optimizer.py",
"chars": 4844,
"preview": "import logging\n\nfrom clearml import Task\nfrom clearml.automation import (HyperParameterOptimizer, GridSearch, UniformInt"
},
{
"path": "torchreid/hyperparameter/optuna_hyperparameter_optimizer.py",
"chars": 11672,
"preview": "# import os\n# import sys\n# import time\n# import os.path as osp\n# import argparse\n#\n# import cv2\n# import optuna\n# import"
},
{
"path": "torchreid/losses/GiLt_loss.py",
"chars": 6361,
"preview": "from __future__ import division, absolute_import\n\nimport torch\nimport torch.nn as nn\nfrom collections import OrderedDict"
},
{
"path": "torchreid/losses/__init__.py",
"chars": 1929,
"preview": "from __future__ import division, print_function, absolute_import\n\nfrom .inter_parts_triplet_loss import InterPartsTriple"
},
{
"path": "torchreid/losses/body_part_attention_loss.py",
"chars": 2309,
"preview": "from __future__ import division, absolute_import\n\nimport torch.nn as nn\nfrom collections import OrderedDict\nfrom monai.l"
},
{
"path": "torchreid/losses/cross_entropy_loss.py",
"chars": 2164,
"preview": "from __future__ import division, absolute_import\nimport torch\nimport torch.nn as nn\n\n\nclass CrossEntropyLoss(nn.Module):"
},
{
"path": "torchreid/losses/hard_mine_triplet_loss.py",
"chars": 2254,
"preview": "from __future__ import division, absolute_import\nimport torch\nimport torch.nn as nn\n\n\nclass TripletLoss(nn.Module):\n "
},
{
"path": "torchreid/losses/inter_parts_triplet_loss.py",
"chars": 2789,
"preview": "from __future__ import division, absolute_import\nfrom torchreid.losses.part_averaged_triplet_loss import PartAveragedTri"
},
{
"path": "torchreid/losses/part_averaged_triplet_loss.py",
"chars": 13369,
"preview": "from __future__ import division, absolute_import\n\nimport warnings\nimport torch\nimport torch.nn as nn\nimport torch.nn.fun"
},
{
"path": "torchreid/losses/part_individual_triplet_loss.py",
"chars": 2278,
"preview": "from __future__ import division, absolute_import\n\nfrom torchreid.losses.part_averaged_triplet_loss import PartAveragedTr"
},
{
"path": "torchreid/losses/part_max_min_triplet_loss.py",
"chars": 2295,
"preview": "from __future__ import division, absolute_import\n\nimport torch\n\nfrom torchreid.losses.part_averaged_triplet_loss import "
},
{
"path": "torchreid/losses/part_max_triplet_loss.py",
"chars": 1115,
"preview": "from __future__ import division, absolute_import\n\nfrom torchreid.losses.part_averaged_triplet_loss import PartAveragedTr"
},
{
"path": "torchreid/losses/part_min_triplet_loss.py",
"chars": 1451,
"preview": "from __future__ import division, absolute_import\n\nimport torch\n\nfrom torchreid.losses.part_averaged_triplet_loss import "
},
{
"path": "torchreid/losses/part_random_max_min_triplet_loss.py",
"chars": 2648,
"preview": "from __future__ import division, absolute_import\n\nimport torch\n\nfrom torchreid.losses.part_averaged_triplet_loss import "
},
{
"path": "torchreid/metrics/__init__.py",
"chars": 149,
"preview": "from __future__ import absolute_import\n\nfrom .rank import evaluate_rank\nfrom .accuracy import accuracy\nfrom .distance im"
},
{
"path": "torchreid/metrics/accuracy.py",
"chars": 1134,
"preview": "from __future__ import division, print_function, absolute_import\n\n\ndef accuracy(output, target, topk=(1, )):\n \"\"\"Comp"
},
{
"path": "torchreid/metrics/distance.py",
"chars": 11518,
"preview": "from __future__ import division, print_function, absolute_import\nimport torch\nfrom torch.nn import functional as F\n\nfrom"
},
{
"path": "torchreid/metrics/rank.py",
"chars": 7270,
"preview": "from __future__ import division, print_function, absolute_import\nimport numpy as np\nimport warnings\nfrom collections imp"
},
{
"path": "torchreid/metrics/rank_cylib/Makefile",
"chars": 101,
"preview": "all:\n\t$(PYTHON) setup.py build_ext --inplace\n\trm -rf build\nclean:\n\trm -rf build\n\trm -f rank_cy.c *.so"
},
{
"path": "torchreid/metrics/rank_cylib/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "torchreid/metrics/rank_cylib/rank_cy.pyx",
"chars": 9134,
"preview": "# cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True\n\nfrom __future__ import print_function\n\ni"
},
{
"path": "torchreid/metrics/rank_cylib/setup.py",
"chars": 521,
"preview": "import numpy as np\nfrom distutils.core import setup\nfrom distutils.extension import Extension\nfrom Cython.Build import c"
},
{
"path": "torchreid/metrics/rank_cylib/test_cython.py",
"chars": 2746,
"preview": "from __future__ import print_function\nimport sys\nimport numpy as np\nimport timeit\nimport os.path as osp\n\nfrom torchreid "
},
{
"path": "torchreid/models/__init__.py",
"chars": 4269,
"preview": "from __future__ import absolute_import\nfrom .hrnet import hrnet32\nfrom .pcb import *\nfrom .mlfn import *\nfrom .hacnn imp"
},
{
"path": "torchreid/models/bpbreid.py",
"chars": 26902,
"preview": "from __future__ import division, absolute_import\n\nimport torch\nimport torch.nn.functional as F\nimport numpy as np\nfrom t"
},
{
"path": "torchreid/models/compact_bilinear_pooling.py",
"chars": 10352,
"preview": "import types\nimport torch\nimport torch.nn as nn\nfrom torch.autograd import Function\n\n\ndef CountSketchFn_forward(h, s, ou"
},
{
"path": "torchreid/models/densenet.py",
"chars": 11627,
"preview": "\"\"\"\nCode source: https://github.com/pytorch/vision\n\"\"\"\nfrom __future__ import division, absolute_import\nimport re\nfrom c"
},
{
"path": "torchreid/models/hacnn.py",
"chars": 13779,
"preview": "from __future__ import division, absolute_import\nimport torch\nfrom torch import nn\nfrom torch.nn import functional as F\n"
},
{
"path": "torchreid/models/hrnet.py",
"chars": 23578,
"preview": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\nimport os\nf"
},
{
"path": "torchreid/models/inceptionresnetv2.py",
"chars": 11194,
"preview": "\"\"\"\nCode imported from https://github.com/Cadene/pretrained-models.pytorch\n\"\"\"\nfrom __future__ import division, absolute"
},
{
"path": "torchreid/models/inceptionv4.py",
"chars": 11271,
"preview": "from __future__ import division, absolute_import\nimport torch\nimport torch.nn as nn\nimport torch.utils.model_zoo as mode"
},
{
"path": "torchreid/models/mlfn.py",
"chars": 8420,
"preview": "from __future__ import division, absolute_import\nimport torch\nimport torch.utils.model_zoo as model_zoo\nfrom torch impor"
},
{
"path": "torchreid/models/mobilenetv2.py",
"chars": 8387,
"preview": "from __future__ import division, absolute_import\nimport torch.utils.model_zoo as model_zoo\nfrom torch import nn\nfrom tor"
},
{
"path": "torchreid/models/mudeep.py",
"chars": 6245,
"preview": "from __future__ import division, absolute_import\nimport torch\nfrom torch import nn\nfrom torch.nn import functional as F\n"
},
{
"path": "torchreid/models/nasnet.py",
"chars": 36186,
"preview": "from __future__ import division, absolute_import\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimpo"
},
{
"path": "torchreid/models/osnet.py",
"chars": 17002,
"preview": "from __future__ import division, absolute_import\nimport warnings\nimport torch\nfrom torch import nn\nfrom torch.nn import "
},
{
"path": "torchreid/models/osnet_ain.py",
"chars": 15946,
"preview": "from __future__ import division, absolute_import\nimport warnings\nimport torch\nfrom torch import nn\nfrom torch.nn import "
},
{
"path": "torchreid/models/pcb.py",
"chars": 9125,
"preview": "from __future__ import division, absolute_import\nimport torch.utils.model_zoo as model_zoo\nfrom torch import nn\nfrom tor"
},
{
"path": "torchreid/models/pvpm.py",
"chars": 18583,
"preview": "from __future__ import absolute_import\nfrom __future__ import division\n\n# Source: https://github.com/hh23333/PVPM\n\n__all"
},
{
"path": "torchreid/models/resnet.py",
"chars": 15630,
"preview": "\"\"\"\nCode source: https://github.com/pytorch/vision\n\"\"\"\nfrom __future__ import division, absolute_import\nimport torch.uti"
},
{
"path": "torchreid/models/resnet_fastreid.py",
"chars": 16916,
"preview": "# encoding: utf-8\n\"\"\"\n@author: liaoxingyu\n@contact: sherlockliao01@gmail.com\n\"\"\"\n\nimport math\n\nimport torch\nfrom torch "
},
{
"path": "torchreid/models/resnet_ibn_a.py",
"chars": 8598,
"preview": "\"\"\"\nCredit to https://github.com/XingangPan/IBN-Net.\n\"\"\"\nfrom __future__ import division, absolute_import\nimport math\nim"
},
{
"path": "torchreid/models/resnet_ibn_b.py",
"chars": 8261,
"preview": "\"\"\"\nCredit to https://github.com/XingangPan/IBN-Net.\n\"\"\"\nfrom __future__ import division, absolute_import\nimport math\nim"
},
{
"path": "torchreid/models/resnetmid.py",
"chars": 9165,
"preview": "from __future__ import division, absolute_import\nimport torch\nimport torch.utils.model_zoo as model_zoo\nfrom torch impor"
},
{
"path": "torchreid/models/senet.py",
"chars": 20684,
"preview": "from __future__ import division, absolute_import\nimport math\nfrom collections import OrderedDict\nimport torch.nn as nn\nf"
},
{
"path": "torchreid/models/shufflenet.py",
"chars": 6264,
"preview": "from __future__ import division, absolute_import\nimport torch\nimport torch.utils.model_zoo as model_zoo\nfrom torch impor"
},
{
"path": "torchreid/models/shufflenetv2.py",
"chars": 8011,
"preview": "\"\"\"\nCode source: https://github.com/pytorch/vision\n\"\"\"\nfrom __future__ import division, absolute_import\nimport torch\nimp"
},
{
"path": "torchreid/models/squeezenet.py",
"chars": 7617,
"preview": "\"\"\"\nCode source: https://github.com/pytorch/vision\n\"\"\"\nfrom __future__ import division, absolute_import\nimport torch\nimp"
},
{
"path": "torchreid/models/xception.py",
"chars": 9687,
"preview": "from __future__ import division, absolute_import\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.util"
},
{
"path": "torchreid/optim/__init__.py",
"chars": 124,
"preview": "from __future__ import absolute_import\n\nfrom .optimizer import build_optimizer\nfrom .lr_scheduler import build_lr_schedu"
},
{
"path": "torchreid/optim/lr_scheduler.py",
"chars": 4610,
"preview": "from __future__ import print_function, absolute_import\nfrom bisect import bisect_right\nimport torch\n\nAVAI_SCH = ['single"
},
{
"path": "torchreid/optim/optimizer.py",
"chars": 5307,
"preview": "from __future__ import print_function, absolute_import\nimport warnings\nimport torch\nimport torch.nn as nn\n\nfrom .radam i"
},
{
"path": "torchreid/optim/radam.py",
"chars": 11626,
"preview": "\"\"\"\nImported from: https://github.com/LiyuanLucasLiu/RAdam\n\nPaper: https://arxiv.org/abs/1908.03265\n\n@article{liu2019rad"
},
{
"path": "torchreid/scripts/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "torchreid/scripts/default_config.py",
"chars": 18778,
"preview": "import random\nimport uuid\nfrom datetime import datetime\nfrom yacs.config import CfgNode as CN\nfrom torchreid.utils.const"
},
{
"path": "torchreid/scripts/get_labels.py",
"chars": 21391,
"preview": "import argparse\nimport glob\nimport os\nfrom pathlib import Path\nfrom typing import List\n\nimport cv2\nimport detectron2.dat"
},
{
"path": "torchreid/scripts/main.py",
"chars": 10339,
"preview": "import os\nimport argparse\nimport torch\nimport torch.nn as nn\nimport torchreid\nfrom torchreid.tools.extract_part_based_fe"
},
{
"path": "torchreid/tools/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "torchreid/tools/compute_mean_std.py",
"chars": 1505,
"preview": "\"\"\"\nCompute channel-wise mean and standard deviation of a dataset.\n\nUsage:\n$ python compute_mean_std.py DATASET_ROOT DAT"
},
{
"path": "torchreid/tools/extract_part_based_features.py",
"chars": 3015,
"preview": "import torch\nimport tqdm\nimport glob\nimport os\nimport numpy as np\nfrom torchreid.scripts.default_config import get_defau"
},
{
"path": "torchreid/tools/feature_extractor.py",
"chars": 6867,
"preview": "from __future__ import absolute_import\nimport numpy as np\nimport torch\nimport torchvision.transforms as T\nfrom PIL impor"
},
{
"path": "torchreid/utils/__init__.py",
"chars": 375,
"preview": "from __future__ import absolute_import\n\nfrom .tools import *\nfrom .rerank import re_ranking\nfrom torchreid.utils.logging"
},
{
"path": "torchreid/utils/avgmeter.py",
"chars": 12525,
"preview": "from __future__ import division, absolute_import\n\nimport datetime\nimport warnings\nfrom collections import defaultdict, O"
},
{
"path": "torchreid/utils/constants.py",
"chars": 1216,
"preview": "GLOBAL = 'globl'\nFOREGROUND = 'foreg'\nBACKGROUND = 'backg'\nCONCAT_PARTS = 'conct'\nPARTS = 'parts'\nBN_GLOBAL = 'bn_globl'"
},
{
"path": "torchreid/utils/distribution.py",
"chars": 3029,
"preview": "import math\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib.ticker import PercentFormatter\n\nfrom torc"
},
{
"path": "torchreid/utils/engine_state.py",
"chars": 2411,
"preview": "import queue\nfrom heapq import heappush\n\n\nclass EngineStateListener:\n def batch_completed(self):\n pass\n\n de"
},
{
"path": "torchreid/utils/imagetools.py",
"chars": 1240,
"preview": "import numpy as np\nfrom scipy import signal\n\n\ndef gkern(kernlen=21, std=None):\n \"\"\"Returns a 2D Gaussian kernel array"
},
{
"path": "torchreid/utils/logging/__init__.py",
"chars": 27,
"preview": "from .logger import Logger\n"
},
{
"path": "torchreid/utils/logging/deprecated_loggers.py",
"chars": 4400,
"preview": "from __future__ import absolute_import\nimport os\nimport sys\nimport os.path as osp\n\nfrom torchreid.utils.tools import mkd"
},
{
"path": "torchreid/utils/logging/logger.py",
"chars": 4573,
"preview": "import os\nimport cv2\nimport wandb\nimport matplotlib.pyplot as plt\nfrom typing import Optional\nfrom pandas.io.json._norma"
},
{
"path": "torchreid/utils/model_complexity.py",
"chars": 9664,
"preview": "from __future__ import division, print_function, absolute_import\nimport math\nimport numpy as np\nfrom itertools import re"
},
{
"path": "torchreid/utils/reidtools.py",
"chars": 5812,
"preview": "from __future__ import print_function, absolute_import\nimport numpy as np\nimport shutil\nimport os.path as osp\nimport cv2"
},
{
"path": "torchreid/utils/rerank.py",
"chars": 4678,
"preview": "#!/usr/bin/env python2/python3\n# -*- coding: utf-8 -*-\n\"\"\"\nSource: https://github.com/zhunzhong07/person-re-ranking\n\nCre"
},
{
"path": "torchreid/utils/tensortools.py",
"chars": 811,
"preview": "\n\ndef replace_values(input, mask, value):\n # TODO test perfs\n output = input * (~mask) + mask * value\n # input["
},
{
"path": "torchreid/utils/tools.py",
"chars": 5371,
"preview": "from __future__ import division, print_function, absolute_import\nimport os\nimport sys\nimport json\nimport time\nimport err"
},
{
"path": "torchreid/utils/torch_receptive_field/__init__.py",
"chars": 99,
"preview": "from .receptive_field import receptive_field\nfrom .receptive_field import receptive_field_for_unit\n"
},
{
"path": "torchreid/utils/torch_receptive_field/receptive_field.py",
"chars": 8169,
"preview": "import torch\nimport torch.nn as nn\nfrom torch.autograd import Variable\n\nfrom collections import OrderedDict\nimport numpy"
},
{
"path": "torchreid/utils/torchtools.py",
"chars": 15179,
"preview": "from __future__ import division, print_function, absolute_import\n\nimport itertools\nimport pickle\nimport shutil\nimport os"
},
{
"path": "torchreid/utils/visualization/__init__.py",
"chars": 122,
"preview": "from .display_batch_triplets import show_triplet_grid\nfrom .visualize_query_gallery_rankings import visualize_ranking_gr"
},
{
"path": "torchreid/utils/visualization/display_batch_triplets.py",
"chars": 3052,
"preview": "import cv2\nimport matplotlib.pyplot as plt\n\n__all__ = ['show_triplet']\n\n# try:\n# import matplotlib.cm\n# CMAP_JET"
},
{
"path": "torchreid/utils/visualization/embeddings_projection.py",
"chars": 1898,
"preview": "import cv2\nimport torch\nimport numpy as np\n\nfrom torchreid.utils import Logger\nfrom torchreid.utils.engine_state import "
},
{
"path": "torchreid/utils/visualization/feature_map_visualization.py",
"chars": 9059,
"preview": "import math\nimport os.path as osp\nimport json\n\nimport cv2\nimport numpy as np\nfrom PIL import Image\nfrom sklearn.decompos"
},
{
"path": "torchreid/utils/visualization/visualize_query_gallery_rankings.py",
"chars": 23205,
"preview": "import ntpath\nimport random\n\nimport cv2\nimport matplotlib\nimport numpy as np\n\nfrom torchreid.utils import Logger, perc\nf"
},
{
"path": "torchreid/utils/writer.py",
"chars": 23436,
"preview": "import datetime\nimport os\nfrom typing import Optional\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport torch\nfr"
}
]
About this extraction
This page contains the full source code of the VlSomers/bpbreid GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 171 files (1009.1 KB), approximately 261.0k tokens, and a symbol index with 1199 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.