In
nn.Sequential,torch.nn.Unflatten()can help you achieve reshape operation.For
nn.Linear, its input shape is(N, *, H_{in})and output shape is(H, *, H_{out}). Note that the feature dimension is last. Sounsqueeze_noise()is not useful here.Based on the network structure, the arguments passed to
make_gen_blockare wrong.
I have checked the following code:
import torch
from torch import nn
class Generator(nn.Module):
def __init__(self, z_dim=100, im_chan=1, hidden_dim=64, rdim=9216):
super(Generator, self).__init__()
self.z_dim = z_dim
self.gen = nn.Sequential(
nn.Linear(z_dim, rdim),
nn.BatchNorm1d(rdim,momentum=0.9), # use BN1d
nn.ReLU(inplace=True),
nn.Unflatten(1, (256,6,6)),
self.make_gen_block(256, hidden_dim*2,kernel_size=2), # note arguments
self.make_gen_block(hidden_dim*2,hidden_dim,kernel_size=2), # note kernel_size
self.make_gen_block(hidden_dim,im_chan,kernel_size=2,final_layer=True), # note kernel_size
)
def make_gen_block(self, input_channels, output_channels, kernel_size=1, stride=2, final_layer=False):
if not final_layer:
return nn.Sequential(
nn.ConvTranspose2d(input_channels, output_channels, kernel_size, stride),
nn.BatchNorm2d(output_channels),
nn.ReLU(inplace=True)
)
else:
return nn.Sequential(
nn.ConvTranspose2d(input_channels, output_channels, kernel_size, stride),
nn.Tanh()
)
def forward(self, x):
return self.gen(x)
def get_noise(n_samples, z_dim, device='cpu'):
return torch.randn(n_samples, z_dim, device=device)
gen = Generator()
num_test = 100
input_noise = get_noise(num_test, gen.z_dim)
output = gen(input_noise)
assert output.shape == (num_test, 1, 48, 48)
Answer from ILS on Stack OverflowIn
nn.Sequential,torch.nn.Unflatten()can help you achieve reshape operation.For
nn.Linear, its input shape is(N, *, H_{in})and output shape is(H, *, H_{out}). Note that the feature dimension is last. Sounsqueeze_noise()is not useful here.Based on the network structure, the arguments passed to
make_gen_blockare wrong.
I have checked the following code:
import torch
from torch import nn
class Generator(nn.Module):
def __init__(self, z_dim=100, im_chan=1, hidden_dim=64, rdim=9216):
super(Generator, self).__init__()
self.z_dim = z_dim
self.gen = nn.Sequential(
nn.Linear(z_dim, rdim),
nn.BatchNorm1d(rdim,momentum=0.9), # use BN1d
nn.ReLU(inplace=True),
nn.Unflatten(1, (256,6,6)),
self.make_gen_block(256, hidden_dim*2,kernel_size=2), # note arguments
self.make_gen_block(hidden_dim*2,hidden_dim,kernel_size=2), # note kernel_size
self.make_gen_block(hidden_dim,im_chan,kernel_size=2,final_layer=True), # note kernel_size
)
def make_gen_block(self, input_channels, output_channels, kernel_size=1, stride=2, final_layer=False):
if not final_layer:
return nn.Sequential(
nn.ConvTranspose2d(input_channels, output_channels, kernel_size, stride),
nn.BatchNorm2d(output_channels),
nn.ReLU(inplace=True)
)
else:
return nn.Sequential(
nn.ConvTranspose2d(input_channels, output_channels, kernel_size, stride),
nn.Tanh()
)
def forward(self, x):
return self.gen(x)
def get_noise(n_samples, z_dim, device='cpu'):
return torch.randn(n_samples, z_dim, device=device)
gen = Generator()
num_test = 100
input_noise = get_noise(num_test, gen.z_dim)
output = gen(input_noise)
assert output.shape == (num_test, 1, 48, 48)
Instead of that you can do this
LATENT_DIM = 100
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.linear = nn.Linear(LATENT_DIM, 4*4*LATENT_DIM)
self.active_0 = nn.ReLU()
self.conv_trans_1 = nn.ConvTranspose2d(LATENT_DIM, 512, kernel_size=4, stride=2, padding=1)
self.norm_1 = nn.BatchNorm2d(512)
self.active_1 = nn.LeakyReLU(0.2)
self.conv_trans_2 = nn.ConvTranspose2d(512, 256, kernel_size=4, stride=2, padding=1)
self.norm_2 = nn.BatchNorm2d(256)
self.active_2 = nn.LeakyReLU(0.2)
self.conv_trans_3 = nn.ConvTranspose2d(256, 128, kernel_size=4, stride=2, padding=1)
self.norm_3 = nn.BatchNorm2d(128)
self.active_3 = nn.LeakyReLU(0.2)
self.conv_trans_4 = nn.ConvTranspose2d(128, 3, kernel_size=4, stride=2, padding=1)
self.norm_4 = nn.BatchNorm2d(3)
self.active_4 = nn.Tanh()
def forward(self, inputs):
x = self.linear(inputs)
x = self.active_0(x)
x = x.view(-1, Config.LATENT_DIM, 4, 4) ################
x = self.conv_trans_1(x)
x = self.norm_1(x)
x = self.active_1(x)
x = self.conv_trans_2(x)
x = self.norm_2(x)
x = self.active_2(x)
x = self.conv_trans_3(x)
x = self.norm_3(x)
x = self.active_3(x)
x = self.conv_trans_4(x)
x = self.norm_4(x)
x = self.active_4(x)
return x
Summary of Model