Я пытаюсь использовать 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 с помощью экспоненциальной функции, но тогда вам придется масштабировать функцию, чтобы избежать бесконечности положительных значений, и мне нужна некоторая гибкость с возможностью установки ограничения.
clamp
в порядке, вам просто нужно сделать это внутриwith torch.no_grad():
- person minhle_r7   schedule 18.01.2020clamp
в порядке, вам просто нужно сделать это внутриwith torch.no_grad():
и использоватьx[:]=x.clamp(
вместоx=x.clamp(
- person 1943 Yonv   schedule 16.09.2020