### Training loop
# Lists
img_list=[]
G_losses = []
D_losses = []
iters = 0
print("start Training Loop...")
# for each epoch
for epoch in range(num_epochs):
for i, data in enumerate(dataloader, 0):
##### (1) Update D Network
## we train with all real_batch
netD.zero_grad()
#format_batch
real_cpu = data[0]#.to(device)
b_size = real_cpu.size(0)
label=torch.full((b_size,), real_label, dtype=torch.float #device=device
)
# forward pass real batch through D
output = netD(real_cpu.permute(1,2,3, 0)).view(-1)
#calculate loss on all real batches
lossD_real = loss_fn(output, label)
#calculate gradients for D in backward pass
lossD_real.backward()
D_x = output.mean().item()
## Train with all fake batch
# Generate batch for latent vetcors
noise = torch.randn(b_size, nz, 1, 1, 1 #device=device
)
#Generate fake image batch with G
fake = netG(noise)
label.fill_(fake_label)
#classify all fake batch with D
output = netD(fake.detach()).view(-1)
#calculate D's loss on the all-fake bach
lossD_fake = loss_fn(output, label)
#calculate the gradient for this batch, accumulated(summed)
lossD_fake.backward()
D_G_z1 = output.mean().item()
#Compute error of D as sum over the fake and real batches
lossD = lossD_real+lossD_fake
#update D
optimizer_D.step()
##### (2) update G network
netG.zero_grad()
label.fill_(real_label)# fake labels are real for generator
#perform forward pass
output = netD(fake).view(-1)
# G's loss based on this output
lossG = loss_fn(output, label)
# Gradients for G
lossG.backward()
D_G_z2 = output.mean().item()
#update G
optimizer_G.step()
#output training stats
if i % 50 == 0:
print(f"epoch: {num_epochs}, Loss_D: {lossD.itemm(): .4f}, Loss_G: {lossG.item(): .4f}, D(x): {D_x: .4f}, D(G(z)): {D_G_z1: .4f/D_G_z2: .4f}")
#save losses fo plotting later
G_losses.append(lossG.item())
D_losses.append(lossD.item())
# Lets save G's output on fixed noise
if (iters % 500 == 0) or ((epoch == num_epochs-1) and (i==len(dataloader)-1)):
with torch.no_grad():
fake = netG(fixed_noise).detach().cpu()
img_list.appen(vutils.make_grid(fake, padding=2, normalize=True))
iters += 1
Which part of your code raises this error message? Could you post the model definition as well as the full error message including the stacktrace?
Geneartor code
class Generator(nn.Module):
def __init__(self, ngpu):
super(Generator, self).__init__()
self.ngpu = ngpu
self.main = nn.Sequential(
#input is z going into a convolution
nn.ConvTranspose3d(nz, ngf*8, 4, 1, 0, bias=False),
nn.BatchNorm3d(ngf*8),
nn.ReLU(True),
nn.ConvTranspose3d(ngf*8, ngf*4, 4, 2, 1, bias=False),
nn.BatchNorm3d(ngf*4),
nn.ReLU(True),
nn.ConvTranspose3d(ngf*4, ngf*2, 4, 2, 1, bias=False),
nn.BatchNorm3d(ngf*2),
nn.ReLU(True),
nn.ConvTranspose3d(ngf*2, ngf, 4, 2, 1, bias=False),
nn.BatchNorm3d(ngf),
nn.ReLU(True),
nn.ConvTranspose3d(ngf, nc, 4, 2, 1, bias=False),
nn.Tanh()
)
def forward(self, x):
return self.main(x)
Discriminator Code
class Discriminator(nn.Module):
def __init__(self, ngpu):
super(Discriminator, self).__init__()
self.main = nn.Sequential(
nn.Conv2d(nc, ndf, 4, 2, 1, bias=False),
nn.LeakyReLU(0.2, inplace=True),
nn.Conv2d(ndf, ndf*2, 4, 2, 1, bias=False),
nn.BatchNorm2d(ndf*2),
nn.LeakyReLU(0.2, inplace=True),
nn.Conv2d(ndf*2, ndf*4, 4, 2, 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),
nn.Sigmoid()
)
def forward(self, x):
return self.main(x)
nn.ConvTranspose3d
layers expect 5D input in the shape [batch_size, channels, depth, height, width]
(newer PyTorch versions also accept an unbatched 4D input where the batch dimension is missing and implicitly set to 1
), so you might need to unsqueeze
the missing dimension.