-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes for CHOP #14
base: main
Are you sure you want to change the base?
Fixes for CHOP #14
Changes from 1 commit
1d2c999
778883e
61d9b54
f9dbca8
a82a0c6
092e92e
5c7943b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,20 +7,22 @@ | |
from torch.utils.data import DataLoader | ||
from torch.utils.data.dataset import TensorDataset | ||
import chop | ||
from sklearn.preprocessing import StandardScaler | ||
|
||
|
||
class Solver(BaseSolver): | ||
name = 'chop' | ||
|
||
install_cmd = 'conda' | ||
requirements = ['pip:https://github.com/openopt/chop/archive/master.zip'] | ||
requirements = ['pip:https://github.com/openopt/chop/archive/master.zip', | ||
'pip:scikit-learn'] | ||
|
||
parameters = { | ||
'solver': ['pgd'], | ||
'line_search': [False, True], | ||
'line_search': [True, False], | ||
'stochastic': [False, True], | ||
'batch_size': ['full', 1], | ||
'momentum': [0., 0.7], | ||
'momentum': [0., 0.9], | ||
'device': ['cpu', 'cuda'] | ||
} | ||
|
||
|
@@ -59,8 +61,11 @@ def set_objective(self, X, y, lmbd): | |
|
||
device = torch.device(self.device) | ||
|
||
self.X = torch.tensor(X).to(device) | ||
self.y = torch.tensor(y > 0, dtype=torch.float64).to(device) | ||
scaler = StandardScaler() | ||
X = scaler.fit_transform(X) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should not be done in the solver but in the dataset as it changes the problem There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can it be an option in the dataset? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the libsvmdata package does some preprocessing like this. I would just offer the good dataset (normalized or not). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, it seems this was the cause of the infinity values... (Since the scaler wasn't applied at eval time) Modifying. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @GeoffNN dont change the solver but the dataset. Otherwise solvers will not be comparable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done; I added standardization as a parameter in Covtype, so it runs on both versions of the dataset. We can also just keep the standardized version if you prefer. |
||
|
||
self.X = torch.tensor(X, dtype=torch.float32, device=device) | ||
self.y = torch.tensor(y, dtype=torch.float32, device=device) | ||
|
||
_, n_features = X.shape | ||
|
||
|
@@ -69,10 +74,12 @@ def set_objective(self, X, y, lmbd): | |
device=self.X.device) | ||
self.criterion = torch.nn.BCEWithLogitsLoss() | ||
|
||
# prepare loader for stochastic methods | ||
if self.stochastic: | ||
dataset = TensorDataset(self.X, self.y) | ||
self.loader = DataLoader(dataset, batch_size=self.batch_size) | ||
|
||
def run_stochastic(self, n_iter): | ||
# prepare dataset | ||
dataset = TensorDataset(self.X, self.y) | ||
loader = DataLoader(dataset, batch_size=self.batch_size) | ||
|
||
# prepare opt variable | ||
x = self.x0.clone().detach().flatten() | ||
|
@@ -108,7 +115,7 @@ def optimal_step_size(t): | |
|
||
while counter < n_iter: | ||
|
||
for data, target in loader: | ||
for data, target in self.loader: | ||
counter += 1 | ||
optimizer.lr = optimal_step_size(counter) | ||
|
||
|
@@ -130,12 +137,10 @@ def run_full_batch(self, n_iter): | |
|
||
@chop.utils.closure | ||
def logloss(x): | ||
|
||
alpha = self.lmbd / self.X.size(0) | ||
out = chop.utils.bmv(self.X, x) | ||
loss = self.criterion(out, self.y) | ||
reg = .5 * alpha * (x ** 2).sum() | ||
return loss + reg | ||
y_X_x = self.y * (self.X @ x.flatten()) | ||
l2 = 0.5 * x.pow(2).sum() | ||
loss = torch.log1p(torch.exp(-y_X_x)).sum() + self.lmbd * l2 | ||
return loss | ||
|
||
# Solve the problem | ||
if self.solver == 'pgd': | ||
|
@@ -146,7 +151,6 @@ def logloss(x): | |
step = None | ||
|
||
result = chop.optim.minimize_pgd(logloss, x0, | ||
prox=lambda x, s=None: x, | ||
step=step, | ||
max_iter=n_iter) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.