-
Notifications
You must be signed in to change notification settings - Fork 3
/
test_ensemble.py
116 lines (103 loc) · 4.15 KB
/
test_ensemble.py
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
104
105
106
107
108
109
110
111
112
113
114
115
import torchvision
from torch.nn import *
from torchvision.transforms import *
from torch.optim import *
from torch.optim.lr_scheduler import CosineAnnealingLR
from torch.utils.data import Dataset
# from adabound import AdaBound
from nntoolbox.vision.components import *
from nntoolbox.vision.learner import SupervisedImageLearner
from nntoolbox.utils import load_model, get_device, LRFinder
from nntoolbox.callbacks import *
from nntoolbox.metrics import Accuracy, Loss
from nntoolbox.vision.transforms import Cutout
from nntoolbox.vision.models import ImageClassifier, EnsembleImageClassifier
from nntoolbox.losses import SmoothedCrossEntropy
from nntoolbox.ensembler import CVEnsembler
data = torchvision.datasets.CIFAR10('data/', train=True, download=True, transform=ToTensor())
test_dataset = torchvision.datasets.CIFAR10('data/', train=False, download=True, transform=ToTensor())
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=512, shuffle=True)
class SEResNeXtShakeShake(ResNeXtBlock):
def __init__(self, in_channels, reduction_ratio=16, cardinality=2, activation=nn.ReLU, normalization=nn.BatchNorm2d):
super(SEResNeXtShakeShake, self).__init__(
branches=nn.ModuleList(
[
nn.Sequential(
ConvolutionalLayer(
in_channels, in_channels, 3, padding=1,
activation=activation, normalization=normalization
),
ConvolutionalLayer(
in_channels, in_channels, 3, padding=1,
activation=activation, normalization=normalization
),
SEBlock(in_channels, reduction_ratio)
) for _ in range(cardinality)
]
),
use_shake_shake=True
)
def model_fn():
return Sequential(
ConvolutionalLayer(in_channels=3, out_channels=16, kernel_size=3, activation=nn.ReLU),
SEResNeXtShakeShake(in_channels=16, activation=nn.ReLU),
ConvolutionalLayer(
in_channels=16, out_channels=32,
activation=nn.ReLU,
kernel_size=2, stride=2
),
SEResNeXtShakeShake(in_channels=32),
ConvolutionalLayer(
in_channels=32, out_channels=64,
kernel_size=2, stride=2
),
SEResNeXtShakeShake(in_channels=64),
ConvolutionalLayer(
in_channels=64, out_channels=128,
kernel_size=2, stride=2
),
SEResNeXtShakeShake(in_channels=128),
FeedforwardBlock(
in_channels=128,
out_features=10,
pool_output_size=2,
hidden_layer_sizes=(512, 256)
)
)
def learn_fn(train_data, val_data, model, save_path):
optimizer = SGD(model.parameters(), weight_decay=0.0001, lr=0.094, momentum=0.9)
train_loader = torch.utils.data.DataLoader(train_data, batch_size=128, shuffle=True)
val_loader = torch.utils.data.DataLoader(val_data, batch_size=128, shuffle=True)
learner = SupervisedImageLearner(
train_data=train_loader,
val_data=val_loader,
model=model,
criterion=SmoothedCrossEntropy(),
optimizer=optimizer,
mixup=True
)
callbacks = [
ToDeviceCallback(),
Tensorboard(),
LRSchedulerCB(CosineAnnealingLR(optimizer, eta_min=0.024, T_max=1600)),
LossLogger(),
ModelCheckpoint(learner=learner, filepath=save_path, monitor='accuracy', mode='max'),
# EarlyStoppingCB(monitor='accuracy', mode='max', patience=20)
]
metrics = {
"accuracy": Accuracy(),
"loss": Loss()
}
final = learner.learn(
n_epoch=10,
callbacks=callbacks,
metrics=metrics,
final_metric='accuracy'
)
print(final)
# load_model(model=model, path=save_path)
# return model
ensembler = CVEnsembler(data, path="weights/", n_model=5, learn_fn=learn_fn, model_fn=model_fn)
ensembler.learn()
ensemble_model = EnsembleImageClassifier([ImageClassifier(model) for model in ensembler.get_models()])
print(ensemble_model.evaluate(test_loader))