I am trying to implement the PGGAN and have the following code for my discriminator model:
# New D model
class Discriminator(nn.Module):
def __init__(self):
super().__init__()
# First conv corresponds to fromRGB
self.fromRGB = None
#self.fromRGB = from_to_RGB(in_channels=3, out_channels=16)
self.block1 = None
self.block2 = None
self.block3 = None
self.block4 = None
self.block5 = None
self.block6 = None
self.block7 = None
# If none we add the model in the forward pass?
# issue remains of last layer and the FC layer
# Now let's try and do this dynamically using a list?
# FC output layer
# I will hardcode the different FC layers
self.FC1 = None
# The output sigmoid
self.sigmoid = nn.Sigmoid()
# We can use this method to reset the FC layer after we complete training for each block
def reset_output_layer(self):
self.FC1 = None
def set_fromRGB(self):
self.fromRGB = None
# def activate_layer(self, layer) Perhaps this is a better way to init the layers?
def forward(self, x, layer_num=1, alpha=0):
# This is the fromRGB transform
#print(x.shape)
# For now, instead of inferring the number of input channels expected by the layer after fromRGB
# Let's hardcode it with a list and we will reinitialise the fromRGB layer each time we grow the network
# until we reach layer 7 at which point fromRGB will be locked in
expected_channels = [512, 512, 256, 128, 64, 32, 16]
if alpha == 0:
self.fromRGB = None
self.fromRGB = from_to_RGB(in_channels=3, out_channels=expected_channels[layer_num-1]).to(x.device)
x = self.fromRGB(x)
#if layer_num == 3:
#print(f'X after fromRGB: {x.shape}')
# Block 7
if layer_num >= 7:
#print("BLOCK 7 ACTIVE")
if self.block1 is None:
self.block1 = d_conv_block(in_channels=16, out_channels=32, kernel_size1=(3,3)).to(x.device)
x = self.block1(x)
# Block 6
if layer_num >= 6:
#print("BLOCK 6 ACTIVE")
if self.block2 is None:
self.block2 = d_conv_block(in_channels=32, out_channels=64, kernel_size1=(3,3)).to(x.device)
x = self.block2(x)
# Block 5
if layer_num >= 5:
#print("BLOCK 5 ACTIVE")
if self.block3 is None:
self.block3 = d_conv_block(in_channels=64, out_channels=128, kernel_size1=(3,3)).to(x.device)
x = self.block3(x)
# Block 4
if layer_num >= 4:
#print("BLOCK 4 ACTIVE")
if self.block4 is None:
self.block4 = d_conv_block(in_channels=128, out_channels=256, kernel_size1=(3,3)).to(x.device)
x = self.block4(x)
# Block 3
if layer_num >= 3:
#print("BLOCK 3 ACTIVE")
if self.block5 is None:
self.block5 = d_conv_block(in_channels=256, out_channels=512, kernel_size1=(3,3)).to(x.device)
x = self.block5(x)
# Block 2
if layer_num >= 2:
#print("BLOCK 2 ACTIVE")
if self.block6 is None:
self.block6 = d_conv_block(in_channels=512, out_channels=512, kernel_size1=(3,3)).to(x.device)
x = self.block6(x)
# Block 1
if layer_num >= 1:
#print("BLOCK 1 ACTIVE")
if self.block7 is None:
self.block7 = d_conv_block(in_channels=512, out_channels=512, kernel_size1=(3,3), kernel_size2=(4,4)).to(x.device)
x = self.block7(x)
# Last FC layer
x = x.view(x.size(0), -1) # Reshape the output, i.e. flatten it
self.FC1 = d_output_layer(x.size(1)).to(x.device)
#print(x.shape)
x = self.FC1(x)
# The output has to be passed through a sigmoid layer for our BCELoss
x = self.sigmoid(x)
return x
final_d = Discriminator().to(device)
The part of code:
expected_channels = [512, 512, 256, 128, 64, 32, 16]
if alpha == 0:
self.fromRGB = None
self.fromRGB = from_to_RGB(in_channels=3, out_channels=expected_channels[layer_num-1]).to(x.device)
x = self.fromRGB(x)
Is showing an error when I switch alpha from 0 to 0.05, the error being:
RuntimeError: Given groups=1, weight of size [256, 256, 3, 3], expected input[32, 512, 16, 16] to have 256 channels, but got 512 channels instead
It seems to be that when alpha changes to 0.05 the fromRGB layer reverts to the old one even though I set fromRGB to match current expected output dims everytime alpha=0?