Trying to understand the torch.multinomial

kuzand: <p>Can someone please explain what <code>torch.multinomial</code> does?</p>
<p>With numpy’s <code>np.random.multinomial</code> it is more or less clear: it take the number of trials (experiments), the probabilities for each outcome (which sum up to 1) and the size of the output (i.e. the number of drawn samples). So for example, if we the experiment is to throw a six-sided fair dice and we do it n=20 times, then</p>
<pre><code class="lang-auto">&gt;&gt;&gt; np.random.multinomial(20, [1/6.]*6, size=1)
array([[4, 1, 7, 5, 2, 1]])
</code></pre>
<p>meaning that the dice landed 4 times on 1, once on 2, etc.</p>
<p>How can we do the same thing with <code>torch.multinomial</code>?</p>
<p>I found the following example which unfortunately doesn’t make much sense to me:</p>
<pre><code class="lang-auto">&gt;&gt;&gt; weights = torch.tensor([0, 10, 3, 0], dtype=torch.float)
&gt;&gt;&gt; torch.multinomial(weights, 2)
tensor([1, 2])
&gt;&gt;&gt; torch.multinomial(weights, 4) # ERROR!
</code></pre>
<p>How do the weights translate to probabilities? What is the meaning of <code>tensor([1, 2])</code> and why the second example gives error?</p>

ptrblck: <p>By default <code>torch.multinomial</code> will use <code>replacement=False</code>.<br>
Since only two weights are positive in your example, you won’t be able to draw 4 samples with this setup.<br>
Using <code>torch.multinomial(weights, 4, replacement=True)</code> will work on the other hand.</p>
<p>The returned tensor will give you the samples indices. In your code example you would sample index1 and index2.</p>

kuzand: <p>What I don’t understand is how can I get the same thing as <code>np.random.multinomial(20, [1/6.]*6, size=1)</code> using <code>torch.multinomial</code>.</p>
<p>If I try</p>
<pre><code class="lang-auto">&gt;&gt;&gt; weights = torch.tensor([1/6.]*6, dtype=torch.float)
&gt;&gt;&gt; torch.multinomial(weights, 6)
tensor([4, 2, 1, 0, 5, 3])
</code></pre>
<p>It has a different interpretation than the numpy’s result (see my dice example): the pytorch returns shuffled indices (?) which doesn’t make much sense to me.</p>
<p>Also, I would like to understand how the weights w1, w2, … (e.g. weights [0, 10, 3, 0]) translate to probabilities p1, p2, … in multinomial distribution:</p>
<p><img src="https://discuss.pytorch.org/uploads/default/original/3X/8/5/859d139140b3cd9c7071abbe6c8e095f1951e412.jpeg" alt="multinomial" data-base62-sha1="j402n9aP0Tk66EMaA5Y5IreVLl8" width="492" height="87"></p>

ptrblck: <p><code>torch.multinomial</code> will return the drawn indices, while <code>numpy</code> returns the count of the drawn samples.<br>
To get the count, you could use <code>unique(return_counts=True)</code>:</p>
<pre><code class="lang-python">weights = torch.tensor([1/6.]*6, dtype=torch.float)
out = torch.multinomial(weights, 20, replacement=True)
out_count = out.unique(return_counts=True)[1]
</code></pre>
<p>The passed <code>weights</code> argument will be normalized to create a probability distribution.</p>

kuzand: <p>Thanks ptrblck! I also found that <code>torch.distributions.Multinomial</code> does what I want more directly:</p>
<pre><code class="lang-auto">m = torch.distributions.Multinomial(20, torch.tensor([1/6]*6))
m.sample()
</code></pre>
<p>I am still not sure how to work with weights (not probabilities) though. Using the previous example <code>weights = torch.tensor([0, 10, 3, 0], dtype=torch.float)</code> we have <code>w1 = 0, w2 = 10, w3 = 3, w4 = 0</code>. Are the probabilities <code>p1 = 0, p2 = 10/13, p3 = 3/13, p4 = 0</code> in this case?</p>

ptrblck: <p>Yes, I think your understanding is correct.<br>
If I’m not mistaken, the weights are simply normalized such that their sum equals to 1.</p>

min-jean-cho: <p>I have raised this problem of <code>torch.multinomial(replacement=True)</code> generating “outcomes of n trials” instead of random variable x that consists of “the number of trial for which the outcome falls into class k” here: <a href="https://github.com/pytorch/pytorch/issues/107406" class="inline-onebox" rel="noopener nofollow ugc">Problems of torch.multinomial · Issue #107406 · pytorch/pytorch · GitHub</a></p>