How to implement pseudo-labeling?

alx: <p>Hi all,</p>
<p>I recently stumbled upon a post mentioning pseudo-labeling and how it helped increase the accuracy of the model. Can anyone point me towards a pytorch implementation of it?</p>
<p>Also, Im still not 100% sure about what PL is (mostly due to the lack of code to look at).</p>

vainaijr: <p>I found one article here,<br>
<aside class="onebox whitelistedgeneric">
  <header class="source">
      <img src="https://cdn-static-1.medium.com/_/fp/icons/favicon-rebrand-medium.3Y6xpZ-0FSdWDnPM3hSBIA.ico" class="site-icon" width="16" height="16">
      <a href="https://towardsdatascience.com/pseudo-labeling-to-deal-with-small-datasets-what-why-how-fd6f903213af" target="_blank" title="04:40PM - 03 December 2019" rel="nofollow noopener">Medium – 3 Dec 19</a>
  </header>
  <article class="onebox-body">
    <div class="aspect-image" style="--aspect-ratio:104/78;"><img src="https://miro.medium.com/freeze/max/787/1*DVgaEZNLtzqeJTvnjZvaWQ.gif" class="thumbnail" width="104" height="78"></div>

<h3><a href="https://towardsdatascience.com/pseudo-labeling-to-deal-with-small-datasets-what-why-how-fd6f903213af" target="_blank" rel="nofollow noopener">Pseudo-Labeling to deal with small datasets — What, Why &amp; How?</a></h3>

<p>A guide to using your model's output to improve your model's output!</p>

  <p><span class="label1">Reading time: 16 min read</span>
    </p>

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>
</p>
<p>I think what they are doing is associate pseudo label for unlabeled dataset,<br>
which is based on neural network trained on labeled dataset.<br>
one example would be,</p>
<pre><code class="lang-auto">import torch, torch.nn as nn
dataset = torch.randn(10, 10)
labeled_dataset = dataset[0:5]
unlabeled_dataset = dataset[5:10]
labels = torch.tensor([0., 1., 3., 2., 4.])
# next five indices are unlabeled
</code></pre>
<pre><code class="lang-auto">model = nn.Linear(10, 1)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
optimizer.zero_grad()
model(labeled_dataset) # make predictions on labeled dataset
</code></pre>
<pre><code class="lang-auto">model(unlabeled_dataset) # make predictions on unlabeled_dataset
# first time these predictions would become our pseudo labels
# for unlabeled_dataset
</code></pre>
<pre><code class="lang-auto">loss_fn = nn.MSELoss()
# first time we only consider labeled_dataset during computing loss
# for every next epoch, we consider unlabeled_dataset along with their pseudo labels
</code></pre>
<p>so, first time our loss would be,</p>
<pre><code class="lang-auto">loss = loss_fn(model(labeled_dataset), labels).sum()
</code></pre>
<p>then, we do,</p>
<pre><code class="lang-auto">pseudo_labels = model(unlabeled_dataset) 
# predictions on unlabeled_dataset act as pseudo labels for unlabeled dataset
loss.backward()
optimizer.step()
</code></pre>
<p>then, carry out training again and<br>
next time, our loss would be,</p>
<pre><code class="lang-auto">loss = loss_fn(model(labeled_dataset), labels).sum() + loss_fn(model(unlabeled_dataset), pseudo_labels).sum() 
# (loss for labeled dataset, considering actual labels) + (loss for unlabeled dataset, considering pseudo_labels)
</code></pre>
<p>and then, same,</p>
<pre><code class="lang-auto">pseudo_labels = model(unlabeled_dataset) 
# predictions on unlabeled_dataset act as pseudo labels for unlabeled dataset
loss.backward()
optimizer.step()
</code></pre>
<p>in the article, they have also mentioned alpha, for how much do we want to prioritize labeled_dataset vs unlabeled_dataset for loss.</p>
<p>and this alpha is based on time, so as time increases we want to prioritize unlabeled dataset more.</p>
<p>also, we could train for some epochs (like 500) on our labeled_dataset, and then begin giving unlabeled_dataset pseudo labels, and then train on unlabeled_dataset only, or switch between training on unlabeled, labeled dataset.</p>
<p>also, we could change when and how often we give pseudo label to our unlabeled dataset, like train for 500 epoch on labeled, then give pseudo label (to unlabeled dataset), then do not change this pseudo label, and train for some epochs, on labeled+unlabeled, then repeat.</p>

alx: <p>Thanks for the detailed answer!</p>
<p>I’ve seen this method used on a dataset where all the labels were known, and they simply used PS to increase the accuracy of their model. Maybe the deleted some labels on purpose? would that make sense?</p>
<p>Is PS only efficient when we’re missing labels in train/test/val?</p>
<p>If I understand this correctly, one should have very good accuracy to use this technique because the opposite would make the weights that make a wrong prediction stronger.</p>

vainaijr: <p>I do not know why would they do this when all labels are known, it could lead to wrong predictions being considered as pseudo labels, which would lead to further wrong predictions.</p>
<p>Maybe they set low priority in the beginning to pseudo labels, when pseudo labels might be incorrect, and with time, as accuracy increases on labeled dataset, give high priority to pseudo labels. But this sounds a bit confusing to me. There might be some other reason.</p>

Mahdi_Farhadi: <p>I think for self-supervised pseudo labels work good!</p>