首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >torch.optim.LBFGS()不更改参数

torch.optim.LBFGS()不更改参数
EN

Stack Overflow用户
提问于 2022-07-18 08:38:13
回答 1查看 322关注 0票数 1

我试图优化图像角的坐标。类似的技术在Ceres中也能很好的工作。但在torch.optim,我遇到了一些问题。特别是,由于某些原因,优化器不会更改正在优化的参数。我没有太多的经验,所以我很确定错误是微不足道的。不幸的是,阅读这些文档对我没有多大帮助。

优化模型类:

代码语言:javascript
复制
class OptimizeCorners(torch.nn.Module):
    def __init__(self, real_corners):
        super().__init__()
        self._real_corners = torch.nn.Parameter(real_corners)

    def forward(self, real_image, synt_image, synt_corners, _threshold):
        # Find homography
        if visualize_warp_interpolate:
            real_image_before_processing = real_image
            synt_image_before_processing = synt_image
        homography_matrix = kornia.geometry.homography.find_homography_dlt(synt_corners,
                                                                           self._real_corners,
                                                                           weights=None)
        # Warp and resize synt image
        synt_image = kornia.geometry.transform.warp_perspective(synt_image.float(),
                                                                homography_matrix,
                                                                dsize=(int(real_image.shape[2]),
                                                                       int(real_image.shape[3])),
                                                                mode='bilinear',
                                                                padding_mode='zeros',
                                                                align_corners=True,
                                                                fill_value=torch.zeros(3))
        # Interpolate images
        real_image = torch.nn.functional.interpolate(real_image.float(),
                                                     scale_factor=5,
                                                     mode='bicubic',
                                                     align_corners=None,
                                                     recompute_scale_factor=None,
                                                     antialias=False)
        synt_image = torch.nn.functional.interpolate(synt_image.float(),
                                                     scale_factor=5,
                                                     mode='bicubic',
                                                     align_corners=None,
                                                     recompute_scale_factor=None,
                                                     antialias=False)

        # Calculate loss
        loss_map = torch.sub(real_image, synt_image, alpha=1)

        # if element > _threshold: element = 0
        loss_map = torch.nn.Threshold(_threshold, 0)(loss_map)

        cumulative_loss = torch.sqrt(torch.sum(torch.pow(loss_map, 2)) /
                                     (loss_map.size(dim=2) * loss_map.size(dim=3)))

        return torch.autograd.Variable(cumulative_loss.data, requires_grad=True)

我是如何尝试执行优化的:

代码语言:javascript
复制
# Convert corresponding images to PyTorch tensors
_image = kornia.utils.image_to_tensor(_image, keepdim=False)
_synt_image = kornia.utils.image_to_tensor(_synt_image, keepdim=False)
_corners = torch.from_numpy(_corners)
_synt_corners = torch.from_numpy(_synt_corners)
# Optimizer L-BFGS
n_iters = 100
h_lbfgs = []
lr = 1
optimize_corners = OptimizeCorners(_corners)
optimizer = torch.optim.LBFGS(optimize_corners.parameters(),
                              lr=lr)
for it in tqdm(range(n_iters), desc='Fitting corners',
               leave=False, position=1):
    loss = optimize_corners(_image, _synt_image, _synt_corners, _threshold)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step(lambda: optimize_corners(_image, _synt_image, _synt_corners, _threshold))
    h_lbfgs.append(loss.item())
    print(h_lbfgs)

控制台输出:图片

因此,正如您所看到的,要优化的参数不会更改。

UPD:我将return torch.autograd.Variable(cumulative_loss.data, requires_grad=True)更改为return cumulative_loss.requires_grad_(),它实际上可以工作,但现在,经过几次迭代之后,我得到了这个错误:控制台输出

UPD:这是因为正在优化的参数经过几次迭代后会变成NaN。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-22 10:42:36

在拥抱调试器一段时间后,我发现主要的问题是,经过几次迭代之后,backward()方法开始错误地计算梯度并输出NaN,因此,被优化的参数也被计算为NaN。我没有机会确切地知道为什么会发生这种情况,因为所有的跟踪(我使用了torch.autograd.set_detect_anomaly(True)方法)都指出了错误发生在POW和SVD函数中的C ++ Torch引擎一侧这一事实。最后,在我的例子中,通过将所有参数从float32转换到float64,并降低了学习速率,解决了这个问题。

下面是最后的代码更新:

代码语言:javascript
复制
# Convert corresponding images to PyTorch tensors
            _image = kornia.utils.image_to_tensor(_image, keepdim=False).double()
            _synt_image = kornia.utils.image_to_tensor(_synt_image, keepdim=False).double()
            _corners = torch.from_numpy(_corners).double()
            _synt_corners = torch.from_numpy(_synt_corners).double()

            # Optimizer L-BFGS
            optimize_corners = OptimizeCorners(_corners)
            optimizer = torch.optim.LBFGS(optimize_corners.parameters(),
                                          max_iter=20,
                                          lr=0.01)
            torch.autograd.set_detect_anomaly(True)

            def closure():
                optimizer.zero_grad()
                loss = optimize_corners(_image, _synt_image, _synt_corners, _threshold)
                loss.backward()
                return loss

            for it in tqdm(range(100), desc="Fitting corners", leave=False, position=1):
                optimizer.step(closure)


def forward(self, real_image, synt_image, synt_corners, _threshold):
    # Find homography
    if visualize_warp_interpolate:
        real_image_before_processing = real_image
        synt_image_before_processing = synt_image

    homography_matrix = kornia.geometry.homography.find_homography_dlt(synt_corners,
                                                                       self._real_corners,
                                                                       weights=None)

    # Warp and resize synt image
    synt_image = kornia.geometry.transform.warp_perspective(synt_image,
                                                            homography_matrix,
                                                            dsize=(int(real_image.shape[2]),
                                                                   int(real_image.shape[3])),
                                                            mode='bilinear',
                                                            padding_mode='zeros',
                                                            align_corners=True,
                                                            fill_value=torch.zeros(3))

    # Interpolate images
    real_image = torch.nn.functional.interpolate(real_image,
                                                 scale_factor=10,
                                                 mode='bicubic',
                                                 align_corners=None,
                                                 recompute_scale_factor=None,
                                                 antialias=False)
    synt_image = torch.nn.functional.interpolate(synt_image,
                                                 scale_factor=10,
                                                 mode='bicubic',
                                                 align_corners=None,
                                                 recompute_scale_factor=None,
                                                 antialias=False)
    # Calculate loss
    loss_map = torch.sub(real_image, synt_image, alpha=1)

    # if element > _threshold: element = 0
    loss_map = torch.nn.Threshold(_threshold, 0)(loss_map)

    cumulative_loss = torch.sqrt(torch.sum(torch.pow(loss_map, 2)) /
                                 (loss_map.size(dim=2) * loss_map.size(dim=3)))

    return cumulative_loss.requires_grad_()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73019486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档