ABrain-One commited on
Commit
b034b1e
·
verified ·
1 Parent(s): a893842

Add files using upload-large-folder tool

Browse files
test/nn/MoE4Own-batch-00034-20260331-223020-b2fdc7ac534972535c85e467f80ad728.py ADDED
@@ -0,0 +1,503 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Auto-generated 4-Expert Heterogeneous MoE: AirNet + AlexNet + DPN107 + SqueezeNet-2
2
+ # Four-expert mixture with learned gating, mixup, and LR scheduling
3
+
4
+ import numpy as np
5
+ import torch.nn.functional as F
6
+ from torchvision.models._api import WeightsEnum
7
+ from torchvision.models._utils import _ovewrite_named_param
8
+ from typing import Any, Optional
9
+ import torch
10
+ import torch.nn as nn
11
+ import torch.nn.init as init
12
+ import torch.optim as optim
13
+
14
+
15
+ def supported_hyperparameters():
16
+ return {'dropout', 'lr', 'momentum'}
17
+
18
+
19
+
20
+ # ============================================================================
21
+ # EXPERT 1: AirNet
22
+ # ============================================================================
23
+
24
+
25
+ class AirInitBlock(nn.Module):
26
+ def __init__(self, in_channels, out_channels):
27
+ super().__init__()
28
+ self.layers = nn.Sequential(
29
+ nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=2, padding=1),
30
+ nn.BatchNorm2d(out_channels),
31
+ nn.ReLU(inplace=True)
32
+ )
33
+
34
+ def forward(self, x):
35
+ return self.layers(x)
36
+
37
+
38
+ class AirUnit(nn.Module):
39
+ def __init__(self, in_channels, out_channels, stride):
40
+ super().__init__()
41
+ self.layers = nn.Sequential(
42
+ nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1),
43
+ nn.BatchNorm2d(out_channels),
44
+ nn.ReLU(inplace=True),
45
+ nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1),
46
+ nn.BatchNorm2d(out_channels)
47
+ )
48
+ self.downsample = (
49
+ nn.Sequential(
50
+ nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
51
+ nn.BatchNorm2d(out_channels)
52
+ ) if stride != 1 or in_channels != out_channels else nn.Identity()
53
+ )
54
+ self.relu = nn.ReLU(inplace=True)
55
+
56
+ def forward(self, x):
57
+ residual = self.downsample(x)
58
+ x = self.layers(x)
59
+ return self.relu(x + residual)
60
+
61
+
62
+ class AirNetExpert(nn.Module):
63
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
64
+ super().__init__()
65
+ self.device = device
66
+ self.in_channels = in_shape[1]
67
+ self.image_size = in_shape[2]
68
+ self.num_classes = out_shape[0]
69
+ self.learning_rate = prm['lr']
70
+ self.momentum = prm['momentum']
71
+
72
+ channels = [64, 128, 256, 512]
73
+ init_block_channels = 64
74
+
75
+ self.features = self.build_features(init_block_channels, channels)
76
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
77
+ self.classifier = nn.Linear(channels[-1], self.num_classes)
78
+
79
+ def build_features(self, init_block_channels, channels):
80
+ layers = [AirInitBlock(self.in_channels, init_block_channels)]
81
+ for i, out_channels in enumerate(channels):
82
+ layers.append(AirUnit(
83
+ in_channels=init_block_channels if i == 0 else channels[i - 1],
84
+ out_channels=out_channels,
85
+ stride=1 if i == 0 else 2))
86
+ return nn.Sequential(*layers)
87
+
88
+ def forward(self, x):
89
+ x = self.features(x)
90
+ x = self.avgpool(x)
91
+ x = torch.flatten(x, 1)
92
+ return self.classifier(x)
93
+
94
+ def train_setup(self, prm):
95
+ self.to(self.device)
96
+ self.criteria = nn.CrossEntropyLoss().to(self.device)
97
+ self.optimizer = torch.optim.SGD(
98
+ self.parameters(),
99
+ lr=self.learning_rate,
100
+ momentum=self.momentum
101
+ )
102
+
103
+ def learn(self, train_data):
104
+ self.train()
105
+ for inputs, labels in train_data:
106
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
107
+ self.optimizer.zero_grad()
108
+ outputs = self(inputs)
109
+ loss = self.criteria(outputs, labels)
110
+ loss.backward()
111
+ nn.utils.clip_grad_norm_(self.parameters(), 3)
112
+ self.optimizer.step()
113
+
114
+
115
+
116
+ # ============================================================================
117
+ # EXPERT 2: AlexNet
118
+ # ============================================================================
119
+
120
+
121
+ class AlexNetExpert(nn.Module):
122
+
123
+ def train_setup(self, prm):
124
+ self.to(self.device)
125
+ self.criteria = (nn.CrossEntropyLoss().to(self.device),)
126
+ self.optimizer = torch.optim.SGD(self.parameters(), lr=prm['lr'], momentum=prm['momentum'])
127
+
128
+ def learn(self, train_data):
129
+ for inputs, labels in train_data:
130
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
131
+ self.optimizer.zero_grad()
132
+ outputs = self(inputs)
133
+ loss = self.criteria[0](outputs, labels)
134
+ loss.backward()
135
+ nn.utils.clip_grad_norm_(self.parameters(), 3)
136
+ self.optimizer.step()
137
+
138
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
139
+ super().__init__()
140
+ self.device = device
141
+ self.features = nn.Sequential(
142
+ nn.Conv2d(in_shape[1], 64, kernel_size=11, stride=4, padding=2),
143
+ nn.ReLU(inplace=True),
144
+ nn.MaxPool2d(kernel_size=3, stride=2),
145
+ nn.Conv2d(64, 192, kernel_size=5, padding=2),
146
+ nn.ReLU(inplace=True),
147
+ nn.MaxPool2d(kernel_size=3, stride=2),
148
+ nn.Conv2d(192, 384, kernel_size=3, padding=1),
149
+ nn.ReLU(inplace=True),
150
+ nn.Conv2d(384, 256, kernel_size=3, padding=1),
151
+ nn.ReLU(inplace=True),
152
+ nn.Conv2d(256, 256, kernel_size=3, padding=1),
153
+ nn.ReLU(inplace=True),
154
+ nn.MaxPool2d(kernel_size=3, stride=2),
155
+ )
156
+ dropout: float = prm['dropout']
157
+ self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
158
+ self.classifier = nn.Sequential(
159
+ nn.Dropout(p=dropout),
160
+ nn.Linear(256 * 6 * 6, 4096),
161
+ nn.ReLU(inplace=True),
162
+ nn.Dropout(p=dropout),
163
+ nn.Linear(4096, 4096),
164
+ nn.ReLU(inplace=True),
165
+ nn.Linear(4096, out_shape[0]),
166
+ )
167
+
168
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
169
+ x = self.features(x)
170
+ x = self.avgpool(x)
171
+ x = torch.flatten(x, 1)
172
+ x = self.classifier(x)
173
+ return x
174
+
175
+
176
+
177
+ # ============================================================================
178
+ # EXPERT 3: DPN107
179
+ # ============================================================================
180
+
181
+
182
+ # Define DPNBlock with Group Convolutions
183
+ class DPNBlock(nn.Module):
184
+ def __init__(self, in_channels, out_channels, stride=1):
185
+ super(DPNBlock, self).__init__()
186
+ self.conv1 = nn.Conv2d(
187
+ in_channels, out_channels, kernel_size=3, stride=stride, padding=1, groups=4, bias=False
188
+ )
189
+ self.bn1 = nn.BatchNorm2d(out_channels)
190
+ self.relu = nn.ReLU(inplace=True)
191
+ self.conv2 = nn.Conv2d(
192
+ out_channels, out_channels, kernel_size=3, padding=1, groups=4, bias=False
193
+ )
194
+ self.bn2 = nn.BatchNorm2d(out_channels)
195
+
196
+ def forward(self, x):
197
+ residual = x
198
+ out = self.conv1(x)
199
+ out = self.bn1(out)
200
+ out = self.relu(out)
201
+ out = self.conv2(out)
202
+ out = self.bn2(out)
203
+ out += residual # Residual connection
204
+ return self.relu(out)
205
+
206
+
207
+ # Memory-Optimized DPN107
208
+ class DPN107(nn.Module):
209
+ def __init__(self, in_channels, num_classes, num_blocks, growth_rate):
210
+ super(DPN107, self).__init__()
211
+ self.conv1 = nn.Conv2d(in_channels, growth_rate, kernel_size=3, padding=1, bias=False)
212
+ self.bn1 = nn.BatchNorm2d(growth_rate)
213
+ self.relu = nn.ReLU(inplace=True)
214
+
215
+ self.blocks = nn.Sequential(
216
+ *[DPNBlock(growth_rate, growth_rate) for _ in range(num_blocks)]
217
+ )
218
+
219
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
220
+ self.fc = nn.Linear(growth_rate, num_classes)
221
+
222
+ def forward(self, x):
223
+ x = self.conv1(x)
224
+ x = self.bn1(x)
225
+ x = self.relu(x)
226
+ x = self.blocks(x)
227
+ x = self.avgpool(x)
228
+ x = torch.flatten(x, 1)
229
+ x = self.fc(x)
230
+ return x
231
+
232
+
233
+ class DPN107Expert(nn.Module):
234
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
235
+ super(DPN107Expert, self).__init__()
236
+ self.device = device
237
+ model_class = DPN107
238
+ self.channel_number = in_shape[1]
239
+ self.image_size = in_shape[2]
240
+ self.class_number = out_shape[0]
241
+
242
+ self.model = model_class(self.channel_number, self.class_number, num_blocks=3, growth_rate=32)
243
+ self.learning_rate = prm['lr']
244
+ self.momentum = prm['momentum']
245
+
246
+ def forward(self, x):
247
+ return self.model(x)
248
+
249
+ def train_setup(self, prm):
250
+ self.to(self.device)
251
+ self.criteria = nn.CrossEntropyLoss().to(self.device)
252
+ self.optimizer = optim.SGD(self.parameters(), lr=self.learning_rate, momentum=self.momentum)
253
+
254
+ def learn(self, train_data):
255
+ self.train()
256
+ for inputs, labels in train_data:
257
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
258
+ inputs = inputs.float()
259
+ self.optimizer.zero_grad()
260
+ outputs = self(inputs)
261
+ loss = self.criteria(outputs, labels)
262
+ loss.backward()
263
+ nn.utils.clip_grad_norm_(self.parameters(), 3)
264
+ self.optimizer.step()
265
+
266
+
267
+
268
+ # ============================================================================
269
+ # EXPERT 4: SqueezeNet-2
270
+ # ============================================================================
271
+
272
+
273
+
274
+ class Fire(nn.Module):
275
+ def __init__(self, inplanes: int, squeeze_planes: int, expand1x1_planes: int, expand3x3_planes: int) -> None:
276
+ super().__init__()
277
+ self.inplanes = inplanes
278
+ self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1)
279
+ self.squeeze_activation = nn.ReLU(inplace=True)
280
+ self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, kernel_size=1)
281
+ self.expand1x1_activation = nn.ReLU(inplace=True)
282
+ self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, kernel_size=3, padding=1)
283
+ self.expand3x3_activation = nn.ReLU(inplace=True)
284
+
285
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
286
+ x = self.squeeze_activation(self.squeeze(x))
287
+ return torch.cat(
288
+ [self.expand1x1_activation(self.expand1x1(x)), self.expand3x3_activation(self.expand3x3(x))], 1
289
+ )
290
+
291
+
292
+ class SqueezeNet_2Expert(nn.Module):
293
+
294
+ def train_setup(self, prm):
295
+ self.to(self.device)
296
+ self.criteria = (nn.CrossEntropyLoss().to(self.device),)
297
+ self.optimizer = torch.optim.SGD(self.parameters(), lr=prm['lr'], momentum=prm['momentum'])
298
+
299
+ def learn(self, train_data):
300
+ for inputs, labels in train_data:
301
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
302
+ self.optimizer.zero_grad()
303
+ outputs = self(inputs)
304
+ loss = self.criteria[0](outputs, labels)
305
+ loss.backward()
306
+ nn.utils.clip_grad_norm_(self.parameters(), 3)
307
+ self.optimizer.step()
308
+
309
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
310
+ super().__init__()
311
+ self.device = device
312
+ version: str = "1_1"
313
+ num_classes: int = out_shape[0]
314
+ dropout: float = prm['dropout']
315
+ self.num_classes = num_classes
316
+ if version == "1_0":
317
+ self.features = nn.Sequential(
318
+ nn.Conv2d(in_shape[1], 96, kernel_size=7, stride=2),
319
+ nn.ReLU(inplace=True),
320
+ nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
321
+ Fire(96, 16, 64, 64),
322
+ Fire(128, 16, 64, 64),
323
+ Fire(128, 32, 128, 128),
324
+ nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
325
+ Fire(256, 32, 128, 128),
326
+ Fire(256, 48, 192, 192),
327
+ Fire(384, 48, 192, 192),
328
+ Fire(384, 64, 256, 256),
329
+ nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
330
+ Fire(512, 64, 256, 256),
331
+ )
332
+ elif version == "1_1":
333
+ self.features = nn.Sequential(
334
+ nn.Conv2d(in_shape[1], 64, kernel_size=3, stride=2),
335
+ nn.ReLU(inplace=True),
336
+ nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
337
+ Fire(64, 16, 64, 64),
338
+ Fire(128, 16, 64, 64),
339
+ nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
340
+ Fire(128, 32, 128, 128),
341
+ Fire(256, 32, 128, 128),
342
+ nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
343
+ Fire(256, 48, 192, 192),
344
+ Fire(384, 48, 192, 192),
345
+ Fire(384, 64, 256, 256),
346
+ Fire(512, 64, 256, 256),
347
+ )
348
+ else:
349
+ raise ValueError(f"Unsupported SqueezeNet version {version}: 1_0 or 1_1 expected")
350
+ final_conv = nn.Conv2d(512, self.num_classes, kernel_size=1)
351
+ self.classifier = nn.Sequential(
352
+ nn.Dropout(p=dropout), final_conv, nn.ReLU(inplace=True), nn.AdaptiveAvgPool2d((1, 1))
353
+ )
354
+
355
+ for m in self.modules():
356
+ if isinstance(m, nn.Conv2d):
357
+ if m is final_conv:
358
+ init.normal_(m.weight, mean=0.0, std=0.01)
359
+ else:
360
+ init.kaiming_uniform_(m.weight)
361
+ if m.bias is not None:
362
+ init.constant_(m.bias, 0)
363
+
364
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
365
+ x = self.features(x)
366
+ x = self.classifier(x)
367
+ return torch.flatten(x, 1)
368
+
369
+
370
+ def _squeezenet(
371
+ version: str,
372
+ weights: Optional[WeightsEnum],
373
+ progress: bool,
374
+ **kwargs: Any,
375
+ ) -> SqueezeNet_2Expert:
376
+ if weights is not None:
377
+ _ovewrite_named_param(kwargs, "num_classes", len(weights.meta["categories"]))
378
+ model = SqueezeNet_2Expert(version, **kwargs)
379
+ if weights is not None:
380
+ model.load_state_dict(weights.get_state_dict(progress=progress, check_hash=True))
381
+
382
+ return model
383
+
384
+
385
+
386
+ # ============================================================================
387
+ # HETEROGENEOUS MOE GATE
388
+ # ============================================================================
389
+ class HeterogeneousGate(nn.Module):
390
+ """Lightweight CNN-based gating network that routes inputs to 4 experts."""
391
+ def __init__(self, input_channels, n_experts=4):
392
+ super().__init__()
393
+ self.n_experts = n_experts
394
+ self.gate_features = nn.Sequential(
395
+ nn.Conv2d(input_channels, 64, 3, stride=2, padding=1),
396
+ nn.BatchNorm2d(64),
397
+ nn.ReLU(inplace=True),
398
+ nn.Conv2d(64, 128, 3, stride=2, padding=1),
399
+ nn.BatchNorm2d(128),
400
+ nn.ReLU(inplace=True),
401
+ nn.AdaptiveAvgPool2d((1, 1)),
402
+ )
403
+ self.gate = nn.Sequential(
404
+ nn.Linear(128, 64),
405
+ nn.ReLU(),
406
+ nn.Dropout(0.1),
407
+ nn.Linear(64, n_experts),
408
+ )
409
+ self.temperature = nn.Parameter(torch.ones(1) * 2.0)
410
+
411
+ def forward(self, x):
412
+ features = self.gate_features(x).flatten(1)
413
+ logits = self.gate(features) / torch.clamp(self.temperature, 0.5, 5.0)
414
+ if self.training:
415
+ logits = logits + torch.randn_like(logits) * 0.1
416
+ return F.softmax(logits, dim=-1), logits
417
+
418
+
419
+ # ============================================================================
420
+ # HETEROGENEOUS MOE NET — AirNet + AlexNet + DPN107 + SqueezeNet_2
421
+ # ============================================================================
422
+ class Net(nn.Module):
423
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
424
+ super().__init__()
425
+ self.device = device
426
+ n_experts = 4
427
+
428
+ # Defaults for expert-specific hyperparameters
429
+ pass # no extra defaults needed
430
+ self.experts = nn.ModuleList([
431
+ AirNetExpert(in_shape, out_shape, prm, device),
432
+ AlexNetExpert(in_shape, out_shape, prm, device),
433
+ DPN107Expert(in_shape, out_shape, prm, device),
434
+ SqueezeNet_2Expert(in_shape, out_shape, prm, device),
435
+ ])
436
+ self.gate = HeterogeneousGate(in_shape[1], n_experts=n_experts)
437
+
438
+ self.load_balance_weight = 0.01
439
+ self.label_smoothing = 0.1
440
+ self.mixup_alpha = 0.2
441
+ self.to(device)
442
+
443
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
444
+ gate_weights, _ = self.gate(x)
445
+ expert_outputs = torch.stack([e(x) for e in self.experts], dim=2)
446
+ return torch.sum(expert_outputs * gate_weights.unsqueeze(1), dim=2)
447
+
448
+ def _load_balance_loss(self):
449
+ if not hasattr(self, '_last_gw'):
450
+ return torch.tensor(0.0, device=self.device)
451
+ gw = self._last_gw
452
+ usage = gw.sum(dim=0)
453
+ target = gw.sum() / len(self.experts)
454
+ return F.mse_loss(usage, target.expand_as(usage))
455
+
456
+ def _mixup_data(self, x, y):
457
+ lam = np.random.beta(self.mixup_alpha, self.mixup_alpha) if self.mixup_alpha > 0 else 1.0
458
+ idx = torch.randperm(x.size(0), device=self.device)
459
+ return lam * x + (1 - lam) * x[idx], y, y[idx], lam
460
+
461
+ def train_setup(self, prm):
462
+ self.to(self.device)
463
+ self.criteria = nn.CrossEntropyLoss(label_smoothing=self.label_smoothing)
464
+ expert_params, gate_params = [], list(self.gate.parameters())
465
+ for e in self.experts:
466
+ expert_params.extend(list(e.parameters()))
467
+ self.optimizer = torch.optim.AdamW([
468
+ {'params': expert_params, 'lr': prm.get('lr', 0.001), 'weight_decay': 5e-4},
469
+ {'params': gate_params, 'lr': prm.get('lr', 0.001) * 2, 'weight_decay': 2.5e-4},
470
+ ])
471
+ self.warmup_scheduler = torch.optim.lr_scheduler.LinearLR(
472
+ self.optimizer, start_factor=0.1, total_iters=5
473
+ )
474
+ self.main_scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
475
+ self.optimizer, T_max=50, eta_min=1e-6
476
+ )
477
+ self._current_epoch = 0
478
+
479
+ def learn(self, train_data):
480
+ self.train()
481
+ for inputs, labels in train_data:
482
+ inputs = inputs.to(self.device, dtype=torch.float32)
483
+ labels = labels.to(self.device, dtype=torch.long)
484
+ if self.mixup_alpha > 0:
485
+ inputs, labels_a, labels_b, lam = self._mixup_data(inputs, labels)
486
+ self.optimizer.zero_grad()
487
+ outputs = self(inputs)
488
+ loss = lam * self.criteria(outputs, labels_a) + (1 - lam) * self.criteria(outputs, labels_b)
489
+ else:
490
+ self.optimizer.zero_grad()
491
+ outputs = self(inputs)
492
+ loss = self.criteria(outputs, labels)
493
+ self._last_gw = self.gate(inputs)[0].detach()
494
+ loss = loss + self.load_balance_weight * self._load_balance_loss()
495
+ loss.backward()
496
+ nn.utils.clip_grad_norm_(self.parameters(), 1.0)
497
+ self.optimizer.step()
498
+ self._current_epoch += 1
499
+ if self._current_epoch <= 5:
500
+ self.warmup_scheduler.step()
501
+ else:
502
+ self.main_scheduler.step()
503
+
test/nn/MoE4Own-batch-00057-20260408-085045-459eacce1d6ebe52380edb28feb88826.py ADDED
@@ -0,0 +1,532 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Auto-generated 4-Expert Heterogeneous MoE: AirNet + BagNet + DPN68 + DarkNet
2
+ # Four-expert mixture with learned gating, mixup, and LR scheduling
3
+
4
+ import numpy as np
5
+ import torch.nn.functional as F
6
+ import torch
7
+ import torch.nn as nn
8
+ import torch.optim as optim
9
+
10
+
11
+ def supported_hyperparameters():
12
+ return {'dropout', 'lr', 'momentum'}
13
+
14
+
15
+
16
+ # ============================================================================
17
+ # EXPERT 1: AirNet
18
+ # ============================================================================
19
+
20
+
21
+ class AirInitBlock(nn.Module):
22
+ def __init__(self, in_channels, out_channels):
23
+ super().__init__()
24
+ self.layers = nn.Sequential(
25
+ nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=2, padding=1),
26
+ nn.BatchNorm2d(out_channels),
27
+ nn.ReLU(inplace=True)
28
+ )
29
+
30
+ def forward(self, x):
31
+ return self.layers(x)
32
+
33
+
34
+ class AirUnit(nn.Module):
35
+ def __init__(self, in_channels, out_channels, stride):
36
+ super().__init__()
37
+ self.layers = nn.Sequential(
38
+ nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1),
39
+ nn.BatchNorm2d(out_channels),
40
+ nn.ReLU(inplace=True),
41
+ nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1),
42
+ nn.BatchNorm2d(out_channels)
43
+ )
44
+ self.downsample = (
45
+ nn.Sequential(
46
+ nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
47
+ nn.BatchNorm2d(out_channels)
48
+ ) if stride != 1 or in_channels != out_channels else nn.Identity()
49
+ )
50
+ self.relu = nn.ReLU(inplace=True)
51
+
52
+ def forward(self, x):
53
+ residual = self.downsample(x)
54
+ x = self.layers(x)
55
+ return self.relu(x + residual)
56
+
57
+
58
+ class AirNetExpert(nn.Module):
59
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
60
+ super().__init__()
61
+ self.device = device
62
+ self.in_channels = in_shape[1]
63
+ self.image_size = in_shape[2]
64
+ self.num_classes = out_shape[0]
65
+ self.learning_rate = prm['lr']
66
+ self.momentum = prm['momentum']
67
+
68
+ channels = [64, 128, 256, 512]
69
+ init_block_channels = 64
70
+
71
+ self.features = self.build_features(init_block_channels, channels)
72
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
73
+ self.classifier = nn.Linear(channels[-1], self.num_classes)
74
+
75
+ def build_features(self, init_block_channels, channels):
76
+ layers = [AirInitBlock(self.in_channels, init_block_channels)]
77
+ for i, out_channels in enumerate(channels):
78
+ layers.append(AirUnit(
79
+ in_channels=init_block_channels if i == 0 else channels[i - 1],
80
+ out_channels=out_channels,
81
+ stride=1 if i == 0 else 2))
82
+ return nn.Sequential(*layers)
83
+
84
+ def forward(self, x):
85
+ x = self.features(x)
86
+ x = self.avgpool(x)
87
+ x = torch.flatten(x, 1)
88
+ return self.classifier(x)
89
+
90
+ def train_setup(self, prm):
91
+ self.to(self.device)
92
+ self.criteria = nn.CrossEntropyLoss().to(self.device)
93
+ self.optimizer = torch.optim.SGD(
94
+ self.parameters(),
95
+ lr=self.learning_rate,
96
+ momentum=self.momentum
97
+ )
98
+
99
+ def learn(self, train_data):
100
+ self.train()
101
+ for inputs, labels in train_data:
102
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
103
+ self.optimizer.zero_grad()
104
+ outputs = self(inputs)
105
+ loss = self.criteria(outputs, labels)
106
+ loss.backward()
107
+ nn.utils.clip_grad_norm_(self.parameters(), 3)
108
+ self.optimizer.step()
109
+
110
+
111
+
112
+ # ============================================================================
113
+ # EXPERT 2: BagNet
114
+ # ============================================================================
115
+
116
+
117
+ class BagNetBottleneck(nn.Module):
118
+ def __init__(self, in_channels, out_channels, kernel_size, stride, bottleneck_factor=4):
119
+ super().__init__()
120
+ mid_channels = out_channels // bottleneck_factor
121
+
122
+ self.conv1 = self.conv1x1_block(in_channels, mid_channels)
123
+ self.conv2 = self.conv_block(mid_channels, mid_channels, kernel_size, stride)
124
+ self.conv3 = self.conv1x1_block(mid_channels, out_channels, activation=False)
125
+
126
+ def conv1x1_block(self, in_channels, out_channels, activation=True):
127
+ layers = [nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False)]
128
+ if activation:
129
+ layers.append(nn.ReLU(inplace=True))
130
+ return nn.Sequential(*layers)
131
+
132
+ def conv_block(self, in_channels, out_channels, kernel_size, stride):
133
+ padding = (kernel_size - 1) // 2
134
+ return nn.Sequential(
135
+ nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, bias=False),
136
+ nn.BatchNorm2d(out_channels),
137
+ nn.ReLU(inplace=True),
138
+ )
139
+
140
+ def forward(self, x):
141
+ x = self.conv1(x)
142
+ x = self.conv2(x)
143
+ x = self.conv3(x)
144
+ return x
145
+
146
+
147
+ class BagNetUnit(nn.Module):
148
+ def __init__(self, in_channels, out_channels, kernel_size, stride):
149
+ super().__init__()
150
+ self.resize_identity = (in_channels != out_channels) or (stride != 1)
151
+ self.body = BagNetBottleneck(in_channels, out_channels, kernel_size, stride)
152
+
153
+ if self.resize_identity:
154
+ self.identity_conv = self.conv1x1_block(in_channels, out_channels, activation=False)
155
+ self.activ = nn.ReLU(inplace=True)
156
+
157
+ def conv1x1_block(self, in_channels, out_channels, activation=True):
158
+ layers = [nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False)]
159
+ if activation:
160
+ layers.append(nn.ReLU(inplace=True))
161
+ return nn.Sequential(*layers)
162
+
163
+ def forward(self, x):
164
+ identity = x
165
+ if self.resize_identity:
166
+ identity = self.identity_conv(x)
167
+
168
+ x = self.body(x)
169
+
170
+ if x.size(2) != identity.size(2) or x.size(3) != identity.size(3):
171
+ identity = nn.functional.interpolate(identity, size=(x.size(2), x.size(3)), mode='bilinear', align_corners=False)
172
+
173
+ return self.activ(x + identity)
174
+
175
+
176
+ class BagNetExpert(nn.Module):
177
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
178
+ super().__init__()
179
+ self.device = device
180
+ channel_number = in_shape[1]
181
+ image_size = in_shape[2]
182
+ class_number = out_shape[0]
183
+ learning_rate = prm['lr']
184
+ momentum = prm['momentum']
185
+ dropout = prm['dropout']
186
+
187
+ self.channels = [[64, 64, 64], [128, 128, 128], [256, 256, 256], [512, 512, 512]]
188
+ self.in_size = image_size
189
+ self.num_classes = class_number
190
+
191
+ self.features = nn.Sequential(
192
+ nn.Conv2d(channel_number, 64, kernel_size=7, stride=2, padding=3, bias=False),
193
+ nn.BatchNorm2d(64),
194
+ nn.ReLU(inplace=True),
195
+ nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
196
+ )
197
+
198
+ in_channels = 64
199
+ for i, stage_channels in enumerate(self.channels):
200
+ stage = nn.Sequential()
201
+ for j, out_channels in enumerate(stage_channels):
202
+ stride = 2 if (j == 0 and i > 0) else 1
203
+ stage.add_module(f"unit{j + 1}", BagNetUnit(in_channels, out_channels, kernel_size=3, stride=stride))
204
+ in_channels = out_channels
205
+ self.features.add_module(f"stage{i + 1}", stage)
206
+
207
+ self.features.add_module("final_pool", nn.AdaptiveAvgPool2d(1))
208
+ self.output = nn.Linear(in_channels, self.num_classes)
209
+
210
+ self.learning_rate = learning_rate
211
+ self.momentum = momentum
212
+ self.dropout = dropout
213
+
214
+ def forward(self, x):
215
+ x = self.features(x)
216
+ x = torch.flatten(x, 1)
217
+ return self.output(x)
218
+
219
+ def train_setup(self, prm):
220
+ self.to(self.device)
221
+ self.criteria = nn.CrossEntropyLoss().to(self.device)
222
+ self.optimizer = torch.optim.SGD(self.parameters(), lr=prm['lr'], momentum=prm['momentum'],)
223
+
224
+ if self.dropout > 0:
225
+ self.dropout_layer = nn.Dropout(self.dropout)
226
+
227
+ def learn(self, train_data):
228
+ self.train()
229
+ for inputs, labels in train_data:
230
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
231
+ self.optimizer.zero_grad()
232
+ outputs = self(inputs)
233
+ loss = self.criteria(outputs, labels)
234
+ loss.backward()
235
+ nn.utils.clip_grad_norm_(self.parameters(), 3)
236
+ self.optimizer.step()
237
+
238
+
239
+
240
+ # ============================================================================
241
+ # EXPERT 3: DPN68
242
+ # ============================================================================
243
+
244
+
245
+ class DPNBlock(nn.Module):
246
+ def __init__(self, in_channels, out_channels):
247
+ super(DPNBlock, self).__init__()
248
+ self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1)
249
+ self.bn1 = nn.BatchNorm2d(out_channels)
250
+ self.relu = nn.ReLU(inplace=True)
251
+ self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)
252
+ self.bn2 = nn.BatchNorm2d(out_channels)
253
+
254
+ def forward(self, x):
255
+ residual = x
256
+ out = self.conv1(x)
257
+ out = self.bn1(out)
258
+ out = self.relu(out)
259
+ out = self.conv2(out)
260
+ out = self.bn2(out)
261
+ out = out + residual
262
+ return self.relu(out)
263
+
264
+
265
+ class DPN68(nn.Module):
266
+ def __init__(self, in_channels, num_classes, num_blocks, growth_rate):
267
+ super(DPN68, self).__init__()
268
+ self.conv1 = nn.Conv2d(in_channels, growth_rate, kernel_size=3, stride=1, padding=1)
269
+ self.bn1 = nn.BatchNorm2d(growth_rate)
270
+ self.relu = nn.ReLU(inplace=True)
271
+
272
+ self.blocks = nn.Sequential(
273
+ *[DPNBlock(growth_rate, growth_rate) for _ in range(num_blocks)]
274
+ )
275
+
276
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
277
+ self.fc = nn.Linear(growth_rate, num_classes)
278
+
279
+ def forward(self, x):
280
+ x = self.conv1(x)
281
+ x = self.bn1(x)
282
+ x = self.relu(x)
283
+ x = self.blocks(x)
284
+ x = self.avgpool(x)
285
+ x = torch.flatten(x, 1)
286
+ x = self.fc(x)
287
+ return x
288
+
289
+
290
+ class DPN68Expert(nn.Module):
291
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
292
+ super(DPN68Expert, self).__init__()
293
+ self.device = device
294
+ model_class = DPN68
295
+ self.channel_number = in_shape[1]
296
+ self.image_size = in_shape[2]
297
+ self.class_number = out_shape[0]
298
+ self.model = model_class(self.channel_number, self.class_number, num_blocks=3, growth_rate=32)
299
+
300
+ def forward(self, x):
301
+ return self.model(x)
302
+
303
+ def train_setup(self, prm):
304
+ self.to(self.device)
305
+ self.criteria = nn.CrossEntropyLoss().to(self.device)
306
+ self.optimizer = optim.SGD(self.parameters(), lr=prm['lr'], momentum=prm['momentum'])
307
+
308
+ def learn(self, train_data):
309
+ self.train()
310
+ for inputs, labels in train_data:
311
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
312
+ self.optimizer.zero_grad()
313
+ outputs = self(inputs)
314
+ loss = self.criteria(outputs, labels)
315
+ loss.backward()
316
+ nn.utils.clip_grad_norm_(self.parameters(), 3)
317
+ self.optimizer.step()
318
+
319
+
320
+
321
+ # ============================================================================
322
+ # EXPERT 4: DarkNet
323
+ # ============================================================================
324
+
325
+
326
+ class DarkNetUnit(nn.Module):
327
+ def __init__(self, in_channels: int, out_channels: int, pointwise: bool, alpha: float):
328
+ super(DarkNetUnit, self).__init__()
329
+ self.activation = nn.LeakyReLU(negative_slope=alpha, inplace=True)
330
+ if pointwise:
331
+ self.conv = nn.Sequential(
332
+ nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, bias=False),
333
+ nn.BatchNorm2d(out_channels),
334
+ self.activation
335
+ )
336
+ else:
337
+ self.conv = nn.Sequential(
338
+ nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False),
339
+ nn.BatchNorm2d(out_channels),
340
+ self.activation
341
+ )
342
+
343
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
344
+ return self.conv(x)
345
+
346
+
347
+ class DarkNetExpert(nn.Module):
348
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
349
+ super(DarkNetExpert, self).__init__()
350
+ self.device = device
351
+ channels: list = None
352
+ odd_pointwise: bool = True
353
+ alpha: float = 0.1
354
+ in_channels = in_shape[1]
355
+ image_size = in_shape[2]
356
+ num_classes = out_shape[0]
357
+
358
+ if channels is None:
359
+ channels = [[64, 64, 64], [128, 128, 128], [256, 256, 256], [512, 512, 512]]
360
+
361
+ self.features = nn.Sequential()
362
+ for i, channels_per_stage in enumerate(channels):
363
+ stage = nn.Sequential()
364
+ for j, out_channels in enumerate(channels_per_stage):
365
+ pointwise = (len(channels_per_stage) > 1) and not (((j + 1) % 2 == 1) ^ odd_pointwise)
366
+ stage.add_module(f"unit{j + 1}", DarkNetUnit(in_channels, out_channels, pointwise, alpha))
367
+ in_channels = out_channels
368
+ if i != len(channels) - 1:
369
+ stage.add_module(f"pool{i + 1}", nn.MaxPool2d(kernel_size=2, stride=2))
370
+ self.features.add_module(f"stage{i + 1}", stage)
371
+
372
+ final_feature_map_size = image_size // (2 ** (len(channels) - 1))
373
+
374
+ self.output = nn.Sequential(
375
+ nn.Conv2d(in_channels=in_channels, out_channels=num_classes, kernel_size=1),
376
+ nn.LeakyReLU(negative_slope=alpha, inplace=True),
377
+ nn.AdaptiveAvgPool2d(output_size=(1, 1))
378
+ )
379
+
380
+ self._initialize_weights()
381
+
382
+ def _initialize_weights(self):
383
+ for module in self.modules():
384
+ if isinstance(module, nn.Conv2d):
385
+ nn.init.kaiming_uniform_(module.weight, mode='fan_in', nonlinearity='leaky_relu')
386
+ if module.bias is not None:
387
+ nn.init.constant_(module.bias, 0)
388
+
389
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
390
+ x = self.features(x)
391
+ x = self.output(x)
392
+ x = x.view(x.size(0), -1)
393
+ return x
394
+
395
+ def train_setup(self, prm: dict):
396
+ self.to(self.device)
397
+ learning_rate = float(prm.get("lr", 0.01))
398
+ momentum = float(prm.get("momentum", 0.9))
399
+ self.criteria = nn.CrossEntropyLoss()
400
+ self.optimizer = optim.SGD(self.parameters(), lr=learning_rate, momentum=momentum)
401
+ self.to(self.device)
402
+
403
+ def learn(self, train_data: torch.utils.data.DataLoader):
404
+ self.train()
405
+ for inputs, targets in train_data:
406
+ inputs, targets = inputs.to(next(self.parameters()).device), targets.to(next(self.parameters()).device)
407
+ self.optimizer.zero_grad()
408
+ outputs = self(inputs)
409
+ loss = self.criteria(outputs, targets)
410
+ loss.backward()
411
+ self.optimizer.step()
412
+
413
+
414
+
415
+ # ============================================================================
416
+ # HETEROGENEOUS MOE GATE
417
+ # ============================================================================
418
+ class HeterogeneousGate(nn.Module):
419
+ """Lightweight CNN-based gating network that routes inputs to 4 experts."""
420
+ def __init__(self, input_channels, n_experts=4):
421
+ super().__init__()
422
+ self.n_experts = n_experts
423
+ self.gate_features = nn.Sequential(
424
+ nn.Conv2d(input_channels, 64, 3, stride=2, padding=1),
425
+ nn.BatchNorm2d(64),
426
+ nn.ReLU(inplace=True),
427
+ nn.Conv2d(64, 128, 3, stride=2, padding=1),
428
+ nn.BatchNorm2d(128),
429
+ nn.ReLU(inplace=True),
430
+ nn.AdaptiveAvgPool2d((1, 1)),
431
+ )
432
+ self.gate = nn.Sequential(
433
+ nn.Linear(128, 64),
434
+ nn.ReLU(),
435
+ nn.Dropout(0.1),
436
+ nn.Linear(64, n_experts),
437
+ )
438
+ self.temperature = nn.Parameter(torch.ones(1) * 2.0)
439
+
440
+ def forward(self, x):
441
+ features = self.gate_features(x).flatten(1)
442
+ logits = self.gate(features) / torch.clamp(self.temperature, 0.5, 5.0)
443
+ if self.training:
444
+ logits = logits + torch.randn_like(logits) * 0.1
445
+ return F.softmax(logits, dim=-1), logits
446
+
447
+
448
+ # ============================================================================
449
+ # HETEROGENEOUS MOE NET — AirNet + BagNet + DPN68 + DarkNet
450
+ # ============================================================================
451
+ class Net(nn.Module):
452
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
453
+ super().__init__()
454
+ self.device = device
455
+ n_experts = 4
456
+
457
+ # Defaults for expert-specific hyperparameters
458
+ pass # no extra defaults needed
459
+ self.experts = nn.ModuleList([
460
+ AirNetExpert(in_shape, out_shape, prm, device),
461
+ BagNetExpert(in_shape, out_shape, prm, device),
462
+ DPN68Expert(in_shape, out_shape, prm, device),
463
+ DarkNetExpert(in_shape, out_shape, prm, device),
464
+ ])
465
+ self.gate = HeterogeneousGate(in_shape[1], n_experts=n_experts)
466
+
467
+ self.load_balance_weight = 0.01
468
+ self.label_smoothing = 0.1
469
+ self.mixup_alpha = 0.2
470
+ self.to(device)
471
+
472
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
473
+ gate_weights, _ = self.gate(x)
474
+ expert_outputs = torch.stack([e(x) for e in self.experts], dim=2)
475
+ return torch.sum(expert_outputs * gate_weights.unsqueeze(1), dim=2)
476
+
477
+ def _load_balance_loss(self):
478
+ if not hasattr(self, '_last_gw'):
479
+ return torch.tensor(0.0, device=self.device)
480
+ gw = self._last_gw
481
+ usage = gw.sum(dim=0)
482
+ target = gw.sum() / len(self.experts)
483
+ return F.mse_loss(usage, target.expand_as(usage))
484
+
485
+ def _mixup_data(self, x, y):
486
+ lam = np.random.beta(self.mixup_alpha, self.mixup_alpha) if self.mixup_alpha > 0 else 1.0
487
+ idx = torch.randperm(x.size(0), device=self.device)
488
+ return lam * x + (1 - lam) * x[idx], y, y[idx], lam
489
+
490
+ def train_setup(self, prm):
491
+ self.to(self.device)
492
+ self.criteria = nn.CrossEntropyLoss(label_smoothing=self.label_smoothing)
493
+ expert_params, gate_params = [], list(self.gate.parameters())
494
+ for e in self.experts:
495
+ expert_params.extend(list(e.parameters()))
496
+ self.optimizer = torch.optim.AdamW([
497
+ {'params': expert_params, 'lr': prm.get('lr', 0.001), 'weight_decay': 5e-4},
498
+ {'params': gate_params, 'lr': prm.get('lr', 0.001) * 2, 'weight_decay': 2.5e-4},
499
+ ])
500
+ self.warmup_scheduler = torch.optim.lr_scheduler.LinearLR(
501
+ self.optimizer, start_factor=0.1, total_iters=5
502
+ )
503
+ self.main_scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
504
+ self.optimizer, T_max=50, eta_min=1e-6
505
+ )
506
+ self._current_epoch = 0
507
+
508
+ def learn(self, train_data):
509
+ self.train()
510
+ for inputs, labels in train_data:
511
+ inputs = inputs.to(self.device, dtype=torch.float32)
512
+ labels = labels.to(self.device, dtype=torch.long)
513
+ if self.mixup_alpha > 0:
514
+ inputs, labels_a, labels_b, lam = self._mixup_data(inputs, labels)
515
+ self.optimizer.zero_grad()
516
+ outputs = self(inputs)
517
+ loss = lam * self.criteria(outputs, labels_a) + (1 - lam) * self.criteria(outputs, labels_b)
518
+ else:
519
+ self.optimizer.zero_grad()
520
+ outputs = self(inputs)
521
+ loss = self.criteria(outputs, labels)
522
+ self._last_gw = self.gate(inputs)[0].detach()
523
+ loss = loss + self.load_balance_weight * self._load_balance_loss()
524
+ loss.backward()
525
+ nn.utils.clip_grad_norm_(self.parameters(), 1.0)
526
+ self.optimizer.step()
527
+ self._current_epoch += 1
528
+ if self._current_epoch <= 5:
529
+ self.warmup_scheduler.step()
530
+ else:
531
+ self.main_scheduler.step()
532
+
test/nn/alt-nn1-f49a24e1253f3039135ce0fdebed8697.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from torch.nn import GELU
4
+
5
+ def supported_hyperparameters():
6
+ return {'lr', 'momentum', 'dropout'}
7
+
8
+
9
+ class Net(nn.Module):
10
+ def train_setup(self, prm):
11
+ self.to(self.device)
12
+ self.criteria = (nn.CrossEntropyLoss().to(self.device),)
13
+ self.optimizer = torch.optim.SGD(
14
+ self.parameters(),
15
+ lr=prm['lr'],
16
+ momentum=prm['momentum']
17
+ )
18
+
19
+ def learn(self, train_data):
20
+ self.train()
21
+ for inputs, labels in train_data:
22
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
23
+ self.optimizer.zero_grad()
24
+ outputs = self(inputs)
25
+ loss = self.criteria[0](outputs, labels)
26
+ loss.backward()
27
+ torch.nn.utils.clip_grad_norm_(self.parameters(), 3)
28
+ self.optimizer.step()
29
+
30
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
31
+ super().__init__()
32
+ self.device = device
33
+ layers = []
34
+ in_channels = in_shape[1]
35
+
36
+ layers += [
37
+ nn.Conv2d(in_channels, 96, kernel_size=7,
38
+ stride=3, padding=2),
39
+ GELU(),
40
+ nn.MaxPool2d(kernel_size=2, stride=2),
41
+ ]
42
+ in_channels = 96
43
+
44
+ layers += [
45
+ nn.Conv2d(in_channels, 192, kernel_size=3, padding=2),
46
+ GELU(),
47
+ nn.MaxPool2d(kernel_size=2, stride=2),
48
+ ]
49
+ in_channels = 192
50
+
51
+ layers += [
52
+ nn.Conv2d(in_channels, 384, kernel_size=3, padding=1),
53
+ GELU(),
54
+ ]
55
+ in_channels = 384
56
+
57
+ layers += [
58
+ nn.Conv2d(in_channels, 256, kernel_size=3, padding=1),
59
+ GELU(),
60
+ ]
61
+ in_channels = 256
62
+
63
+ layers += [
64
+ nn.Conv2d(in_channels, 256, kernel_size=3, padding=1),
65
+ GELU(),
66
+ nn.MaxPool2d(kernel_size=2, stride=2),
67
+ ]
68
+ in_channels = 256
69
+ self.features = nn.Sequential(*layers)
70
+ self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
71
+
72
+ dropout_p = prm['dropout']
73
+ classifier_input_features = in_channels * 6 * 6
74
+ self.classifier = nn.Sequential(
75
+ nn.Dropout(p=dropout_p),
76
+ nn.Linear(classifier_input_features, 4096),
77
+ GELU(),
78
+ nn.Dropout(p=dropout_p),
79
+ nn.Linear(4096, 2048),
80
+ GELU(),
81
+ nn.Linear(2048, out_shape[0]),
82
+ )
83
+
84
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
85
+ x = self.features(x)
86
+ x = self.avgpool(x)
87
+ x = torch.flatten(x, 1)
88
+ x = self.classifier(x)
89
+ return x
test/nn/alt-nn2-54f7346afec7cd2c53b2f5654e8c7da9.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+ def supported_hyperparameters():
5
+ return {'lr', 'momentum', 'dropout'}
6
+
7
+ class Net(nn.Module):
8
+
9
+ def train_setup(self, prm):
10
+ self.to(self.device)
11
+ self.criteria = (nn.CrossEntropyLoss().to(self.device),)
12
+ self.optimizer = torch.optim.SGD(
13
+ self.parameters(),
14
+ lr=prm['lr'],
15
+ momentum=prm['momentum']
16
+ )
17
+
18
+ def learn(self, train_data):
19
+ self.train()
20
+ for inputs, labels in train_data:
21
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
22
+ self.optimizer.zero_grad()
23
+ outputs = self(inputs)
24
+ loss = self.criteria[0](outputs, labels)
25
+ loss.backward()
26
+ nn.utils.clip_grad_norm_(self.parameters(), 3)
27
+ self.optimizer.step()
28
+
29
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
30
+ super().__init__()
31
+ self.device = device
32
+ layers = []
33
+ in_channels = in_shape[1]
34
+
35
+ layers += [
36
+ nn.Conv2d(in_channels, 64, kernel_size=7, stride=3, padding=2),
37
+ nn.ReLU(inplace=True),
38
+ nn.MaxPool2d(kernel_size=2, stride=2)
39
+ ]
40
+ in_channels = 64
41
+
42
+ layers += [
43
+ nn.Conv2d(in_channels, 192, kernel_size=3, padding=2),
44
+ nn.ReLU(inplace=True),
45
+ nn.MaxPool2d(kernel_size=2, stride=2)
46
+ ]
47
+ in_channels = 192
48
+
49
+ layers += [
50
+ nn.Conv2d(in_channels, 384, kernel_size=3, padding=1),
51
+ nn.ReLU(inplace=True),
52
+ ]
53
+ in_channels = 384
54
+
55
+ layers += [
56
+ nn.Conv2d(in_channels, 384, kernel_size=3, padding=1),
57
+ nn.ReLU(inplace=True),
58
+ ]
59
+ in_channels = 384
60
+
61
+ layers += [
62
+ nn.Conv2d(in_channels, 256, kernel_size=3, padding=1),
63
+ nn.ReLU(inplace=True),
64
+ nn.MaxPool2d(kernel_size=2, stride=2)
65
+ ]
66
+ in_channels = 256
67
+
68
+ self.features = nn.Sequential(*layers)
69
+ self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
70
+
71
+ dropout_p = prm['dropout']
72
+ classifier_input_features = in_channels * 6 * 6
73
+ self.classifier = nn.Sequential(
74
+ nn.Dropout(p=dropout_p),
75
+ nn.Linear(classifier_input_features, 3072),
76
+ nn.ReLU(inplace=True),
77
+ nn.Dropout(p=dropout_p),
78
+ nn.Linear(3072, 3072),
79
+ nn.ReLU(inplace=True),
80
+ nn.Linear(3072, out_shape[0])
81
+ )
82
+
83
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
84
+ x = self.features(x)
85
+ x = self.avgpool(x)
86
+ x = torch.flatten(x, 1)
87
+ x = self.classifier(x)
88
+ return x
89
+
90
+
91
+
92
+ addon_accuracy: 0.7753
test/nn/ga-524.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+
5
+ def supported_hyperparameters():
6
+ return {'lr', 'momentum', 'dropout'}
7
+
8
+
9
+ class Net(nn.Module):
10
+ def train_setup(self, prm):
11
+ self.to(self.device)
12
+ self.criteria = (nn.CrossEntropyLoss().to(self.device),)
13
+ self.optimizer = torch.optim.SGD(
14
+ self.parameters(),
15
+ lr=prm['lr'],
16
+ momentum=prm['momentum']
17
+ )
18
+
19
+ def learn(self, train_data):
20
+ self.train()
21
+ for inputs, labels in train_data:
22
+ inputs, labels = inputs.to(self.device), labels.to(self.device)
23
+ self.optimizer.zero_grad()
24
+ outputs = self(inputs)
25
+ loss = self.criteria[0](outputs, labels)
26
+ loss.backward()
27
+ torch.nn.utils.clip_grad_norm_(self.parameters(), 3)
28
+ self.optimizer.step()
29
+
30
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
31
+ super().__init__()
32
+ self.device = device
33
+ layers = []
34
+ in_channels = in_shape[1]
35
+
36
+ layers += [
37
+ nn.Conv2d(in_channels, 64, kernel_size=7,
38
+ stride=3, padding=2),
39
+ nn.ReLU(inplace=True),
40
+ nn.MaxPool2d(kernel_size=2, stride=2),
41
+ ]
42
+ in_channels = 64
43
+
44
+ layers += [
45
+ nn.Conv2d(in_channels, 192, kernel_size=3, padding=2),
46
+ nn.ReLU(inplace=True),
47
+ nn.MaxPool2d(kernel_size=2, stride=2),
48
+ ]
49
+ in_channels = 192
50
+
51
+ layers += [
52
+ nn.Conv2d(in_channels, 440, kernel_size=3, padding=1),
53
+ nn.ReLU(inplace=True),
54
+ ]
55
+ in_channels = 440
56
+
57
+ layers += [
58
+ nn.Conv2d(in_channels, 384, kernel_size=3, padding=1),
59
+ nn.ReLU(inplace=True),
60
+ ]
61
+ in_channels = 384
62
+
63
+ layers += [
64
+ nn.Conv2d(in_channels, 192, kernel_size=3, padding=1),
65
+ nn.ReLU(inplace=True),
66
+ nn.MaxPool2d(kernel_size=2, stride=2),
67
+ ]
68
+ in_channels = 192
69
+ self.features = nn.Sequential(*layers)
70
+ self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
71
+
72
+ dropout_p = prm['dropout']
73
+ classifier_input_features = in_channels * 6 * 6
74
+ self.classifier = nn.Sequential(
75
+ nn.Dropout(p=dropout_p),
76
+ nn.Linear(classifier_input_features, 2048),
77
+ nn.ReLU(inplace=True),
78
+ nn.Dropout(p=dropout_p),
79
+ nn.Linear(2048, 4096),
80
+ nn.ReLU(inplace=True),
81
+ nn.Linear(4096, out_shape[0]),
82
+ )
83
+
84
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
85
+ x = self.features(x)
86
+ x = self.avgpool(x)
87
+ x = torch.flatten(x, 1)
88
+ x = self.classifier(x)
89
+ return x
90
+
91
+ # --- Chromosome used to generate this model ---
92
+ # Chromosome: {'conv1_filters': 64, 'conv1_kernel': 7, 'conv1_stride': 3, 'conv2_filters': 192, 'conv2_kernel': 3, 'conv3_filters': 440, 'conv4_filters': 384, 'conv5_filters': 192, 'fc1_neurons': 2048, 'fc2_neurons': 4096, 'lr': 0.01, 'momentum': 0.95, 'dropout': 0.4}
test/nn/rl-bb-init-b4de916c853aa8113c079065856dc78a.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import numpy as np
4
+ import gc
5
+ import torchvision
6
+ from torch.nn import MaxPool2d
7
+ from torch.amp import autocast, GradScaler
8
+
9
+ # -------------------------------------------------
10
+ # Wrapper & Helpers
11
+ # -------------------------------------------------
12
+ class TorchVision(nn.Module):
13
+ def __init__(self, model: str, weights: str = "DEFAULT", unwrap: bool = True, truncate: int = 1, in_channels: int = 3):
14
+ super().__init__()
15
+ self.adapter = nn.Conv2d(in_channels, 3, kernel_size=1) if in_channels != 3 else nn.Identity()
16
+ if hasattr(torchvision.models, "get_model"):
17
+ self.m = torchvision.models.get_model(model, weights=weights)
18
+ else:
19
+ self.m = torchvision.models.__dict__[model](pretrained=bool(weights))
20
+ if unwrap:
21
+ layers = []
22
+ for name, module in self.m.named_children():
23
+ if "aux" in name.lower(): continue
24
+ layers.append(module)
25
+ self.m = nn.Sequential(*(layers[:-truncate] if truncate else layers))
26
+ else:
27
+ self.m.head = nn.Identity()
28
+
29
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
30
+ if x.dim() == 2:
31
+ x = x.unsqueeze(-1).unsqueeze(-1)
32
+ return self.m(self.adapter(x))
33
+
34
+ def adaptive_pool_flatten(x):
35
+ if x.ndim == 4: return torch.nn.functional.adaptive_avg_pool2d(x, (1, 1)).flatten(1)
36
+ if x.ndim == 3: return x.mean(dim=1)
37
+ return x.flatten(1) if x.ndim > 2 else x
38
+
39
+ # -------------------------------------------------
40
+ # AMP / Hyperparams
41
+ # -------------------------------------------------
42
+ from torch.amp import autocast, GradScaler
43
+ def autocast_ctx(enabled=True):
44
+ return autocast("cuda", enabled=enabled)
45
+ def make_scaler(enabled=True):
46
+ return GradScaler("cuda", enabled=enabled)
47
+
48
+ def supported_hyperparameters():
49
+ return { 'lr', 'dropout', 'momentum' }
50
+
51
+ # -------------------------------------------------
52
+ # Generated Conv Block (Crucial Fix)
53
+ # -------------------------------------------------
54
+ def drop_conv3x3_block(in_channels, out_channels, stride=1, padding=1, bias=False, dropout_prob=0.0):
55
+ return nn.Sequential(
56
+ nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=padding, bias=bias),
57
+ nn.GELU(),
58
+ nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=bias),
59
+ nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=bias),
60
+ nn.Dropout2d(p=dropout_prob) if dropout_prob > 0 else nn.Identity()
61
+ )
62
+
63
+ # -------------------------------------------------
64
+ # Fractal Components (Using drop_conv3x3_block)
65
+ # -------------------------------------------------
66
+ class FractalBlock(nn.Module):
67
+ def __init__(self, in_channels, out_channels, num_columns, loc_drop_prob, dropout_prob):
68
+ super().__init__()
69
+ self.num_columns = int(num_columns)
70
+ depth = 2 ** max(self.num_columns - 1, 0)
71
+ blocks = []
72
+ for i in range(depth):
73
+ level = nn.ModuleList()
74
+ for j in range(self.num_columns):
75
+ if (i + 1) % (2 ** j) == 0:
76
+ in_ch_ij = in_channels if (i + 1 == 2 ** j) else out_channels
77
+ level.append(drop_conv3x3_block(in_ch_ij, out_channels, dropout_prob=dropout_prob))
78
+ blocks.append(level)
79
+ self.blocks = nn.ModuleList(blocks)
80
+ self.use_checkpoint_per_subblock = False
81
+
82
+ def forward(self, x):
83
+ outs = [x] * self.num_columns
84
+ for level_block in self.blocks:
85
+ outs_i = [blk(inp) for blk, inp in zip(level_block, outs)]
86
+ joined = torch.stack(outs_i, dim=0).mean(dim=0)
87
+ outs[:len(level_block)] = [joined] * len(level_block)
88
+ return outs[0]
89
+
90
+ class FractalUnit(nn.Module):
91
+ def __init__(self, in_channels, out_channels, num_columns, loc_drop_prob, dropout_prob):
92
+ super().__init__()
93
+ self.block = FractalBlock(in_channels, out_channels, num_columns, loc_drop_prob, dropout_prob)
94
+ self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
95
+
96
+ def forward(self, x):
97
+ return self.pool(self.block(x))
98
+
99
+ # -------------------------------------------------
100
+ # Net (Dynamic Fusion Architecture)
101
+ # -------------------------------------------------
102
+ class Net(nn.Module):
103
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
104
+ super().__init__()
105
+ self.device = device
106
+ self.pattern = "Split_A_Parallel_BF"
107
+ self.use_amp = prm.get("use_amp", False)
108
+ dropout_prob = float(prm.get('dropout', 0.1))
109
+
110
+ # --- Filled by Generator ---
111
+ self.backbone_a = TorchVision("mnasnet1_0", in_channels=3).to(device)
112
+
113
+ self.features = nn.Sequential()
114
+ curr_ch = 912
115
+ channels = [64 * (2 ** i) for i in range(1)]
116
+ for i, out_ch in enumerate(channels):
117
+ self.features.add_module(f"unit{i+1}", FractalUnit(curr_ch, out_ch, 3, 0.15, dropout_prob))
118
+ curr_ch = out_ch
119
+
120
+ self.backbone_b = TorchVision("regnet_x_1_6gf", in_channels=3).to(device)
121
+
122
+ self.infer_dimensions_dynamically(in_shape, out_shape[0])
123
+ self._scaler = GradScaler("cuda", enabled=self.use_amp)
124
+
125
+ def infer_dimensions_dynamically(self, in_shape, num_classes):
126
+ self.to(self.device)
127
+ self.eval()
128
+ with torch.no_grad():
129
+ C = in_shape[1] if len(in_shape)==4 else in_shape[0]
130
+ dummy = torch.zeros(1, C, 224, 224).to(self.device)
131
+ output_feat = self.forward(dummy, is_probing=True)
132
+ dim_fused = output_feat.shape[1]
133
+
134
+ self.classifier = nn.Linear(dim_fused, num_classes)
135
+ self.train()
136
+
137
+ def _init_params(self):
138
+ for m in self.features.modules():
139
+ if isinstance(m, nn.Conv2d):
140
+ nn.init.kaiming_uniform_(m.weight, a=np.sqrt(5))
141
+ if m.bias is not None: nn.init.zeros_(m.bias)
142
+
143
+ @staticmethod
144
+ def _norm4d(x: torch.Tensor) -> torch.Tensor:
145
+ if x.dim() == 4: return x
146
+ if x.dim() == 5:
147
+ B, T, C, H, W = x.shape
148
+ return x.reshape(B * T, C, H, W)
149
+ raise ValueError(f"Expected 4D/5D input, got {tuple(x.shape)}")
150
+
151
+
152
+ def forward(self, x: torch.Tensor, is_probing: bool = False) -> torch.Tensor:
153
+ x = self._norm4d(x).to(self.device)
154
+
155
+ f_a = adaptive_pool_flatten(self.backbone_a(x))
156
+
157
+ x_bf = self.backbone_b(x)
158
+ if x_bf.dim() == 2:
159
+ x_bf = x_bf.unsqueeze(-1).unsqueeze(-1)
160
+ if x_bf.shape[-1] < 14:
161
+ x_bf = torch.nn.functional.interpolate(x_bf, size=(14,14), mode='nearest')
162
+
163
+ f_bf = adaptive_pool_flatten(self.features(x_bf))
164
+ fused = torch.cat([f_a, f_bf], dim=1)
165
+ if is_probing: return fused
166
+ return self.classifier(fused)
167
+
168
+
169
+ def train_setup(self, prm):
170
+ self.to(self.device)
171
+ self.criterion = nn.CrossEntropyLoss().to(self.device)
172
+ self.optimizer = torch.optim.SGD(
173
+ self.parameters(),
174
+ lr=prm['lr'],
175
+ momentum=prm['momentum']
176
+ )
177
+ self._scaler = make_scaler(enabled=self.use_amp)
178
+
179
+ def learn(self, train_data):
180
+ self.train()
181
+ scaler = self._scaler
182
+ train_iter = iter(train_data)
183
+ try:
184
+ for batch_idx, (inputs, labels) in enumerate(train_iter):
185
+ inputs = inputs.to(self.device).float()
186
+ labels = labels.to(self.device)
187
+ self.optimizer.zero_grad(set_to_none=True)
188
+
189
+ with autocast_ctx(enabled=self.use_amp):
190
+ outputs = self(inputs)
191
+ loss = self.criterion(outputs, labels)
192
+
193
+ if not torch.isfinite(loss):
194
+ continue
195
+
196
+ if self.use_amp:
197
+ scaler.scale(loss).backward()
198
+ scaler.unscale_(self.optimizer)
199
+ nn.utils.clip_grad_norm_(self.parameters(), 3.0)
200
+ scaler.step(self.optimizer)
201
+ scaler.update()
202
+ else:
203
+ loss.backward()
204
+ nn.utils.clip_grad_norm_(self.parameters(), 3.0)
205
+ self.optimizer.step()
206
+ finally:
207
+ if hasattr(train_iter, 'shutdown'):
208
+ train_iter.shutdown()
209
+ del train_iter
210
+ gc.collect()
test/nn/unq-03221882bffefdd92eb8ae1d1fb46b22.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+ def supported_hyperparameters():
5
+ return {'lr', 'momentum'}
6
+
7
+ class Net(nn.Module):
8
+ def __init__(self, in_shape: tuple, out_shape: tuple, prm: dict, device: torch.device) -> None:
9
+ super().__init__()
10
+ self.device = device
11
+ self.in_channels = in_shape[1]
12
+ self.num_classes = out_shape[0]
13
+ self.learning_rate = prm.get('lr', 0.01)
14
+ self.momentum = prm.get('momentum', 0.9)
15
+
16
+ self.features = nn.Sequential(
17
+ nn.Conv2d(self.in_channels, 64, kernel_size=3, stride=1, padding=1),
18
+ nn.BatchNorm2d(64),
19
+ nn.ReLU(inplace=True),
20
+ nn.MaxPool2d(kernel_size=2, stride=2),
21
+ nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
22
+ nn.BatchNorm2d(128),
23
+ nn.ReLU(inplace=True),
24
+ nn.MaxPool2d(kernel_size=2, stride=2),
25
+ )
26
+
27
+ self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
28
+
29
+ self.classifier = nn.Sequential(
30
+ nn.Dropout(p=prm.get('dropout', 0.5)),
31
+ nn.Linear(128 * 6 * 6, 4096),
32
+ nn.ReLU(inplace=True),
33
+ nn.Dropout(p=prm.get('dropout', 0.5)),
34
+ nn.Linear(4096, self.num_classes),
35
+ )
36
+
37
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
38
+ x = self.features(x)
39
+ x = self.avgpool(x)
40
+ x = torch.flatten(x, 1)
41
+ x = self.classifier(x)
42
+ return x
43
+
44
+ def train_setup(self, prm):
45
+ self.to(self.device)
46
+ self.criteria = (nn.CrossEntropyLoss().to(self.device),)
47
+ self.optimizer = torch.optim.SGD(
48
+ self.parameters(),
49
+ lr=prm.get('lr', 0.01),
50
+ momentum=prm.get('momentum', 0.9),
51
+ )
52
+
53
+ def learn(self, train_data):
54
+ self.train()
55
+ for inputs, labels in train_data:
56
+ inputs = inputs.to(self.device)
57
+ labels = labels.to(self.device)
58
+ self.optimizer.zero_grad()
59
+ outputs = self(inputs)
60
+ loss = self.criteria[0](outputs, labels)
61
+ loss.backward()
62
+ self.optimizer.step()