簡體   English   中英

在 Pytorch 中執行優化時如何對變量應用邊界?

[英]How to apply bounds on a variable when performing optimisation in Pytorch?

我正在嘗試使用 Pytorch 進行非凸優化,試圖最大化我的目標(因此最小化 SGD)。 我想限制我的因變量 x > 0,並且我的 x 值的總和小於 1000。

我認為我以斜坡懲罰的形式正確實施了懲罰,但我正在努力解決 x 變量的邊界問題。 在 Pytorch 中,您可以使用clamp設置邊界,但在這種情況下似乎不合適。 我認為這是因為 optim 需要引擎蓋下的免費梯度。 完整的工作示例:

import torch
from torch.autograd import Variable
import numpy as np

def objective(x, a, b, c):   # Want to maximise this quantity (so minimise in SGD)
    d = 1 / (1 + torch.exp(-a * (x)))

    # Checking constraint 
    exceeded_limit = constraint(x).item()
    #print(exceeded_limit)

    obj = torch.sum(d * (b * c - x))

    # If overlimit add ramp penalty
    if  exceeded_limit < 0:
        obj = obj - (exceeded_limit * 10)
        print("Exceeded limit")

    return - obj

def constraint(x, limit = 1000): # Must be > 0
    return limit - x.sum()

N = 1000

# x is variable to optimise for 
x = Variable(torch.Tensor([1 for ii in range(N)]), requires_grad=True)
a = Variable(torch.Tensor(np.random.uniform(0,100,N)), requires_grad=True)
b = Variable(torch.Tensor(np.random.rand(N)), requires_grad=True)
c = Variable(torch.Tensor(np.random.rand(N)), requires_grad=True)

# Would like to include the clamp
# x = torch.clamp(x, min=0)

# Non-convex methodf
opt = torch.optim.SGD([x], lr=.01)

for i in range(10000):
    # Zeroing gradients
    opt.zero_grad()

    # Evaluating the objective
    obj = objective(x, a, b, c)

    # Calculate gradients
    obj.backward() 
    opt.step()
    if i%1000==0:  print("Objective: %.1f" % -obj.item())

print("\nObjective: {}".format(-obj))
print("Limit: {}".format(constraint(x).item()))

if torch.sum(x<0) > 0: print("Bounds not met")
if  constraint(x).item() < 0: print("Constraint not met")

任何關於如何施加邊界的建議將不勝感激,無論是使用夾具還是其他方式。 或者一般建議使用 Pytorch 進行非凸優化。 這是我正在處理的問題的一個更簡單和縮小的版本,所以如果可能的話,我試圖找到一個輕量級的解決方案。 我正在考慮使用一種解決方法,例如使用指數函數轉換 x 變量,但是您必須縮放函數以避免正值變得無限,並且我希望能夠設置約束的靈活性。

我和你遇到了同樣的問題。 我也想對 PyTorch 中的變量應用邊界。 我通過下面的Way3解決了這個問題。

你的例子有點復雜,但我仍在學習英語。 所以我在下面舉一個更簡單的例子。

例如,有一個可訓練變量v ,它的邊界是 (-1, 1)

v = torch.tensor((0.5, ), require_grad=True)
v_loss = xxxx
optimizer.zero_grad()
v_loss.backward()
optimizer.step()

方式1。 運行時錯誤:在就地操作中使用了需要 grad 的葉變量。

v.clamp_(-1, 1)             

方式2。 RuntimeError: 試圖再次向后瀏覽圖表,但緩沖區已被釋放。

v = torch.clamp(v, -1, +1)  # equal to v = v.clamp(-1, +1)  

方式3。 不是錯誤 我在 Way3 中解決了這個問題。

with torch.no_grad():
    v[:] = v.clamp(-1, +1)  # You must use v[:]=xxx instead of v=xxx

暫無
暫無

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

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