<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://trung-dt.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://trung-dt.com/" rel="alternate" type="text/html" /><updated>2026-09-12T03:54:08+00:00</updated><id>https://trung-dt.com/feed.xml</id><title type="html">Trung Dao</title><subtitle>1st-year PhD student at UW-Madison, advised by Prof. Yong Jae Lee. I work on vision-language-action (VLA) models and world models, with the broader goal of teaching machines to perceive, simulate, and act. Previously I was a Staff Machine Learning Engineer at Qualcomm AI Research (efficient generative &amp; multimodal models for edge) and a Research Resident at VinAI Research (advised by Dr. Anh Tran and Dr. Cuong Pham), where I focused on diffusion distillation and GANs.

</subtitle><entry><title type="html">Paper recap: Focal Loss for Dense Object Detection</title><link href="https://trung-dt.com/paper-recap/2020/10/12/focalloss.html" rel="alternate" type="text/html" title="Paper recap: Focal Loss for Dense Object Detection" /><published>2020-10-12T00:00:00+00:00</published><updated>2020-10-12T00:00:00+00:00</updated><id>https://trung-dt.com/paper-recap/2020/10/12/focalloss</id><content type="html" xml:base="https://trung-dt.com/paper-recap/2020/10/12/focalloss.html"><![CDATA[<h2 id="focal-loss-for-dense-object-detection">Focal Loss for Dense Object Detection</h2>
<p><a href="https://arxiv.org/abs/1708.02002">Lin et al, 2020</a></p>

<h2 id="research-topic">Research Topic</h2>
<ul>
  <li>Category (General): Deep Learning</li>
  <li>Category (Specific): Computer Vision</li>
</ul>

<h2 id="paper-summary">Paper summary</h2>
<ul>
  <li>Propose a new loss function tackling the extreme class imbalance problem encountered in object detections.</li>
  <li>Reshaping Cross Entropy Loss Function such that it down-weights the loss assigned to well-classified examples.</li>
  <li>Understand if one-stage de-tectors can match or surpass the accuracy of two-stage detectors while running at similar or faster speeds.</li>
  <li>Introduce the RetinaNet to evaluate the effectiveness of the loss, but since the author stated: “Our simple detector achieves top results not based on innovations in network design but due to our novel loss.”, I’m gonna skip the RetinaNet in this recap.</li>
</ul>

<h2 id="explain-like-im-5-eli5-">Explain Like I’m 5 (ELI5) 👶👶👶</h2>
<ul>
  <li>Basically it is Balanced Cross Entropy Loss Function but with a tunable modulating factor such that it controls the weight loss of easy/hard samples.</li>
</ul>

<h2 id="issues-addressed-by-the-paper">Issues addressed by the paper</h2>
<ul>
  <li>Current state-of-the-art object detectors are based on a two-stage, proposal-driven mechanism, which  consistently achieves top accuracy on the challenging COCO benchmark.</li>
  <li>Could a simple one-stage detector achieve similar accuracy?</li>
  <li>Recent work on one-stage detectors yield faster detectors with accuracy within 10-40% relative to state-of-the-art two-stage methods, but takes also a lot of time.</li>
  <li>Class imbalance is addressed in R-CNN-like (one-stage) detectors by a two-stage cascade and sampling heuristics.</li>
  <li>An one-stage detector must process a much larger set of candidate object locations regularly sampled across an image, which makes the model inefficient as the training procedure is still dominated by easily classified background examples.</li>
  <li>Balanced CE loss function: while \(\alpha\) balances the importance of positive/negative examples, it does not differentiate between easy/hard examples.</li>
</ul>

<h2 id="approachmethod">Approach/Method</h2>
<ul>
  <li>Present a one-stage object detector (RetinaNet) that, for the first time (by the time of publish), matches the state-of-the-art COCO AP.</li>
  <li>To achieve this result:
    <ul>
      <li>Identify class imbalance during training as the main obstacle impeding one-stage detector from achieving state-of-the-art accuracy,</li>
      <li>Propose a new loss function that eliminates this barrier.</li>
    </ul>
  </li>
  <li>Focal Loss:
    <ul>
      <li>Dynamically scaled cross entropy loss.</li>
      <li>Automatically down-weight the contribution of easy examples (inliers) during training and rapidly focus the model on hard examples.</li>
      <li>Focal loss performs the <em>opposite role</em> of a robust loss (e.g: Huber Loss): it focuses training on a sparse set of hard examples.</li>
      <li>They first defined the probability function like this:</li>
    </ul>

\[p_t = \left\{
          \begin{array}{ll}
              p &amp; if \ y=1 \\
              1-p &amp; otherwise.
          \end{array}
      \right.\]

    <ul>
      <li>Using this definition, we can define CE loss func like this: \(CE(p,y) = CE(p_t) = -log(p_t)\) for comparision.</li>
      <li>Balanced Focal Loss’s definition:</li>
    </ul>

\[FL(p_t) = -\alpha_{t}(1-p_t)^{\gamma}log(p_t)\]

    <ul>
      <li>When an example is misclassified and \(p_t\) is small, the modulating factor is near 1 and the loss is unaffected. As \(p_t \to 1\), the factor goes to 0 and the loss for well-classified is down-weighted.</li>
      <li>The focusing parameter \(\gamma\) smoothly adjusts the rate at which easy examples are down-weighted.</li>
      <li>When \(\gamma = 0\), focal loss is equivalent to cross entropy loss, as \(\gamma\) is increased the effect of the modulating factor is likewise increased.</li>
    </ul>

    <p align="center">
      <img src="/assets/images/focal/focal_ce.png" style="width: 50%;" alt="focal_ce" />
  </p>
  </li>
</ul>

<h2 id="best-practice">Best practice</h2>
<ul>
  <li>\(\gamma = 2\) works well in practice.</li>
  <li>The benefit of changing \(\gamma\) is much larger, and indeed the best \(\alpha\)’s ranged in just [.25,.75].</li>
  <li>In general \(\alpha\) should be decreased slightly as \(\gamma\) is increased.</li>
</ul>

<h2 id="hidden-gems">Hidden gems💎💎💎</h2>
<ul>
  <li>In practice \(\alpha\) (of Balanced CE) may be set by inverse class frequency or treated as a hyperparameter to set by cross validation.</li>
  <li>One notable property of CE loss, which can be easily seen in the upper plot, is that even examples that are easily classified incur a loss with non-trivial magnitude. When summed over a large number of easy examples, these small loss values can overwhelm the rare class.</li>
  <li>Two-stage detectors are often trained with the CE loss without use of \(\alpha\)-balancing, but address class imbalance through two mechanisms: (1) a two-stage cascade and (2) biased minibatch sampling.</li>
  <li>Feature Pyramid Network augments a standard convolutional network with a top-down pathway and lateral connections so the network efficiently constructs a rich, multi-scale feature pyramid from a single resolution input image.</li>
  <li>Larger backbone networks yield higher accuracy, but also slower inference speeds, likewise for input image scale.</li>
</ul>

<h2 id="confusing-aspects-of-the-paper">Confusing aspects of the paper</h2>
<ul>
  <li>The different between easy and hard sample?
    <ul>
      <li>The difference between the two is not obvious from the paper.</li>
      <li>IMO, easy samples means that the probability \(p_t\) is close to the class (1 for positive, 0 for negative), vice versa for the hard samples.</li>
    </ul>
  </li>
  <li>Why \(\alpha\)-balancing of CE doesn’t differentiate between easy/ hard examples?
    <ul>
      <li>This issue is also not verified in the paper.</li>
      <li>IMO, \(\alpha\) is only used to address the imbalanced class problem (since its value also tuned for the same reason), Focal Loss adds the modular factor which directly affected by the probability that the model suggested and adjust the loss.</li>
    </ul>
  </li>
</ul>

<h2 id="results">Results</h2>
<p align="center">
    <img src="/assets/images/focal/result.png" style="width: 80%;" alt="result" />
</p>
<ul>
  <li>The model achieves top results, outperforming both one-stage and two-stage models.</li>
</ul>

<h2 id="conclusions">Conclusions</h2>

<h3 id="the-authors-conclusions">The author’s conclusions</h3>
<ul>
  <li>Focal loss applies a modulating term to the cross entropy loss in order to focus learning on hard negative examples.</li>
  <li>The approach is simple and highly effective.</li>
</ul>

<h3 id="rating">Rating</h3>
<p><img src="https://media.giphy.com/media/3o6vY7UsuMPx3Yj9Xa/giphy.gif" alt="rating" /></p>

<h2 id="paper-implementation">Paper implementation</h2>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">FocalLoss</span><span class="p">(</span><span class="n">nn</span><span class="p">.</span><span class="n">Module</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">n_class</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">gamma</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">reduction</span><span class="o">=</span><span class="s">'mean'</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">FocalLoss</span><span class="p">,</span> <span class="bp">self</span><span class="p">).</span><span class="n">__init__</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">alpha</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">alpha</span> <span class="o">=</span> <span class="n">Variable</span><span class="p">(</span><span class="n">torch</span><span class="p">.</span><span class="n">ones</span><span class="p">(</span><span class="n">n_class</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">alpha</span> <span class="o">=</span> <span class="n">alpha</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">alpha</span><span class="p">,</span> <span class="n">Variable</span><span class="p">)</span> <span class="k">else</span> <span class="n">Variable</span><span class="p">(</span><span class="n">alpha</span><span class="p">)</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">gamma</span> <span class="o">=</span> <span class="n">gamma</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">n_class</span> <span class="o">=</span> <span class="n">n_class</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">reduction</span> <span class="o">=</span> <span class="n">reduction</span>

    <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">targets</span><span class="p">):</span>
        <span class="n">device</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">.</span><span class="n">device</span>
        <span class="n">bs</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">.</span><span class="n">size</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
        <span class="n">n_channel</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">.</span><span class="n">size</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">probs</span> <span class="o">=</span> <span class="n">F</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">inputs</span><span class="p">)</span>
        <span class="n">class_mask</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">bs</span><span class="p">,</span> <span class="n">n_channel</span><span class="p">).</span><span class="n">fill_</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
        <span class="n">class_mask</span> <span class="o">=</span> <span class="n">Variable</span><span class="p">(</span><span class="n">class_mask</span><span class="p">)</span>
        <span class="n">ys</span> <span class="o">=</span> <span class="n">targets</span><span class="p">.</span><span class="n">view</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
        <span class="c1"># onehot encoding
</span>        <span class="n">class_mask</span><span class="p">.</span><span class="n">scatter_</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">ys</span><span class="p">.</span><span class="n">data</span><span class="p">,</span> <span class="mf">1.</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">inputs</span><span class="p">.</span><span class="n">is_cuda</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="p">.</span><span class="n">alpha</span><span class="p">.</span><span class="n">is_cuda</span><span class="p">:</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">alpha</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">alpha</span><span class="p">.</span><span class="n">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span>

        <span class="n">alphas</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">alpha</span><span class="p">[</span><span class="n">ys</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">view</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)]</span>
        <span class="n">probs</span> <span class="o">=</span> <span class="p">(</span><span class="n">probs</span><span class="o">*</span><span class="n">class_mask</span><span class="p">).</span><span class="nb">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="n">view</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">log_p</span> <span class="o">=</span> <span class="n">probs</span><span class="p">.</span><span class="n">log</span><span class="p">()</span>
        <span class="n">batch_loss</span> <span class="o">=</span> <span class="o">-</span><span class="n">alphas</span><span class="o">*</span><span class="p">(</span><span class="n">torch</span><span class="p">.</span><span class="nb">pow</span><span class="p">((</span><span class="mi">1</span><span class="o">-</span><span class="n">probs</span><span class="p">),</span> <span class="bp">self</span><span class="p">.</span><span class="n">gamma</span><span class="p">))</span><span class="o">*</span><span class="n">log_p</span>
        <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">reduction</span> <span class="o">==</span> <span class="s">"mean"</span><span class="p">:</span>
            <span class="n">loss</span> <span class="o">=</span> <span class="n">batch_loss</span><span class="p">.</span><span class="n">mean</span><span class="p">()</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">loss</span> <span class="o">=</span> <span class="n">batch_loss</span><span class="p">.</span><span class="nb">sum</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">loss</span>
</code></pre></div></div>

<h2 id="cited-references-and-used-images-from">Cited references and used images from:</h2>
<ul>
  <li><a href="https://arxiv.org/abs/1708.02002">Focal Loss for Dense Object Detection</a></li>
  <li><a href="https://www.reddit.com/r/computervision/comments/9blsrl/focal_loss_for_dense_object_detection_retinanet/">Reddit post</a></li>
</ul>

<h2 id="papers-needed-to-be-conquered-next-">Papers needed to be conquered next 👏👏👏</h2>
<ul>
  <li>SIMCLR maybe?</li>
</ul>]]></content><author><name></name></author><category term="paper-recap" /><summary type="html"><![CDATA[Focal Loss for Dense Object Detection Lin et al, 2020]]></summary></entry><entry><title type="html">Paper recap: Bag of Tricks for Image Classification with Convolutional Neural Networks</title><link href="https://trung-dt.com/paper-recap/2020/09/07/bagoftricks.html" rel="alternate" type="text/html" title="Paper recap: Bag of Tricks for Image Classification with Convolutional Neural Networks" /><published>2020-09-07T00:00:00+00:00</published><updated>2020-09-07T00:00:00+00:00</updated><id>https://trung-dt.com/paper-recap/2020/09/07/bagoftricks</id><content type="html" xml:base="https://trung-dt.com/paper-recap/2020/09/07/bagoftricks.html"><![CDATA[<h2 id="bag-of-tricks-for-image-classification-with-convolutional-neural-networks">Bag of Tricks for Image Classification with Convolutional Neural Networks</h2>
<p><a href="https://arxiv.org/abs/1812.01187">He, Tong Zhang, Zhi Zhang, Hang Zhang, Zhongyue Xie, Junyuan Li, Mu, 2019</a></p>

<h2 id="research-topic">Research Topic</h2>
<ul>
  <li>Category (General): Deep Learning</li>
  <li>Category (Specific): Computer Vision</li>
</ul>

<h2 id="paper-summary">Paper summary</h2>
<ul>
  <li>Synthesize multiple effective methods that are briefly mentioned in litterature, in order to evaluate their impact on the final model accuracy through ablation study.</li>
</ul>

<h2 id="issues-addressed-by-the-paper">Issues addressed by the paper</h2>
<ul>
  <li>Find a combination of training procedure and model architecture refinements that improve model accuracy but barely change computational complexity.</li>
  <li>These “tricks” usually are minor ones (such as changing the stride of a convolutional layer), but create a big impact.</li>
  <li>These methods lead to significant accuracy improvement and combining them together can further boost the model accuracy. Transfer learning’s performance of these “boosted” model would be much better too.</li>
</ul>

<h2 id="approachmethod">Approach/Method</h2>

<h3 id="training-baseline">Training baseline</h3>
<ul>
  <li>Use the same training transformation (random sampling, random crop, random flip, hue/saturation/brightness, PCA noise, normalize).</li>
  <li>Only resize in validation set.</li>
  <li>Xavier initialization for weights of both convolutional and fully connected.</li>
  <li>Use NAG (Nesterov), 120 epochs, 8 GPUs, batch-size = 256.</li>
  <li>LR initialized to 0.1 and divided by 10 at the 30th, 60th, and 90th epochs.</li>
</ul>

<p align="center">
  <img src="/assets/images/bot/baseline.png" style="width: 50%;" alt="baseline" />
</p>

<h3 id="efficient-training">Efficient Training</h3>
<ol>
  <li>Larger training batch-size:
    <ul>
      <li>Since we’re using mini-batch SGD, for the same number of epochs, training with a large batch size results in a model with degraded validation accuracy compared to the ones trained with smaller batch sizes.</li>
      <li>Some heuristics the help scale the batch size up like:
        <ul>
          <li><strong>Linear scaling learning rate</strong>: a large batch size reduces the noise in the gradient, so we may increase the learning rate to make a larger progress along the op- posite of the gradient direction.</li>
          <li><strong>Learning rate warmup</strong>: Using a too large learning rate may result in numerical instability, so we gradually increase it.</li>
          <li><strong>Zero \(\gamma\)</strong>: we initialize \(\gamma = 0\) for all BN layers that sit at the end of a residual block. Therefore, all residual blocks just return their inputs, mimics network that has less number of layers and is easier to train at the initial stage.</li>
          <li><strong>No bias decay</strong>: Only apply to the regularization to weights to avoid overfitting.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Low-precision training:
    <ul>
      <li>Use FP16 to train since new hardware may have enhanced arithmetic logic unit for lower precision data types.</li>
    </ul>
  </li>
</ol>

<p align="center">
  <img src="/assets/images/bot/efficient_training.png" style="width: 85%;" alt="efficient_training" />
</p>

<h3 id="model-tweaks">Model Tweaks</h3>
<ul>
  <li>A model tweak is a minor adjustment to the network architecture (changing the stride of convlution layer).</li>
  <li>Such a tweak barely changes the computational complexity but might have a non-negligible effect on the model accuracy.</li>
  <li>Take a closer look at Resnet architecture:
    <ul>
      <li>Resnet network consists of an input stem (reduces the input W/H by 4 times and increases its channel size to 64), four subsequent stages and a final output layer.</li>
      <li>Resnet has a basic block called Bottleneck Block (downsampling block). There are 2 paths in the block:
        <ul>
          <li>Path A: has three convolutions, whose kernel sizes are 1×1 (stride 2 - halve the input size), 3×3 and 1×1 (output channels x4 the previous 2), respectively.</li>
          <li>Path B: uses a 1×1 convolution (stride of 2) to create the same output shape as path A, so we can sum outputs of both paths to obtain the output of the downsampling block.</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<p align="center">
  <img src="/assets/images/bot/resnet.png" style="width: 50%;" alt="resnet" />
</p>

<ul>
  <li>There are 3 tweaks mentioned is this paper:</li>
</ul>
<p align="center">
  <img src="/assets/images/bot/resnet_tweak.png" style="width: 50%;" alt="resnet_tweak" />
</p>
<ul>
  <li><strong>Resnet-B</strong>: modifies downsampling block
    <ul>
      <li>Observation: convolution in path A (original) ignores \(\frac{3}{4}\) of the input feature map because it uses a kernel size 1×1 with a stride of 2.</li>
      <li>Tweak: Change stride of the first two conv, so no information is ignored.</li>
    </ul>
  </li>
  <li><strong>Resnet-C</strong>: modifies input stem
    <ul>
      <li>Observation: the computational cost of a convolution is quadratic to the kernel width or height (A 7 × 7 convolution is 5.4 times more expensive than a 3 × 3 convolution).</li>
      <li>Tweak: replacing the 7×7 convolution with 3 conservative 3 × 3 convolutions, with the first and second convolutions have their output channel of 32 and a stride of 2, while the last convolution uses a 64 output channel.</li>
    </ul>
  </li>
  <li><strong>Resnet-D</strong>: modifies downsampling block
    <ul>
      <li>Observation: Inspired by Resnet-B, 1×1 convolution in the path B also ignores \(\frac{3}{4}\) of input feature maps.</li>
      <li>Tweak: Change stride to 1 and add a 2×2 average pooling layer with a stride of 2 before the convolution, since it works well in practice and impacts the computational cost little.</li>
    </ul>
  </li>
</ul>

<p align="center">
  <img src="/assets/images/bot/resnet_tweak_res.png" style="width: 50%;" alt="resnet_tweak_res" />
</p>

<h3 id="training-refinements">Training Refinements</h3>
<ul>
  <li><strong>Cosine Learning Rate Decay</strong>:
    <ul>
      <li>Method: Same as my previous post.</li>
      <li>Result: Compared to the step decay, the cosine decay starts to decay the learning since the beginning but remains large until step decay reduces the learning rate by 10x, which potentially improves the training progress.</li>
    </ul>
  </li>
</ul>
<p align="center">
  <img src="/assets/images/bot/cosanneal.png" style="width: 50%;" alt="cosanneal" />
</p>

<ul>
  <li><strong>Label Smoothing</strong>:
    <ul>
      <li>Method: Same as my previous post.</li>
      <li>Result: Compared to the softmax, it encourages a finite output from the fully-connected layer and can generalize better.</li>
    </ul>
  </li>
  <li><strong>Knowledge Distillation</strong>: skipped.</li>
  <li><strong>Mixup</strong>: Same as my previous post.</li>
</ul>

<p align="center">
  <img src="/assets/images/bot/refinements.png" style="width: 50%;" alt="refinements" />
</p>

<h2 id="conclusions">Conclusions</h2>

<h3 id="rating">Rating</h3>
<p><img src="https://media.giphy.com/media/xl3Bs2qfS1jDOSHA8V/giphy.gif" alt="rating" /></p>

<h2 id="papers-needs-to-conquer-next-">Papers needs to conquer next 👏👏👏</h2>
<ul>
  <li>Focal Loss</li>
</ul>]]></content><author><name></name></author><category term="paper-recap" /><summary type="html"><![CDATA[Bag of Tricks for Image Classification with Convolutional Neural Networks He, Tong Zhang, Zhi Zhang, Hang Zhang, Zhongyue Xie, Junyuan Li, Mu, 2019 Research Topic Category (General): Deep Learning Category (Specific): Computer Vision Paper summary Synthesize multiple effective methods that are briefly mentioned in litterature, in order to evaluate their impact on the final model accuracy through ablation study. Issues addressed by the paper Find a combination of training procedure and model architecture refinements that improve model accuracy but barely change computational complexity. These “tricks” usually are minor ones (such as changing the stride of a convolutional layer), but create a big impact. These methods lead to significant accuracy improvement and combining them together can further boost the model accuracy. Transfer learning’s performance of these “boosted” model would be much better too. Approach/Method Training baseline Use the same training transformation (random sampling, random crop, random flip, hue/saturation/brightness, PCA noise, normalize). Only resize in validation set. Xavier initialization for weights of both convolutional and fully connected. Use NAG (Nesterov), 120 epochs, 8 GPUs, batch-size = 256. LR initialized to 0.1 and divided by 10 at the 30th, 60th, and 90th epochs. Efficient Training Larger training batch-size: Since we’re using mini-batch SGD, for the same number of epochs, training with a large batch size results in a model with degraded validation accuracy compared to the ones trained with smaller batch sizes. Some heuristics the help scale the batch size up like: Linear scaling learning rate: a large batch size reduces the noise in the gradient, so we may increase the learning rate to make a larger progress along the op- posite of the gradient direction. Learning rate warmup: Using a too large learning rate may result in numerical instability, so we gradually increase it. Zero \(\gamma\): we initialize \(\gamma = 0\) for all BN layers that sit at the end of a residual block. Therefore, all residual blocks just return their inputs, mimics network that has less number of layers and is easier to train at the initial stage. No bias decay: Only apply to the regularization to weights to avoid overfitting. Low-precision training: Use FP16 to train since new hardware may have enhanced arithmetic logic unit for lower precision data types. Model Tweaks A model tweak is a minor adjustment to the network architecture (changing the stride of convlution layer). Such a tweak barely changes the computational complexity but might have a non-negligible effect on the model accuracy. Take a closer look at Resnet architecture: Resnet network consists of an input stem (reduces the input W/H by 4 times and increases its channel size to 64), four subsequent stages and a final output layer. Resnet has a basic block called Bottleneck Block (downsampling block). There are 2 paths in the block: Path A: has three convolutions, whose kernel sizes are 1×1 (stride 2 - halve the input size), 3×3 and 1×1 (output channels x4 the previous 2), respectively. Path B: uses a 1×1 convolution (stride of 2) to create the same output shape as path A, so we can sum outputs of both paths to obtain the output of the downsampling block. There are 3 tweaks mentioned is this paper: Resnet-B: modifies downsampling block Observation: convolution in path A (original) ignores \(\frac{3}{4}\) of the input feature map because it uses a kernel size 1×1 with a stride of 2. Tweak: Change stride of the first two conv, so no information is ignored. Resnet-C: modifies input stem Observation: the computational cost of a convolution is quadratic to the kernel width or height (A 7 × 7 convolution is 5.4 times more expensive than a 3 × 3 convolution). Tweak: replacing the 7×7 convolution with 3 conservative 3 × 3 convolutions, with the first and second convolutions have their output channel of 32 and a stride of 2, while the last convolution uses a 64 output channel. Resnet-D: modifies downsampling block Observation: Inspired by Resnet-B, 1×1 convolution in the path B also ignores \(\frac{3}{4}\) of input feature maps. Tweak: Change stride to 1 and add a 2×2 average pooling layer with a stride of 2 before the convolution, since it works well in practice and impacts the computational cost little. Training Refinements Cosine Learning Rate Decay: Method: Same as my previous post. Result: Compared to the step decay, the cosine decay starts to decay the learning since the beginning but remains large until step decay reduces the learning rate by 10x, which potentially improves the training progress. Label Smoothing: Method: Same as my previous post. Result: Compared to the softmax, it encourages a finite output from the fully-connected layer and can generalize better. Knowledge Distillation: skipped. Mixup: Same as my previous post. Conclusions Rating Papers needs to conquer next 👏👏👏 Focal Loss]]></summary></entry><entry><title type="html">Paper recap: CutMix</title><link href="https://trung-dt.com/paper-recap/2020/08/31/cutmix.html" rel="alternate" type="text/html" title="Paper recap: CutMix" /><published>2020-08-31T00:00:00+00:00</published><updated>2020-08-31T00:00:00+00:00</updated><id>https://trung-dt.com/paper-recap/2020/08/31/cutmix</id><content type="html" xml:base="https://trung-dt.com/paper-recap/2020/08/31/cutmix.html"><![CDATA[<h2 id="cutmix-regularization-strategy-to-train-strong-classifiers-with-localizable-features">CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features</h2>
<p><a href="https://arxiv.org/abs/1710.09412">Yun, Sangdoo Han, Dongyoon Chun, Sanghyuk Oh, Seong Joon Choe, Junsuk Yoo, Youngjoon</a></p>

<h2 id="research-topic">Research Topic</h2>
<ul>
  <li>Category (General): Deep Learning</li>
  <li>Category (Specific): Data Augmentation</li>
</ul>

<h2 id="paper-summary">Paper summary</h2>
<ul>
  <li>Introduce a new data augmentation method: CutMix, which helps:
    <ul>
      <li>Generates new samples by cutting and pasting patches within mini-batches, leading to performance boosts in many computer vision tasks.</li>
      <li>Improves the model robustness against input corruptions</li>
      <li>Performs better when facing out-of-distribution detection problems.</li>
    </ul>
  </li>
</ul>

<h2 id="explain-like-im-5-eli5-">Explain Like I’m 5 (ELI5) 👶👶👶</h2>
<p align="center">
  <img src="/assets/images/cutmix/example.jpeg" style="width: 50%;" alt="ex" />
</p>

<h2 id="issues-addressed-by-the-paper">Issues addressed by the paper</h2>
<ul>
  <li>Regional cutout may remove informative pixels, in addition to it, these techniques also add noises by replace those cut pixels with black area.</li>
  <li>How can we maximally utilize the deleted regions, while taking advantage of better generalization and localization using regional dropout?</li>
  <li>While certainly improving classification performance, Mixup samples tend to be unnatural.</li>
  <li>Synthesizing training data guides also improves model performance, but introduces costly computations.</li>
  <li>Recently, methods adding noises to the internal features of CNNs or adding extra path to the architecture have been proposed to enhance image classification performance.</li>
  <li>Cutmix has properties such that can compensate all of those mentioned above.</li>
</ul>

<h2 id="approachmethod">Approach/Method</h2>
<ul>
  <li>Core idea: We have 2 pictures, choose a region (apply to both pictures) in the image that is proportional to the image’s ratio, then swap those regions, leads to a new sample.
    <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="n">new_image</span> <span class="o">=</span> <span class="n">MASK</span> <span class="o">*</span> <span class="n">image_1</span> <span class="o">+</span> <span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="n">MASK</span><span class="p">)</span> <span class="o">*</span> <span class="n">image_2</span>
  <span class="n">new_label</span> <span class="o">=</span> <span class="k">lambda</span> <span class="o">*</span> <span class="n">label_1</span> <span class="o">+</span> <span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="k">lambda</span><span class="p">)</span> <span class="o">*</span> <span class="n">label_2</span>
</code></pre></div>    </div>
  </li>
  <li><code class="language-plaintext inlined highlighter-rouge">lambda</code> is sampled from symmetric Beta distribution (having same \(\alpha\) and \(\beta\) value), which looks like the following image. This distribution makes sure that the new image will most of the time be close only to the first or the second picture. Only sometimes both images have the same intensity (of course if in a case of multicategorical, other label will be 0).</li>
</ul>

<p align="center">
  <img src="/assets/images/mixup/beta.png" style="width: 50%;" alt="lr" />
</p>

<ul>
  <li><code class="language-plaintext inlined highlighter-rouge">MASK</code> has the same WxH like the original image, having full 0s in the region that is gonna be cutout (let’s call it <code class="language-plaintext inlined highlighter-rouge">B</code>) and full 1s in the leftover pixels.</li>
  <li><code class="language-plaintext inlined highlighter-rouge">B</code> is a bounding box, having coordinates defined as \(B = (r_x, r_y, r_w, r_h)\) indicating the cropping regions.</li>
</ul>

\[r_x \sim Unif(0,W); \: r_w = W \sqrt{1 - \lambda} \\
    r_y \sim Unif(0,H); \: r_h = H \sqrt{1 - \lambda}\]

<ul>
  <li>Having these coordinates defined like this would make the cropped area ratio equals to \(1 - \lambda\).</li>
</ul>

<h2 id="result">Result</h2>
<p align="center">
  <img src="/assets/images/cutmix/compare.png" style="width: 50%;" alt="compare" />
</p>
<ul>
  <li>CutMix overcomes the problem of both Mixup (its samples tend to be unnatural) and regional cutout (removes informative pixels) by replacing the image region with a patch from another training image.</li>
  <li>CutMix incurs only negligible additional cost for training.</li>
  <li>Cutout successfully lets a model focus on less discriminative parts of the object.</li>
</ul>
<p align="center">
  <img src="/assets/images/cutmix/CAM.png" style="width: 50%;" alt="CAM" />
</p>
<ul>
  <li>Outperforms other SOTAs using data augmentation during the time of publish.</li>
</ul>
<p align="center">
  <img src="/assets/images/cutmix/result.png" style="width: 50%;" alt="result" />
</p>

<h2 id="best-practice">Best practice</h2>
<ul>
  <li>\(\alpha = 1\) usually performs well.</li>
  <li>Cutout, Mixup, and CutMix require a greater number of training epochs till convergence.</li>
  <li>CutMix achieves the best performance when it is applied on the input images rather than hidden features.</li>
  <li>A new state-of-the-art performance 13.81% (in CIFAR-100) by combining CutMix and ShakeDrop, a regularization that adds noise on intermediate features.</li>
</ul>

<h2 id="hidden-gems">Hidden gems💎💎💎</h2>
<ul>
  <li>Label-smoothing is good when apply together with data augmentation such as Cutout, Mixup, Dropblock.</li>
  <li>Mixup, Manifold Mixup achieve higher accuracies when Cutout is applied on input images.</li>
</ul>

<h2 id="conclusions">Conclusions</h2>

<h3 id="rating">Rating</h3>
<p><img src="https://media.giphy.com/media/l2JeeiVJzPmuMIRlS/giphy.gif" alt="rating" /></p>

<h2 id="paper-implementation">Paper implementation</h2>
<ul>
  <li>Using Pytorch Lightning Callback system, inspired by fastai implementation.
    <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">class</span> <span class="nc">MixLoss</span><span class="p">(</span><span class="n">nn</span><span class="p">.</span><span class="n">Module</span><span class="p">):</span>
      <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_lf</span><span class="p">,</span> <span class="n">mixup_cb</span><span class="p">):</span>
          <span class="nb">super</span><span class="p">().</span><span class="n">__init__</span><span class="p">()</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span> <span class="o">=</span> <span class="n">old_lf</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span> <span class="o">=</span> <span class="n">mixup_cb</span>

      <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pred</span><span class="p">,</span> <span class="n">yb</span><span class="p">):</span>
          <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">pl_module</span><span class="p">.</span><span class="n">testing</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span><span class="p">(</span><span class="n">pred</span><span class="p">,</span> <span class="n">yb</span><span class="p">)</span>
          <span class="k">with</span> <span class="n">NoneReduce</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span><span class="p">)</span> <span class="k">as</span> <span class="n">lf</span><span class="p">:</span>
              <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">yb_1</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">yb_1</span><span class="p">.</span><span class="n">to</span><span class="p">(</span><span class="n">pred</span><span class="p">.</span><span class="n">device</span><span class="p">)</span>
              <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">lam</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">lam</span><span class="p">.</span><span class="n">to</span><span class="p">(</span><span class="n">pred</span><span class="p">.</span><span class="n">device</span><span class="p">)</span>
              <span class="n">loss</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">lerp</span><span class="p">(</span><span class="n">lf</span><span class="p">(</span><span class="n">pred</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">yb_1</span><span class="p">),</span> <span class="n">lf</span><span class="p">(</span><span class="n">pred</span><span class="p">,</span><span class="n">yb</span><span class="p">),</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">lam</span><span class="p">)</span>
          <span class="k">return</span> <span class="n">reduce_loss</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span><span class="p">,</span> <span class="s">'reduction'</span><span class="p">,</span> <span class="s">'mean'</span><span class="p">))</span>

  <span class="c1"># Cell
</span>  <span class="k">class</span> <span class="nc">CutmixDict</span><span class="p">(</span><span class="n">Callback</span><span class="p">):</span>
      <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">1.</span><span class="p">):</span>
          <span class="nb">super</span><span class="p">().</span><span class="n">__init__</span><span class="p">()</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">distrib</span> <span class="o">=</span> <span class="n">Beta</span><span class="p">(</span><span class="n">tensor</span><span class="p">(</span><span class="n">alpha</span><span class="p">),</span> <span class="n">tensor</span><span class="p">(</span><span class="n">alpha</span><span class="p">))</span>

      <span class="k">def</span> <span class="nf">on_train_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">):</span>
          <span class="k">assert</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">pl_module</span><span class="p">,</span> <span class="s">'loss_func'</span><span class="p">),</span> <span class="s">'Your LightningModule should have loss_func attribute as your loss function.'</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span> <span class="o">=</span> <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">loss_fnc</span> <span class="o">=</span> <span class="n">MixLoss</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
          <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">loss_fnc</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">pl_module</span> <span class="o">=</span> <span class="n">pl_module</span>

      <span class="k">def</span> <span class="nf">_cutmix</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">batch</span><span class="p">,</span> <span class="n">logger</span><span class="p">,</span> <span class="n">log_image</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">pre_fix</span><span class="o">=</span><span class="s">'train'</span><span class="p">):</span>
          <span class="n">xb</span><span class="p">,</span> <span class="n">yb</span> <span class="o">=</span> <span class="n">batch</span><span class="p">[</span><span class="s">"img"</span><span class="p">],</span> <span class="n">batch</span><span class="p">[</span><span class="s">"label"</span><span class="p">]</span>
          <span class="n">bs</span> <span class="o">=</span> <span class="n">yb</span><span class="p">.</span><span class="n">size</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
          <span class="n">W</span><span class="p">,</span> <span class="n">H</span> <span class="o">=</span> <span class="n">xb</span><span class="p">.</span><span class="n">size</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span> <span class="n">xb</span><span class="p">.</span><span class="n">size</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

          <span class="n">lam</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">distrib</span><span class="p">.</span><span class="n">sample</span><span class="p">((</span><span class="mi">1</span><span class="p">,)).</span><span class="n">squeeze</span><span class="p">()</span>
          <span class="n">lam</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">stack</span><span class="p">([</span><span class="n">lam</span><span class="p">,</span> <span class="mi">1</span><span class="o">-</span><span class="n">lam</span><span class="p">])</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">lam</span> <span class="o">=</span> <span class="n">lam</span><span class="p">.</span><span class="nb">max</span><span class="p">()</span>

          <span class="c1"># Permute the batch
</span>          <span class="n">shuffle</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">randperm</span><span class="p">(</span><span class="n">bs</span><span class="p">)</span>
          <span class="n">xb_1</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">yb_1</span> <span class="o">=</span> <span class="n">xb</span><span class="p">[</span><span class="n">shuffle</span><span class="p">],</span> <span class="n">yb</span><span class="p">[</span><span class="n">shuffle</span><span class="p">]</span>

          <span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">,</span> <span class="n">x2</span><span class="p">,</span> <span class="n">y2</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">rand_bbox</span><span class="p">(</span><span class="n">W</span><span class="p">,</span> <span class="n">H</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">lam</span><span class="p">)</span>
          <span class="n">xb</span><span class="p">[:,</span> <span class="p">:,</span> <span class="n">x1</span><span class="p">:</span><span class="n">x2</span><span class="p">,</span> <span class="n">y1</span><span class="p">:</span><span class="n">y2</span><span class="p">]</span> <span class="o">=</span> <span class="n">xb_1</span><span class="p">[:,</span> <span class="p">:,</span> <span class="n">x1</span><span class="p">:</span><span class="n">x2</span><span class="p">,</span> <span class="n">y1</span><span class="p">:</span><span class="n">y2</span><span class="p">]</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">lam</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="p">((</span><span class="n">x2</span><span class="o">-</span><span class="n">x1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">y2</span><span class="o">-</span><span class="n">y1</span><span class="p">))</span> <span class="o">/</span> <span class="nb">float</span><span class="p">(</span><span class="n">W</span><span class="o">*</span><span class="n">H</span><span class="p">))</span>

          <span class="k">if</span> <span class="n">log_image</span><span class="p">:</span>
              <span class="n">grid</span> <span class="o">=</span> <span class="n">torchvision</span><span class="p">.</span><span class="n">utils</span><span class="p">.</span><span class="n">make_grid</span><span class="p">(</span><span class="n">xb</span><span class="p">)</span>
              <span class="n">logger</span><span class="p">.</span><span class="n">experiment</span><span class="p">.</span><span class="n">add_image</span><span class="p">(</span><span class="n">pre_fix</span> <span class="o">+</span> <span class="s">'_cutmix'</span><span class="p">,</span> <span class="n">grid</span><span class="p">)</span>
              <span class="n">grid_g</span> <span class="o">=</span> <span class="n">torchvision</span><span class="p">.</span><span class="n">utils</span><span class="p">.</span><span class="n">make_grid</span><span class="p">(</span><span class="n">xb_1</span><span class="p">)</span>
              <span class="n">logger</span><span class="p">.</span><span class="n">experiment</span><span class="p">.</span><span class="n">add_image</span><span class="p">(</span><span class="n">pre_fix</span> <span class="o">+</span> <span class="s">'_cut_from'</span><span class="p">,</span> <span class="n">grid_g</span><span class="p">)</span>
              <span class="n">dif</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="n">xb</span> <span class="o">-</span> <span class="n">xb_1</span><span class="p">)</span>
              <span class="n">grid_d</span> <span class="o">=</span> <span class="n">torchvision</span><span class="p">.</span><span class="n">utils</span><span class="p">.</span><span class="n">make_grid</span><span class="p">(</span><span class="n">dif</span><span class="p">)</span>
              <span class="n">logger</span><span class="p">.</span><span class="n">experiment</span><span class="p">.</span><span class="n">add_image</span><span class="p">(</span><span class="n">pre_fix</span> <span class="o">+</span> <span class="s">'_dif'</span><span class="p">,</span> <span class="n">grid_d</span><span class="p">)</span>
          <span class="k">return</span> <span class="n">xb</span>

      <span class="k">def</span> <span class="nf">on_train_batch_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">,</span> <span class="n">batch</span><span class="p">,</span> <span class="n">batch_idx</span><span class="p">,</span> <span class="n">dataloader_idx</span><span class="p">):</span>
          <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">_cutmix</span><span class="p">(</span><span class="n">batch</span><span class="p">,</span> <span class="n">trainer</span><span class="p">.</span><span class="n">logger</span><span class="p">)</span>
          <span class="n">batch</span><span class="p">[</span><span class="s">"img"</span><span class="p">]</span> <span class="o">=</span> <span class="n">x</span>

      <span class="k">def</span> <span class="nf">on_validation_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">):</span>
          <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span>

      <span class="k">def</span> <span class="nf">on_validation_end</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">):</span>
          <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">loss_fnc</span>

      <span class="k">def</span> <span class="nf">on_fit_end</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">):</span>
          <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span>

      <span class="k">def</span> <span class="nf">rand_bbox</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">W</span><span class="p">,</span> <span class="n">H</span><span class="p">,</span> <span class="n">lam</span><span class="p">):</span>
          <span class="n">cut_rat</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mf">1.</span> <span class="o">-</span> <span class="n">lam</span><span class="p">)</span>
          <span class="n">cut_w</span> <span class="o">=</span> <span class="p">(</span><span class="n">W</span> <span class="o">*</span> <span class="n">cut_rat</span><span class="p">).</span><span class="nb">type</span><span class="p">(</span><span class="n">torch</span><span class="p">.</span><span class="nb">long</span><span class="p">)</span>
          <span class="n">cut_h</span> <span class="o">=</span> <span class="p">(</span><span class="n">H</span> <span class="o">*</span> <span class="n">cut_rat</span><span class="p">).</span><span class="nb">type</span><span class="p">(</span><span class="n">torch</span><span class="p">.</span><span class="nb">long</span><span class="p">)</span>
          <span class="c1"># uniform
</span>          <span class="n">cx</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">W</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,))</span>
          <span class="n">cy</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">H</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,))</span>
          <span class="n">x1</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">clamp</span><span class="p">(</span><span class="n">cx</span> <span class="o">-</span> <span class="n">cut_w</span> <span class="o">//</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">W</span><span class="p">)</span>
          <span class="n">y1</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">clamp</span><span class="p">(</span><span class="n">cy</span> <span class="o">-</span> <span class="n">cut_h</span> <span class="o">//</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">H</span><span class="p">)</span>
          <span class="n">x2</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">clamp</span><span class="p">(</span><span class="n">cx</span> <span class="o">+</span> <span class="n">cut_w</span> <span class="o">//</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">W</span><span class="p">)</span>
          <span class="n">y2</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">clamp</span><span class="p">(</span><span class="n">cy</span> <span class="o">+</span> <span class="n">cut_h</span> <span class="o">//</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">H</span><span class="p">)</span>
          <span class="k">return</span> <span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">,</span> <span class="n">x2</span><span class="p">,</span> <span class="n">y2</span>
</code></pre></div>    </div>
  </li>
</ul>

<h2 id="papers-needs-to-conquer-next-">Papers needs to conquer next 👏👏👏</h2>
<ul>
  <li>Any recommendation?</li>
</ul>]]></content><author><name></name></author><category term="paper-recap" /><summary type="html"><![CDATA[CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features Yun, Sangdoo Han, Dongyoon Chun, Sanghyuk Oh, Seong Joon Choe, Junsuk Yoo, Youngjoon Research Topic Category (General): Deep Learning Category (Specific): Data Augmentation Paper summary Introduce a new data augmentation method: CutMix, which helps: Generates new samples by cutting and pasting patches within mini-batches, leading to performance boosts in many computer vision tasks. Improves the model robustness against input corruptions Performs better when facing out-of-distribution detection problems. Explain Like I’m 5 (ELI5) 👶👶👶 Issues addressed by the paper Regional cutout may remove informative pixels, in addition to it, these techniques also add noises by replace those cut pixels with black area. How can we maximally utilize the deleted regions, while taking advantage of better generalization and localization using regional dropout? While certainly improving classification performance, Mixup samples tend to be unnatural. Synthesizing training data guides also improves model performance, but introduces costly computations. Recently, methods adding noises to the internal features of CNNs or adding extra path to the architecture have been proposed to enhance image classification performance. Cutmix has properties such that can compensate all of those mentioned above. Approach/Method Core idea: We have 2 pictures, choose a region (apply to both pictures) in the image that is proportional to the image’s ratio, then swap those regions, leads to a new sample. new_image = MASK * image_1 + (1-MASK) * image_2 new_label = lambda * label_1 + (1-lambda) * label_2 lambda is sampled from symmetric Beta distribution (having same \(\alpha\) and \(\beta\) value), which looks like the following image. This distribution makes sure that the new image will most of the time be close only to the first or the second picture. Only sometimes both images have the same intensity (of course if in a case of multicategorical, other label will be 0). MASK has the same WxH like the original image, having full 0s in the region that is gonna be cutout (let’s call it B) and full 1s in the leftover pixels. B is a bounding box, having coordinates defined as \(B = (r_x, r_y, r_w, r_h)\) indicating the cropping regions. \[r_x \sim Unif(0,W); \: r_w = W \sqrt{1 - \lambda} \\ r_y \sim Unif(0,H); \: r_h = H \sqrt{1 - \lambda}\] Having these coordinates defined like this would make the cropped area ratio equals to \(1 - \lambda\). Result CutMix overcomes the problem of both Mixup (its samples tend to be unnatural) and regional cutout (removes informative pixels) by replacing the image region with a patch from another training image. CutMix incurs only negligible additional cost for training. Cutout successfully lets a model focus on less discriminative parts of the object. Outperforms other SOTAs using data augmentation during the time of publish. Best practice \(\alpha = 1\) usually performs well. Cutout, Mixup, and CutMix require a greater number of training epochs till convergence. CutMix achieves the best performance when it is applied on the input images rather than hidden features. A new state-of-the-art performance 13.81% (in CIFAR-100) by combining CutMix and ShakeDrop, a regularization that adds noise on intermediate features. Hidden gems💎💎💎 Label-smoothing is good when apply together with data augmentation such as Cutout, Mixup, Dropblock. Mixup, Manifold Mixup achieve higher accuracies when Cutout is applied on input images. Conclusions Rating Paper implementation Using Pytorch Lightning Callback system, inspired by fastai implementation. class MixLoss(nn.Module): def __init__(self, old_lf, mixup_cb): super().__init__() self.old_lf = old_lf self.mixup_cb = mixup_cb def forward(self, pred, yb): if self.mixup_cb.pl_module.testing: return self.old_lf(pred, yb) with NoneReduce(self.old_lf) as lf: self.mixup_cb.yb_1 = self.mixup_cb.yb_1.to(pred.device) self.mixup_cb.lam = self.mixup_cb.lam.to(pred.device) loss = torch.lerp(lf(pred, self.mixup_cb.yb_1), lf(pred,yb), self.mixup_cb.lam) return reduce_loss(loss, getattr(self.old_lf, 'reduction', 'mean')) # Cell class CutmixDict(Callback): def __init__(self, alpha=1.): super().__init__() self.distrib = Beta(tensor(alpha), tensor(alpha)) def on_train_start(self, trainer, pl_module): assert hasattr(pl_module, 'loss_func'), 'Your LightningModule should have loss_func attribute as your loss function.' self.old_lf = pl_module.loss_func self.loss_fnc = MixLoss(self.old_lf, self) pl_module.loss_func = self.loss_fnc self.pl_module = pl_module def _cutmix(self, batch, logger, log_image=False, pre_fix='train'): xb, yb = batch["img"], batch["label"] bs = yb.size(0) W, H = xb.size(3), xb.size(2) lam = self.distrib.sample((1,)).squeeze() lam = torch.stack([lam, 1-lam]) self.lam = lam.max() # Permute the batch shuffle = torch.randperm(bs) xb_1, self.yb_1 = xb[shuffle], yb[shuffle] x1, y1, x2, y2 = self.rand_bbox(W, H, self.lam) xb[:, :, x1:x2, y1:y2] = xb_1[:, :, x1:x2, y1:y2] self.lam = (1 - ((x2-x1) * (y2-y1)) / float(W*H)) if log_image: grid = torchvision.utils.make_grid(xb) logger.experiment.add_image(pre_fix + '_cutmix', grid) grid_g = torchvision.utils.make_grid(xb_1) logger.experiment.add_image(pre_fix + '_cut_from', grid_g) dif = abs(xb - xb_1) grid_d = torchvision.utils.make_grid(dif) logger.experiment.add_image(pre_fix + '_dif', grid_d) return xb def on_train_batch_start(self, trainer, pl_module, batch, batch_idx, dataloader_idx): x = self._cutmix(batch, trainer.logger) batch["img"] = x def on_validation_start(self, trainer, pl_module): pl_module.loss_func = self.old_lf def on_validation_end(self, trainer, pl_module): pl_module.loss_func = self.loss_fnc def on_fit_end(self, trainer, pl_module): pl_module.loss_func = self.old_lf def rand_bbox(self, W, H, lam): cut_rat = torch.sqrt(1. - lam) cut_w = (W * cut_rat).type(torch.long) cut_h = (H * cut_rat).type(torch.long) # uniform cx = torch.randint(0, W, (1,)) cy = torch.randint(0, H, (1,)) x1 = torch.clamp(cx - cut_w // 2, 0, W) y1 = torch.clamp(cy - cut_h // 2, 0, H) x2 = torch.clamp(cx + cut_w // 2, 0, W) y2 = torch.clamp(cy + cut_h // 2, 0, H) return x1, y1, x2, y2 Papers needs to conquer next 👏👏👏 Any recommendation?]]></summary></entry><entry><title type="html">Paper recap: MixUp: Beyond empirical risk minimization</title><link href="https://trung-dt.com/paper-recap/2020/08/24/mixup.html" rel="alternate" type="text/html" title="Paper recap: MixUp: Beyond empirical risk minimization" /><published>2020-08-24T00:00:00+00:00</published><updated>2020-08-24T00:00:00+00:00</updated><id>https://trung-dt.com/paper-recap/2020/08/24/mixup</id><content type="html" xml:base="https://trung-dt.com/paper-recap/2020/08/24/mixup.html"><![CDATA[<h2 id="mixup-beyond-empirical-risk-minimization">MixUp: Beyond empirical risk minimization</h2>
<p><a href="https://arxiv.org/abs/1710.09412">Zhang, Hongyi Cisse, Moustapha Dauphin, Yann N.Lopez-Paz, David, 2018</a></p>

<h2 id="research-topic">Research Topic</h2>
<ul>
  <li>Category (General): Deep Learning</li>
  <li>Category (Specific): Data Augmentation</li>
</ul>

<h2 id="paper-summary">Paper summary</h2>
<ul>
  <li>Introduce a new data augmentation method: MixUp, which helps:
    <ul>
      <li>Improve generalization of neural network architectures.</li>
      <li>Reduces memorization of corrupt labels.</li>
      <li>Increases the robustness to adversarial learning.</li>
      <li>Stabilize the training of GANs.</li>
    </ul>
  </li>
</ul>

<h2 id="explain-like-im-5-eli5-">Explain Like I’m 5 (ELI5) 👶👶👶</h2>
<ul>
  <li>Well this gif sums up pretty well…
<img src="https://media.giphy.com/media/BHeCjdyGJck6c/giphy.gif" alt="pineapple-pen" /></li>
</ul>

<h2 id="issues-addressed-by-the-paper">Issues addressed by the paper</h2>
<ul>
  <li>As the model is being trained by minimizing the loss/objective function using a known set of training data (Empirical Risk Minimization), it can choose to <em>memorize</em> the training data rather than <em>generalize</em> it, even when in the presence of strong regularization. So the model will perform terribly when evaluating on examples outside the training distribution.</li>
  <li>Normal data augmentation can help model to improve generalization, but it requires costly computations, and also needs human experts to decide how to augment the data.</li>
</ul>

<h2 id="approachmethod">Approach/Method</h2>
<ul>
  <li>Core idea: Linear interpolate (lerp) two images and its labels together, then do it for the whole batch. Use soft label for better performance. How much to interpolate is used by a number call <code class="language-plaintext inlined highlighter-rouge">lambda</code> generated by Beta Distribution.
    <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="n">new_image</span> <span class="o">=</span> <span class="k">lambda</span> <span class="o">*</span> <span class="n">image_1</span> <span class="o">+</span> <span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="k">lambda</span><span class="p">)</span> <span class="o">*</span> <span class="n">image_2</span>
  <span class="n">new_label</span> <span class="o">=</span> <span class="k">lambda</span> <span class="o">*</span> <span class="n">label_1</span> <span class="o">+</span> <span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="k">lambda</span><span class="p">)</span> <span class="o">*</span> <span class="n">label_2</span>
</code></pre></div>    </div>
  </li>
  <li><code class="language-plaintext inlined highlighter-rouge">lambda</code> is sampled from symmetric Beta distribution (having same \(\alpha\) and \(\beta\) value), which looks like the following image. This distribution makes sure that the new image will most of the time be close only to the first or the second picture. Only sometimes both images have the same intensity (of course if in a case of multicategorical, other label will be 0).</li>
</ul>

<p align="center">
  <img src="/assets/images/mixup/beta.png" style="width: 50%;" alt="lr" />
</p>

<ul>
  <li>They tried multiple ways to pick images:
    <ul>
      <li>Use 2 different dataloader, take one of each then interpolate -&gt; good mix, but need 2 loaders which takes more time to run.</li>
      <li>Use more than two pictures to mix: non-significant improvement, but increases the computation cost.</li>
      <li>Use only 1 dataloader, then mixup the batch and its shuffled-version -&gt; may have duplicates, but peforms equally well -&gt; <strong>RECOMMEND</strong>.</li>
    </ul>
  </li>
</ul>

<h2 id="result">Result</h2>
<ul>
  <li>Reduces the amount of undesirable oscillations when predicting outside the training examples, also makes memorization more difficult to achieve (generalizes better). The author had make tests by training both normal (ERM) and mixup model against randomly corruptled labels:
    <ul>
      <li>As you can see, the ERM model starts to overfit the corrupted labels when the LR starts to slow down to fine tune.</li>
      <li>mixup model doesn’t do the same, so when it’s tested against the real label, it still performs fairly well -&gt; not overfitted.
<img src="/assets/images/mixup/generalize.png" alt="generalize" /></li>
    </ul>
  </li>
  <li>Leads to decision boundaries that transition linearly from class to class, providing a smoother estimate of uncertainty:
    <ul>
      <li>In the ERM model, if an adversarial example (class orange) can push through the blue boundary, the model will definately determine that example is class 0.</li>
      <li>On the other hand, since mixup model produce a smooth boundary, it may still classify that example correctly.</li>
    </ul>
  </li>
</ul>
<p align="center">
  <img src="/assets/images/mixup/boundaries.png" style="width: 75%;" alt="lr" />
</p>
<ul>
  <li>Significantly improve the robustness of neural networks without hindering the speed of ERM.</li>
</ul>

<h2 id="best-practice">Best practice</h2>
<ul>
  <li>\(\alpha \in [0.1, 0.4]\) usually performs well, whereas larger \(\alpha\) may lead to underfitting.</li>
  <li>When using mixup, use larger neural network and also train longer for better result.</li>
  <li>mixup + dropout performs very nicely together (produced SOTA in the paper).</li>
</ul>

<h2 id="hidden-gems">Hidden gems💎💎💎</h2>
<ul>
  <li>For normal data augmentation, one usually uses rotation, translation, cropping, resizing, flipping and random erasing to enforce visually plausible invariances in the model through the training data.</li>
</ul>

<h2 id="conclusions">Conclusions</h2>

<h3 id="rating">Rating</h3>
<p><img src="https://media.giphy.com/media/8xfNjg3mJPj68/giphy.gif" alt="rating" /></p>

<h2 id="paper-implementation">Paper implementation</h2>
<ul>
  <li>Using Pytorch Lightning Callback system, inspired by fastai implementation.
    <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">class</span> <span class="nc">MixLoss</span><span class="p">(</span><span class="n">nn</span><span class="p">.</span><span class="n">Module</span><span class="p">):</span>
      <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_lf</span><span class="p">,</span> <span class="n">mixup_cb</span><span class="p">):</span>
          <span class="nb">super</span><span class="p">().</span><span class="n">__init__</span><span class="p">()</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span> <span class="o">=</span> <span class="n">old_lf</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span> <span class="o">=</span> <span class="n">mixup_cb</span>

      <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pred</span><span class="p">,</span> <span class="n">yb</span><span class="p">):</span>
          <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">pl_module</span><span class="p">.</span><span class="n">testing</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span><span class="p">(</span><span class="n">pred</span><span class="p">,</span> <span class="n">yb</span><span class="p">)</span>
          <span class="k">with</span> <span class="n">NoneReduce</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span><span class="p">)</span> <span class="k">as</span> <span class="n">lf</span><span class="p">:</span>
              <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">yb_1</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">yb_1</span><span class="p">.</span><span class="n">to</span><span class="p">(</span><span class="n">pred</span><span class="p">.</span><span class="n">device</span><span class="p">)</span>
              <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">lam</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">lam</span><span class="p">.</span><span class="n">to</span><span class="p">(</span><span class="n">pred</span><span class="p">.</span><span class="n">device</span><span class="p">)</span>
              <span class="n">loss</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">lerp</span><span class="p">(</span><span class="n">lf</span><span class="p">(</span><span class="n">pred</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">yb_1</span><span class="p">),</span> <span class="n">lf</span><span class="p">(</span><span class="n">pred</span><span class="p">,</span><span class="n">yb</span><span class="p">),</span> <span class="bp">self</span><span class="p">.</span><span class="n">mixup_cb</span><span class="p">.</span><span class="n">lam</span><span class="p">)</span>
          <span class="k">return</span> <span class="n">reduce_loss</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span><span class="p">,</span> <span class="s">'reduction'</span><span class="p">,</span> <span class="s">'mean'</span><span class="p">))</span>

  <span class="k">class</span> <span class="nc">MixupDict</span><span class="p">(</span><span class="n">Callback</span><span class="p">):</span>
      <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.4</span><span class="p">):</span>
          <span class="nb">super</span><span class="p">().</span><span class="n">__init__</span><span class="p">()</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">distrib</span> <span class="o">=</span> <span class="n">Beta</span><span class="p">(</span><span class="n">tensor</span><span class="p">(</span><span class="n">alpha</span><span class="p">),</span> <span class="n">tensor</span><span class="p">(</span><span class="n">alpha</span><span class="p">))</span>

      <span class="k">def</span> <span class="nf">on_train_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">):</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span> <span class="o">=</span> <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">loss_fnc</span> <span class="o">=</span> <span class="n">MixLoss</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
          <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">loss_fnc</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">pl_module</span> <span class="o">=</span> <span class="n">pl_module</span>

      <span class="k">def</span> <span class="nf">_mixup</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">batch</span><span class="p">,</span> <span class="n">logger</span><span class="p">,</span> <span class="n">log_image</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">pre_fix</span><span class="o">=</span><span class="s">'train'</span><span class="p">):</span>
          <span class="n">xb</span><span class="p">,</span> <span class="n">yb</span> <span class="o">=</span> <span class="n">batch</span><span class="p">[</span><span class="s">"img"</span><span class="p">],</span> <span class="n">batch</span><span class="p">[</span><span class="s">"label"</span><span class="p">]</span>
          <span class="n">bs</span> <span class="o">=</span> <span class="n">yb</span><span class="p">.</span><span class="n">size</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

          <span class="c1"># Produce "bs" probability for each sample
</span>          <span class="n">lam</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">distrib</span><span class="p">.</span><span class="n">sample</span><span class="p">((</span><span class="n">bs</span><span class="p">,)).</span><span class="n">squeeze</span><span class="p">()</span>

          <span class="c1"># Get those probability that &gt;0.5, so that the first img (in the nonshuffle batch) has bigger coeff
</span>          <span class="c1"># Which avoid duplication mixup
</span>          <span class="n">lam</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">stack</span><span class="p">([</span><span class="n">lam</span><span class="p">,</span> <span class="mi">1</span><span class="o">-</span><span class="n">lam</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span>
          <span class="bp">self</span><span class="p">.</span><span class="n">lam</span> <span class="o">=</span> <span class="n">lam</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>

          <span class="c1"># Permute the batch
</span>          <span class="n">shuffle</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">randperm</span><span class="p">(</span><span class="n">bs</span><span class="p">)</span>
          <span class="n">xb_1</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">yb_1</span> <span class="o">=</span> <span class="n">xb</span><span class="p">[</span><span class="n">shuffle</span><span class="p">],</span> <span class="n">yb</span><span class="p">[</span><span class="n">shuffle</span><span class="p">]</span>
          <span class="n">nx_dims</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">xb</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
          <span class="n">weight</span> <span class="o">=</span> <span class="n">unsqueeze</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">lam</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="n">nx_dims</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
          <span class="n">x_new</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="n">lerp</span><span class="p">(</span><span class="n">xb_1</span><span class="p">,</span> <span class="n">xb</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="n">weight</span><span class="p">)</span>
          <span class="k">if</span> <span class="n">log_image</span><span class="p">:</span>
              <span class="n">grid</span> <span class="o">=</span> <span class="n">torchvision</span><span class="p">.</span><span class="n">utils</span><span class="p">.</span><span class="n">make_grid</span><span class="p">(</span><span class="n">x_new</span><span class="p">)</span>
              <span class="n">logger</span><span class="p">.</span><span class="n">experiment</span><span class="p">.</span><span class="n">add_image</span><span class="p">(</span><span class="n">pre_fix</span> <span class="o">+</span> <span class="s">'mixup'</span><span class="p">,</span> <span class="n">grid</span><span class="p">)</span>
              <span class="n">grid_g</span> <span class="o">=</span> <span class="n">torchvision</span><span class="p">.</span><span class="n">utils</span><span class="p">.</span><span class="n">make_grid</span><span class="p">(</span><span class="n">xb</span><span class="p">)</span>
              <span class="n">logger</span><span class="p">.</span><span class="n">experiment</span><span class="p">.</span><span class="n">add_image</span><span class="p">(</span><span class="n">pre_fix</span> <span class="o">+</span> <span class="s">'norm'</span><span class="p">,</span> <span class="n">grid_g</span><span class="p">)</span>
              <span class="n">dif</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="n">xb</span> <span class="o">-</span> <span class="n">x_new</span><span class="p">)</span>
              <span class="n">grid_d</span> <span class="o">=</span> <span class="n">torchvision</span><span class="p">.</span><span class="n">utils</span><span class="p">.</span><span class="n">make_grid</span><span class="p">(</span><span class="n">dif</span><span class="p">)</span>
              <span class="n">logger</span><span class="p">.</span><span class="n">experiment</span><span class="p">.</span><span class="n">add_image</span><span class="p">(</span><span class="n">pre_fix</span> <span class="o">+</span> <span class="s">'dif'</span><span class="p">,</span> <span class="n">grid_d</span><span class="p">)</span>
          <span class="k">return</span> <span class="n">x_new</span>

      <span class="k">def</span> <span class="nf">on_train_batch_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">,</span> <span class="n">batch</span><span class="p">,</span> <span class="n">batch_idx</span><span class="p">,</span> <span class="n">dataloader_idx</span><span class="p">):</span>
          <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">_mixup</span><span class="p">(</span><span class="n">batch</span><span class="p">,</span> <span class="n">trainer</span><span class="p">.</span><span class="n">logger</span><span class="p">)</span>
          <span class="n">batch</span><span class="p">[</span><span class="s">"img"</span><span class="p">]</span> <span class="o">=</span> <span class="n">x</span>

      <span class="k">def</span> <span class="nf">on_validation_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">):</span>
          <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span>

      <span class="k">def</span> <span class="nf">on_validation_end</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">):</span>
          <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">loss_fnc</span>

      <span class="k">def</span> <span class="nf">on_fit_end</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trainer</span><span class="p">,</span> <span class="n">pl_module</span><span class="p">):</span>
          <span class="n">pl_module</span><span class="p">.</span><span class="n">loss_func</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">old_lf</span>
</code></pre></div>    </div>
  </li>
</ul>

<h2 id="papers-needs-to-conquer-next-">Papers needs to conquer next 👏👏👏</h2>
<ul>
  <li><a href="https://arxiv.org/abs/1905.04899">Cutmix</a></li>
</ul>]]></content><author><name></name></author><category term="paper-recap" /><summary type="html"><![CDATA[MixUp: Beyond empirical risk minimization Zhang, Hongyi Cisse, Moustapha Dauphin, Yann N.Lopez-Paz, David, 2018 Research Topic Category (General): Deep Learning Category (Specific): Data Augmentation Paper summary Introduce a new data augmentation method: MixUp, which helps: Improve generalization of neural network architectures. Reduces memorization of corrupt labels. Increases the robustness to adversarial learning. Stabilize the training of GANs. Explain Like I’m 5 (ELI5) 👶👶👶 Well this gif sums up pretty well… Issues addressed by the paper As the model is being trained by minimizing the loss/objective function using a known set of training data (Empirical Risk Minimization), it can choose to memorize the training data rather than generalize it, even when in the presence of strong regularization. So the model will perform terribly when evaluating on examples outside the training distribution. Normal data augmentation can help model to improve generalization, but it requires costly computations, and also needs human experts to decide how to augment the data. Approach/Method Core idea: Linear interpolate (lerp) two images and its labels together, then do it for the whole batch. Use soft label for better performance. How much to interpolate is used by a number call lambda generated by Beta Distribution. new_image = lambda * image_1 + (1-lambda) * image_2 new_label = lambda * label_1 + (1-lambda) * label_2 lambda is sampled from symmetric Beta distribution (having same \(\alpha\) and \(\beta\) value), which looks like the following image. This distribution makes sure that the new image will most of the time be close only to the first or the second picture. Only sometimes both images have the same intensity (of course if in a case of multicategorical, other label will be 0). They tried multiple ways to pick images: Use 2 different dataloader, take one of each then interpolate -&gt; good mix, but need 2 loaders which takes more time to run. Use more than two pictures to mix: non-significant improvement, but increases the computation cost. Use only 1 dataloader, then mixup the batch and its shuffled-version -&gt; may have duplicates, but peforms equally well -&gt; RECOMMEND. Result Reduces the amount of undesirable oscillations when predicting outside the training examples, also makes memorization more difficult to achieve (generalizes better). The author had make tests by training both normal (ERM) and mixup model against randomly corruptled labels: As you can see, the ERM model starts to overfit the corrupted labels when the LR starts to slow down to fine tune. mixup model doesn’t do the same, so when it’s tested against the real label, it still performs fairly well -&gt; not overfitted. Leads to decision boundaries that transition linearly from class to class, providing a smoother estimate of uncertainty: In the ERM model, if an adversarial example (class orange) can push through the blue boundary, the model will definately determine that example is class 0. On the other hand, since mixup model produce a smooth boundary, it may still classify that example correctly. Significantly improve the robustness of neural networks without hindering the speed of ERM. Best practice \(\alpha \in [0.1, 0.4]\) usually performs well, whereas larger \(\alpha\) may lead to underfitting. When using mixup, use larger neural network and also train longer for better result. mixup + dropout performs very nicely together (produced SOTA in the paper). Hidden gems💎💎💎 For normal data augmentation, one usually uses rotation, translation, cropping, resizing, flipping and random erasing to enforce visually plausible invariances in the model through the training data. Conclusions Rating Paper implementation Using Pytorch Lightning Callback system, inspired by fastai implementation. class MixLoss(nn.Module): def __init__(self, old_lf, mixup_cb): super().__init__() self.old_lf = old_lf self.mixup_cb = mixup_cb def forward(self, pred, yb): if self.mixup_cb.pl_module.testing: return self.old_lf(pred, yb) with NoneReduce(self.old_lf) as lf: self.mixup_cb.yb_1 = self.mixup_cb.yb_1.to(pred.device) self.mixup_cb.lam = self.mixup_cb.lam.to(pred.device) loss = torch.lerp(lf(pred, self.mixup_cb.yb_1), lf(pred,yb), self.mixup_cb.lam) return reduce_loss(loss, getattr(self.old_lf, 'reduction', 'mean')) class MixupDict(Callback): def __init__(self, alpha=0.4): super().__init__() self.distrib = Beta(tensor(alpha), tensor(alpha)) def on_train_start(self, trainer, pl_module): self.old_lf = pl_module.loss_func self.loss_fnc = MixLoss(self.old_lf, self) pl_module.loss_func = self.loss_fnc self.pl_module = pl_module def _mixup(self, batch, logger, log_image=False, pre_fix='train'): xb, yb = batch["img"], batch["label"] bs = yb.size(0) # Produce "bs" probability for each sample lam = self.distrib.sample((bs,)).squeeze() # Get those probability that &gt;0.5, so that the first img (in the nonshuffle batch) has bigger coeff # Which avoid duplication mixup lam = torch.stack([lam, 1-lam], 1) self.lam = lam.max(1)[0] # Permute the batch shuffle = torch.randperm(bs) xb_1, self.yb_1 = xb[shuffle], yb[shuffle] nx_dims = len(xb.size()) weight = unsqueeze(self.lam, n=nx_dims-1) x_new = torch.lerp(xb_1, xb, weight=weight) if log_image: grid = torchvision.utils.make_grid(x_new) logger.experiment.add_image(pre_fix + 'mixup', grid) grid_g = torchvision.utils.make_grid(xb) logger.experiment.add_image(pre_fix + 'norm', grid_g) dif = abs(xb - x_new) grid_d = torchvision.utils.make_grid(dif) logger.experiment.add_image(pre_fix + 'dif', grid_d) return x_new def on_train_batch_start(self, trainer, pl_module, batch, batch_idx, dataloader_idx): x = self._mixup(batch, trainer.logger) batch["img"] = x def on_validation_start(self, trainer, pl_module): pl_module.loss_func = self.old_lf def on_validation_end(self, trainer, pl_module): pl_module.loss_func = self.loss_fnc def on_fit_end(self, trainer, pl_module): pl_module.loss_func = self.old_lf Papers needs to conquer next 👏👏👏 Cutmix]]></summary></entry><entry><title type="html">Paper recap: SGDR, Super-convergence</title><link href="https://trung-dt.com/paper-recap/2020/08/17/sgdr.html" rel="alternate" type="text/html" title="Paper recap: SGDR, Super-convergence" /><published>2020-08-17T00:00:00+00:00</published><updated>2020-08-17T00:00:00+00:00</updated><id>https://trung-dt.com/paper-recap/2020/08/17/sgdr</id><content type="html" xml:base="https://trung-dt.com/paper-recap/2020/08/17/sgdr.html"><![CDATA[<h2 id="sgdr-stochastic-gradient-descent-with-warm-restarts">SGDR: Stochastic Gradient Descent with Warm Restarts</h2>
<p><a href="https://arxiv.org/abs/1506.01186">Ilya Loshchilov, Frank Hutter, 2016</a></p>

<h2 id="super-convergence-very-fast-training-of-neural-networks-using-large-learning-rates">Super-Convergence: Very Fast Training of Neural Networks Using Large Learning Rates</h2>
<p><a href="https://arxiv.org/abs/1708.07120">Leslie N. Smith, Nicholay Topin, 2017</a></p>

<h2 id="research-topic">Research Topic</h2>
<ul>
  <li>Category (General): Deep Learning</li>
  <li>Category (Specific): Hyper Tuning, Optimization</li>
</ul>

<h2 id="paper-summary">Paper summary</h2>

<h3 id="sgdr">SGDR</h3>
<ul>
  <li>Partial warm restarts improve rate of convergence, often used in gradient-free optimization.</li>
  <li>Propose a warm restart technique for stochastic gradient descent.</li>
  <li>Study its performance on CIFAR-10/100</li>
  <li>Show that this technique improve its anytime performance when training deep neural network:
    <ul>
      <li>SGD with warm restarts requires 2× to 4× fewer epochs than the currently-used learning rate schedule schemes to achieve comparable or even better results</li>
    </ul>
  </li>
</ul>

<h3 id="super-convergence">Super-convergence</h3>
<ul>
  <li>Introduce “Super-convergence” term: where neural networks can be train and converge much faster than standard training methods.</li>
  <li>Propoce a way to achieve super-convergence: one-cycle policy + large learning rate.</li>
  <li>Use Hessian Free optimization method to produce an estimate of the optimal learning rate.</li>
  <li>Study its performance on CIFAR-10/100, MNIST, Imagenet with various model.</li>
  <li>Show that this phenomenon can also happen when the amount of labeled training data is limited but still boost the model performance.</li>
  <li>Mostly all of these are mentioned in the previous recap, so it will not be discussed more in the sections below.</li>
</ul>

<h2 id="explain-like-im-5-eli5-">Explain Like I’m 5 (ELI5) 👶👶👶</h2>

<h3 id="sgdr-1">SGDR</h3>
<ul>
  <li>Just like a normal person works everyday. You start the day with maximum effort, but then time goes by you feel tired and the productivity reduces. You go home, rest. The next day, you’re recharged and start the cycle once again.</li>
</ul>

<h3 id="super-convergence-1">Super-convergence</h3>
<ul>
  <li>As a result of CLR, super-convergence is born.</li>
</ul>

<h2 id="issues-addressed-by-the-paper">Issues addressed by the paper</h2>

<h3 id="sgdr-2">SGDR</h3>
<ul>
  <li>Despite of the existance of advanced optimization methods like Adam, AdaDelta, SOTA result on CIFAR-10/100, ImageNet still based on SGD with momentum, associated with Resnet model.</li>
  <li>Current way to get out of the plateau while using SGD is LR scheduler and L2 regularization.</li>
  <li>They want to break through and produce a new approach to SGD.</li>
</ul>

<h3 id="super-convergence-2">Super-convergence</h3>
<ul>
  <li>They found a way to train DNN faster and achieve better performance.</li>
  <li>Large LR regularizes training, so other regularization method should be reduced to maintain optimal balance of optimization</li>
  <li>Hessian-free optimization method estimates optimal LR, demonstrating that large LR find wide, flat minima.</li>
</ul>

<h2 id="approachmethod">Approach/Method</h2>

<h3 id="sgdr-3">SGDR</h3>
<ul>
  <li>SGDR simulates a new warm-started run/restart of SGD after \(T_{i}\) epochs are performed.</li>
</ul>

<p align="center">
<img src="/assets/images/sgdr/cos_annealing.png" style="width: 50%;" alt="cosann" />
</p>
<ul>
  <li>Learning rate is calculated by cos annealing function.</li>
</ul>

\[\eta_{t}=\eta_{\min }^{i}+\frac{1}{2}\left(\eta_{\max }^{i}-\eta_{\min }^{i}\right)\left(1+\cos \left(\frac{T_{\text {cur}}}{T_{i}} \pi\right)\right)\]

<ul>
  <li>\(\eta\): learning rate.</li>
  <li>\(T_{cur}\): how many epochs passed since the restart.</li>
  <li>
    <p>\(T_{i}\): how mane epochs for a restart, you can leave it constant or increase over-time.</p>
  </li>
  <li>How the learning rate looks after training:</li>
</ul>
<p align="center">
<img src="/assets/images/sgdr/sgdr.png" style="width: 50%;" alt="sgdr" />
</p>

<h2 id="best-practice">Best practice</h2>

<h3 id="sgdr-4">SGDR</h3>
<ul>
  <li>Start with small \(T_{i}\), then increase it by factor of \(T_{mult}\) at every start.</li>
</ul>
<p align="center">
<img src="/assets/images/sgdr/sgdrs.png" style="width: 100%;" alt="sgdrs" />
</p>
<ul>
  <li>Decreate max_lr and min_lr at every new start may increase performance.</li>
  <li>Stop training when current learning rate is equal to min_lr.</li>
  <li>SGDR allows to train larger network.</li>
</ul>

<h2 id="results">Results</h2>
<p align="center">
<img src="/assets/images/sgdr/sgdr_res.png" style="width: 100%;" alt="sgdres" />
</p>
<ul>
  <li>SGDR technique helps the author to surpass the SOTA at the time with much faster computational time.</li>
</ul>

<h2 id="conclusions">Conclusions</h2>

<h3 id="the-authors-conclusions">The author’s conclusions</h3>
<ul>
  <li>Our SGDR simulates warm restarts by scheduling the learning rate to achieve competitive results on CIFAR-10 and CIFAR-100 roughly two to four times faster, achieved new state- of-the-art results with SGDR.</li>
  <li>SGDR might also reduce the problem of learning rate selection because the annealing and restarts of SGDR scan / consider a range of learning rate values.</li>
</ul>

<h3 id="rating">Rating</h3>
<p><img src="https://media.giphy.com/media/z8rEcJ6I0hiUM/giphy.gif" alt="rating" /></p>

<h3 id="my-conclusion">My Conclusion</h3>
<ul>
  <li>Another technique can be considered when training in new project, should quick test overall before stick to one and go deeper.</li>
</ul>

<h2 id="paper-implementation">Paper implementation</h2>

<h3 id="cos-annealing">Cos Annealing</h3>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">sched_cos</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">,</span> <span class="n">T_cur</span><span class="p">,</span> <span class="n">T_i</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">start</span> <span class="o">+</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">math</span><span class="p">.</span><span class="n">cos</span><span class="p">(</span><span class="n">math</span><span class="p">.</span><span class="n">pi</span><span class="o">*</span><span class="p">(</span><span class="n">T_cur</span> <span class="o">/</span> <span class="n">T_i</span><span class="p">)))</span> <span class="o">*</span> <span class="p">(</span><span class="n">end</span><span class="o">-</span><span class="n">start</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span></code></pre></figure>

<h3 id="sgdr-5">SGDR</h3>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">step</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">epoch</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">epoch</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">and</span> <span class="bp">self</span><span class="p">.</span><span class="n">last_epoch</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">epoch</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="k">if</span> <span class="n">epoch</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
        <span class="n">epoch</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">last_epoch</span> <span class="o">+</span> <span class="mi">1</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span> <span class="o">+</span> <span class="mi">1</span>
        <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_i</span><span class="p">:</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span> <span class="o">-</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_i</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">T_i</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_i</span> <span class="o">*</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_mult</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">epoch</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span>
        <span class="k">if</span> <span class="n">epoch</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_0</span><span class="p">:</span>
            <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_mult</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
                <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span> <span class="o">=</span> <span class="n">epoch</span> <span class="o">%</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_0</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">math</span><span class="p">.</span><span class="n">log</span><span class="p">((</span><span class="n">epoch</span> <span class="o">/</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_0</span> <span class="o">*</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">T_mult</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_mult</span><span class="p">))</span>
                <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span> <span class="o">=</span> <span class="n">epoch</span> <span class="o">-</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_0</span> <span class="o">*</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">T_mult</span> <span class="o">**</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">T_mult</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
                <span class="bp">self</span><span class="p">.</span><span class="n">T_i</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_0</span> <span class="o">*</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_mult</span> <span class="o">**</span> <span class="p">(</span><span class="n">n</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">T_i</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_0</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span> <span class="o">=</span> <span class="n">epoch</span>
    <span class="bp">self</span><span class="p">.</span><span class="n">last_epoch</span> <span class="o">=</span> <span class="n">math</span><span class="p">.</span><span class="n">floor</span><span class="p">(</span><span class="n">epoch</span><span class="p">)</span>
    <span class="bp">self</span><span class="p">.</span><span class="n">lr</span> <span class="o">=</span> <span class="n">sched_cos</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">base_lr</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">max_lr</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_cur</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">T_i</span><span class="p">)</span></code></pre></figure>

<h2 id="cited-references-and-used-images-from">Cited references and used images from:</h2>
<ul>
  <li>https://towardsdatascience.com/https-medium-com-reina-wang-tw-stochastic-gradient-descent-with-restarts-5f511975163</li>
  <li>https://arxiv.org/abs/1608.03983</li>
  <li>Pytorch library</li>
</ul>

<h2 id="papers-needs-to-conquer-next-">Papers needs to conquer next 👏👏👏</h2>
<ul>
  <li><a href="https://arxiv.org/abs/1710.09412">Mixup</a></li>
  <li><a href="https://arxiv.org/abs/1905.04899">Cutmix</a></li>
</ul>]]></content><author><name></name></author><category term="paper-recap" /><summary type="html"><![CDATA[SGDR: Stochastic Gradient Descent with Warm Restarts Ilya Loshchilov, Frank Hutter, 2016 Super-Convergence: Very Fast Training of Neural Networks Using Large Learning Rates Leslie N. Smith, Nicholay Topin, 2017 Research Topic Category (General): Deep Learning Category (Specific): Hyper Tuning, Optimization Paper summary SGDR Partial warm restarts improve rate of convergence, often used in gradient-free optimization. Propose a warm restart technique for stochastic gradient descent. Study its performance on CIFAR-10/100 Show that this technique improve its anytime performance when training deep neural network: SGD with warm restarts requires 2× to 4× fewer epochs than the currently-used learning rate schedule schemes to achieve comparable or even better results Super-convergence Introduce “Super-convergence” term: where neural networks can be train and converge much faster than standard training methods. Propoce a way to achieve super-convergence: one-cycle policy + large learning rate. Use Hessian Free optimization method to produce an estimate of the optimal learning rate. Study its performance on CIFAR-10/100, MNIST, Imagenet with various model. Show that this phenomenon can also happen when the amount of labeled training data is limited but still boost the model performance. Mostly all of these are mentioned in the previous recap, so it will not be discussed more in the sections below. Explain Like I’m 5 (ELI5) 👶👶👶 SGDR Just like a normal person works everyday. You start the day with maximum effort, but then time goes by you feel tired and the productivity reduces. You go home, rest. The next day, you’re recharged and start the cycle once again. Super-convergence As a result of CLR, super-convergence is born. Issues addressed by the paper SGDR Despite of the existance of advanced optimization methods like Adam, AdaDelta, SOTA result on CIFAR-10/100, ImageNet still based on SGD with momentum, associated with Resnet model. Current way to get out of the plateau while using SGD is LR scheduler and L2 regularization. They want to break through and produce a new approach to SGD. Super-convergence They found a way to train DNN faster and achieve better performance. Large LR regularizes training, so other regularization method should be reduced to maintain optimal balance of optimization Hessian-free optimization method estimates optimal LR, demonstrating that large LR find wide, flat minima. Approach/Method SGDR SGDR simulates a new warm-started run/restart of SGD after \(T_{i}\) epochs are performed. Learning rate is calculated by cos annealing function. \[\eta_{t}=\eta_{\min }^{i}+\frac{1}{2}\left(\eta_{\max }^{i}-\eta_{\min }^{i}\right)\left(1+\cos \left(\frac{T_{\text {cur}}}{T_{i}} \pi\right)\right)\] \(\eta\): learning rate. \(T_{cur}\): how many epochs passed since the restart. \(T_{i}\): how mane epochs for a restart, you can leave it constant or increase over-time. How the learning rate looks after training: Best practice SGDR Start with small \(T_{i}\), then increase it by factor of \(T_{mult}\) at every start. Decreate max_lr and min_lr at every new start may increase performance. Stop training when current learning rate is equal to min_lr. SGDR allows to train larger network. Results SGDR technique helps the author to surpass the SOTA at the time with much faster computational time. Conclusions The author’s conclusions Our SGDR simulates warm restarts by scheduling the learning rate to achieve competitive results on CIFAR-10 and CIFAR-100 roughly two to four times faster, achieved new state- of-the-art results with SGDR. SGDR might also reduce the problem of learning rate selection because the annealing and restarts of SGDR scan / consider a range of learning rate values. Rating My Conclusion Another technique can be considered when training in new project, should quick test overall before stick to one and go deeper. Paper implementation Cos Annealing def sched_cos(start, end, T_cur, T_i): return start + (1 + math.cos(math.pi*(T_cur / T_i))) * (end-start) / 2 SGDR def step(self, epoch=None): if epoch is None and self.last_epoch &lt; 0: epoch = 0 if epoch is None: epoch = self.last_epoch + 1 self.T_cur = self.T_cur + 1 if self.T_cur &gt;= self.T_i: self.T_cur = self.T_cur - self.T_i self.T_i = self.T_i * self.T_mult else: if epoch &lt; 0: return if epoch &gt;= self.T_0: if self.T_mult == 1: self.T_cur = epoch % self.T_0 else: n = int(math.log((epoch / self.T_0 * (self.T_mult - 1) + 1), self.T_mult)) self.T_cur = epoch - self.T_0 * (self.T_mult ** n - 1) / (self.T_mult - 1) self.T_i = self.T_0 * self.T_mult ** (n) else: self.T_i = self.T_0 self.T_cur = epoch self.last_epoch = math.floor(epoch) self.lr = sched_cos(self.base_lr, self.max_lr, self.T_cur, self.T_i) Cited references and used images from: https://towardsdatascience.com/https-medium-com-reina-wang-tw-stochastic-gradient-descent-with-restarts-5f511975163 https://arxiv.org/abs/1608.03983 Pytorch library Papers needs to conquer next 👏👏👏 Mixup Cutmix]]></summary></entry><entry><title type="html">Paper recap: A disciplined approach to neural network hyper-parameters: Part 1</title><link href="https://trung-dt.com/paper-recap/2020/08/10/1cycle.html" rel="alternate" type="text/html" title="Paper recap: A disciplined approach to neural network hyper-parameters: Part 1" /><published>2020-08-10T00:00:00+00:00</published><updated>2020-08-10T00:00:00+00:00</updated><id>https://trung-dt.com/paper-recap/2020/08/10/1cycle</id><content type="html" xml:base="https://trung-dt.com/paper-recap/2020/08/10/1cycle.html"><![CDATA[<h2 id="a-disciplined-approach-to-neural-network-hyper-parameters-part-1">A disciplined approach to neural network hyper-parameters: Part 1</h2>
<p><a href="http://arxiv.org/abs/1803.09820">Lesli N.Smith, 2018</a></p>

<h2 id="research-topic">Research Topic</h2>
<ul>
  <li>Category (General): Deep Learning.</li>
  <li>Category (Specific): Hyperparameters Tuning.</li>
</ul>

<h2 id="paper-summary">Paper summary</h2>
<ul>
  <li>Introduce techniques to set some essential hyper-parameters such as: learning rate, batch size, momentum, weight decay.</li>
  <li>How to examine training/ test loss curve for clues of underfitting, overfitting.</li>
  <li>Introduce a new method of cyclical learning rate: <strong>1cycle policy</strong>.</li>
  <li>Discuss about cyclical momentum, cyclical weight decay.</li>
  <li>Produce multiples examples to show the importance of balanced regularization for each dataset/ architecture.</li>
</ul>

<h2 id="explain-like-im-5-eli5-">Explain Like I’m 5 (ELI5) 👶👶👶</h2>
<ul>
  <li>Not necessary since this paper mostly tackle best pratices while working on projects.</li>
</ul>

<h2 id="issues-addressed-by-the-paper">Issues addressed by the paper</h2>
<ul>
  <li>Grid-search is computationally expensive and time consumming. But a good choice of hyper-parameters is vital for a model to perform well, so how to do grid-search efficiently?</li>
  <li>Underfitting/ overfitting trade-off.</li>
</ul>

<ol>
  <li>Learning rate:
    <ul>
      <li>Too small: overfitting can occur.</li>
      <li>Too large: can have regularize but will diverge.</li>
    </ul>
  </li>
  <li>Batch size:
    <ul>
      <li>Suggest that when we comparing batch size, neither maintaining <em>constant #epochs</em> (train the same #epochs for each batch size) nor <em>constant #iterations</em> (train the same #iterations/epoch each batch size) is appropriate:
        <ul>
          <li>constant #epochs:
            <ul>
              <li>Computationally efficient, but penalized more since we see a big proportion of samples each time.</li>
            </ul>
          </li>
          <li>constant #iterations:
            <ul>
              <li>Overfit will occur.</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>Batch size directly affect computational time.</li>
    </ul>
  </li>
  <li>Momentum:
    <ul>
      <li>Momentum and learning rate are closely related and its optimal values are dependent on each other.</li>
      <li>Momentum’s effect on updating the weights is of the same magnitude as the learning rate (used SGD with momentum equation to verify).</li>
    </ul>
  </li>
  <li>Weight decay:
    <ul>
      <li>Weight decay is one form of regularization and it plays an important role in training so its value needs to be set properly.</li>
    </ul>
  </li>
</ol>

<h2 id="approachmethod">Approach/Method</h2>
<!-- ![lr](/assets/images/1cycle/lr.png) -->
<p align="center">
  <img src="/assets/images/1cycle/lr.png" style="width: 50%;" alt="lr" />
</p>

<ul>
  <li>1cycle policy:
    <ul>
      <li>Instead of cyclical learning rate using <code class="language-plaintext inlined highlighter-rouge">triangular</code> as the <a href="/paper-recap/2020/08/03/clr.html">previous post</a>, the author suggest to:
        <ol>
          <li>Train all epochs in more than one cycle just a small proportion.</li>
          <li>In the remaining iterations, the learning rate will decline from <code class="language-plaintext inlined highlighter-rouge">base_lr</code> to several orders of magnitude less.</li>
        </ol>
      </li>
      <li>Experiments show that this policy allows the accuracy to plateau before the training ends.</li>
    </ul>
  </li>
  <li>The author show these 6 remarks after multiple researchs and experiments:
    <ol>
      <li>The test/validation loss is a good indicator of the network’s convergence and should be examined for clues.
        <ul>
          <li>Look at the loss curve and also plot generalization error curve (<code class="language-plaintext inlined highlighter-rouge">valid_loss - train_loss</code>), one can determine whether the architechture has the capacity to overfit or has too small learning rate (which also leads to overfit)</li>
        </ul>
      </li>
      <li>Achieving the horizontal part of the test loss is the goal of hyperparameter tuning.
  <img src="/assets/images/1cycle/under_over_plot.png" alt="under_over_plot" />
        <ul>
          <li>The horizontal part is the red line.</li>
        </ul>
      </li>
      <li>The amount of regularization must be balanced for each dataset and architecture.</li>
      <li>The practitioner’s goal is obtaining the highest performance while minimizing the needed computational time.</li>
      <li>Optimal momentum value(s) will improve network training.</li>
      <li>Since the amount of regularization must be balanced for each dataset and architecture, the value of weight decay is a key knob to turn for tuning regularization against the regularization from an increasing learning rate.</li>
    </ol>
  </li>
</ul>

<h2 id="best-practices">Best practices</h2>
<p><img src="/assets/images/1cycle/lr_m.png" alt="lr_m" /></p>
<ol>
  <li>Learning rate:
    <ul>
      <li>Use learning rate range test to find the minimum and maximum learning rate boundaries:
        <ul>
          <li>Maximum learning rate bound: the maximum value that the model can still converge</li>
          <li>Minumum learning rate bound:
            <ol>
              <li>\(\frac{1}{3};\frac{1}{4}\) of max bound.</li>
              <li>\(\frac{1}{10};\frac{1}{20}\) of max bound if using 1cycle.</li>
            </ol>
          </li>
        </ul>
      </li>
      <li>Use 1cycle policy to achive super-convergence (reachs global optima with iterations much less than regulars).</li>
      <li>Other regularization methods must be reduced to compensate for the regularization effects of large learning rates.</li>
    </ul>
  </li>
  <li>Batch size:
    <ul>
      <li>Small batch sizes add regularization, large batch sizes add less; utilize this while balancing the proper amount of regularization.</li>
      <li>Often better to use a larger batch size so a larger learning rate can be used (leads to using a larger batch size when using the 1cycle learning rate schedule).</li>
    </ul>
  </li>
  <li>Momentum:
    <ul>
      <li>Short runs with momentum values of 0.99, 0.97, 0.95, and 0.9 will quickly show the best value for momentum.</li>
      <li>If use 1cycle policy, should use cyclical momentum starting at maximum momentum value and decreasing to a value of 0.8 or 0.85 (performance is almost independent of the minimum momentum value).</li>
      <li>Decreasing cyclical momentum when the learning rate increases provides an equivalent result to the best constant momentum value.</li>
      <li>Using cyclical momentum along with the LR range test stabilizes the convergence when using large learning rate values more than a constant momentum does.</li>
    </ul>
  </li>
  <li>Weight decay:
    <ul>
      <li>Should be a constant value.</li>
      <li>Should use grid search to find a proper value; validation loss early in the training is sufficient for determining a good value.</li>
      <li>Another option as a grid search for weight decay is to make a single run at a middle value for weight decay and save a snapshot after the loss plateaus. Use this snapshot to restart runs, each with a different value of WD. This can save time in searching for the best weight decay.</li>
      <li>A complex dataset requires less regularization so test smaller weight decay values, such as \(10^{−4}, 10^{−5}, 10^{−6}, 0\)</li>
      <li>A shallow architecture requires more regularization so test larger weight decay values, such as \(10^{−2}, 10^{−3}, 10^{−4}\).</li>
      <li>The optimal weight decay is different if you search with a constant learning rate versus using a learning rate range.</li>
    </ul>
  </li>
</ol>

<h2 id="hidden-gems">Hidden gems💎💎💎</h2>
<p><img src="/assets/images/1cycle/test_loss_dec.png" alt="test_loss_dec" /></p>

<ul>
  <li>Test loss decreases more rapidly during the initial iterations and is then horizontal is an early positive clue indicating that the model will produce a better final accuracy. (Blue curve)</li>
  <li>Learning rates that are too small can exhibit some overfitting behavior.</li>
  <li>There is a maximum speed the learning rate can increase without the training becoming unstable.</li>
  <li>The very large learning rates provided the twin benefits of regularization that prevented overfitting and faster training of the network.</li>
  <li>Set momentum as large as possible without causing instabilities during training.</li>
  <li>Momentum range test is not useful for finding an optimal momentum, you should use grid search.</li>
  <li>Decreasing the momentum while the learning rate increases provides three benefits (by experiments):
    <ol>
      <li>a lower minimum test loss.</li>
      <li>faster initial convergence.</li>
      <li>greater convergence stability over a larger range of learning rates.</li>
    </ol>
  </li>
  <li>Large momentum helps escape saddle points but can hurt the final convergence, implying that momentum should be reduced at the end of training.</li>
  <li>A good procedure is to test momentum values in the range of 0.9 to 0.99.</li>
  <li>All the general ideas can apply to shallow or deep networks, although the details (i.e., specific values for momentum) varied.</li>
</ul>

<h2 id="results">Results</h2>
<p><img src="/assets/images/1cycle/result.png" alt="result" /></p>
<ul>
  <li>As the experiment shown, if one can find optimal values for these hyper-parameters, the model would achieve super-convergence, which saves computational cost and time.
    <h2 id="limitations">Limitations</h2>
  </li>
  <li>These disciplines are not proved but mostly achieved by experiments. So we can only use this as a guide and apply it to our projects.</li>
</ul>

<h2 id="confusing-aspects-of-the-paper">Confusing aspects of the paper</h2>
<ul>
  <li>Very straightforward, confusing-free.</li>
</ul>

<h2 id="conclusions">Conclusions</h2>

<h3 id="rating">Rating</h3>
<p>Would read again.</p>

<h3 id="my-conclusion">My conclusion</h3>
<ul>
  <li>Good workflow to deal with hyper-parameters.</li>
  <li>Can be use as a reference when start a new projects.</li>
</ul>

<h2 id="paper-implementation">Paper implementation</h2>
<p><img src="https://media.giphy.com/media/nKZEvTua5D4o0XD6Ge/giphy.gif" alt="Nope" /></p>

<h2 id="cited-references-and-used-images-from">Cited references and used images from:</h2>
<ul>
  <li><a href="http://arxiv.org/abs/1803.09820">Lesli N.Smith, 2018</a></li>
  <li>https://sgugger.github.io/the-1cycle-policy.html</li>
  <li>https://github.com/asvcode/1_cycle</li>
</ul>

<h2 id="papers-needs-to-conquer-next-">Papers needs to conquer next 👏👏👏</h2>
<ul>
  <li><a href="https://arxiv.org/abs/1608.03983">SGDR</a></li>
</ul>]]></content><author><name></name></author><category term="paper-recap" /><summary type="html"><![CDATA[A disciplined approach to neural network hyper-parameters: Part 1 Lesli N.Smith, 2018 Research Topic Category (General): Deep Learning. Category (Specific): Hyperparameters Tuning. Paper summary Introduce techniques to set some essential hyper-parameters such as: learning rate, batch size, momentum, weight decay. How to examine training/ test loss curve for clues of underfitting, overfitting. Introduce a new method of cyclical learning rate: 1cycle policy. Discuss about cyclical momentum, cyclical weight decay. Produce multiples examples to show the importance of balanced regularization for each dataset/ architecture. Explain Like I’m 5 (ELI5) 👶👶👶 Not necessary since this paper mostly tackle best pratices while working on projects. Issues addressed by the paper Grid-search is computationally expensive and time consumming. But a good choice of hyper-parameters is vital for a model to perform well, so how to do grid-search efficiently? Underfitting/ overfitting trade-off. Learning rate: Too small: overfitting can occur. Too large: can have regularize but will diverge. Batch size: Suggest that when we comparing batch size, neither maintaining constant #epochs (train the same #epochs for each batch size) nor constant #iterations (train the same #iterations/epoch each batch size) is appropriate: constant #epochs: Computationally efficient, but penalized more since we see a big proportion of samples each time. constant #iterations: Overfit will occur. Batch size directly affect computational time. Momentum: Momentum and learning rate are closely related and its optimal values are dependent on each other. Momentum’s effect on updating the weights is of the same magnitude as the learning rate (used SGD with momentum equation to verify). Weight decay: Weight decay is one form of regularization and it plays an important role in training so its value needs to be set properly. Approach/Method 1cycle policy: Instead of cyclical learning rate using triangular as the previous post, the author suggest to: Train all epochs in more than one cycle just a small proportion. In the remaining iterations, the learning rate will decline from base_lr to several orders of magnitude less. Experiments show that this policy allows the accuracy to plateau before the training ends. The author show these 6 remarks after multiple researchs and experiments: The test/validation loss is a good indicator of the network’s convergence and should be examined for clues. Look at the loss curve and also plot generalization error curve (valid_loss - train_loss), one can determine whether the architechture has the capacity to overfit or has too small learning rate (which also leads to overfit) Achieving the horizontal part of the test loss is the goal of hyperparameter tuning. The horizontal part is the red line. The amount of regularization must be balanced for each dataset and architecture. The practitioner’s goal is obtaining the highest performance while minimizing the needed computational time. Optimal momentum value(s) will improve network training. Since the amount of regularization must be balanced for each dataset and architecture, the value of weight decay is a key knob to turn for tuning regularization against the regularization from an increasing learning rate. Best practices Learning rate: Use learning rate range test to find the minimum and maximum learning rate boundaries: Maximum learning rate bound: the maximum value that the model can still converge Minumum learning rate bound: \(\frac{1}{3};\frac{1}{4}\) of max bound. \(\frac{1}{10};\frac{1}{20}\) of max bound if using 1cycle. Use 1cycle policy to achive super-convergence (reachs global optima with iterations much less than regulars). Other regularization methods must be reduced to compensate for the regularization effects of large learning rates. Batch size: Small batch sizes add regularization, large batch sizes add less; utilize this while balancing the proper amount of regularization. Often better to use a larger batch size so a larger learning rate can be used (leads to using a larger batch size when using the 1cycle learning rate schedule). Momentum: Short runs with momentum values of 0.99, 0.97, 0.95, and 0.9 will quickly show the best value for momentum. If use 1cycle policy, should use cyclical momentum starting at maximum momentum value and decreasing to a value of 0.8 or 0.85 (performance is almost independent of the minimum momentum value). Decreasing cyclical momentum when the learning rate increases provides an equivalent result to the best constant momentum value. Using cyclical momentum along with the LR range test stabilizes the convergence when using large learning rate values more than a constant momentum does. Weight decay: Should be a constant value. Should use grid search to find a proper value; validation loss early in the training is sufficient for determining a good value. Another option as a grid search for weight decay is to make a single run at a middle value for weight decay and save a snapshot after the loss plateaus. Use this snapshot to restart runs, each with a different value of WD. This can save time in searching for the best weight decay. A complex dataset requires less regularization so test smaller weight decay values, such as \(10^{−4}, 10^{−5}, 10^{−6}, 0\) A shallow architecture requires more regularization so test larger weight decay values, such as \(10^{−2}, 10^{−3}, 10^{−4}\). The optimal weight decay is different if you search with a constant learning rate versus using a learning rate range. Hidden gems💎💎💎 Test loss decreases more rapidly during the initial iterations and is then horizontal is an early positive clue indicating that the model will produce a better final accuracy. (Blue curve) Learning rates that are too small can exhibit some overfitting behavior. There is a maximum speed the learning rate can increase without the training becoming unstable. The very large learning rates provided the twin benefits of regularization that prevented overfitting and faster training of the network. Set momentum as large as possible without causing instabilities during training. Momentum range test is not useful for finding an optimal momentum, you should use grid search. Decreasing the momentum while the learning rate increases provides three benefits (by experiments): a lower minimum test loss. faster initial convergence. greater convergence stability over a larger range of learning rates. Large momentum helps escape saddle points but can hurt the final convergence, implying that momentum should be reduced at the end of training. A good procedure is to test momentum values in the range of 0.9 to 0.99. All the general ideas can apply to shallow or deep networks, although the details (i.e., specific values for momentum) varied. Results As the experiment shown, if one can find optimal values for these hyper-parameters, the model would achieve super-convergence, which saves computational cost and time. Limitations These disciplines are not proved but mostly achieved by experiments. So we can only use this as a guide and apply it to our projects. Confusing aspects of the paper Very straightforward, confusing-free. Conclusions Rating Would read again. My conclusion Good workflow to deal with hyper-parameters. Can be use as a reference when start a new projects. Paper implementation Cited references and used images from: Lesli N.Smith, 2018 https://sgugger.github.io/the-1cycle-policy.html https://github.com/asvcode/1_cycle Papers needs to conquer next 👏👏👏 SGDR]]></summary></entry><entry><title type="html">Paper recap: Cyclical Learning Rates for Training Neural Networks</title><link href="https://trung-dt.com/paper-recap/2020/08/03/clr.html" rel="alternate" type="text/html" title="Paper recap: Cyclical Learning Rates for Training Neural Networks" /><published>2020-08-03T00:00:00+00:00</published><updated>2020-08-03T00:00:00+00:00</updated><id>https://trung-dt.com/paper-recap/2020/08/03/clr</id><content type="html" xml:base="https://trung-dt.com/paper-recap/2020/08/03/clr.html"><![CDATA[<h2 id="cyclical-learning-rates-for-training-neural-networks">Cyclical Learning Rates for Training Neural Networks</h2>
<p><a href="https://arxiv.org/abs/1506.01186">Lesli N.Smith, 2017</a></p>

<h2 id="research-topic">Research Topic</h2>
<ul>
  <li>Category (General): Deep Learning</li>
  <li>Category (Specific): Hyperparameters (Learning rate) Tuning</li>
</ul>

<h2 id="paper-summary">Paper summary</h2>
<ul>
  <li>Instead of monotonically decreasing the learning rate as in the traditional way, the author introduced a new method (called Cyclical Learning Rates) to control it, allowing the hyper-parameter to rise and fall systematically during training.</li>
  <li>CLR improves classification accuracy without tuning and does not require any computations.</li>
  <li>The author also showed a way to estimate the bounds for the learning rate to vary while training.</li>
</ul>

<h2 id="explain-like-im-5-eli5-">Explain Like I’m 5 (ELI5) 👶👶👶</h2>
<p>Imagine you try to draw a picture, there are multiple ways to tackle this:</p>
<ul>
  <li>You jump straight-in, drawing up to ~80-90% of the picture. However, to refine it, you have to slow down to finish the touches, which very tiring, so you might have to slow down much more until you finish it or abandon it midway. (~ Learning rate schedule)</li>
  <li>You start by drawing the layout, and then you calculate how much effort you should spend on each section. After you finish one, you reevaluate again and continue to draw until the picture is done. (~Adaptive learning rate)</li>
  <li>You start simple, draw a tree today, draw some more trees tomorrow, and draw a sun and a mountain the following day. The gist is that you start slow and progress over time until you reach a particular intensity. Then you slow down again to avoid burnout until you’re at the initial state (finish a cycle), you will restart the cycle again until the picture is done. (~Cyclical Learning Rates)</li>
</ul>

<h2 id="issues-addressed-by-the-paper">Issues addressed by the paper</h2>
<ul>
  <li>To train a deep neural network to convergence requires one to experiment with a variety of LR.</li>
  <li>There are already multiple solutions to this. These include learning rate scheduling (e.g., time-based decay, step decay, exponential decay), or adaptive learning rate (e.g., RMSProp, AdaGrad, AdaDelta, Adam), but there are still some drawbacks such as:
    <ul>
      <li>Learning rate scheduling: Monotonically decreased learning rate, which later proved that it would not help the model escape from the saddle point.</li>
      <li>Adaptive learning rate: requires high computational cost.</li>
    </ul>
  </li>
</ul>

<h2 id="approachmethod">Approach/Method</h2>
<ul>
  <li>Observation: increasing the learning rate might have a short term negative effect and yet achieve a longer-term beneficial effect. (since increasing the learning rate allows more rapid traversal of saddle point plateaus)</li>
  <li>Pick minimum (<code class="language-plaintext inlined highlighter-rouge">base_lr</code>) and maximum (<code class="language-plaintext inlined highlighter-rouge">max_lr</code>) boundaries, and the learning rate will cyclically vary between these bounds.</li>
</ul>

<p><img src="/assets/images/clr/window.png" alt="Window type" /></p>
<ul>
  <li>
    <p>For the cyclical function, triangular(Bartlett) window, parabolic(Welch) window, and sinusoidal(Hanning) window produced equivalent results, which led to adopting a triangular window thanks to its simplicity.</p>
  </li>
  <li>
    <p>Other variations:</p>
    <ul>
      <li><code class="language-plaintext inlined highlighter-rouge">triangular</code>: using triangular window</li>
      <li><code class="language-plaintext inlined highlighter-rouge">triangular_2</code>: same as triangular but after every cycle, <code class="language-plaintext inlined highlighter-rouge">max_lr</code> is halved</li>
      <li><code class="language-plaintext inlined highlighter-rouge">exp_range</code>: each boundary value declines by exponential factor of current iterations.</li>
    </ul>
  </li>
</ul>

<p><img src="/assets/images/clr/triangular.png" alt="Triangular window" /></p>

<ul>
  <li>How to find the bounds?
    <ul>
      <li>Using “LR range test”:
        <ul>
          <li>Run model for several epochs while letting the learning rate increase linearly between low and high LR values.</li>
          <li>Notice these 2 points:
            <ul>
              <li>When accuracy starts to increase. -&gt; <code class="language-plaintext inlined highlighter-rouge">base_lr</code></li>
              <li>When accuracy slows down, becomes ragged or falls down. -&gt; <code class="language-plaintext inlined highlighter-rouge">max_lr</code></li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<p><img src="/assets/images/clr/lr_range.png" alt="LR_finder" /></p>

<h2 id="best-practices">Best practices</h2>
<ul>
  <li>Set <code class="language-plaintext inlined highlighter-rouge">stepsize</code> to 2-10 times of #iterations/epoch.</li>
  <li>Best to stop training at the end of the cycle (LR at <code class="language-plaintext inlined highlighter-rouge">base_lr</code> and the accuracy peaks)
    <ul>
      <li>-&gt; Early stopping might not be good for CLR.</li>
    </ul>
  </li>
  <li>Optimum learning rate is usually within a factor of two of the largest one that converges, and set <code class="language-plaintext inlined highlighter-rouge">base_lr</code> = \(\frac{1}{3}\) or \(\frac{1}{4}\)  of <code class="language-plaintext inlined highlighter-rouge">max_lr</code>.</li>
</ul>

<h2 id="results">Results</h2>
<p><img src="/assets/images/clr/clr_result.png" alt="Result" /></p>
<ul>
  <li><code class="language-plaintext inlined highlighter-rouge">CLR</code> helps to model to converge much faster.</li>
  <li><code class="language-plaintext inlined highlighter-rouge">Decay</code> (monotonically decreasing LR)’s result provides evidence that both increasing and decreasing LR are essential.</li>
</ul>

<h2 id="limitations">Limitations</h2>
<p><img src="/assets/images/clr/clr_adaptive_result.png" alt="Result" /></p>
<ul>
  <li>When using with adaptive learning rate methods, the benefits from CLR are reduced.</li>
</ul>

<h2 id="confusing-aspects-of-the-paper">Confusing aspects of the paper</h2>
<p><img src="/assets/images/clr/triangular_code.png" alt="Triangular code" /></p>
<ul>
  <li>The variables of the code weren’t explained clearly, so I redefine it here:
    <ul>
      <li><strong>1 epoch</strong>: converted to #iterations (= training_size / batch_size).</li>
      <li><strong>1 cycle</strong>: LR goes from <code class="language-plaintext inlined highlighter-rouge">base_lr</code> -&gt; <code class="language-plaintext inlined highlighter-rouge">max_lr</code> -&gt; <code class="language-plaintext inlined highlighter-rouge">base_lr</code>.</li>
      <li><code class="language-plaintext inlined highlighter-rouge">epochCounter</code>: current #iterations (e.g: 1 epoch has 2000 iters, the model’s at epochs 1.5 =&gt; <code class="language-plaintext inlined highlighter-rouge">epochCounter</code> = 3000).</li>
      <li><code class="language-plaintext inlined highlighter-rouge">stepsize</code>: #iterations to reach 1/2 cycle.</li>
      <li><code class="language-plaintext inlined highlighter-rouge">opt.LR</code>: base lr</li>
      <li><code class="language-plaintext inlined highlighter-rouge">cycle</code>: which cycle the model’s currently in (1-2-…), always starts from 1 (first cycle).</li>
      <li><code class="language-plaintext inlined highlighter-rouge">x</code>: which part of the half-cycle, in range [0,1].</li>
      <li><code class="language-plaintext inlined highlighter-rouge">lr</code>: the updated lr, with <code class="language-plaintext inlined highlighter-rouge">triangular</code> method.</li>
    </ul>
  </li>
</ul>

<h2 id="conclusions">Conclusions</h2>

<h3 id="the-authors-conclusions">The author’s conclusions</h3>
<ul>
  <li>All experiments show similar or better accuracy performance when using CLR versus using a fixed learning rate, even though the performance drops at some of the learning rate values within this range.</li>
</ul>

<h3 id="rating">Rating</h3>
<p>Noice</p>

<h3 id="my-conclusion">My Conclusion</h3>
<ul>
  <li>This paper is straightforward, well-explained, so I highly recommend new DL-practitioners to try reading it.</li>
  <li>CLR is an impressive technique to control the learning rate. We should try this method when we started a new model or a new dataset, giving a lovely baseline for further optimization.</li>
  <li>CLR is also widely used by kagglers.</li>
</ul>

<h2 id="paper-implementation">Paper implementation</h2>

<h3 id="cyclical-learning-rates">Cyclical Learning Rates</h3>
<ul>
  <li><code class="language-plaintext inlined highlighter-rouge">triangular</code> implementation:
<img src="/assets/images/clr/triangular_code_pt.png" alt="triangular_code_pt" /></li>
  <li><code class="language-plaintext inlined highlighter-rouge">triangular_2</code> implementation:
<img src="/assets/images/clr/triangular2_code_pt.png" alt="triangular2_code_pt" /></li>
  <li><code class="language-plaintext inlined highlighter-rouge">exp_range</code> implementation:
<img src="/assets/images/clr/exp_range_code_pt.png" alt="exp_range_code_pt" /></li>
  <li>
    <p>Plot:
<img src="/assets/images/clr/all_res.png" alt="all_test" /></p>
  </li>
  <li>Explaination for how x is calculated:
    <ul>
      <li>\(raw\_x = \frac{current\_iteration}{step\_size}\): current cycle in term of half-cycles (floatting point)
<img src="/assets/images/clr/raw_x.png" alt="raw_x" /></li>
      <li>\(x’ = raw\_x - 2*cycle\): how many half-cycles left to complete this cycle
<img src="/assets/images/clr/x_prime.png" alt="x_prime" /></li>
      <li>\(x’ = x’ + 1\): Shift so that the function 0-centered on the y-axis, so that when we take absolute, we can achieve cycles.
<img src="/assets/images/clr/x_shifted.png" alt="x_prime_shift" /></li>
    </ul>
  </li>
</ul>

<h3 id="learning-rate-finder">Learning Rate Finder</h3>
<ul>
  <li>An implementation of LRFinder using CLR using Callback (highly influenced by fastai):
<img src="/assets/images/clr/lr_finder.png" alt="lr_finder" /></li>
</ul>

<h2 id="cited-references-and-used-images-from">Cited references and used images from:</h2>
<ul>
  <li>https://www.jeremyjordan.me/nn-learning-rate/</li>
  <li>https://github.com/bckenstler/CLR/</li>
</ul>

<h2 id="papers-needs-to-conquer-next-">Papers needs to conquer next 👏👏👏</h2>
<ul>
  <li><a href="https://arxiv.org/abs/1608.03983">SGDR</a></li>
  <li><a href="https://arxiv.org/abs/1803.09820">Fit One Cycle</a></li>
</ul>]]></content><author><name></name></author><category term="paper-recap" /><summary type="html"><![CDATA[Cyclical Learning Rates for Training Neural Networks Lesli N.Smith, 2017 Research Topic Category (General): Deep Learning Category (Specific): Hyperparameters (Learning rate) Tuning Paper summary Instead of monotonically decreasing the learning rate as in the traditional way, the author introduced a new method (called Cyclical Learning Rates) to control it, allowing the hyper-parameter to rise and fall systematically during training. CLR improves classification accuracy without tuning and does not require any computations. The author also showed a way to estimate the bounds for the learning rate to vary while training. Explain Like I’m 5 (ELI5) 👶👶👶 Imagine you try to draw a picture, there are multiple ways to tackle this: You jump straight-in, drawing up to ~80-90% of the picture. However, to refine it, you have to slow down to finish the touches, which very tiring, so you might have to slow down much more until you finish it or abandon it midway. (~ Learning rate schedule) You start by drawing the layout, and then you calculate how much effort you should spend on each section. After you finish one, you reevaluate again and continue to draw until the picture is done. (~Adaptive learning rate) You start simple, draw a tree today, draw some more trees tomorrow, and draw a sun and a mountain the following day. The gist is that you start slow and progress over time until you reach a particular intensity. Then you slow down again to avoid burnout until you’re at the initial state (finish a cycle), you will restart the cycle again until the picture is done. (~Cyclical Learning Rates) Issues addressed by the paper To train a deep neural network to convergence requires one to experiment with a variety of LR. There are already multiple solutions to this. These include learning rate scheduling (e.g., time-based decay, step decay, exponential decay), or adaptive learning rate (e.g., RMSProp, AdaGrad, AdaDelta, Adam), but there are still some drawbacks such as: Learning rate scheduling: Monotonically decreased learning rate, which later proved that it would not help the model escape from the saddle point. Adaptive learning rate: requires high computational cost. Approach/Method Observation: increasing the learning rate might have a short term negative effect and yet achieve a longer-term beneficial effect. (since increasing the learning rate allows more rapid traversal of saddle point plateaus) Pick minimum (base_lr) and maximum (max_lr) boundaries, and the learning rate will cyclically vary between these bounds. For the cyclical function, triangular(Bartlett) window, parabolic(Welch) window, and sinusoidal(Hanning) window produced equivalent results, which led to adopting a triangular window thanks to its simplicity. Other variations: triangular: using triangular window triangular_2: same as triangular but after every cycle, max_lr is halved exp_range: each boundary value declines by exponential factor of current iterations. How to find the bounds? Using “LR range test”: Run model for several epochs while letting the learning rate increase linearly between low and high LR values. Notice these 2 points: When accuracy starts to increase. -&gt; base_lr When accuracy slows down, becomes ragged or falls down. -&gt; max_lr Best practices Set stepsize to 2-10 times of #iterations/epoch. Best to stop training at the end of the cycle (LR at base_lr and the accuracy peaks) -&gt; Early stopping might not be good for CLR. Optimum learning rate is usually within a factor of two of the largest one that converges, and set base_lr = \(\frac{1}{3}\) or \(\frac{1}{4}\) of max_lr. Results CLR helps to model to converge much faster. Decay (monotonically decreasing LR)’s result provides evidence that both increasing and decreasing LR are essential. Limitations When using with adaptive learning rate methods, the benefits from CLR are reduced. Confusing aspects of the paper The variables of the code weren’t explained clearly, so I redefine it here: 1 epoch: converted to #iterations (= training_size / batch_size). 1 cycle: LR goes from base_lr -&gt; max_lr -&gt; base_lr. epochCounter: current #iterations (e.g: 1 epoch has 2000 iters, the model’s at epochs 1.5 =&gt; epochCounter = 3000). stepsize: #iterations to reach 1/2 cycle. opt.LR: base lr cycle: which cycle the model’s currently in (1-2-…), always starts from 1 (first cycle). x: which part of the half-cycle, in range [0,1]. lr: the updated lr, with triangular method. Conclusions The author’s conclusions All experiments show similar or better accuracy performance when using CLR versus using a fixed learning rate, even though the performance drops at some of the learning rate values within this range. Rating Noice My Conclusion This paper is straightforward, well-explained, so I highly recommend new DL-practitioners to try reading it. CLR is an impressive technique to control the learning rate. We should try this method when we started a new model or a new dataset, giving a lovely baseline for further optimization. CLR is also widely used by kagglers. Paper implementation Cyclical Learning Rates triangular implementation: triangular_2 implementation: exp_range implementation: Plot: Explaination for how x is calculated: \(raw\_x = \frac{current\_iteration}{step\_size}\): current cycle in term of half-cycles (floatting point) \(x’ = raw\_x - 2*cycle\): how many half-cycles left to complete this cycle \(x’ = x’ + 1\): Shift so that the function 0-centered on the y-axis, so that when we take absolute, we can achieve cycles. Learning Rate Finder An implementation of LRFinder using CLR using Callback (highly influenced by fastai): Cited references and used images from: https://www.jeremyjordan.me/nn-learning-rate/ https://github.com/bckenstler/CLR/ Papers needs to conquer next 👏👏👏 SGDR Fit One Cycle]]></summary></entry><entry><title type="html">First blog</title><link href="https://trung-dt.com/talk/2020/08/01/first_blog.html" rel="alternate" type="text/html" title="First blog" /><published>2020-08-01T00:00:00+00:00</published><updated>2020-08-01T00:00:00+00:00</updated><id>https://trung-dt.com/talk/2020/08/01/first_blog</id><content type="html" xml:base="https://trung-dt.com/talk/2020/08/01/first_blog.html"><![CDATA[<p>Hello.
This is my very first blog.
Lorem ipsum?</p>]]></content><author><name></name></author><category term="talk" /><summary type="html"><![CDATA[Hello. This is my very first blog. Lorem ipsum?]]></summary></entry></feed>