I want to optimize a custom vector of parameters, which are used to generate a 2D-matrix.
This matrix is then compared to a ground truth image. Basically, it’s similar to a Generative network, except the model itself doesn’t generate the image.
So, I have something like this:
class DipoleModel(torch.nn.Module):
def __init__(self):
super().__init__()
# the trainable vector of parameters
self.weight = torch.nn.Parameter(torch.rand(9))
def forward(self, input_image):
canvas = np.zeros((input_image.shape[0], input_image.shape[1]))
x, y, z = self.weight[:3]
pitch, yaw, roll = self.weight[3:6]
w, h = self.weight[6:8]
m = self.weight[-1]
# generate the image (numpy 2D array)
output_image = some_package.generate_image(m=m, position=(x,y,z), size=(w, h), rotation=(pitch, yaw, roll))
output_image = torch.tensor(output_image, requires_grad=True)
return output_image
I have to set requires_grad=True
to my output_image
here, because otherwise I get the error:
element 0 of tensors does not require grad and does not have a grad_fn
Anyway, then it should be trained something like this:
model = DipoleModel()
model.train()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9, weight_decay=0.1)
loss_function = torch.nn.MSELoss()
# ground truth image
input_image = torch.rand((320, 320))
for epoch in range(100):
optimizer.zero_grad()
output_image = model(input_image)
loss = loss_function(input_image, output_image)
loss.backward()
optimizer.step()
But the optimizer doesn’t do anything, the parameters stay the same and don’t change, and the loss doesn’t change either.
What would be the correct way to do this?