<liclass="toctree-l2"><aclass="reference internal"href="#combine-train-query-and-gallery">Combine train, query and gallery</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="#optimize-layers-with-different-learning-rates">Optimize layers with different learning rates</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="#do-two-stepped-transfer-learning">Do two-stepped transfer learning</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="#test-a-trained-model">Test a trained model</a></li>
<li><p><aclass="reference internal"href="#combine-train-query-and-gallery"id="id9">Combine train, query and gallery</a></p></li>
<li><p><aclass="reference internal"href="#optimize-layers-with-different-learning-rates"id="id10">Optimize layers with different learning rates</a></p></li>
<li><p><aclass="reference internal"href="#do-two-stepped-transfer-learning"id="id11">Do two-stepped transfer learning</a></p></li>
<li><p><aclass="reference internal"href="#test-a-trained-model"id="id12">Test a trained model</a></p></li>
<li><p><aclass="reference internal"href="#visualize-learning-curves-with-tensorboard"id="id13">Visualize learning curves with tensorboard</a></p></li>
<h2><aclass="toc-backref"href="#id1">Find model keys</a><aclass="headerlink"href="#find-model-keys"title="Permalink to this headline">¶</a></h2>
<p>Keys are listed under the <em>Public keys</em> section within each model class in <aclass="reference internal"href="pkg/models.html#torchreid-models"><spanclass="std std-ref">torchreid.models</span></a>.</p>
</div>
<divclass="section"id="show-available-models">
<h2><aclass="toc-backref"href="#id2">Show available models</a><aclass="headerlink"href="#show-available-models"title="Permalink to this headline">¶</a></h2>
<h2><aclass="toc-backref"href="#id3">Change the training sampler</a><aclass="headerlink"href="#change-the-training-sampler"title="Permalink to this headline">¶</a></h2>
<p>The default <codeclass="docutils literal notranslate"><spanclass="pre">train_sampler</span></code> is “RandomSampler”. You can give the specific sampler name as input to <codeclass="docutils literal notranslate"><spanclass="pre">train_sampler</span></code>, e.g. <codeclass="docutils literal notranslate"><spanclass="pre">train_sampler='RandomIdentitySampler'</span></code> for triplet loss.</p>
<h2><aclass="toc-backref"href="#id4">Choose an optimizer/lr_scheduler</a><aclass="headerlink"href="#choose-an-optimizer-lr-scheduler"title="Permalink to this headline">¶</a></h2>
<p>Please refer to the source code of <codeclass="docutils literal notranslate"><spanclass="pre">build_optimizer</span></code>/<codeclass="docutils literal notranslate"><spanclass="pre">build_lr_scheduler</span></code> in <aclass="reference internal"href="pkg/optim.html#torchreid-optim"><spanclass="std std-ref">torchreid.optim</span></a> for details.</p>
</div>
<divclass="section"id="resume-training">
<h2><aclass="toc-backref"href="#id5">Resume training</a><aclass="headerlink"href="#resume-training"title="Permalink to this headline">¶</a></h2>
<p>Suppose the checkpoint is saved in “log/resnet50/model.pth.tar-30”, you can do</p>
<h2><aclass="toc-backref"href="#id6">Compute model complexity</a><aclass="headerlink"href="#compute-model-complexity"title="Permalink to this headline">¶</a></h2>
<p>We provide a tool in <codeclass="docutils literal notranslate"><spanclass="pre">torchreid.utils.model_complexity.py</span></code> to automatically compute the model complexity, i.e. number of parameters and FLOPs.</p>
<p>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 <codeclass="docutils literal notranslate"><spanclass="pre">forward()</span></code>.</p>
<h2><aclass="toc-backref"href="#id7">Combine multiple datasets</a><aclass="headerlink"href="#combine-multiple-datasets"title="Permalink to this headline">¶</a></h2>
<p>Easy. Just give whatever datasets (keys) you want to the <codeclass="docutils literal notranslate"><spanclass="pre">sources</span></code> argument when instantiating a data manager. For example,</p>
<p>In this example, the target datasets are Market1501, DukeMTMC-reID, CUHK03 and MSMT17 as the <codeclass="docutils literal notranslate"><spanclass="pre">targets</span></code> argument is not specified. Please refer to <codeclass="docutils literal notranslate"><spanclass="pre">Engine.test()</span></code> in <aclass="reference internal"href="pkg/engine.html#torchreid-engine"><spanclass="std std-ref">torchreid.engine</span></a> for details regarding how evaluation is performed.</p>
<h2><aclass="toc-backref"href="#id8">Do cross-dataset evaluation</a><aclass="headerlink"href="#do-cross-dataset-evaluation"title="Permalink to this headline">¶</a></h2>
<p>Easy. Just give whatever datasets (keys) you want to the argument <codeclass="docutils literal notranslate"><spanclass="pre">targets</span></code>, like</p>
<spanclass="n">targets</span><spanclass="o">=</span><spanclass="s1">'dukemtmcreid'</span><spanclass="p">,</span><spanclass="c1"># or targets='cuhk03' or targets=['dukemtmcreid', 'cuhk03']</span>
<h2><aclass="toc-backref"href="#id9">Combine train, query and gallery</a><aclass="headerlink"href="#combine-train-query-and-gallery"title="Permalink to this headline">¶</a></h2>
<p>This can be easily done by setting <codeclass="docutils literal notranslate"><spanclass="pre">combineall=True</span></code> when instantiating a data manager. Below is an example of using Market1501,</p>
<h2><aclass="toc-backref"href="#id10">Optimize layers with different learning rates</a><aclass="headerlink"href="#optimize-layers-with-different-learning-rates"title="Permalink to this headline">¶</a></h2>
<p>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 <codeclass="docutils literal notranslate"><spanclass="pre">new_layers</span></code>). <codeclass="docutils literal notranslate"><spanclass="pre">torchreid.optim.optimizer</span></code> has implemented such feature. What you need to do is to set <codeclass="docutils literal notranslate"><spanclass="pre">staged_lr=True</span></code> and give the names of <codeclass="docutils literal notranslate"><spanclass="pre">new_layers</span></code> such as “classifier”.</p>
<p>Below is an example of setting different learning rates for base layers and new layers in ResNet50,</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># New layer "classifier" has a learning rate of 0.01</span>
<spanclass="c1"># The base layers have a learning rate of 0.001</span>
<p>Please refer to <aclass="reference internal"href="pkg/optim.html#torchreid-optim"><spanclass="std std-ref">torchreid.optim</span></a> for more details.</p>
<h2><aclass="toc-backref"href="#id11">Do two-stepped transfer learning</a><aclass="headerlink"href="#do-two-stepped-transfer-learning"title="Permalink to this headline">¶</a></h2>
<p>To prevent the pretrained layers from being damaged by harmful gradients back-propagated from randomly initialized layers, one can adopt the <em>two-stepped transfer learning strategy</em> presented in <aclass="reference external"href="https://arxiv.org/abs/1611.05244">Deep Transfer Learning for Person Re-identification</a>. 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.</p>
<p>This has been implemented in <codeclass="docutils literal notranslate"><spanclass="pre">Engine.train()</span></code> (see <aclass="reference internal"href="pkg/engine.html#torchreid-engine"><spanclass="std std-ref">torchreid.engine</span></a>). The arguments related to this feature are <codeclass="docutils literal notranslate"><spanclass="pre">fixbase_epoch</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">open_layers</span></code>. Intuitively, <codeclass="docutils literal notranslate"><spanclass="pre">fixbase_epoch</span></code> denotes the number of epochs to keep the base layers frozen; <codeclass="docutils literal notranslate"><spanclass="pre">open_layers</span></code> means which layer is open for training.</p>
<p>For example, say you want to pretrain the classification layer named “classifier” in ResNet50 for 5 epochs before training all layers, you can do</p>
<p>Note that <codeclass="docutils literal notranslate"><spanclass="pre">fixbase_epoch</span></code> is counted into <codeclass="docutils literal notranslate"><spanclass="pre">max_epoch</span></code>. 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 <codeclass="docutils literal notranslate"><spanclass="pre">fixbase_epoch</span></code> equal to <codeclass="docutils literal notranslate"><spanclass="pre">max_epoch</span></code> and put the layer names in <codeclass="docutils literal notranslate"><spanclass="pre">open_layers</span></code> which you want to train.</p>
<h2><aclass="toc-backref"href="#id12">Test a trained model</a><aclass="headerlink"href="#test-a-trained-model"title="Permalink to this headline">¶</a></h2>
<p>You can load a trained model using <codeclass="code docutils literal notranslate"><spanclass="pre">torchreid.utils.load_pretrained_weights(model,</span><spanclass="pre">weight_path)</span></code> and set <codeclass="docutils literal notranslate"><spanclass="pre">test_only=True</span></code> in <codeclass="docutils literal notranslate"><spanclass="pre">engine.run()</span></code>.</p>
<h2><aclass="toc-backref"href="#id13">Visualize learning curves with tensorboard</a><aclass="headerlink"href="#visualize-learning-curves-with-tensorboard"title="Permalink to this headline">¶</a></h2>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">SummaryWriter()</span></code> for tensorboard will be automatically initialized in <codeclass="docutils literal notranslate"><spanclass="pre">engine.run()</span></code> when you are training your model. Therefore, you do not need to do extra jobs. After the training is done, the <codeclass="docutils literal notranslate"><spanclass="pre">*tf.events*</span></code> file will be saved in <codeclass="docutils literal notranslate"><spanclass="pre">save_dir</span></code>. Then, you just call <codeclass="docutils literal notranslate"><spanclass="pre">tensorboard</span><spanclass="pre">--logdir=your_save_dir</span></code> in your terminal and visit <codeclass="docutils literal notranslate"><spanclass="pre">http://localhost:6006/</span></code> in a web browser. See <aclass="reference external"href="https://pytorch.org/docs/stable/tensorboard.html">pytorch tensorboard</a> for further information.</p>
<h2><aclass="toc-backref"href="#id14">Visualize ranked results</a><aclass="headerlink"href="#visualize-ranked-results"title="Permalink to this headline">¶</a></h2>
<p>Ranked images can be visualized by setting <codeclass="docutils literal notranslate"><spanclass="pre">visrank</span></code> to true in <codeclass="docutils literal notranslate"><spanclass="pre">engine.run()</span></code>. <codeclass="docutils literal notranslate"><spanclass="pre">visrank_topk</span></code> determines the top-k images to be visualized (Default is <codeclass="docutils literal notranslate"><spanclass="pre">visrank_topk=10</span></code>). Note that <codeclass="docutils literal notranslate"><spanclass="pre">visrank</span></code> can only be used in test mode, i.e. <codeclass="docutils literal notranslate"><spanclass="pre">test_only=True</span></code> in <codeclass="docutils literal notranslate"><spanclass="pre">engine.run()</span></code>. The images will be saved under <codeclass="docutils literal notranslate"><spanclass="pre">save_dir/visrank_DATASETNAME</span></code> where each image contains the top-k ranked list given a query. An example is shown below. Red and green denote incorrect and correct matches respectively.</p>
<h2><aclass="toc-backref"href="#id15">Visualize activation maps</a><aclass="headerlink"href="#visualize-activation-maps"title="Permalink to this headline">¶</a></h2>
<p>To understand where the CNN focuses on to extract features for ReID, you can visualize the activation maps as in <aclass="reference external"href="https://arxiv.org/abs/1905.00953">OSNet</a>. This can be achieved by setting <codeclass="docutils literal notranslate"><spanclass="pre">visactmap=True</span></code> in <codeclass="docutils literal notranslate"><spanclass="pre">engine.run()</span></code> (<codeclass="docutils literal notranslate"><spanclass="pre">test_only</span></code> does not have to be True as <codeclass="docutils literal notranslate"><spanclass="pre">visactmap</span></code> is independent of <codeclass="docutils literal notranslate"><spanclass="pre">test_only</span></code>. See the code for details). Images will be saved in <codeclass="docutils literal notranslate"><spanclass="pre">save_dir/actmap_DATASETNAME</span></code>. An example is shown below (from left to right: image, activation map, overlapped image)</p>
<p>In order to visualize activation maps, the CNN needs to output the last convolutional feature maps at eval mode. See <codeclass="docutils literal notranslate"><spanclass="pre">torchreid/models/osnet.py</span></code> for example.</p>
<h2><aclass="toc-backref"href="#id16">Use your own dataset</a><aclass="headerlink"href="#use-your-own-dataset"title="Permalink to this headline">¶</a></h2>
<li><p>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 <codeclass="docutils literal notranslate"><spanclass="pre">ImageDataset</span></code> to <codeclass="docutils literal notranslate"><spanclass="pre">VideoDataset</span></code>.</p></li>
<spanclass="n">targets</span><spanclass="o">=</span><spanclass="s1">'market1501'</span><spanclass="c1"># or targets=['market1501', 'cuhk03']</span>
<h2><aclass="toc-backref"href="#id17">Design your own Engine</a><aclass="headerlink"href="#design-your-own-engine"title="Permalink to this headline">¶</a></h2>
<p>A new Engine should be designed if you have your own loss function. The base Engine class <codeclass="docutils literal notranslate"><spanclass="pre">torchreid.engine.Engine</span></code> 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 <codeclass="docutils literal notranslate"><spanclass="pre">ImageSoftmaxEngine</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">ImageTripletEngine</span></code> are constructed (also <codeclass="docutils literal notranslate"><spanclass="pre">VideoSoftmaxEngine</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">VideoTripletEngine</span></code>). All you need to implement might be just a <codeclass="docutils literal notranslate"><spanclass="pre">train()</span></code> function.</p>
Built with <ahref="http://sphinx-doc.org/">Sphinx</a> using a <ahref="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <ahref="https://readthedocs.org">Read the Docs</a>.