henriquebsena
henriquebsena

Reputation: 11

How to do constrained optimization in PyTorch?

I'm studying Pytorch and I'm trying to construct a code to get the maximum likelihood estimates.

I would like to put some constrains into optimization process to contemplate the parameter space, but I did not find something like this (in a easy way) in Pytorch.

For example, I would like to get the maximum likelihood estimates for a normal distribution with mean mu and standard deviation sigma, in which mu is a real number and sigma is a positive number.

This way, I would like to put a constrain in my code to sigma always to be a positive number.

Here my code:

##### PACKAGES
import numpy as np
from scipy.integrate import quad
from scipy.optimize import minimize_scalar
import torch
from matplotlib import pyplot as plt
import pandas as pd
import math 

##### SAMPLE
np.random.seed(3)
sample = np.random.normal(loc=5, scale=2, size=(1000, 1))

##### TENSORS
X = torch.tensor(sample, dtype=torch.float64, requires_grad=False) #sample tensor
mu_ = torch.tensor(np.array([0.5]), dtype=torch.float64, requires_grad=True) # mean
s_ = torch.tensor(np.array([5]), dtype=torch.float64, requires_grad=True) # s. desviation

##### OPTMIZATION METHOD: SGD
learning_rate = 0.0002
OPT_OBJ = torch.optim.SGD([mu_, s_], lr = learning_rate)

##### OPTIMAZTION METHOD
for t in range(2000):
    NLL = X.size()[0]*s_.log()+((((X-mu_)/s_ ).pow(2))/2).sum() #negative likelihood
    OPT_OBJ.zero_grad()
    NLL.backward()

    if t % 100 == 0:
        print("Log_Likehood: {}; Estimate mu: {}; Estimate sigma: {}".format(NLL.data.numpy(), mu_.data.numpy(), s_.data.numpy()))

    OPT_OBJ.step()

print("True value of mu and sigma: {} e {}".format(5, 2))

Upvotes: 1

Views: 2788

Answers (2)

dherrera
dherrera

Reputation: 141

There is actually a built-in Pytorch tool to do this conveniently: torch.nn.utils.parametrize, which implements parametrizations. The idea is that if you want to optimize a parameter theta that is constrained to be in some set C, you find some function f that maps from an unconstrained parameter eta into your thetas, i.e. f(eta)=theta, then you do optimization over eta rather than theta directly.

This is the official parametrizations tutorial in Pytorch. I also wrote a more begginer-friendly tutorial "Easy constrained optimization in Pytorch with Parametrizations", explaining how to implement parametrizations in Pytorch.

Upvotes: 1

Ivan
Ivan

Reputation: 40738

It is common to work with logarithms for this kind of learned parameter, this is the case for estimating a variance parameter which you will usually find estimated in log space.

In practice, you predict the log-variance instead of the variance or standard deviation. Then you can apply the exponential on it to infer the actual var or std value.

Upvotes: 0

Related Questions