torch.distributions.kumaraswamy.Kumaraswamy generates samples outside its support

kiranchari: <p>The Kumaraswamy distribution is defined over the open interval (0,1) but torch.distributions.kumaraswamy.Kumaraswamy can generate samples that equal 1. This causes “nan” outputs when computing the log_prob of such samples.</p>
<pre><code class="lang-auto">import torch as ch
import torch.distributions as dist
kumaraswamy = dist.kumaraswamy.Kumaraswamy(ch.Tensor([0.2]), ch.Tensor([0.2]))
samples = kumaraswamy.sample(ch.Size([1000000]))
assert len(samples[samples==1.0]) &gt; 0
</code></pre>
<p>I suspect this happens to due to the use of torch’s Uniform distribution, which is defined on the half-open interval [0,1), in the sample() method: <a href="https://pytorch.org/docs/stable/_modules/torch/distributions/transformed_distribution.html#TransformedDistribution.sample" class="inline-onebox" rel="noopener nofollow ugc">torch.distributions.transformed_distribution — PyTorch 1.13 documentation</a></p>
<p>Since torch.distributions.uniform.Uniform can generate samples that equal 0, these are perhaps transformed to samples that equal 1 for the Kumaraswamy distribution, outside its support.</p>

KFrank: <p>Hi Kiranchari!</p>
<aside class="quote no-group" data-username="kiranchari" data-post="1" data-topic="173404" data-full="true">
<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/kiranchari/48/33753_2.png" class="avatar"> kiranchari:</div>
<blockquote>
<p>The Kumaraswamy distribution is defined over the open interval (0,1)</p>
</blockquote>
</aside>
<p>I think that it is legitimate to expect that pytorch’s <code>Kumaraswamy</code> <em>not</em> return<br>
samples that are equal to <code>1.0</code> (nor <code>0.0</code>).</p>
<aside class="quote no-group">
<blockquote>
<p>but torch.distributions.kumaraswamy.Kumaraswamy can generate samples that equal 1.</p>
</blockquote>
</aside>
<p>I can reproduce this issue running your code.</p>
<p>Furthermore, <code>Kumaraswamy (0.1, 0.1)</code> generates samples of <code>0.0</code> as well<br>
as <code>1.0</code>.</p>
<p>(Note, performing the analogous test with <code>Beta</code> does not produce samples<br>
outside of its open-interval, <code>(0, 1)</code> support.)</p>
<p>I would consider this a legitimate bug – could you file a github issue?</p>
<p>(<a class="mention" href="/u/ptrblck">@ptrblck</a>, perhaps an expert could chime in.)</p>
<aside class="quote no-group">
<blockquote>
<p>I suspect this happens to due to the use of torch’s Uniform distribution, which is defined on the half-open interval [0,1), in the sample() method</p>
<p>Since torch.distributions.uniform.Uniform can generate samples that equal 0</p>
</blockquote>
</aside>
<p>This doesn’t seem likely because your test with “only” 1,000,000 samples is<br>
quite unlikely to sample an exact <code>0.0</code> from <code>Uniform</code>.</p>
<aside class="quote no-group">
<blockquote>
<p>these are perhaps transformed to samples that equal 1 for the Kumaraswamy distribution, outside its support.</p>
</blockquote>
</aside>
<p>Note that floating-point numbers can get closer to <code>0.0</code> than to <code>1.0</code>.  I expect<br>
that samples from <code>Uniform</code> that are close to <code>0.0</code> (but not equal) get transformed<br>
to <code>1.0</code> (and <code>Uniform</code> samples that are close to <code>1.0</code> get transformed to <code>0.0</code>).</p>
<p>Best.</p>
<p>K. Frank</p>

ptrblck: <p>Thanks for pinging on this issue!<br>
I assume <a href="https://github.com/pytorch/pytorch/blob/22e2fd554cf370765d4c44fe2b99c8bb6e42b0bb/torch/distributions/kumaraswamy.py#L44-L46">this <code>Uniform</code> usage</a> might create these invalid values?<br>
<a class="mention" href="/u/kiranchari">@kiranchari</a> As <a class="mention" href="/u/kfrank">@KFrank</a> mentioned, would you mind creating an issue on <a href="https://github.com/pytorch/pytorch/issues">GitHub</a> so that we could track and fix it, please?</p>
<p>CC <a class="mention" href="/u/vishwakftw">@vishwakftw</a> for viz</p>

kiranchari: <p>Thanks <a class="mention" href="/u/ptrblck">@ptrblck</a> and <a class="mention" href="/u/kfrank">@KFrank</a>. I have created an issue on Github: <a href="https://github.com/pytorch/pytorch/issues/95548" class="inline-onebox" rel="noopener nofollow ugc">torch.distributions.kumaraswamy.Kumaraswamy generates samples outside its support (0,1) · Issue #95548 · pytorch/pytorch · GitHub</a></p>

wilhelm: <p>I found the same bug and lately discovered, that this topic was already open.<br>
What is the status?<br>
I’m using pytorch 2.5 and the Kumaraswamy distribution still has that bug: sampling from it I can get 0, which should not be.</p>

maxwass: <p>Some of this behavior can also be due to underflow in the sampling computation. See <a href="https://github.com/pytorch/pytorch/issues/139019" class="inline-onebox" rel="noopener nofollow ugc">Stabilizing the Kumaraswamy Distribution · Issue #139019 · pytorch/pytorch · GitHub</a> where I am attempting to fix many of the bugs in the current Kumarswamy implementation.</p>

wilhelm: <p>Thanks,</p>
<p>but at the end I ended up by implementing the Kumaraswamy distribution completely from scratch , ignoring the pytorch version, and it works perfectly.</p>

wilhelm: <p>It seems that I’m not the only one experiencing problem with the pytorch version of the kumaraswamy distribution. I found this paper: <a href="https://arxiv.org/pdf/2410.00660" rel="noopener nofollow ugc">https://arxiv.org/pdf/2410.00660</a> and they use the exact pytorch version, which is known to be unstable, for their study.</p>

maxwass: <p>Hi Dave,</p>
<p>That is my paper, it’s linked in the original pull request I posted above. We find all common implementations have unresolved numerical issues in the relevant distribution-related functions used for probabilistic inference. We provide a stable Kumaraswamy implementation, which I’m trying to integrate into PyTorch.</p>

wilhelm: <p><img src="https://discuss.pytorch.org/images/emoji/apple/rofl.png?v=12" title=":rofl:" class="emoji only-emoji" alt=":rofl:" loading="lazy" width="20" height="20"><br>
I did not see, that your name here the same is on the paper.<br>
But you are g**damn right. KM is strangly under-unused.</p>
<p>By the way, I couldn’t find the code you mention in the paper, because there is not link to any repository. In the link you posted above, I’m not sure how to get to right place.</p>
<p>Have you the link to your repository somewhere?</p>

maxwass: <p>The Kumaraswamy <em>was</em> strangely under-used. But hopefully this paper explains why!</p>
<p>I haven’t put up a Github repo yet. I’m planning to post one upon the paper’s acceptance to the journal I’m submitting it to.</p>
<p>For now, the code is available in the Arxiv submission.</p>

maxwass: <p>The paper ‘Stabilizing the Kumaraswamy Distribution’ is now accepted in TMLR: <a href="https://openreview.net/forum?id=baZLwdphqw" class="inline-onebox" rel="noopener nofollow ugc">Stabilizing the Kumaraswamy Distribution | OpenReview</a></p>
<p>The paper’s associated Github Repo now also public: <a href="https://github.com/maxwass/stabilizing-the-kumaraswamy-distribution" class="inline-onebox" rel="noopener nofollow ugc">GitHub - maxwass/stabilizing-the-kumaraswamy-distribution</a></p>