Meu código:
import torch
import random
image_width, image_height = 128, 128
def apply_ellipse_mask(img, pos, axes):
r = torch.arange(image_height)[:, None]
c = torch.arange(image_width)[None, :]
val_array = ((c - pos[0]) ** 2) / axes[0] ** 2 + ((r - pos[1]) ** 2) / axes[1] ** 2
mask = torch.where((0.9 < val_array) & (val_array < 1), torch.tensor(1.0), torch.tensor(0.0))
return img * (1.0 - mask) + mask
random.seed(0xced)
sphere_radius = image_height / 3
sphere_position = torch.tensor([image_width / 2, image_height / 2 ,0], requires_grad=True)
ref_image = apply_ellipse_mask(torch.zeros(image_width, image_height, requires_grad=True), sphere_position, [sphere_radius, sphere_radius, sphere_radius])
ellipsoid_pos = torch.tensor([sphere_position[0], sphere_position[1], 0], requires_grad=True)
ellipsoid_axes = torch.tensor([image_width / 3 + (random.random() - 0.5) * image_width / 5, image_height / 3 + (random.random() - 0.5) * image_height / 5, image_height / 2], requires_grad=True)
optimizer = torch.optim.Adam([ellipsoid_axes], lr=0.1)
criterion = torch.nn.MSELoss()
for _ in range(100):
optimizer.zero_grad()
current_image = torch.zeros(image_width, image_height, requires_grad=True)
current_image = apply_ellipse_mask(current_image, ellipsoid_pos, ellipsoid_axes)
loss = criterion(current_image, ref_image)
loss.backward()
print(_, loss)
optimizer.step()
Erro:
RuntimeError: Tentando retroceder no gráfico uma segunda vez (ou acessar diretamente tensores salvos após eles já terem sido liberados). Valores intermediários salvos do gráfico são liberados quando você chama .backward() ou autograd.grad(). Especifique retain_graph=True se você precisar retroceder no gráfico uma segunda vez ou se precisar acessar tensores salvos após chamar backward.
Por que ele estaria tentando retroceder pelo mesmo gráfico uma segunda vez? Estou acessando diretamente os tensores salvos depois que eles foram liberados?