in models.py [0:0]
def train(self, data, l2=0, init=None, weights=None):
n = len(data["targets"])
if weights is None:
weights = torch.ones(n)
assert len(weights) == n, "Invalid number of weights"
# Save for the jacobian:
self.weights = weights
self.l2 = n * l2
X = data["features"]
y = data["targets"].float()
theta = torch.randn(X.shape[1], requires_grad=True)
if init is not None:
theta.data[:] = init[:]
crit = torch.nn.BCEWithLogitsLoss(reduction="none")
optimizer = torch.optim.LBFGS([theta], line_search_fn="strong_wolfe")
def closure():
optimizer.zero_grad()
loss = (crit(X @ theta, y) * weights).sum()
loss += (self.l2 / 2.0) * (theta**2).sum()
loss.backward()
return loss
for _ in range(100):
loss = optimizer.step(closure)
self.theta = theta