Skip to content

Commit 5dc8dd6

Browse files
net mapk
1 parent 460780d commit 5dc8dd6

3 files changed

Lines changed: 283 additions & 2 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
77

88
[project]
99
name = "spotPython"
10-
version = "0.6.47"
10+
version = "0.6.48"
1111
authors = [
1212
{ name="T. Bartz-Beielstein", email="tbb@bartzundbartz.de" }
1313
]

src/spotPython/data/light_hyper_dict.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"lower": 0,
8181
"upper": 2}
8282
},
83-
"NetLightBase":
83+
"NetLightBaseMAPK":
8484
{
8585
"l1": {
8686
"type": "int",
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
import lightning as L
2+
import torch
3+
import torch.nn.functional as F
4+
from torch import nn
5+
from torchmetrics.functional import accuracy
6+
from spotPython.torch.mapk import MAPK
7+
from spotPython.hyperparameters.optimizer import optimizer_handler
8+
9+
10+
class NetLightBaseMAPK(L.LightningModule):
11+
"""
12+
A LightningModule class for a neural network model.
13+
14+
Attributes:
15+
l1 (int):
16+
The number of neurons in the first hidden layer.
17+
epochs (int):
18+
The number of epochs to train the model for.
19+
batch_size (int):
20+
The batch size to use during training.
21+
initialization (str):
22+
The initialization method to use for the weights.
23+
act_fn (nn.Module):
24+
The activation function to use in the hidden layers.
25+
optimizer (str):
26+
The optimizer to use during training.
27+
dropout_prob (float):
28+
The probability of dropping out a neuron during training.
29+
lr_mult (float):
30+
The learning rate multiplier for the optimizer.
31+
patience (int):
32+
The number of epochs to wait before early stopping.
33+
_L_in (int):
34+
The number of input features.
35+
_L_out (int):
36+
The number of output classes.
37+
layers (nn.Sequential):
38+
The neural network model.
39+
40+
Examples:
41+
>>> from torch.utils.data import DataLoader
42+
>>> from torchvision.datasets import MNIST
43+
>>> from torchvision.transforms import ToTensor
44+
>>> train_data = MNIST(PATH_DATASETS,
45+
train=True,
46+
download=True,
47+
transform=ToTensor())
48+
>>> train_loader = DataLoader(train_data,
49+
batch_size=BATCH_SIZE)
50+
>>> net_light_base = NetLightBase(l1=128,
51+
epochs=10,
52+
batch_size=BATCH_SIZE,
53+
initialization='xavier',
54+
act_fn=nn.ReLU(),
55+
optimizer='Adam',
56+
dropout_prob=0.1,
57+
lr_mult=0.1,
58+
patience=5)
59+
>>> trainer = L.Trainer(max_epochs=10)
60+
>>> trainer.fit(net_light_base, train_loader)
61+
"""
62+
63+
def __init__(
64+
self,
65+
l1: int,
66+
epochs: int,
67+
batch_size: int,
68+
initialization: str,
69+
act_fn: nn.Module,
70+
optimizer: str,
71+
dropout_prob: float,
72+
lr_mult: float,
73+
patience: int,
74+
_L_in: int,
75+
_L_out: int,
76+
):
77+
"""
78+
Initializes the NetLightBase object.
79+
80+
Args:
81+
l1 (int): The number of neurons in the first hidden layer.
82+
epochs (int): The number of epochs to train the model for.
83+
batch_size (int): The batch size to use during training.
84+
initialization (str): The initialization method to use for the weights.
85+
act_fn (nn.Module): The activation function to use in the hidden layers.
86+
optimizer (str): The optimizer to use during training.
87+
dropout_prob (float): The probability of dropping out a neuron during training.
88+
lr_mult (float): The learning rate multiplier for the optimizer.
89+
patience (int): The number of epochs to wait before early stopping.
90+
_L_in (int): The number of input features. Not a hyperparameter, but needed to create the network.
91+
_L_out (int): The number of output classes. Not a hyperparameter, but needed to create the network.
92+
93+
Returns:
94+
(NoneType): None
95+
96+
Raises:
97+
ValueError: If l1 is less than 4.
98+
Examples:
99+
>>> from torch.utils.data import DataLoader
100+
>>> from torchvision.datasets import MNIST
101+
>>> from torchvision.transforms import ToTensor
102+
>>> train_data = MNIST(PATH_DATASETS, train=True, download=True, transform=ToTensor())
103+
>>> train_loader = DataLoader(train_data, batch_size=BATCH_SIZE)
104+
>>> net_light_base = NetLightBase(l1=128, epochs=10, batch_size=BATCH_SIZE,
105+
initialization='xavier', act_fn=nn.ReLU(),
106+
optimizer='Adam', dropout_prob=0.1, lr_mult=0.1,
107+
patience=5)
108+
>>> trainer = L.Trainer(max_epochs=10)
109+
>>> trainer.fit(net_light_base, train_loader)
110+
111+
"""
112+
super().__init__()
113+
# Attribute 'act_fn' is an instance of `nn.Module` and is already saved during
114+
# checkpointing. It is recommended to ignore them
115+
# using `self.save_hyperparameters(ignore=['act_fn'])`
116+
# self.save_hyperparameters(ignore=["act_fn"])
117+
#
118+
self._L_in = _L_in
119+
self._L_out = _L_out
120+
# _L_in and _L_out are not hyperparameters, but are needed to create the network
121+
self.save_hyperparameters(ignore=["_L_in", "_L_out"])
122+
if self.hparams.l1 < 4:
123+
raise ValueError("l1 must be at least 4")
124+
125+
hidden_sizes = [self.hparams.l1, self.hparams.l1 // 2, self.hparams.l1 // 2, self.hparams.l1 // 4]
126+
self.train_mapk = MAPK(k=3)
127+
self.valid_mapk = MAPK(k=3)
128+
self.test_mapk = MAPK(k=3)
129+
130+
# Create the network based on the specified hidden sizes
131+
layers = []
132+
layer_sizes = [self._L_in] + hidden_sizes
133+
layer_size_last = layer_sizes[0]
134+
for layer_size in layer_sizes[1:]:
135+
layers += [
136+
nn.Linear(layer_size_last, layer_size),
137+
self.hparams.act_fn,
138+
nn.Dropout(self.hparams.dropout_prob),
139+
]
140+
layer_size_last = layer_size
141+
layers += [nn.Linear(layer_sizes[-1], self._L_out)]
142+
# nn.Sequential summarizes a list of modules into a single module, applying them in sequence
143+
self.layers = nn.Sequential(*layers)
144+
145+
def forward(self, x: torch.Tensor) -> torch.Tensor:
146+
"""
147+
Performs a forward pass through the model.
148+
149+
Args:
150+
x (torch.Tensor): A tensor containing a batch of input data.
151+
152+
Returns:
153+
torch.Tensor: A tensor containing the probabilities for each class.
154+
Examples:
155+
>>> from torch.utils.data import DataLoader
156+
>>> from torchvision.datasets import MNIST
157+
>>> from torchvision.transforms import ToTensor
158+
>>> train_data = MNIST(PATH_DATASETS, train=True, download=True, transform=ToTensor())
159+
>>> train_loader = DataLoader(train_data, batch_size=BATCH_SIZE)
160+
>>> net_light_base = NetLightBase(l1=128,
161+
epochs=10,
162+
batch_size=BATCH_SIZE,
163+
initialization='xavier', act_fn=nn.ReLU(),
164+
optimizer='Adam', dropout_prob=0.1, lr_mult=0.1,
165+
patience=5)
166+
167+
"""
168+
x = self.layers(x)
169+
return F.softmax(x, dim=1)
170+
171+
def training_step(self, batch: tuple) -> torch.Tensor:
172+
"""
173+
Performs a single training step.
174+
175+
Args:
176+
batch (tuple): A tuple containing a batch of input data and labels.
177+
178+
Returns:
179+
torch.Tensor: A tensor containing the loss for this batch.
180+
Examples:
181+
>>> from torch.utils.data import DataLoader
182+
>>> from torchvision.datasets import MNIST
183+
>>> from torchvision.transforms import ToTensor
184+
>>> train_data = MNIST(PATH_DATASETS, train=True, download=True, transform=ToTensor())
185+
>>> train_loader = DataLoader(train_data, batch_size=BATCH_SIZE)
186+
>>> net_light_base = NetLightBase(l1=128,
187+
epochs=10,
188+
batch_size=BATCH_SIZE,
189+
initialization='xavier', act_fn=nn.ReLU(),
190+
optimizer='Adam', dropout_prob=0.1, lr_mult=0.1,
191+
patience=5)
192+
>>> trainer = L.Trainer(max_epochs=10)
193+
>>> trainer.fit(net_light_base, train_loader)
194+
195+
"""
196+
x, y = batch
197+
logits = self(x)
198+
# compute cross entropy loss from logits and y
199+
loss = F.cross_entropy(logits, y)
200+
# self.train_mapk(logits, y)
201+
# self.log("train_mapk", self.train_mapk, on_step=True, on_epoch=False)
202+
return loss
203+
204+
def validation_step(self, batch: tuple, batch_idx: int, prog_bar: bool = False):
205+
"""
206+
Performs a single validation step.
207+
208+
Args:
209+
batch (tuple): A tuple containing a batch of input data and labels.
210+
batch_idx (int): The index of the current batch.
211+
prog_bar (bool, optional): Whether to display the progress bar. Defaults to False.
212+
213+
Returns:
214+
(NoneType): None
215+
Examples:
216+
>>> from torch.utils.data import DataLoader
217+
>>> from torchvision.datasets import MNIST
218+
>>> from torchvision.transforms import ToTensor
219+
>>> val_data = MNIST(PATH_DATASETS, train=False, download=True, transform=ToTensor())
220+
>>> val_loader = DataLoader(val_data, batch_size=BATCH_SIZE)
221+
>>> net_light_base = NetLightBase(l1=128,
222+
epochs=10,
223+
batch_size=BATCH_SIZE,
224+
initialization='xavier', act_fn=nn.ReLU(),
225+
optimizer='Adam', dropout_prob=0.1, lr_mult=0.1,
226+
patience=5)
227+
>>> trainer = L.Trainer(max_epochs=10)
228+
>>> trainer.fit(net_light_base, val_loader)
229+
230+
"""
231+
x, y = batch
232+
logits = self(x)
233+
# compute cross entropy loss from logits and y
234+
loss = F.cross_entropy(logits, y)
235+
# loss = F.nll_loss(logits, y)
236+
preds = torch.argmax(logits, dim=1)
237+
acc = accuracy(preds, y, task="multiclass", num_classes=self._L_out)
238+
self.valid_mapk(logits, y)
239+
self.log("valid_mapk", self.valid_mapk, on_step=False, on_epoch=True, prog_bar=prog_bar)
240+
self.log("val_loss", loss, prog_bar=prog_bar)
241+
self.log("val_acc", acc, prog_bar=prog_bar)
242+
self.log("hp_metric", loss, prog_bar=prog_bar)
243+
244+
def test_step(self, batch: tuple, batch_idx: int, prog_bar: bool = False) -> tuple:
245+
"""
246+
Performs a single test step.
247+
248+
Args:
249+
batch (tuple): A tuple containing a batch of input data and labels.
250+
batch_idx (int): The index of the current batch.
251+
prog_bar (bool, optional): Whether to display the progress bar. Defaults to False.
252+
253+
Returns:
254+
tuple: A tuple containing the loss and accuracy for this batch.
255+
"""
256+
x, y = batch
257+
logits = self(x)
258+
# compute cross entropy loss from logits and y
259+
loss = F.cross_entropy(logits, y)
260+
preds = torch.argmax(logits, dim=1)
261+
acc = accuracy(preds, y, task="multiclass", num_classes=self._L_out)
262+
self.test_mapk(logits, y)
263+
self.log("test_mapk", self.test_mapk, on_step=True, on_epoch=True, prog_bar=prog_bar)
264+
self.log("val_loss", loss, prog_bar=prog_bar)
265+
self.log("val_acc", acc, prog_bar=prog_bar)
266+
self.log("hp_metric", loss, prog_bar=prog_bar)
267+
return loss, acc
268+
269+
def configure_optimizers(self) -> torch.optim.Optimizer:
270+
"""
271+
Configures the optimizer for the model.
272+
273+
Returns:
274+
torch.optim.Optimizer: The optimizer to use during training.
275+
276+
"""
277+
# optimizer = torch.optim.Adam(self.parameters(), lr=self.learning_rate)
278+
optimizer = optimizer_handler(
279+
optimizer_name=self.hparams.optimizer, params=self.parameters(), lr_mult=self.hparams.lr_mult
280+
)
281+
return optimizer

0 commit comments

Comments
 (0)