Skip to content

Commit bba1519

Browse files
committed
add automl example
Signed-off-by: reiase <[email protected]>
1 parent 8b0b0cf commit bba1519

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import torch
2+
import torch.nn as nn
3+
import torch.nn.functional as F
4+
import torch.optim as optim
5+
from torchvision import datasets, transforms
6+
from torch.optim.lr_scheduler import StepLR
7+
import optuna
8+
9+
from hyperparameter import param_scope, auto_param, lazy_dispatch
10+
11+
12+
@auto_param
13+
class Backbone(nn.Module):
14+
def __init__(
15+
self,
16+
chn1=32,
17+
chn2=64,
18+
ker1_size=3,
19+
ker2_size=3,
20+
activation="relu",
21+
) -> None:
22+
super().__init__()
23+
self.conv1 = nn.Conv2d(1, chn1, ker1_size, 1)
24+
self.conv2 = nn.Conv2d(chn1, chn2, ker2_size, 1)
25+
self.activation = getattr(F, activation)
26+
27+
def forward(self, x):
28+
x = self.conv1(x)
29+
x = self.activation(x)
30+
x = self.conv2(x)
31+
x = self.activation(x)
32+
x = F.max_pool2d(x, 2)
33+
return torch.flatten(x, 1)
34+
35+
36+
@auto_param
37+
class Head(nn.Module):
38+
def __init__(
39+
self,
40+
fc1=128,
41+
fc2=128,
42+
activation="relu",
43+
dropout=0.25,
44+
) -> None:
45+
super().__init__()
46+
self.fc1 = nn.LazyLinear(fc1)
47+
self.fc2 = nn.LazyLinear(fc2)
48+
self.dropout1 = nn.Dropout(dropout)
49+
self.dropout2 = nn.Dropout(dropout)
50+
self.activation = getattr(F, activation)
51+
52+
def forward(self, x):
53+
x = self.dropout1(x)
54+
x = self.fc1(x)
55+
x = self.activation(x)
56+
x = self.dropout2(x)
57+
return self.fc2(x)
58+
59+
60+
class Net(nn.Module):
61+
def __init__(self) -> None:
62+
super().__init__()
63+
self.backbone = Backbone()
64+
self.head = Head()
65+
66+
def forward(self, x):
67+
x = self.backbone(x)
68+
x = self.head(x)
69+
return F.log_softmax(x, dim=1)
70+
71+
72+
def train(model, train_loader, optimizer):
73+
model.train()
74+
for batch_idx, (data, target) in enumerate(train_loader):
75+
optimizer.zero_grad()
76+
output = model(data)
77+
loss = F.nll_loss(output, target)
78+
loss.backward()
79+
optimizer.step()
80+
if batch_idx % 100 == 0:
81+
print(
82+
"Train Epoch: [{}/{} ({:.0f}%)]\tLoss: {:.6f}".format(
83+
batch_idx * len(data),
84+
len(train_loader.dataset),
85+
100.0 * batch_idx / len(train_loader),
86+
loss.item(),
87+
)
88+
)
89+
90+
91+
def test(model, test_loader):
92+
model.eval()
93+
test_loss = 0
94+
correct = 0
95+
with torch.no_grad():
96+
for data, target in test_loader:
97+
output = model(data)
98+
test_loss += F.nll_loss(
99+
output, target, reduction="sum"
100+
).item() # sum up batch loss
101+
pred = output.argmax(
102+
dim=1, keepdim=True
103+
) # get the index of the max log-probability
104+
correct += pred.eq(target.view_as(pred)).sum().item()
105+
test_loss /= len(test_loader.dataset)
106+
print(
107+
"\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n".format(
108+
test_loss,
109+
correct,
110+
len(test_loader.dataset),
111+
100.0 * correct / len(test_loader.dataset),
112+
)
113+
)
114+
return test_loss / len(test_loader.dataset)
115+
116+
117+
@auto_param
118+
def train_model(batch_size=128, epochs=1, lr=1.0, momentum=0.9, step_lr_gamma=0.7):
119+
torch.manual_seed(0)
120+
transform = transforms.Compose(
121+
[transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]
122+
)
123+
dataset1 = datasets.MNIST("../data", train=True, download=True, transform=transform)
124+
dataset2 = datasets.MNIST("../data", train=False, transform=transform)
125+
train_loader = torch.utils.data.DataLoader(dataset1, batch_size=batch_size)
126+
test_loader = torch.utils.data.DataLoader(dataset2, batch_size=batch_size)
127+
128+
model = Net()
129+
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)
130+
131+
scheduler = StepLR(optimizer, step_size=1, gamma=step_lr_gamma)
132+
for epoch in range(1, epochs + 1):
133+
train(model, train_loader, optimizer)
134+
scheduler.step()
135+
return test(model, test_loader)
136+
137+
138+
def wrapper(trial):
139+
trial = lazy_dispatch(trial)
140+
with param_scope(
141+
**{
142+
"train_model.lr": trial.suggest_categorical("train_model.lr", [0.1, 0.01]),
143+
"train_model.momentum": trial.suggest_categorical(
144+
"train_model.momentum", [0.9, 0.85]
145+
),
146+
"Backbone.ker1_size": trial.suggest_categorical(
147+
"Backbone.ker1_size", [3, 5]
148+
),
149+
"Head.dropout": trial.suggest_categorical("Head.dropout", [0.25, 0.15]),
150+
}
151+
):
152+
return train_model()
153+
154+
155+
study = optuna.create_study()
156+
study.optimize(wrapper, n_trials=10)
157+
158+
optuna.visualization.plot_contour(study)
159+
optuna.visualization.plot_parallel_coordinate(study)

0 commit comments

Comments
 (0)