I want to train a generator to simulate the distribution of the output of a ResNet18. But pytorch gives an error in the second iteration of the for loop:
RuntimeError: Trying to backward through the graph a second time (or directly access saved
tensors after they have already been freed). Saved intermediate values of the graph are freed
when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to
backward through the graph a second time or if you need to access saved tensors after
calling backward.
Here is my code for training:
def noise(batch_size):
"""
Generates a 1-d vector of gaussian sampled random values
"""
return torch.randn(batch_size, 100, requires_grad=True)
def noise_loss(self, noise_data):
n0 = noise_data[0].reshape((1, -1))
n1 = noise_data[1].reshape((1, -1))
n_loss0 = torch.linalg.norm(n0)
n_loss1 = torch.linalg.norm(n1)
return n_loss0 + n_loss1
def verification_loss(self, fake_pred):
# target_feature is computed by ArcFace with image input and saved.
v_loss0 = F.cosine_similarity(fake_pred[0], self.target_feature[0], dim=0)
v_loss1 = F.cosine_similarity(fake_pred[1], self.target_feature[1], dim=0)
return v_loss0 + v_loss1
def optimize(self, num_epochs):
# freeze ArcFace
self.predictor.eval()
batch_size = 2
# start to train the generator
for epoch in range(num_epochs):
# generate batch of noises
noise_data = self.generator(noise(batch_size).to(self.device))
fake_data = noise_data * self.imposter_mask + self.imposter_image
# get feature from ArcFace
fake_pred = self.predictor(fake_data)
# noise loss
n_loss = self.noise_loss(noise_data)
# verification loss
v_loss = self.verification_loss(fake_pred)
g_error = n_loss + v_loss
# Update the generator
self.g_optimizer.zero_grad()
g_error.backward()
self.g_optimizer.step()