Hello please i need help with this error
RuntimeError: Given transposed=1, weight of size [192, 64, 4, 4], expected input[8, 252, 258, 258] to have 192 channels, but got 252 channels instead
the error is at the def forward of the generator
x = nn.functional.relu(self.deconv1(x), inplace=True)
here is the full code
import torch
import torch.nn as nn
import torch.nn.functional as F
# Depthwise dilated convolutional layer
class DepthwiseDilatedConv(nn.Module):
def __init__(self, in_channels, latent_dim, out_channels, dilation_factor):
super(DepthwiseDilatedConv, self).__init__()
self.depthwise_conv = nn.Conv2d(in_channels + latent_dim, in_channels + latent_dim,
kernel_size=3, padding=dilation_factor, dilation=dilation_factor, groups=in_channels + latent_dim)
self.batch_norm1 = nn.BatchNorm2d(in_channels + latent_dim, momentum=0.78)
self.pointwise_conv = nn.Conv2d(in_channels + latent_dim, out_channels, kernel_size=1)
self.batch_norm2 = nn.BatchNorm2d(out_channels, momentum=0.78)
def forward(self, x, latent_noise):
latent_noise = latent_noise.expand(-1, -1, x.size(2), x.size(3))
x = torch.cat([x, latent_noise], dim=1)
x = self.depthwise_conv(x)
x = self.batch_norm1(x)
x = F.relu(x, inplace=True)
x = self.pointwise_conv(x)
x = self.batch_norm2(x)
return x
class FeatureReuseResidualBlock(nn.Module):
def __init__(self, in_channels, out_channels):
super(FeatureReuseResidualBlock, self).__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=1, padding=1)
self.batch_norm1 = nn.BatchNorm2d(out_channels, momentum=0.78)
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)
self.batch_norm2 = nn.BatchNorm2d(out_channels, momentum=0.78)
self.conv3 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)
self.batch_norm3 = nn.BatchNorm2d(out_channels, momentum=0.78)
self.conv4 = nn.Conv2d(out_channels, in_channels, kernel_size=3, padding=1)
self.batch_norm4 = nn.BatchNorm2d(in_channels, momentum=0.78)
def forward(self, x):
residual1 = x
x = self.conv1(x)
x = self.batch_norm1(x)
residual2 = x
x = self.conv2(x)
x = self.batch_norm2(x)
x = F.relu(x, inplace=True)
x = self.conv3(x)
x = self.batch_norm3(x)
x = F.relu(x, inplace=True)
x = self.conv4(x)
x = self.batch_norm4(x)
x = torch.cat((x, residual2), dim=1)
residual1 = F.pad(residual1, (0, x.shape[3] - residual1.shape[3], 0, x.shape[2] - residual1.shape[2], 0, x.shape[1] - residual1.shape[1]))
x += residual1
x = F.relu(x, inplace=True)
print("FeatureReuseResidualBlock x - Output Shape:", x.shape)
return x
# InceptionV3 with Factorization// 2
class InceptionV3Factorized(nn.Module):
def __init__(self, in_channels, out_channels):
super(InceptionV3Factorized, self).__init__()
self.conv1x1 = nn.Conv2d(128, out_channels, kernel_size=1) # Adjust the output channels here
self.conv3x3_reduce = nn.Conv2d(128, out_channels // 3, kernel_size=1)
self.conv3x3_1 = nn.Conv2d(out_channels // 3, out_channels // 3, kernel_size=(1, 3), padding=(0, 1))
self.conv3x3_2 = nn.Conv2d(out_channels // 3, out_channels // 3, kernel_size=(3, 1), padding=(1, 0))
self.conv5x5_reduce = nn.Conv2d(128, out_channels // 6, kernel_size=1)
self.conv5x5_1 = nn.Conv2d(out_channels // 6, out_channels // 6, kernel_size=(1, 5), padding=(0, 2))
self.conv5x5_2 = nn.Conv2d(out_channels // 6, out_channels // 6, kernel_size=(5, 1), padding=(2, 0))
self.pool_proj = nn.Conv2d(128, out_channels // 3, kernel_size=1)
def forward(self, x):
print("InceptionV3Factorized x - Output Shape:", x.shape)
x1 = nn.functional.relu(self.conv1x1(x), inplace=True)
print("InceptionV3Factorized x1 - Output Shape:", x1.shape)
x2 = nn.functional.relu(self.conv3x3_reduce(x), inplace=True)
x2_1 = nn.functional.relu(self.conv3x3_1(x2), inplace=True)
x2_2 = nn.functional.relu(self.conv3x3_2(x2), inplace=True)
print("InceptionV3Factorized x2 - Output Shape:", x2.shape)
x3 = nn.functional.relu(self.conv5x5_reduce(x), inplace=True)
x3_1 = nn.functional.relu(self.conv5x5_1(x3), inplace=True)
x3_2 = nn.functional.relu(self.conv5x5_2(x3), inplace=True)
print("InceptionV3Factorized x3 - Output Shape:", x3.shape)
x4 = nn.functional.relu(F.max_pool2d(x, kernel_size=3, stride=1, padding=1))
x4 = nn.functional.relu(self.pool_proj(x4), inplace=True)
print("InceptionV3Factorized x4 - Output Shape:", x4.shape)
# Adjust the concatenation to have the desired shape
x1 = F.pad(x1, (0, x4.shape[3] - x1.shape[3], 0, x4.shape[2] - x1.shape[2], 0, x4.shape[1] - x1.shape[1]))
x2_1 = F.pad(x2_1, (0, x4.shape[3] - x2_1.shape[3], 0, x4.shape[2] - x2_1.shape[2], 0, x4.shape[1] - x2_1.shape[1]))
x2_2 = F.pad(x2_2, (0, x4.shape[3] - x2_2.shape[3], 0, x4.shape[2] - x2_2.shape[2], 0, x4.shape[1] - x2_2.shape[1]))
x3_1 = F.pad(x3_1, (0, x4.shape[3] - x3_1.shape[3], 0, x4.shape[2] - x3_1.shape[2], 0, x4.shape[1] - x3_1.shape[1]))
x3_2 = F.pad(x3_2, (0, x4.shape[3] - x3_2.shape[3], 0, x4.shape[2] - x3_2.shape[2], 0, x4.shape[1] - x3_2.shape[1]))
output = torch.cat([x1, x2_1, x2_2, x3_1, x3_2, x4], dim=1)
print("InceptionV3Factorized - Output Shape:", output.shape)
return output
# GAN Generator Architecture
class Generator(nn.Module):
def __init__(self, image_channels, latent_dim, channels=64, inception_out_channels=128):
super(Generator, self).__init__()
self.depthwise_dilated_conv = DepthwiseDilatedConv(image_channels, latent_dim, channels, dilation_factor=2)
self.feature_reuse_residual_block = FeatureReuseResidualBlock(channels, channels)
self.inception_block = InceptionV3Factorized(channels, inception_out_channels)
# Adjust the input channels for deconv1
deconv1_input_channels = inception_out_channels + channels
self.deconv1 = nn.ConvTranspose2d(deconv1_input_channels, channels, kernel_size=4, stride=2, padding=1)
self.deconv2 = nn.ConvTranspose2d(channels, 64, kernel_size=4, stride=2, padding=1)
self.final_conv = nn.Conv2d(64, image_channels, kernel_size=3, stride=1, padding=1)
self.tanh = nn.Tanh()
def forward(self, images, latent_noise):
x = self.depthwise_dilated_conv(images, latent_noise)
print("generator depthwise_dilated_conv- Output Shape:", x.shape)
x = self.feature_reuse_residual_block(x)
print("generator feature_reuse_residual_block - Output Shape:", x.shape)
x = self.inception_block(x)
print("generator inception_block - Output Shape:", x.shape)
# Verify the number of channels in the deconv1 input
channels=64
deconv1_input_channels = x.shape[1] + channels
print(f"Expected deconv1 input channels: {deconv1_input_channels}")
# Debugging: print the shapes before deconv1
print(f"Before deconv1 - x.shape: {x.shape}")
# Adjust the number of channels in the deconv1 layer
x = nn.functional.relu(self.deconv1(x), inplace=True)
x = nn.functional.relu(self.deconv2(x), inplace=True)
x = self.tanh(self.final_conv(x))
print("Generator - Final Output Shape:", x.shape)
return x
# Testing the model with random noise and images
torch.manual_seed(42)
# Instantiate the generator
image_channels = 1 # Grayscale images
latent_dim = 100
generator = Generator(image_channels, latent_dim, channels=64, inception_out_channels=128)
# Generate random noise and images
random_noise = torch.randn(8, latent_dim, 1, 1)
random_images = torch.randn(8, image_channels, 256, 256)
# Forward pass through the generator
generated_image = generator(random_images, random_noise)
# Print the shape of the generated image
print("Generated Image Shape:", generated_image.shape)