0
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F


class InvConv(nn.Module):
    """Invertible 1x1 Convolution for 2D inputs. Originally described in Glow
    (https://arxiv.org/abs/1807.03039). Does not support LU-decomposed version.

    Args:
        num_channels (int): Number of channels in the input and output.
    """
    def __init__(self, num_channels):
        super(InvConv, self).__init__()
        
        self.num_channels = num_channels

        # Initialize with a random orthogonal matrix
        #creat a random matrix
        w_init = np.random.randn(num_channels, num_channels)
        #w_init = q
        w_init = np.linalg.qr(w_init)[0].astype(np.float32)
        # turn array to tensor and turn it to a learnable parameter
        self.weight = nn.Parameter(torch.from_numpy(w_init))

    def forward(self, x, sldj, reverse=False):

        ldj = torch.slogdet(self.weight)[1] * x.size(2) * x.size(3)

        if reverse:
            weight = torch.inverse(self.weight.double()).float()
            sldj = sldj - ldj
        else:
            weight = self.weight
            sldj = sldj + ldj
        
        
        weight = weight.view(self.num_channels, self.num_channels, 1,1)
        z = F.conv2d(x, weight)

        return z, sldj

here is the original code

self.num_channel = 12

self.weight = torch([12,12])

weight is reshaped to tensor([12,12,1,1])

and x is the image size = tensor([64,12,16,16]) #(batch size,channels,H,W)

z = tensor([64,12,16,16])

the code is to use a 1X1 cone matrix ''self.weight'' to rearrange the input image x , the size of the kernel is 1x1 and have 12 channels (it has 12 kernels to formed a [12,12] self.weight) and because my model applies flow-based model , hence, I need to calculate the inverse of the convolution (reverse=True)

my problem is now I want to change the 1X1 kernel to a 2X2 kernel ,and the input and output shape is same as the above , hence I wrote my code as below

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F


class InvConv(nn.Module):
    """Invertible 1x1 Convolution for 2D inputs. Originally described in Glow
    (https://arxiv.org/abs/1807.03039). Does not support LU-decomposed version.

    Args:
        num_channels (int): Number of channels in the input and output.
    """
    def __init__(self, num_channels):
        super(InvConv, self).__init__()
        self.num_channels = num_channels

        # Initialize with a random orthogonal matrix
        #creat a random matrix
        w_init = np.random.randn(2*num_channels, 2*num_channels)
        #w_init = q
        w_init = np.linalg.qr(w_init)[0].astype(np.float32)
        # turn array to tensor and turn it to a learnable parameter
        self.weight = nn.Parameter(torch.from_numpy(w_init))

    def forward(self, x, sldj, reverse=False):
        ldj = torch.slogdet(self.weight)[1] * x.size(2) * x.size(3)

        if reverse:
            weight = torch.inverse(self.weight.double()).float()
            sldj = sldj - ldj
        else:
            weight = self.weight
            sldj = sldj + ldj
        
        
        weight = weight.contiguous().view(self.num_channels, self.num_channels, 2,2)
        
        z = F.conv2d(x, weight, stride=2, padding=x.size(2)//2)

        return z, sldj

so now my self.weight is a tensor([24,24])

because I hope my output still remains at [64,12,16,16]

but I need my kernel size to be 2X2 , so the only way is to make self.weight larger

but if I use this code , my negative log-likelihood becomes negative , and the bits-per-dim is negative too , this is weird , and the bigger error is that the training will stop because of an error like the below

Traceback (most recent call last):
  File "train.py", line 182, in <module>
    main(parser.parse_args())
  File "train.py", line 77, in main
    train(epoch, net, trainloader, device, optimizer, scheduler,
  File "/home/claire/miniconda3/envs/glow/lib/python3.8/site-packages/torch/autograd/grad_mode.py", line 27, in decorate_context
    return func(*args, **kwargs)
  File "train.py", line 95, in train
    loss.backward()
  File "/home/claire/miniconda3/envs/glow/lib/python3.8/site-packages/torch/_tensor.py", line 396, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph, inputs=inputs)
  File "/home/claire/miniconda3/envs/glow/lib/python3.8/site-packages/torch/autograd/__init__.py", line 173, in backward
    Variable._execution_engine.run_backward(  # Calls into the C++ engine to run the backward pass
torch._C._LinAlgError: cusolver error: CUSOLVER_STATUS_EXECUTION_FAILED, when calling `cusolverDnSgesvd( handle, jobu, jobvt, m, n, A, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info)`. This error may appear if the input matrix contains NaN.

0 Answers0