-
由 openaiops 创作于2565a902
basic_loop.py 2.85 KiB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import mltk
import numpy as np
import torch
from torch import nn, Tensor, optim
from torch.nn import functional as F
class Net(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.Sequential(
nn.Linear(784, 500),
nn.ReLU(),
nn.Linear(500, 10),
nn.LogSoftmax(-1),
)
def forward(self, x: Tensor) -> Tensor:
return self.layers(x)
if __name__ == '__main__':
# prepare for the data
(train_x, train_y), (test_x, test_y) = \
mltk.data.load_mnist(x_shape=[784], x_dtype=np.float32, y_dtype=np.int64)
train_x /= 255.
test_x /= 255.
(train_x, train_y), (valid_x, valid_y) = \
mltk.utils.split_numpy_arrays([train_x, train_y], portion=0.2,
shuffle=True)
train_stream = mltk.DataStream.arrays(
[train_x, train_y],
batch_size=32,
shuffle=True,
skip_incomplete=True). \
to_torch_tensors().threaded(5)
val_stream = mltk.DataStream.arrays(
[valid_x, valid_y], batch_size=128). \
to_torch_tensors().threaded(5)
test_stream = mltk.DataStream.arrays(
[test_x, test_y], batch_size=128). \
to_torch_tensors().threaded(5)
predict_stream = mltk.DataStream.arrays(
[test_x], batch_size=128). \
to_torch_tensors().threaded(5)
# construct the model
model: nn.Module = Net()
# construct the optimizer
optimizer = optim.Adam(model.parameters(), lr=0.001)
# prepare for the train loop
train_loop = mltk.TrainLoop(max_epoch=10)
# set the model to `train` mode at the beginning of each epoch,
# required by PyTorch
train_loop.on_epoch_begin.do(model.train)
def train_step(x, y):
optimizer.zero_grad()
out = model(x)
loss = F.nll_loss(out, y)
loss.backward()
optimizer.step()
acc = (torch.argmax(out, dim=-1) == y).to(torch.float32).mean()
return {'loss': loss, 'acc': acc}
def test_step(x, y):
pred = predict_step(x)['y']
acc = (pred == y).to(torch.float32).mean()
return {'acc': acc}
def predict_step(x):
return {'y': torch.argmax(model(x).detach(), dim=-1)}
@train_loop.on_epoch_end.do
def run_validation():
# set the model to `eval` mode at the beginning of each validation,
# required by PyTorch
model.eval()
train_loop.validation().run(test_step, val_stream)
# train the model
train_loop.run(train_step, train_stream)
# do final test
model.eval()
result = mltk.TestLoop().run(test_step, test_stream)
print(f'test acc: {result["acc"]:.6g}')
# run predict loop
model.eval()
result = mltk.PredictLoop().run(predict_step, predict_stream)
print(f'predicted y: {result["y"].shape}, {result["y"]}')