class DCGenerator(nn.Module):
def __init__(self, z_dim=100, ngf=64, nc=1):
super().__init__()
# Input: (B, z_dim, 1, 1) -> output (B, nc, 32, 32)
self.net = nn.Sequential(
nn.ConvTranspose2d(z_dim, ngf*4, 4, 1, 0, bias=False), nn.BatchNorm2d(ngf*4), nn.ReLU(True), # -> (ngf*4, 4, 4)
nn.ConvTranspose2d(ngf*4, ngf*2, 4, 2, 1, bias=False), nn.BatchNorm2d(ngf*2), nn.ReLU(True), # -> (ngf*2, 8, 8)
nn.ConvTranspose2d(ngf*2, ngf, 4, 2, 1, bias=False), nn.BatchNorm2d(ngf), nn.ReLU(True), # -> (ngf, 16, 16)
nn.ConvTranspose2d(ngf, nc, 4, 2, 1, bias=False), nn.Tanh(), # -> (nc, 32, 32)
)
def forward(self, z):
return self.net(z)
class DCDiscriminator(nn.Module):
def __init__(self, ndf=64, nc=1):
super().__init__()
# Input: (B, nc, 32, 32) -> output (B, 1, 1, 1)
self.net = nn.Sequential(
nn.Conv2d(nc, ndf, 4, 2, 1, bias=False), nn.LeakyReLU(0.2, True), # -> (ndf, 16, 16)
nn.Conv2d(ndf, ndf*2, 4, 2, 1, bias=False), nn.BatchNorm2d(ndf*2), nn.LeakyReLU(0.2, True), # -> (ndf*2, 8, 8)
nn.Conv2d(ndf*2, ndf*4, 4, 2, 1, bias=False), nn.BatchNorm2d(ndf*4), nn.LeakyReLU(0.2, True), # -> (ndf*4, 4, 4)
nn.Conv2d(ndf*4, 1, 4, 1, 0, bias=False), nn.Sigmoid(), # -> (1, 1, 1)
)
def forward(self, x):
return self.net(x).view(-1, 1) # (B, 1)
G = DCGenerator(); D = DCDiscriminator()
z = torch.randn(8, 100, 1, 1)
fake = G(z)
print(fake.shape, D(fake).shape) # torch.Size([8, 1, 32, 32]) torch.Size([8, 1])