In this python code
import numpy as np
import scipy.stats as st
import operator
from functools import reduce
import torch
import torch.nn as nn
from torch.autograd import Variable, Function
from torch.nn.parameter import Parameter
import torch.optim as optim
import torch.cuda
import qpth
from qpth.qp import QPFunction
import ipdb
class Net(nn.Module):
def __init__(self, X, Y, hidden_layer_sizes):
super(Net, self).__init__()
# Initialize linear layer with least squares solution
X_ = np.hstack([X, np.ones((X.shape[0],1))])
Theta = np.linalg.solve(X_.T.dot(X_), X_.T.dot(Y))
self.lin = nn.Linear(X.shape[1], Y.shape[1])
W,b = self.lin.parameters()
W.data = torch.Tensor(Theta[:-1,:].T)
b.data = torch.Tensor(Theta[-1,:])
# Set up non-linear network of
# Linear -> BatchNorm -> ReLU -> Dropout layers
layer_sizes = [X.shape[1]] + hidden_layer_sizes
layers = reduce(operator.add,
[[nn.Linear(a,b), nn.BatchNorm1d(b), nn.ReLU(), nn.Dropout(p=0.2)]
for a,b in zip(layer_sizes[0:-1], layer_sizes[1:])])
layers += [nn.Linear(layer_sizes[-1], Y.shape[1])]
self.net = nn.Sequential(*layers)
self.sig = Parameter(torch.ones(1, Y.shape[1]).cuda())
def forward(self, x):
return self.lin(x) + self.net(x), \
self.sig.expand(x.size(0), self.sig.size(1))
def set_sig(self, X, Y):
Y_pred = self.lin(X) + self.net(X)
var = torch.mean((Y_pred-Y)**2, 0)
self.sig.data = torch.sqrt(var).cuda().data.unsqueeze(0)
class GLinearApprox(Function):
""" Linear (gradient) approximation of G function at z"""
def __init__(self, gamma_under, gamma_over):
self.gamma_under = gamma_under
self.gamma_over = gamma_over
def forward(self, z, mu, sig):
self.save_for_backward(z, mu, sig)
p = st.norm(mu.cpu().numpy(),sig.cpu().numpy())
return torch.DoubleTensor((self.gamma_under + self.gamma_over) * p.cdf(
z.cpu().numpy()) - self.gamma_under).cuda()
@staticmethod
def backward(self, grad_output):
z, mu, sig = self.saved_tensors
p = st.norm(mu.cpu().numpy(),sig.cpu().numpy())
pz = torch.DoubleTensor(p.pdf(z.cpu().numpy())).cuda()
dz = (self.gamma_under + self.gamma_over) * pz
dmu = -dz
dsig = -(self.gamma_under + self.gamma_over)*(z-mu) / sig * pz
return grad_output * dz, grad_output * dmu, grad_output * dsig
class GQuadraticApprox(Function):
""" Quadratic (gradient) approximation of G function at z"""
def __init__(self, gamma_under, gamma_over):
self.gamma_under = gamma_under
self.gamma_over = gamma_over
def forward(self, z, mu, sig):
self.save_for_backward(z, mu, sig)
p = st.norm(mu.cpu().numpy(),sig.cpu().numpy())
return torch.DoubleTensor((self.gamma_under + self.gamma_over) * p.pdf(
z.cpu().numpy())).cuda()
def backward(self, grad_output):
z, mu, sig = self.saved_tensors
p = st.norm(mu.cpu().numpy(),sig.cpu().numpy())
pz = torch.DoubleTensor(p.pdf(z.cpu().numpy())).cuda()
dz = -(self.gamma_under + self.gamma_over) * (z-mu) / (sig**2) * pz
dmu = -dz
dsig = (self.gamma_under + self.gamma_over) * ((z-mu)**2 - sig**2) / \
(sig**3) * pz
return grad_output * dz, grad_output * dmu, grad_output * dsig
class SolveSchedulingQP(nn.Module):
""" Solve a single SQP iteration of the scheduling problem"""
def __init__(self, params):
super(SolveSchedulingQP, self).__init__()
self.c_ramp = params["c_ramp"]
self.n = params["n"]
D = np.eye(self.n - 1, self.n) - np.eye(self.n - 1, self.n, 1)
self.G = Variable(torch.DoubleTensor(np.vstack([D,-D])).cuda())
self.h = Variable((self.c_ramp * torch.ones((self.n - 1) * 2))\
.double().cuda())
self.e = Variable(torch.Tensor().double().cuda())
def forward(self, z0, mu, dg, d2g):
nBatch, n = z0.size()
Q = torch.cat([torch.diag(d2g[i] + 1).unsqueeze(0)
for i in range(nBatch)], 0).double()
p = (dg - d2g*z0 - mu).double()
G = self.G.unsqueeze(0).expand(nBatch, self.G.size(0), self.G.size(1))
h = self.h.unsqueeze(0).expand(nBatch, self.h.size(0))
out = QPFunction(verbose=False)(Q, p, G, h, self.e, self.e)
return out
class SolveScheduling(nn.Module):
""" Solve the entire scheduling problem, using sequential quadratic
programming. """
def __init__(self, params):
super(SolveScheduling, self).__init__()
self.params = params
self.c_ramp = params["c_ramp"]
self.n = params["n"]
D = np.eye(self.n - 1, self.n) - np.eye(self.n - 1, self.n, 1)
self.G = Variable(torch.DoubleTensor(np.vstack([D, -D])).cuda())
self.h = Variable((self.c_ramp * torch.ones((self.n - 1) * 2))\
.double().cuda())
self.e = Variable(torch.Tensor().double().cuda())
def forward(self, mu, sig):
nBatch, n = mu.size()
# Find the solution via sequential quadratic programming,
# not preserving gradients
z0 = Variable(1. * mu.data, requires_grad=False)
mu0 = Variable(1. * mu.data, requires_grad=False)
sig0 = Variable(1. * sig.data, requires_grad=False)
for i in range(20):
dg = GLinearApprox(self.params["gamma_under"],
self.params["gamma_over"])(z0, mu0, sig0)
d2g = GQuadraticApprox(self.params["gamma_under"],
self.params["gamma_over"])(z0, mu0, sig0)
z0_new = SolveSchedulingQP(self.params)(z0, mu0, dg, d2g)
solution_diff = (z0-z0_new).norm().data[0]
print("+ SQP Iter: {}, Solution diff = {}".format(i, solution_diff))
z0 = z0_new
if solution_diff < 1e-10:
break
# Now that we found the solution, compute the gradient-propagating
# version at the solution
dg = GLinearApprox(self.params["gamma_under"],
self.params["gamma_over"])(z0, mu, sig)
d2g = GQuadraticApprox(self.params["gamma_under"],
self.params["gamma_over"])(z0, mu, sig)
return SolveSchedulingQP(self.params)(z0, mu, dg, d2g)
'''
I am getting error as
` /content/e2e-model-learning/power_sched/model_classes.py in forward(self=SolveScheduling(), mu=tensor([[1.6614, 1.5842, 1.5505, ..., 2.1037, 2...0', dtype=torch.float64, grad_fn=<CopyBackwards>), sig=tensor([[0.0194, 0.0241, 0.0263, ..., 0.0823, 0...0', dtype=torch.float64, grad_fn=<CopyBackwards>))
151 for i in range(20):
152 dg = GLinearApprox(self.params["gamma_under"],
--> 153 self.params["gamma_over"])(z0, mu0, sig0)
self.params = {'n': 24, 'c_ramp': 0.4, 'gamma_under': 50, 'gamma_over': 0.5}
z0 = tensor([[1.6614, 1.5842, 1.5505, ..., 2.1037, 2.0368, 1.9119],
[1.7478, 1.6636, 1.6318, ..., 2.0573, 1.9935, 1.8867],
[1.7980, 1.7113, 1.6673, ..., 1.9362, 1.8971, 1.7941],
...,
[1.4203, 1.3474, 1.3094, ..., 1.6379, 1.5986, 1.5301],
[1.3920, 1.3247, 1.2893, ..., 1.6337, 1.5924, 1.5241],
[1.5190, 1.4434, 1.4108, ..., 1.8642, 1.8024, 1.6948]],
device='cuda:0', dtype=torch.float64)
mu0 = tensor([[1.6614, 1.5842, 1.5505, ..., 2.1037, 2.0368, 1.9119],
[1.7478, 1.6636, 1.6318, ..., 2.0573, 1.9935, 1.8867],
[1.7980, 1.7113, 1.6673, ..., 1.9362, 1.8971, 1.7941],
...,
[1.4203, 1.3474, 1.3094, ..., 1.6379, 1.5986, 1.5301],
[1.3920, 1.3247, 1.2893, ..., 1.6337, 1.5924, 1.5241],
[1.5190, 1.4434, 1.4108, ..., 1.8642, 1.8024, 1.6948]],
device='cuda:0', dtype=torch.float64)
sig0 = tensor([[0.0194, 0.0241, 0.0263, ..., 0.0823, 0.0799, 0.0746],
[0.0194, 0.0241, 0.0263, ..., 0.0823, 0.0799, 0.0746],
[0.0194, 0.0241, 0.0263, ..., 0.0823, 0.0799, 0.0746],
...,
[0.0194, 0.0241, 0.0263, ..., 0.0823, 0.0799, 0.0746],
[0.0194, 0.0241, 0.0263, ..., 0.0823, 0.0799, 0.0746],
[0.0194, 0.0241, 0.0263, ..., 0.0823, 0.0799, 0.0746]],
device='cuda:0', dtype=torch.float64)
154 d2g = GQuadraticApprox(self.params["gamma_under"],
155 self.params["gamma_over"])(z0, mu0, sig0)
/usr/local/lib/python3.6/dist-packages/torch/autograd/function.py in __call__(self=<model_classes.GLinearApprox object>, *args=(tensor([[1.6614, 1.5842, 1.5505, ..., 2.1037, 2...8]],
device='cuda:0', dtype=torch.float64), tensor([[1.6614, 1.5842, 1.5505, ..., 2.1037, 2...8]],
device='cuda:0', dtype=torch.float64), tensor([[0.0194, 0.0241, 0.0263, ..., 0.0823, 0...6]],
device='cuda:0', dtype=torch.float64)), **kwargs={})
147 def __call__(self, *args, **kwargs):
148 raise RuntimeError(
--> 149 "Legacy autograd function with non-static forward method is deprecated. "
150 "Please use new-style autograd function with static forward method. "
151 "(Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function)")
RuntimeError: Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method. (Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function)
> /usr/local/lib/python3.6/dist-packages/torch/autograd/function.py(149)__call__()
147 def __call__(self, *args, **kwargs):
148 raise RuntimeError(
--> 149 "Legacy autograd function with non-static forward method is deprecated. "
150 "Please use new-style autograd function with static forward method. "
151 "(Example: https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function)")
ipdb>
'