Your code works fine after replacing the undefined classes:
shape_parameters_estimated = torch.zeros(1, 1, dtype=torch.float32, requires_grad=True)
stat_model = nn.Linear(1, 1)

learning_rate = 0.1
optimizer = torch.optim.Adagrad([shape_parameters_estimated], lr=learning_rate)
max_iter = 20
criterion = nn.MSELoss()

for iteration in range(max_iter):
    theta_estimated = shape_parameters_estimated
    out = stat_model(theta_estimated)

    loss = criterion(out, torch.rand_like(out))
    print('theta=', theta_estimated[0])
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

Output:
theta= tensor([0.], grad_fn=<SelectBackward0>)
theta= tensor([0.1000], grad_fn=<SelectBackward0>)
theta= tensor([0.1397], grad_fn=<SelectBackward0>)
theta= tensor([0.1831], grad_fn=<SelectBackward0>)
theta= tensor([0.2331], grad_fn=<SelectBackward0>)
theta= tensor([0.2467], grad_fn=<SelectBackward0>)
theta= tensor([0.2960], grad_fn=<SelectBackward0>)
theta= tensor([0.3146], grad_fn=<SelectBackward0>)
theta= tensor([0.3339], grad_fn=<SelectBackward0>)
theta= tensor([0.3832], grad_fn=<SelectBackward0>)
theta= tensor([0.4118], grad_fn=<SelectBackward0>)
theta= tensor([0.4494], grad_fn=<SelectBackward0>)
theta= tensor([0.4717], grad_fn=<SelectBackward0>)
theta= tensor([0.4924], grad_fn=<SelectBackward0>)
theta= tensor([0.5206], grad_fn=<SelectBackward0>)
theta= tensor([0.5551], grad_fn=<SelectBackward0>)
theta= tensor([0.5686], grad_fn=<SelectBackward0>)
theta= tensor([0.5911], grad_fn=<SelectBackward0>)
theta= tensor([0.6077], grad_fn=<SelectBackward0>)
theta= tensor([0.6128], grad_fn=<SelectBackward0>)

Maybe you are detaching the computation graph in one of your modules.