Python 构造矩阵中单个变量的自动加载失败

Python 构造矩阵中单个变量的自动加载失败,python,torch,autograd,Python,Torch,Autograd,我想创建一个4x4矩阵来变形我的4xn张量图像,并将其优化为损失函数。损失函数是有效的,但我初始化变形的方式有点错误,尽管我使用了纯向量演算来确保它应该是可微的 def affine_transform( points1, points2, stepSize=0.01, iterations=2000): def zero_grads(elements): for elem in elements:

我想创建一个
4x4
矩阵来变形我的
4xn
张量图像,并将其优化为损失函数。损失函数是有效的,但我初始化变形的方式有点错误,尽管我使用了纯向量演算来确保它应该是可微的

def affine_transform(
        points1,
        points2,
        stepSize=0.01,
        iterations=2000):

    def zero_grads(elements):
        for elem in elements:
            elem.grad.data.zero_()

    # Constructing the affine transformation matrix

    ## translation in x and y which should be optimised
    tx = tc.zeros((1, 1), requires_grad=True).float()
    ty = tc.zeros((1, 1), requires_grad=True).float()

    # Construct vectors from the single variables size 4x1
    v1 = tc.from_numpy(np.array([[0, 0, 0, 1]]).T).float()
    vx = v1.mm(tx)
    v2 = tc.from_numpy(np.array([[0, 0, 1, 0]]).T).float()
    vy = v2.mm(ty)

    ## use outer product to increase dimentionality to 4x4
    u = tc.from_numpy(np.array([[1, 0, 0, 0]]).T).float()
    T = u.mm(vx.T) + u.mm(vy.T).float()

    I = tc.from_numpy(np.eye(4)).float()
    R = I + T

    # Add ones to data
    n = points1.shape[1]
    one = np.ones(n)
    p1 = tc.from_numpy(np.vstack((points1, one))).float()
    p2 = tc.from_numpy(np.vstack((points2, one))).float()

    # Setup optimizer to tx and ty only
    optimizer = optim.Adam([tx, ty], stepSize)

    count = 0
    first = True
    while True:
        # Constructing the affine transformation matrix
        R = I + T  # + P

        # Calculate transition image (works as expected)
        transImg = bilinear_interpolate_torch(
                p1, tc.mm(R, p1))

        # Calculate loss
        loss = tc_ssd(p2, transImg)

        if first:
            loss.backward(retain_graph=True)
        else:
            loss.backward()
            
        # take a step
        optimizer.step()

        # Zero the gradients
        zero_grads([tx, ty])

        if count >= iterations and iterations != -1:
            print("Max iterations reached!")
            break

        count += 1

    R = I + T
    H3 = bilinear_interpolate_torch(p1.float(), tc.mm(R, p1.float()))

    return (H3, R)
它抛出了错误

[W python_anomaly_mode.cpp:60] Warning: Error detected in MmBackward. Traceback of forward call that caused the error:
  File "<stdin>", line 1, in <module>
  File "/home/fuzie/Dropbox/KU/7.aar/MIA/Handins/hw4/code/affine_im.py", line 314, in <module>
    b1mesh.T, b2mesh.T)
  File "/home/fuzie/Dropbox/KU/7.aar/MIA/Handins/hw4/code/affine_im.py", line 225, in affine_transform
    vy = v2.mm(ty)
 (function print_stack)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/fuzie/Dropbox/KU/7.aar/MIA/Handins/hw4/code/affine_im.py", line 314, in <module>
    b1mesh.T, b2mesh.T)
  File "/home/fuzie/Dropbox/KU/7.aar/MIA/Handins/hw4/code/affine_im.py", line 257, in affine_transform
    # Stepping
  File "/home/fuzie/.pyenv/versions/mia/lib/python3.8/site-packages/torch/tensor.py", line 185, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph)
  File "/home/fuzie/.pyenv/versions/mia/lib/python3.8/site-packages/torch/autograd/__init__.py", line 125, in backward
    Variable._execution_engine.run_backward(
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [1, 1]] is at version 1; expected version 0 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!
[W python\u normal\u mode.cpp:60]警告:在MmBackward中检测到错误。对导致错误的转发呼叫的回溯:
文件“”,第1行,在
文件“/home/fuzie/Dropbox/KU/7.aar/MIA/Handins/hw4/code/affine_im.py”,第314行,在
b1mesh.T,b2mesh.T)
文件“/home/fuzie/Dropbox/KU/7.aar/MIA/Handins/hw4/code/affine_im.py”,第225行,仿射变换
vy=v2.mm(ty)
(功能打印_堆栈)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/home/fuzie/Dropbox/KU/7.aar/MIA/Handins/hw4/code/affine_im.py”,第314行,在
b1mesh.T,b2mesh.T)
文件“/home/fuzie/Dropbox/KU/7.aar/MIA/Handins/hw4/code/affine_im.py”,第257行,仿射变换
#步进
文件“/home/fuzie/.pyenv/versions/mia/lib/python3.8/site packages/torch/tensor.py”,第185行,向后
火炬。自动标记。向后(自我、梯度、保留图、创建图)
文件“/home/fuzie/.pyenv/versions/mia/lib/python3.8/site packages/torch/autograd/_init__.py”,第125行,向后
变量。\u执行\u引擎。向后运行\u(
RuntimeError:梯度计算所需的一个变量已被一个就地操作修改:[torch.FloatTensor[1,1]]为版本1;应为版本0。提示:上面的回溯显示无法计算其梯度的操作。相关变量已在那里或以后的任何地方更改。祝您好运!
但是我不明白为什么不允许我用这种方式构造矩阵
t