在DCGAN中,报错尺寸不一样

ValueError: Using a target size (torch.Size([16])) that is different to the input size (torch.Size([400])) is deprecated. Please ensure they have the same size.
三天了,因为想输出的图片尺寸大一点,改了生成器,判别器中的部分卷积层想输出128*128,还是报错,求解决办法🤥😭

这个错误通常是由于在训练过程中使用了不同大小的目标图像导致的。在DCGAN中,通常使用的目标图像尺寸是torch.Size([16]),而输入图像的尺寸是torch.Size([400])。这个错误提示您需要确保目标图像和输入图像具有相同的尺寸,否则训练将无法正常进行。

为了解决这个问题,您可以尝试以下几种方法:

将目标图像和输入图像的尺寸调整为相同的大小。您可以使用torch.nn.functional.interpolate函数来实现这一点,该函数可以将输入图像的尺寸调整为与目标图像相同的大小。
将目标图像和输入图像的尺寸调整为相同的大小,并使用torch.nn.functional.interpolate函数来实现这一点。
在训练过程中,使用相同的目标图像和输入图像,并将其传递给训练过程。
无论您选择哪种方法,都需要确保在训练过程中使用相同的目标图像和输入图像,以避免出现这个错误。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    首先,这个报错提示我我们的目标尺寸(target size)和输入尺寸(input size)大小不一致,但是这不应该导致这个被废弃的错误。因此,我们需要仔细观察代码并确定原因。

    通过分析代码和错误信息,可以看出问题发生在模型训练的部分。我们正在使用输入张量的大小训练模型,尝试使用不同的目标大小。这可能是由于我们的模型定义需要更新以支持更大的图像尺寸。

    基于这个问题,我建议你需要仔细检查你的模型定义,并进行以下修改:

    1. 首先,你需要检查你的模型定义,确认你的输入大小是否正确设置。你可能需要更改模型定义中的部分卷积层的参数以支持128*128的图像尺寸输出。

    2. 接着,你可以在调整模型定义后检查数据加载器和批处理的参数,确保在训练期间使用的张量大小与模型期望的输入大小相匹配。

    3. 最后,你可以检查损失函数和优化器等模型训练参数是否会引起错误。确保它们与新的输入/目标大小相适应。

    这些步骤应该帮助你解决这个问题。下面是一个示例代码,帮助你调整DCGAN模型以支持128*128的图像尺寸输出。

    import torch.nn as nn
    
    class Generator(nn.Module):
        def __init__(self, nz, ngf, nc):
            super(Generator, self).__init__()
            self.main = nn.Sequential(
                # input is Z, going into a convolution
                nn.ConvTranspose2d(nz, ngf * 8, 4, 1, 0, bias=False),
                nn.BatchNorm2d(ngf * 8),
                nn.ReLU(True),
                # state size. (ngf*8) x 4 x 4
                nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ngf * 4),
                nn.ReLU(True),
                # state size. (ngf*4) x 8 x 8
                nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ngf * 2),
                nn.ReLU(True),
                # state size. (ngf*2) x 16 x 16
                nn.ConvTranspose2d(ngf * 2, ngf, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ngf),
                nn.ReLU(True),
                # state size. (ngf) x 32 x 32
                nn.ConvTranspose2d(ngf, nc, 4, 2, 1, bias=False),
                nn.Tanh()
                # state size. (nc) x 64 x 64
            )
    
        def forward(self, input):
            return self.main(input)
    
    
    class Discriminator(nn.Module):
        def __init__(self, nc, ndf):
            super(Discriminator, self).__init__()
            self.main = nn.Sequential(
                # input is (nc) x 64 x 64
                nn.Conv2d(nc, ndf, 4, 2, 1, bias=False),
                nn.LeakyReLU(0.2, inplace=True),
                # state size. (ndf) x 32 x 32
                nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ndf * 2),
                nn.LeakyReLU(0.2, inplace=True),
                # state size. (ndf*2) x 16 x 16
                nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ndf * 4),
                nn.LeakyReLU(0.2, inplace=True),
                # state size. (ndf*4) x 8 x 8
                nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ndf * 8),
                nn.LeakyReLU(0.2, inplace=True),
                # state size. (ndf*8) x 4 x 4
                nn.Conv2d(ndf * 8, 1, 4, 1, 0, bias=False),
                nn.Sigmoid()
            )
    
        def forward(self, input):
            return self.main(input).view(-1, 1)
    

    在这个示例中,我们升级了Generator和Discriminator,以支持更高的输入图像尺寸。Generator使用卷积转置层来反卷积图像,以便输出128x128像素的图像。Discriminator使用标准卷积层来缩小图像,以适应128x128像素的输入。这样我们就能够在执行模型训练时避免ValueError错误。

    # 示例 - 模型定义使用
    nz = 100 # 确定初始噪声向量的长度
    ngf = 64 # 设置生成器特征图的尺寸
    nc = 3   # 设置图像通道数
    
    # 初始化生成器和鉴别器
    netG = Generator(nz, ngf, nc)
    netD = Discriminator(nc, ngf)
    
    # 设置优化器和损失函数
    criterion = nn.BCELoss()
    optimizerD = optim.Adam(netD.parameters(), lr=0.0002, betas=(0.5, 0.999))
    optimizerG = optim.Adam(netG.parameters(), lr=0.0002, betas=(0.5, 0.999))
    
    # 训练GAN
    for epoch in range(num_epochs):
        for i, data in enumerate(dataloader, 0):
            # 输入数据
            real_cpu = data[0].to(device)
            batch_size = real_cpu.size(0)
            label = torch.full((batch_size,), real_label, dtype=torch.float, device=device)
            noise = torch.randn(batch_size, nz, 1, 1, device=device)
    
            # 训练鉴别器
            netD.zero_grad()
            output = netD(real_cpu)
            errD_real = criterion(output, label)
            errD_real.backward()
            D_x = output.mean().item()
    
            # 让D尽可能地区分真和假
            fake = netG(noise)
            label.fill_(fake_label)
            output = netD(fake.detach())
            errD_fake = criterion(output, label)
            errD_fake.backward()
            D_G_z1 = output.mean().item()
            errD = errD_real + errD_fake
            optimizerD.step()
    
            # 训练生成器
            netG.zero_grad()
            label.fill_(real_label) 
            output = netD(fake)
            errG = criterion(output, label)
            errG.backward()
            D_G_z2 = output.mean().item()
            optimizerG.step()
    
            # 输出统计信息
            print('[%d/%d][%d/%d] Loss_D: %.4f Loss_G: %.4f D(x): %.4f D(G(z)): %.4f / %.4f'
                  % (epoch+1, num_epochs, i+1, len(dataloader),
                     errD.item(), errG.item(), D_x, D_G_z1, D_G_z2))
    

    以上是修改模型定义和训练循环的一个示例解决方案。请注意,你的模型定义可能会因应用和需求不同而有所不同。我建议你注意代码中的特定细节,以便在修改模型定义时充分考虑它们。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^