Cubic-Rate Third-Order Langevin Optimizer / benchmark_mlp.py

Failed on benchmark

Raw ⬇ ZIP
 1import json, random, time
 2import numpy as np
 3import torch
 4from torch import nn
 5from third_order_optimizer import ThirdOrderLangevin
 6
 7SEED=123
 8
 9def seed(s):
10    random.seed(s); np.random.seed(s); torch.manual_seed(s)
11    if torch.cuda.is_available(): torch.cuda.manual_seed_all(s)
12
13def make_data(n=2048):
14    g=np.random.default_rng(77)
15    x=g.normal(size=(n,2)).astype('float32')
16    y=((x[:,0]*x[:,1] + .25*x[:,0] - .15*x[:,1])>0).astype('int64')
17    return torch.from_numpy(x), torch.from_numpy(y)
18
19def run(kind, device):
20    seed(SEED); x,y=make_data(); x,y=x.to(device),y.to(device)
21    model=nn.Sequential(nn.Linear(2,32),nn.Tanh(),nn.Linear(32,32),nn.Tanh(),nn.Linear(32,2)).to(device)
22    if kind=='sgd': opt=torch.optim.SGD(model.parameters(),lr=.08)
23    elif kind=='momentum': opt=torch.optim.SGD(model.parameters(),lr=.04,momentum=.9)
24    else: opt=ThirdOrderLangevin(model.parameters(),dt=.035,gamma=1.0,temperature=1e-4)
25    lossfn=nn.CrossEntropyLoss(); losses=[]; t0=time.perf_counter()
26    for step in range(300):
27        opt.zero_grad(set_to_none=True); loss=lossfn(model(x),y); loss.backward(); opt.step()
28        if step%50==0: losses.append(float(loss.detach().cpu()))
29    with torch.no_grad(): acc=float((model(x).argmax(1)==y).float().mean().cpu())
30    return {'loss_checkpoints':losses,'final_loss':float(loss.detach().cpu()),'train_accuracy':acc,'seconds':time.perf_counter()-t0}
31
32def main():
33    device='cuda' if torch.cuda.is_available() else 'cpu'
34    try:
35        out={k:run(k,device) for k in ['sgd','momentum','third_order']}
36    except Exception:
37        device='cpu'; out={k:run(k,device) for k in ['sgd','momentum','third_order']}
38    result={'device':device,'steps':300,'results':out}
39    with open('benchmark_results.json','w') as f: json.dump(result,f,indent=2)
40    print(json.dumps(result,indent=2))
41if __name__=='__main__': main()