bayesiains / nflows

Normalizing flows in PyTorch
MIT License
845 stars 118 forks source link

InputOutsideDomain() error raised with cubic spline #62

Closed rmastand closed 1 year ago

rmastand commented 2 years ago

I am testing out a few different types of architectures for training normalising flows, and I am running into an unexpected bug.

The first architecture uses a MaskedPiecewiseRationalQuadraticAutoregressiveTransform:

transforms = []

for _ in range(num_layers):

        transforms.append(MaskedPiecewiseRationalQuadraticAutoregressiveTransform(features = n_features, hidden_features = 128, num_blocks = 2,  tail_bound=3.5, context_features=1,tails="linear",num_bins = 10))
        transforms.append(ReversePermutation(features=n_features)) 

This architecture trains without issue, and sampling from the base distribution produces good results.

However, when I replace MaskedPiecewiseRationalQuadraticAutoregressiveTransform with MaskedPiecewiseCubicAutoregressiveTransform, i.e.

transforms = []

for _ in range(num_layers):

        transforms.append(MaskedPiecewiseCubicAutoregressiveTransform(features = n_features, hidden_features = 128, num_blocks = 2, context_features=1, num_bins = 10))
        transforms.append(ReversePermutation(features=n_features))     

I get an error

  File "/global/home/users/rrmastandrea/computingML2/lib64/python3.6/site-packages/nflows/transforms/splines/cubic.py", line 85, in cubic_spline
    raise InputOutsideDomain()
nflows.transforms.base.InputOutsideDomain

It seems that both types of flows are implemented similarly in the nflows repo, so I am not sure why changing the type of transform would cause such an error to be thrown?

imurray commented 2 years ago

You've specified tail behavior (what to do when outside the bins where the spline is defined) in the first case but not the second.

rmastand commented 2 years ago

When I do specify tail behavior, I get

Traceback (most recent call last):
    transforms_.append(MaskedPiecewiseCubicAutoregressiveTransform(features = n_features, hidden_features = 128, num_blocks = 8,  tail_bound=3.5, context_features=1,tails="linear",num_bins = 10, dropout_probability = 0.0))

TypeError: __init__() got an unexpected keyword argument 'tail_bound'

So tail behavior does not seem to be implemented for the cubic transform?

imurray commented 2 years ago

Ah, MaskedPiecewiseCubicAutoregressiveTransform is hardecoded to use a cubic_spline not an unconstrained_cubic_spline that can deal with unconstrained inputs.

In constrast, MaskedPiecewiseRationalQuadraticAutoregressiveTransform has code that checks to see if there are tails and uses the appropriate transform.

At least in the first instance, you could check if altering the MaskedPiecewiseCubicAutoregressiveTransform class to use unconstrained_cubic_spline, or porting the few relevant lines from MaskedPiecewiseRationalQuadraticAutoregressiveTransform, does what you want.

arturbekasov commented 1 year ago

Closing as stale.