Trouble getting probability from softmax

Ky6000: <p>I am trying to get a confidence from a model after giving it one sample to test. I am very new to this so I am not sure what I am doing. I read somewhere that I should use softmax to get a probability/confidence. I am using code from another implementation that doesn’t get the probability, it just returns a 1 or a 0. I am using Pytorch 3.0</p>
<p>Here is my code:</p>
<pre><code class="lang-auto">    for batch_idx, (x, y) in enumerate(dataloader): #comprised of one sample
        x = Variable(x.cuda())
        y = Variable(y.cuda())

        # forward pass
        y_model = model(x)

        # loss pass
        loss = loss_fct(y_model, y).mean()

        # predict pass
        _, predicted = torch.topk(y_model, k=1)
        correct = predicted.data.eq(y.data.view_as(predicted.data)).cpu().sum()

        # metrics
        total_loss += loss.data[0] * len(y)

        total_correct += correct
        total += len(y)

        print("{} set for {} {}: Average Loss: {:.4f}, Accuracy: {:.2f}%".format(
            "Test", "benign", "null?", total_loss / total,
                               total_correct * 100. / total))
        
</code></pre>
<p>I am not sure what a lot of this code means, or why it was used. The code was originally taken from here:<br>
<aside class="onebox githubblob">
  <header class="source">
      <a href="https://github.com/ALFA-group/robust-adv-malware-detection/blob/master/framework.py" target="_blank" rel="nofollow noopener">github.com</a>
  </header>
  <article class="onebox-body">
    <h4><a href="https://github.com/ALFA-group/robust-adv-malware-detection/blob/master/framework.py" target="_blank" rel="nofollow noopener">ALFA-group/robust-adv-malware-detection/blob/master/framework.py</a></h4>
<pre><code class="lang-py"># coding=utf-8
"""
Python module for performing adversarial training for malware detection
"""
import os
import torch
import random
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
from utils.utils import load_parameters, stack_tensors
from datasets.datasets import load_data
from inner_maximizers.inner_maximizers import inner_maximizer
from nets.ff_classifier import build_ff_classifier
from blindspot_coverage.covering_number import CoveringNumber
import losswise
import time
import json
import numpy as np

</code></pre>

  This file has been truncated. <a href="https://github.com/ALFA-group/robust-adv-malware-detection/blob/master/framework.py" target="_blank" rel="nofollow noopener">show original</a>

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>
</p>
<p>How to I feed the model the sample, which I assume is the variable “y” and get the confidence.</p>
<p>Thanks in advance.</p>

ptrblck: <p>You could apply softmax on the output of your model, if it’s raw logits. Try to call <code>F.softmax(y_model, dim=1)</code> which should give you the probabilities of all classes. Could you check the last layer of your model so see if it’s just a linear layer without an activation function?</p>

Ky6000: <p>Here’s how my network looks like:</p>
<pre><code class="lang-auto">Sequential(
  (0): Linear(in_features=22761, out_features=300, bias=True)
  (1): ReLU()
  (2): Linear(in_features=300, out_features=300, bias=True)
  (3): ReLU()
  (4): Linear(in_features=300, out_features=300, bias=True)
  (5): ReLU()
  (6): Linear(in_features=300, out_features=2, bias=True)
  (7): Softmax()
)
</code></pre>
<p>I tried running the code you gave me and got this as the output:</p>
<pre><code class="lang-auto">Variable containing:
 0.7311  0.2689
[torch.cuda.FloatTensor of size 1x2 (GPU 0)]
</code></pre>
<p>I am not sure what these two numbers mean however. They are the same for every input. Could you please explain what is going on? Thanks</p>

ptrblck: <p>Since your model already has a softmax layer at the end, you don’t have to use <code>F.softmax</code> on top of it. The outputs of your model are already “probabilities” of the classes.</p>
<p>However, your training might not work, depending on your loss function.<br>
For a classification use case you would most likely use a <code>nn.LogSoftmax</code> layer with <code>nn.NLLLoss</code> as the critertion or raw logits, i.e. no non-linearity and <code>nn.CrossEntropyLoss</code>.<br>
As you are currently using <code>nn.Softmax</code>, you would need to call <code>torch.log</code> on the output and feed it to <code>nn.NLLLoss</code>, which might be numerically unstable.<br>
I would recommend to use the raw logits + <code>nn.CrossEntropyLoss</code> for training and if you really need to see the probabilities, just call <code>F.softmax</code> on the output as described in the other post.</p>

Ky6000: <p>Thanks for the replies.</p>
<p>I tried running the following code for my model trained with softmax and nn.NLLLoss.</p>
<pre><code class="lang-auto">        loss_fct = nn.NLLLoss(reduce=False)
        print(loss_fct(torch.log(y_model), y))
</code></pre>
<p>This outputs:</p>
<pre><code class="lang-auto">Variable containing:
 16.9570
[torch.cuda.FloatTensor of size 1 (GPU 0)]
</code></pre>
<p>I’m not sure if NLLLoss is supposed to be used with softmax, in their code they used logsoftmax with NLLLoss, but I changed it to softmax to get probabilities. Does this mean I need to change the loss function to nn.CrossEntropyLoss to get the model to train right?</p>

ptrblck: <p>Well, I’ve tried to explain this use case in my last answer.<br>
Basically you have these options:</p>
<ul>
<li>
<code>nn.Softmax</code> + <code>torch.log</code> + <code>nn.NLLLoss</code> -&gt; might be numerically unstable</li>
<li>
<code>nn.LogSoftmax</code> + <code>nn.NLLLoss</code> -&gt; is perfectly fine for training; to get probabilities you would have to call <code>torch.exp</code> on the output</li>
<li>raw logits + <code>nn.CrossEntropyLoss</code> -&gt; also perfectly fine as it calls the second approach internally; to get probabilities you would have to call <code>torch.softmax</code> on the output</li>
</ul>
<p>Note that you should not feed the probabilities (using softmax) to any loss function.</p>

Ky6000: <p>I understand now, Thanks</p>

Sanjeev_Dubey: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> I see people using logits like this for KL divergence loss:<br>
both pred_x and pred_x_h are logits of same dimensions, applying softmax is converting them into probablilities.<br>
pred_x = F.softmax(model(x), dim=1)<br>
pred_x_h = F.log_softmax(model(x_h), dim=1)<br>
F.kl_div(pred_x_h, pred_x, None, None, reduction=‘sum’).</p>
<p>I am new to pytorch, not sure if thats the right thing to do?</p>

ptrblck: <p>That seems to be right. From the docs:</p>
<blockquote>
<p>As with <a href="https://pytorch.org/docs/stable/nn.html?highlight=kl#torch.nn.NLLLoss"> <code>NLLLoss</code> </a>, the input given is expected to contain <em>log-probabilities</em> and is not restricted to a 2D Tensor. The targets are given as <em>probabilities</em> (i.e. without taking the logarithm).</p>
</blockquote>

Shubhankar: <aside class="quote no-group" data-username="ptrblck" data-post="6" data-topic="26764">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/48/1823_2.png" class="avatar"> ptrblck:</div>
<blockquote>
<p><code>torch.softmax</code></p>
</blockquote>
</aside>
<p>Why can’t I find <code>torch.softmax</code> anywhere in the documentation?</p>

ptrblck: <p>It seems to be undocumented, so please stick to <code>torch.nn.functional.softmax</code>.</p>

Shubhankar: <p>Any plans on its depreciation similar to <code>nn.functional.sigmoid</code> as mentioned <a href="https://discuss.pytorch.org/t/is-there-any-different-between-torch-sigmoid-and-torch-nn-functional-sigmoid/995/6">here</a></p>

vckd: <p>What are typical values to get probabilites in the second case of the three you listed? Are probabilites values between 0 and 1 or between 0 and 100 (percent) in this case? I get a tensor containing two values for binary classification, how do I know which probability refers to which class label?</p>

fupanbo: <p>everytime reading your reply to others always help me get more knowledge~~</p>

ptrblck: <p>If you apply the <code>torch.exp</code> on your <code>nn.LogSoftmax</code> output, the values should be in the range <code>[0, 100]</code>.</p>
<p>You define the order of the classes by creating the target. I.e. <code>output[0]</code> will correspond to the class with index 0 in your target, <code>output[1]</code> to index 1, etc.</p>