簡體   English   中英

自定義 torch.nn.Module 不學習,即使 grad_fn=MmBackward

[英]Custom torch.nn.Module not learning, even though grad_fn=MmBackward

我正在使用自定義Pytorch model 訓練 model 來預測姿勢。 但是,下面的 V1 永遠不會學習(參數不會改變)。 output 連接到背景圖和grad_fn=MmBackward

我不明白為什么V1不學習而V2是?

V1

class cam_pose_transform_V1(torch.nn.Module):
    def __init__(self):
        super(cam_pose_transform, self).__init__()
        self.elevation_x_rotation_radians = torch.nn.Parameter(torch.normal(0., 1e-6, size=()))
        self.azimuth_y_rotation_radians = torch.nn.Parameter(torch.normal(0., 1e-6, size=()))
        self.z_rotation_radians = torch.nn.Parameter(torch.normal(0., 1e-6, size=()))

    def forward(self, x):
        exp_i = torch.zeros((4,4))

        c1 = torch.cos(self.elevation_x_rotation_radians)
        s1 = torch.sin(self.elevation_x_rotation_radians)
        c2 = torch.cos(self.azimuth_y_rotation_radians)
        s2 = torch.sin(self.azimuth_y_rotation_radians)
        c3 = torch.cos(self.z_rotation_radians)
        s3 = torch.sin(self.z_rotation_radians)

        rotation_in_matrix = torch.tensor([
            [c2, s2 * s3, c3 * s2],
            [s1 * s2, c1 * c3 - c2 * s1 * s3, -c1 * s3 - c2 * c3 * s1],
            [-c1 * s2, c3 * s1 + c1 * c2 * s3, c1 * c2 * c3 - s1 * s3]
        ], requires_grad=True)

        exp_i[:3, :3] = rotation_in_matrix
        exp_i[3, 3] = 1.

        return torch.matmul(exp_i, x)

但是,此版本按預期學習(參數和損失更改)並且在 output 上也有grad_fn=MmBackward MmBackward:

V2


def vec2ss_matrix(vector):  # vector to skewsym. matrix

    ss_matrix = torch.zeros((3,3))
    ss_matrix[0, 1] = -vector[2]
    ss_matrix[0, 2] = vector[1]
    ss_matrix[1, 0] = vector[2]
    ss_matrix[1, 2] = -vector[0]
    ss_matrix[2, 0] = -vector[1]
    ss_matrix[2, 1] = vector[0]

    return ss_matrix


class cam_pose_transform_V2(torch.nn.Module):
    def __init__(self):
        super(camera_transf, self).__init__()
        self.w = torch.nn.Parameter(torch.normal(0., 1e-6, size=(3,)))
        self.v = torch.nn.Parameter(torch.normal(0., 1e-6, size=(3,)))
        self.theta = torch.nn.Parameter(torch.normal(0., 1e-6, size=()))

    def forward(self, x):
        exp_i = torch.zeros((4,4))
        w_skewsym = vec2ss_matrix(self.w)
        v_skewsym = vec2ss_matrix(self.v)
        exp_i[:3, :3] = torch.eye(3) + torch.sin(self.theta) * w_skewsym + (1 - torch.cos(self.theta)) * torch.matmul(w_skewsym, w_skewsym)
        exp_i[:3, 3] = torch.matmul(torch.eye(3) * self.theta + (1 - torch.cos(self.theta)) * w_skewsym + (self.theta - torch.sin(self.theta)) * torch.matmul(w_skewsym, w_skewsym), self.v)
        exp_i[3, 3] = 1.

        return torch.matmul(exp_i, x)

更新#1

在訓練循環中,我使用以下方法打印了.grad屬性:

print([i.grad for i in list(cam_pose.parameters())])
loss.backward()
print([i.grad for i in list(cam_pose.parameters())])

結果:

# V1
[None, None, None]
[None, None, None]

# V2
[None, None, None]
[tensor([-0.0032,  0.0025, -0.0053]), tensor([ 0.0016, -0.0013,  0.0054]), tensor(-0.0559)]

代碼中沒有其他任何更改,只是將 V1 model 替換為 V2。

這是您的問題:

rotation_in_matrix = torch.tensor([
    [c2, s2 * s3, c3 * s2],
    [s1 * s2, c1 * c3 - c2 * s1 * s3, -c1 * s3 - c2 * c3 * s1],
    [-c1 * s2, c3 * s1 + c1 * c2 * s3, c1 * c2 * c3 - s1 * s3]], requires_grad=True)

您正在從張量列表中創建一個張量,這不是一個可微的操作——即沒有從rotation_in_matrix到其元素c1..c3的梯度流

解決方案是使用諸如stackcat之類的張量操作來創建rotation_in_matrix

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM