Is the current SigmoidTransform implementation correct?

The log_abs_det_jacobian in the SigmoidTransform, is implemented as

-(y.reciprocal() + (1 - y).reciprocal()).log()

but I think the correct implementation should be

-(y.reciprocal().log() + (1 - y).reciprocal().log())

or even simpler y.log() + (1-y).log() since log(a) + log(b) does not equal to log(a + b).

1 Like

Hi Xiucheng, I agree it’s a bit confusing although the log_abs_det_jacobian is correct in the current implementation.

The function log_abs_det_jacobian calculates log(|dy/dx|) where y is the output and x is the input. Now, this is equal to -log(|dx/dy|), which is closer to the formula log_abs_det_jacobian uses in this implementation for the sigmoid transform.

For the sigmoid transform we have, dy/dx = sigma(x) * (1 - sigma(x)) = y(1-y). Then the function should return log(y*(1-y)). If we multiple and divide by -1 we get that it’s equal to -log((y*(1-y))^-1). Expanding the fraction into two terms gives, -log(1/y + (1/(1-y))) which is what is calculated in the code.

Alternative, you could start from dx/dy and x = logit(y) to get the same result. Hope this helps!

1 Like

Hi @stefanwebb. Thanks so much for your step by step analysis. But expanding -log((y*(1-y))^-1) into two terms, should not it be -log(1/y) - log(1/(1-y))?

The fraction is expanded inside the log to give -log(1/y + (1/(1-y))) using 1/(y*(1-y)) = 1/y + 1/(1-y). Expanding the log into two terms gives an equivalent expression

Oh, I see. In this case, log(1/y + (1/(1-y))) actually is equivalent to log(1/y) + log(1/(1-y)).

1 Like