Hi, I implement the BiGAN code and I face this error:
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [1, 1024, 1, 1]] is at version 2; expected version 1 instead. Hint: the backtrace further above shows the operation that failed to compute its gradient. The variable in question was changed in there or anywhere later. Good luck!
Here is the code:
import torch
import torch.nn as nn
import torch.nn.functional as F
class Discriminator(nn.Module):
def init(self, z_dim=32, wasserstein=False):
super(Discriminator, self).init()
self.wass = wasserstein
# Inference over x
self.conv1x = nn.Conv2d(3, 32, 5, stride=1, bias=False)
self.conv2x = nn.Conv2d(32, 64, 4, stride=2, bias=False)
self.bn2x = nn.BatchNorm2d(64)
self.conv3x = nn.Conv2d(64, 128, 4, stride=1, bias=False)
self.bn3x = nn.BatchNorm2d(128)
self.conv4x = nn.Conv2d(128, 256, 4, stride=2, bias=False)
self.bn4x = nn.BatchNorm2d(256)
self.conv5x = nn.Conv2d(256, 512, 4, stride=1, bias=False)
self.bn5x = nn.BatchNorm2d(512)
# Inference over z
self.conv1z = nn.Conv2d(z_dim, 512, 1, stride=1, bias=False)
self.conv2z = nn.Conv2d(512, 512, 1, stride=1, bias=False)
# Joint inference
self.conv1xz = nn.Conv2d(1024, 1024, 1, stride=1, bias=False)
self.conv2xz = nn.Conv2d(1024, 1024, 1, stride=1, bias=False)
self.conv3xz = nn.Conv2d(1024, 1, 1, stride=1, bias=False)
def inf_x(self, x):
x = F.dropout2d(F.leaky_relu(self.conv1x(x), negative_slope=0.1), 0.2, inplace=False)
x = F.dropout2d(F.leaky_relu(self.bn2x(self.conv2x(x)), negative_slope=0.1), 0.2,inplace=False)
x = F.dropout2d(F.leaky_relu(self.bn3x(self.conv3x(x)), negative_slope=0.1), 0.2,inplace=False)
x = F.dropout2d(F.leaky_relu(self.bn4x(self.conv4x(x)), negative_slope=0.1), 0.2,inplace=False)
x = F.dropout2d(F.leaky_relu(self.bn5x(self.conv5x(x)), negative_slope=0.1), 0.2,inplace=False)
return x
def inf_z(self, z):
z = F.dropout2d(F.leaky_relu(self.conv1z(z), negative_slope=0.1), 0.2, inplace=False)
z = F.dropout2d(F.leaky_relu(self.conv2z(z), negative_slope=0.1), 0.2,inplace=False)
return z
def inf_xz(self, xz):
xz = F.dropout(F.leaky_relu(self.conv1xz(xz), negative_slope=0.1), 0.2,inplace=False)
xz = F.dropout(F.leaky_relu(self.conv2xz(xz), negative_slope=0.1), 0.2,inplace=False)
return self.conv3xz(xz)
def forward(self, x, z):
x = self.inf_x(x)
z = self.inf_z(z)
xz = torch.cat((x,z), dim=1)
out = self.inf_xz(xz)
if self.wass:
return out
else:
return torch.sigmoid(out)
class Generator(nn.Module):
def init(self, z_dim=32):
super(Generator, self).init()
self.z_dim = z_dim
self.output_bias = nn.Parameter(torch.zeros(3, 32, 32), requires_grad=True)
self.deconv1 = nn.ConvTranspose2d(z_dim, 256, 4, stride=1, bias=False)
self.bn1 = nn.BatchNorm2d(256)
self.deconv2 = nn.ConvTranspose2d(256, 128, 4, stride=2, bias=False)
self.bn2 = nn.BatchNorm2d(128)
self.deconv3 = nn.ConvTranspose2d(128, 64, 4, stride=1, bias=False)
self.bn3 = nn.BatchNorm2d(64)
self.deconv4 = nn.ConvTranspose2d(64, 32, 4, stride=2, bias=False)
self.bn4 = nn.BatchNorm2d(32)
self.deconv5 = nn.ConvTranspose2d(32, 32, 5, stride=1, bias=False)
self.bn5 = nn.BatchNorm2d(32)
self.deconv6 = nn.Conv2d(32, 3, 1, stride=1, bias=True)
def forward(self, z):
z = F.leaky_relu(self.bn1(self.deconv1(z)), negative_slope=0.1,inplace=False)
z = F.leaky_relu(self.bn2(self.deconv2(z)), negative_slope=0.1,inplace=False)
z = F.leaky_relu(self.bn3(self.deconv3(z)), negative_slope=0.1,inplace=False)
z = F.leaky_relu(self.bn4(self.deconv4(z)), negative_slope=0.1,inplace=False)
z = F.leaky_relu(self.bn5(self.deconv5(z)), negative_slope=0.1,inplace=False)
return torch.sigmoid(self.deconv6(z) + self.output_bias)
class Encoder(nn.Module):
def init(self, z_dim=32):
super(Encoder, self).init()
self.z_dim = z_dim
self.conv1 = nn.Conv2d(3, 32, 5, stride=1, bias=False)
self.bn1 = nn.BatchNorm2d(32)
self.conv2 = nn.Conv2d(32, 64, 4, stride=2, bias=False)
self.bn2 = nn.BatchNorm2d(64)
self.conv3 = nn.Conv2d(64, 128, 4, stride=1, bias=False)
self.bn3 = nn.BatchNorm2d(128)
self.conv4 = nn.Conv2d(128, 256, 4, stride=2, bias=False)
self.bn4 = nn.BatchNorm2d(256)
self.conv5 = nn.Conv2d(256, 512, 4, stride=1, bias=False)
self.bn5 = nn.BatchNorm2d(512)
self.conv6 = nn.Conv2d(512, 512, 1, stride=1, bias=False)
self.bn6 = nn.BatchNorm2d(512)
self.bn7 = nn.Conv2d(512, z_dim*2, 1, stride=1, bias=True)
def reparameterize(self, z):
z = z.view(z.size(0), -1)
mu, log_sigma = z[:, :self.z_dim], z[:, self.z_dim:]
std = torch.exp(log_sigma)
eps = torch.randn_like(std)
return mu + eps * std
def forward(self, x):
x = F.leaky_relu(self.bn1(self.conv1(x)), negative_slope=0.1,inplace=False)
x = F.leaky_relu(self.bn2(self.conv2(x)), negative_slope=0.1,inplace=False)
x = F.leaky_relu(self.bn3(self.conv3(x)), negative_slope=0.1,inplace=False)
x = F.leaky_relu(self.bn4(self.conv4(x)), negative_slope=0.1,inplace=False)
x = F.leaky_relu(self.bn5(self.conv5(x)), negative_slope=0.1,inplace=False)
x = F.leaky_relu(self.bn6(self.conv6(x)), negative_slope=0.1,inplace=False)
z = self.reparameterize(self.conv6(x))
return z.view(x.size(0), self.z_dim, 1, 1)
import torch
import torch.nn as nn
from torch import optim
from torch.autograd import Variable
import torch.nn.functional as F
import torchvision.utils as vutils
import numpy as np
from barbar import Bar
class TrainerBiGAN:
def init(self, args, data, device):
self.args = args
self.train_loader = data
self.device = device
def train(self):
"""Training the BiGAN"""
self.G = Generator(self.args.latent_dim).to(self.device)
self.E = Encoder(self.args.latent_dim).to(self.device)
self.D = Discriminator(self.args.latent_dim, self.args.wasserstein).to(self.device)
self.G.apply(weights_init_normal)
self.E.apply(weights_init_normal)
self.D.apply(weights_init_normal)
if self.args.wasserstein:
optimizer_ge = optim.RMSprop(list(self.G.parameters()) +
list(self.E.parameters()), lr=self.args.lr_rmsprop)
optimizer_d = optim.RMSprop(self.D.parameters(), lr=self.args.lr_rmsprop)
else:
optimizer_ge = optim.Adam(list(self.G.parameters()) +
list(self.E.parameters()), lr=self.args.lr_adam)
optimizer_d = optim.Adam(self.D.parameters(), lr=self.args.lr_adam)
fixed_z = Variable(torch.randn((16, self.args.latent_dim, 1, 1)),
requires_grad=False).to(self.device)
criterion = nn.BCELoss()
for epoch in range(self.args.num_epochs+1):
ge_losses = 0
d_losses = 0
for x, _ in Bar(self.train_loader):
#Defining labels
y_true = Variable(torch.ones((x.size(0), 1)).to(self.device))
y_fake = Variable(torch.zeros((x.size(0), 1)).to(self.device))
#Noise for improving training.
noise1 = Variable(torch.Tensor(x.size()).normal_(0,
0.1 * (self.args.num_epochs - epoch) / self.args.num_epochs),
requires_grad=False).to(self.device)
noise2 = Variable(torch.Tensor(x.size()).normal_(0,
0.1 * (self.args.num_epochs - epoch) / self.args.num_epochs),
requires_grad=False).to(self.device)
#Cleaning gradients.
optimizer_d.zero_grad()
optimizer_ge.zero_grad()
#Generator:
z_fake = Variable(torch.randn((x.size(0), self.args.latent_dim, 1, 1)).to(self.device),
requires_grad=False)
x_fake = self.G(z_fake)
#Encoder:
x_true = x.float().to(self.device)
z_true = self.E(x_true)
#Discriminator
out_true = self.D(x_true + noise1, z_true)
out_fake = self.D(x_fake + noise2, z_fake)
#Losses
if self.args.wasserstein:
loss_d = - torch.mean(out_true) + torch.mean(out_fake)
loss_ge = - torch.mean(out_fake) + torch.mean(out_true)
else:
# 27/01/21
y_true = y_true.unsqueeze(1)
y_true = y_true.unsqueeze(1)
y_fake=y_fake.unsqueeze(1)
y_fake=y_fake.unsqueeze(1)
loss_d = criterion(out_true, y_true) + criterion(out_fake, y_fake)
loss_ge =(criterion(out_fake, y_true) + criterion(out_true, y_fake)).clone()
#Computing gradients and backpropagate.
loss_d.backward(retain_graph=True)
optimizer_d.step()
#with torch.autograd.set_detect_anomaly(True):
torch.autograd.set_detect_anomaly(True)
loss_ge.backward(retain_graph=True)
optimizer_ge.step()
if self.args.wasserstein:
for p in self.D.parameters():
p.data.clamp_(-self.args.clamp, self.args.clamp)
torch.autograd.backward(self, gradient, retain_graph, create_graph)
ge_losses += loss_ge.item()
d_losses += loss_d.item()
if epoch % 50 == 0:
vutils.save_image(self.G(fixed_z).data, './images/{}_fake.png'.format(epoch))
print("Training... Epoch: {}, Discrimiantor Loss: {:.3f}, Generator Loss: {:.3f}".format(
epoch, d_losses/len(self.train_loader), ge_losses/len(self.train_loader)
))
import torch
def weights_init_normal(m):
classname = m.class.name
if classname.find(“Conv”) != -1 and classname != ‘Conv’:
torch.nn.init.normal_(m.weight.data, 0.0, 0.02)
if m.bias is not None:
m.bias.data.fill_(0)
elif classname.find(“Linear”) != -1:
torch.nn.init.normal_(m.weight.data, 0.0, 0.02)
if m.bias is not None:
m.bias.data.fill_(0)
elif classname.find(‘BatchNorm’) != -1:
m.weight.data.normal_(1.0, 0.01)
if m.bias is not None:
m.bias.data.fill_(0)
import torch
import numpy as np
from torchvision import datasets
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
def get_cifar10(args, data_dir=’./data/cifar/’):
“”“Returning cifar dataloder.”""
transform = transforms.Compose([transforms.Resize(32), #3x32x32 images.
transforms.ToTensor()])
data = datasets.CIFAR10(root=data_dir, train=True, download=True, transform=transform)
dataloader = DataLoader(data, batch_size=args.batch_size, shuffle=True)
return dataloader
import numpy as np
import argparse
import torch
if name == ‘main’:
parser = argparse.ArgumentParser()
parser.add_argument("–num_epochs", type=int, default=200,
help=“number of epochs”)
parser.add_argument(’–lr_adam’, type=float, default=1e-4,
help=‘learning rate’)
parser.add_argument(’–lr_rmsprop’, type=float, default=1e-4,
help=‘learning rate RMSprop if WGAN is True.’)
parser.add_argument("–batch_size", type=int, default=128,
help=“Batch size”)
parser.add_argument(’–latent_dim’, type=int, default=256,
help=‘Dimension of the latent variable z’)
parser.add_argument(’–wasserstein’, type=bool, default=False,
help=‘If WGAN.’)
parser.add_argument(’–clamp’, type=float, default=1e-2,
help=‘Clipping gradients for WGAN.’)
#parsing arguments.
args = parser.parse_args()
#check if cuda is available.
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
data = get_cifar10(args)
bigan = TrainerBiGAN(args, data, device)
bigan.train()
Someone coul help me please?