Currently you are re-creating a nn.Linear layer in your forward method in each call.
This will reinitialize its parameters in each forward pass, so that this layer won’t be able to learn anything.
That being said, the to() operator also cannot push this module to the device, so that you would have to do it manually in the forward method.
However, since I assume you would like to train this layer, just define it inside __init__:
class Discriminator(nn.Module):
    def __init__(self,ngpu):
        super().__init__()
        self.ngpu=ngpu
        self.main=nn.Sequential(
            nn.Conv2d(in_channels=nc, out_channels=ndf, kernel_size=(4,4), stride=2, padding=1, bias=False),
            nn.LeakyReLU(0.2, inplace=True),
            nn.BatchNorm2d(ndf),
            nn.Conv2d(ndf, ndf * 2, kernel_size=(4,4), stride=2, padding=1, bias=False),
            nn.BatchNorm2d(ndf * 2),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(ndf*2, ndf * 4, kernel_size=(4,4), stride=2, padding=1, bias=False),
            nn.BatchNorm2d(ndf * 4),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 8),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(ndf * 8, 1, 4, 1, 0, bias=False),
        )
        self.fc = nn.Linear(INPUT_FEATURES, 128)

    def forward(self, inputs):
        x = self.main(inputs)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        x = torch.sigmoid(x)
        return x

I’ve also removed the Flatten module, since it flattens the complete tensor to a single dimension, which is probably also not desired.