NeuralNetworks 0.1.12__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,51 @@
1
+ # NeuralNetworksBeta - Multi-Layer Perceptrons avec encodage Fourier
2
+ # Copyright (C) 2025 Alexandre Brun
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ from .Dependances import *
9
+
10
+ class Latent(nn.Module):
11
+ def __init__(self, insize, outsize):
12
+ super().__init__()
13
+
14
+ self.insize = insize
15
+ self.outsize = outsize
16
+
17
+ # Start latent conv channels
18
+ channels = 128
19
+
20
+ # ----- Encoder -----
21
+ layers = []
22
+ for k in range(5):
23
+ layers.append(nn.Conv2d(channels, channels // 2, kernel_size=3, padding=1))
24
+ channels = channels // 2
25
+ layers.append(nn.BatchNorm2d(channels))
26
+ layers.append(nn.ReLU(inplace=True))
27
+ layers.append(nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
28
+
29
+ layers.append(nn.Flatten())
30
+ layers.append(nn.Linear(channels * 1 * 1, outsize)) # adjust if spatial dims not 1x1
31
+
32
+ self.Emodel = nn.Sequential(*layers).to(device)
33
+
34
+ # ----- Decoder -----
35
+ layers = []
36
+ layers.append(nn.Linear(outsize, channels)) # output same number of channels
37
+ layers.append(nn.Unflatten(1, (channels, 1, 1)))
38
+
39
+ for k in range(5):
40
+ layers.append(nn.ConvTranspose2d(channels, channels * 2, kernel_size=3, stride=2, padding=1, output_padding=1))
41
+ channels = channels * 2
42
+ layers.append(nn.BatchNorm2d(channels))
43
+ layers.append(nn.ReLU(inplace=True))
44
+
45
+ self.Dmodel = nn.Sequential(*layers).to(device)
46
+
47
+ def encode(self, image):
48
+ return self.Emodel(image)
49
+
50
+ def decode(self, vector):
51
+ return self.Dmodel(vector)
NeuralNetworks/MLP.py CHANGED
@@ -28,12 +28,14 @@ class MLP():
28
28
  Dimensions successives du réseau (entrée → couches cachées → sortie).
29
29
  Exemple : [in_features, hidden1, hidden2, ..., out_features].
30
30
  Default: [1, 1, 1]
31
- learning_rate : float, optional
32
- Taux d’apprentissage pour l’optimiseur.
31
+ init_lr : float, optional
32
+ Taux d’apprentissage initial pour l’optimiseur.
33
33
  Default: 1e-3
34
- Fourier : bool, optional
35
- Si True, applique un encodage Fourier gaussien (RFF) sur les entrées.
36
- Default: True
34
+ Fourier : list[float] or None, optional
35
+ Liste de valeurs sigma pour appliquer plusieurs encodages RFF
36
+ (Random Fourier Features).
37
+ Si None : aucune transformation, l’entrée est passée via nn.Identity().
38
+ Chaque sigma ajoute un encodage distinct et double la dimension d’entrée.
37
39
  optim : str, optional
38
40
  Nom de l’optimiseur à utiliser (doit exister dans `optim_list`).
39
41
  Default: "ADAM"
@@ -56,8 +58,9 @@ class MLP():
56
58
  Historique des pertes cumulées lors de l'entraînement.
57
59
  layers : list[int]
58
60
  Dimensions du réseau, ajustées si encodage Fourier actif.
59
- encoding : nn.Module
60
- Module appliquant l'encodage des entrées (RFF ou identity).
61
+ encodings : list[nn.Module]
62
+ Liste de modules RFF GaussianEncoding ou Identity appliqués aux entrées.
63
+ Un module par valeur sigma dans `Fourier`.
61
64
  norm : nn.Module
62
65
  Normalisation ou activation utilisée dans les couches cachées.
63
66
  crit : nn.Module
@@ -98,57 +101,69 @@ class MLP():
98
101
  - Le suivi des pertes permet d’afficher l’évolution du training loss.
99
102
  """
100
103
 
101
- def __init__(self, layers=[1,1,1], learning_rate=1e-3, Fourier=True,
104
+ def __init__(self, layers=[1,1,1], init_lr=1e-3, Fourier=None,
102
105
  optim="Adam", crit="MSE", norm="Relu",
103
106
  name="Net", Iscompiled=False):
104
107
  """
105
- Initialise un réseau MLP avec options avancées : encodage Fourier,
106
- normalisation, choix d’optimiseur et de fonction de perte, et compilation.
108
+ Initialise un réseau MLP flexible avec support multi-encodage Fourier,
109
+ choix d’activation, perte, optimiseur, et compilation optionnelle.
107
110
 
108
111
  Parameters
109
112
  ----------
110
113
  layers : list[int], optional
111
114
  Dimensions successives du réseau (entrée → couches cachées → sortie).
115
+ Le premier élément est utilisé comme input_size avant encodage Fourier.
112
116
  Default: [1, 1, 1]
113
- learning_rate : float, optional
114
- Taux d’apprentissage pour l’optimiseur (default: 1e-3).
115
- Fourier : bool, optional
116
- Si True, applique un encodage RFF (Random Fourier Features) sur les entrées.
117
- Default: True
117
+ init_lr : float, optional
118
+ Taux d’apprentissage initial pour l’optimiseur.
119
+ Default: 1e-3
120
+ Fourier : list[float] or None, optional
121
+ Liste de valeurs sigma pour appliquer plusieurs encodages RFF
122
+ (Random Fourier Features).
123
+ Si None : aucune transformation, l’entrée est passée via nn.Identity().
124
+ Chaque sigma ajoute un encodage distinct et double la dimension d’entrée.
118
125
  optim : str, optional
119
- Nom de l’optimiseur à utiliser (doit être présent dans `optim_list`).
126
+ Nom de l’optimiseur (doit appartenir à `optim_list(self, init_lr)`).
120
127
  Default: "Adam"
121
128
  crit : str, optional
122
- Nom de la fonction de perte à utiliser (doit être présent dans `crit_list`).
129
+ Nom de la fonction de perte (doit appartenir à `crit_list`).
123
130
  Default: "MSE"
124
131
  norm : str, optional
125
- Type de normalisation / activation à appliquer entre les couches cachées.
132
+ Nom de la fonction d’activation entre couches cachées
133
+ (doit appartenir à `norm_list`).
126
134
  Default: "Relu"
127
135
  name : str, optional
128
- Nom du réseau (pour identification et affichage).
136
+ Nom du modèle, utilisé pour l’identification.
129
137
  Default: "Net"
130
138
  Iscompiled : bool, optional
131
- Si True, compile le modèle avec `torch.compile` pour accélérer l’inférence.
132
- Default: True
139
+ Si True, compile le MLP avec `torch.compile` pour accélérer l’inférence.
140
+ Si GCC est absent, la compilation est automatiquement désactivée.
141
+ Default: False
133
142
 
134
143
  Attributes
135
144
  ----------
136
145
  losses : list
137
- Historique des pertes durant l’entraînement.
146
+ Historique des pertes pendant l’entraînement.
138
147
  layers : list[int]
139
- Dimensions du réseau après ajustement pour encodage Fourier.
140
- encoding : nn.Module
141
- Module appliquant l’encodage des entrées (RFF ou identité).
148
+ Dimensions du réseau, modifiées si un encodage Fourier est appliqué
149
+ (l’entrée devient 2 * encoded_size).
150
+ encodings : list[nn.Module]
151
+ Liste de modules RFF GaussianEncoding ou Identity appliqués aux entrées.
152
+ Un module par valeur sigma dans `Fourier`.
142
153
  norm : nn.Module
143
- Normalisation / activation utilisée entre les couches cachées.
154
+ Fonction d’activation utilisée dans les couches cachées.
144
155
  crit : nn.Module
145
- Fonction de perte PyTorch sur GPU.
156
+ Fonction de perte PyTorch.
146
157
  model : nn.Sequential
147
- MLP complet construit dynamiquement.
158
+ Réseau MLP construit dynamiquement via `Create_MLP()`.
148
159
  optim : torch.optim.Optimizer
149
160
  Optimiseur associé au MLP.
150
161
  name : str
151
162
  Nom du réseau.
163
+ f : nn.Linear
164
+ Couche linéaire appliquée après le MLP, prenant en entrée
165
+ (nb_encodings * layers[-1]) et renvoyant layers[-1].
166
+ Utilisée pour agréger les sorties des différents encodages.
152
167
  """
153
168
 
154
169
  super().__init__()
@@ -158,16 +173,18 @@ class MLP():
158
173
  self.name = name
159
174
 
160
175
  # --- Encodage Fourier (RFF) ou passthrough ---
161
- if self.Fourier:
162
- self.encoding = rff.layers.GaussianEncoding(
163
- sigma=10.0,
164
- input_size=self.layers[0],
165
- encoded_size=self.layers[1]
166
- ).to(device)
167
- self.layers[0] = self.layers[1] * 2 # chaque entrée est doublée après encodage
176
+ self.encodings = []
177
+ if self.Fourier is None:
178
+ self.encodings.append(nn.Identity().to(device)) # passthrough si pas de Fourier
168
179
  else:
169
- self.encoding = nn.Identity().to(device) # passthrough si pas de Fourier
170
-
180
+ for sigma_val in Fourier:
181
+ self.encodings.append(rff.layers.GaussianEncoding(
182
+ sigma=sigma_val,
183
+ input_size=self.layers[0],
184
+ encoded_size=self.layers[1]
185
+ ).to(device))
186
+ self.layers[0] = self.layers[1] * 2 # chaque entrée est doublée après encodage
187
+
171
188
  # --- Sélection du normalisateur / activation ---
172
189
  self.norm = norm_list.get(norm)
173
190
  if self.norm is None:
@@ -187,11 +204,11 @@ class MLP():
187
204
  self.model = self.Create_MLP(self.layers)
188
205
 
189
206
  # --- Sélection de l’optimiseur ---
190
- self.optim = optim_list(self, learning_rate).get(optim)
207
+ self.optim = optim_list(self, init_lr).get(optim)
191
208
  if self.optim is None:
192
209
  print("")
193
210
  print (f"{optim} n'est pas reconnu")
194
- self.optim = optim_list(self, learning_rate).get("Adam")
211
+ self.optim = optim_list(self, init_lr).get("Adam")
195
212
  print (f"Retour au paramètre par défaut: 'Adam'")
196
213
 
197
214
  # --- Compilation optionnelle du modèle pour accélérer l’inférence ---
@@ -208,6 +225,7 @@ class MLP():
208
225
 
209
226
  # --- Envoi du modèle sur le device GPU / CPU ---
210
227
  self.model.to(device)
228
+ self.f = nn.Linear(len(self.encodings) * self.layers[-1], self.layers[-1]).to(device)
211
229
 
212
230
  def __repr__(self):
213
231
  """
@@ -267,37 +285,45 @@ class MLP():
267
285
  background_fill=(0, 0, 0, 0),
268
286
  opacity=255
269
287
  )
270
- )
271
-
272
- plt.show()
273
- return ""
288
+ ); plt.show(); return ""
274
289
 
275
290
  def __call__(self, x):
276
291
  """
277
- Effectue une inférence complète : encodage éventuel, passage
278
- dans le MLP, puis retour en numpy.
292
+ Effectue une inférence complète en appliquant :
293
+ - chaque encodage d'entrée défini dans `self.encodings`,
294
+ - un passage dans le MLP (`self.model`) pour chaque encodage,
295
+ - une concaténation des sorties,
296
+ - une couche linéaire finale (`self.f`) pour produire la prédiction.
279
297
 
280
- Cette méthode permet d’utiliser l’objet comme une fonction
281
- directement : `y = net(x)`.
298
+ Cette méthode permet d’utiliser l’objet comme une fonction :
299
+ y = net(x)
282
300
 
283
- Paramètres
301
+ Parameters
284
302
  ----------
285
303
  x : array-like
286
- Entrée(s) à prédire. Peut être un tableau numpy, une liste,
287
- ou déjà un tenseur compatible.
304
+ Entrée(s) à prédire. Peut être un tableau NumPy, une liste Python
305
+ ou un tenseur PyTorch convertible par `tensorise()`.
288
306
 
289
307
  Returns
290
308
  -------
291
309
  np.ndarray
292
- Sortie du MLP après encodage et propagation avant,
293
- convertie en tableau numpy sur CPU.
310
+ Sortie finale du modèle après :
311
+ encodage(s) MLP concaténation → couche finale.
312
+ Résultat renvoyé sous forme de tableau NumPy CPU aplati.
294
313
  """
295
314
 
296
315
  # Inférence sans calcul de gradient (plus rapide et évite la construction du graphe)
297
316
  with torch.no_grad():
298
- return self.model(
299
- self.encoding(tensorise(x))
300
- ).cpu().numpy()
317
+ inputs = tensorise(x)
318
+ if inputs.dim() == 1:
319
+ inputs = inputs.unsqueeze(0)
320
+
321
+ # --- Initialisation du scaler pour l'entraînement en précision mixte ---
322
+
323
+ results_list = []
324
+ for encoding in self.encodings:
325
+ results_list.append(self.model(encoding(inputs)))
326
+ return self.f(torch.cat(results_list, dim=1)).cpu().numpy().flatten()
301
327
 
302
328
  def params(self):
303
329
  """
@@ -430,154 +456,140 @@ class MLP():
430
456
  self.norm
431
457
  ])
432
458
 
433
- # Ajout de la couche finale : Linear → Sigmoid
459
+ # Ajout de la couche finale : Linear
434
460
  layer_list.extend([
435
- nn.Linear(layers[-2], layers[-1]),
436
- nn.Sigmoid()
461
+ nn.Linear(layers[-2], layers[-1])
437
462
  ])
438
463
 
439
464
  return nn.Sequential(*layer_list)
440
465
 
441
- def plot(self, img_array, inputs):
442
- """
443
- Affiche côte à côte :
444
- - l’image originale,
445
- - l’image prédite par le MLP,
446
- - l’évolution de la fonction de perte (loss) au cours de l’entraînement.
447
-
448
- Parameters
449
- ----------
450
- img_array : np.ndarray
451
- Image originale sous forme de tableau (H, W, 3) utilisée comme référence.
452
- inputs : array-like or torch.Tensor
453
- Tableau des coordonnées (ou features) servant d’entrée au réseau.
454
- Doit correspondre à la grille permettant de reconstruire l’image.
455
-
456
- Notes
457
- -----
458
- Cette méthode :
459
- - tensorise les entrées puis les encode avant passage dans le MLP,
460
- - reshape la sortie du modèle pour retrouver la forme (H, W, 3),
461
- - trace également la courbe de pertes stockée dans `self.losses`.
466
+ def train(self, inputs, outputs, num_epochs=1500, batch_size=1024):
462
467
  """
463
-
464
- # Conversion des inputs en tenseur + récupération du nombre d'échantillons
465
- inputs, n_samples = tensorise(inputs), inputs.size(0)
466
-
467
- # Dimensions de l'image originale
468
- h, w = img_array.shape[:2]
469
-
470
- # Figure principale avec 3 panneaux : original / prédiction / loss
471
- fig = plt.figure(figsize=(15, 5))
472
- gs = GridSpec(1, 3, figure=fig)
473
-
474
- # --- Image originale ---
475
- ax_orig = fig.add_subplot(gs[0,0])
476
- ax_orig.axis('off')
477
- ax_orig.set_title("Original Image")
478
- ax_orig.imshow(img_array)
479
-
480
- # --- Image prédite ---
481
- ax = fig.add_subplot(gs[0,1])
482
- ax.axis('off')
483
- ax.set_title("Predicted Image")
484
- # Prédiction → CPU → numpy → reshape en (H, W, 3)
485
- ax.imshow(
486
- self.model(self.encoding(inputs))
487
- .cpu()
488
- .detach()
489
- .numpy()
490
- .reshape(h, w, 3)
491
- )
492
-
493
- # --- Courbe de loss ---
494
- los = fig.add_subplot(gs[0,2])
495
- los.set_title("Loss")
496
-
497
- # Axe X = 1..N
498
- los.plot(
499
- np.linspace(1, len(self.losses), len(self.losses)),
500
- [loss.item() for loss in self.losses]
501
- )
502
- if len(self.losses) ==1:
503
- lenlosses = 2
504
- else:
505
- lenlosses = len(self.losses)
506
- los.set_xlim(1, lenlosses)
468
+ Entraîne le modèle en utilisant un schéma mini-batch et la précision
469
+ mixte (AMP). Chaque batch subit :
507
470
 
508
- # Évite un ylim min = 0 pile si les pertes sont trop faibles
509
- maxarray = [0.00000001] + [loss.item() for loss in self.losses]
510
- los.set_ylim(0, max(maxarray))
471
+ encodages multiples MLP concaténation couche finale perte
511
472
 
512
- # Rafraîchissement non bloquant
513
- fig.canvas.draw_idle()
514
- plt.tight_layout()
515
- plt.ion()
516
- plt.show()
517
-
518
- def train(self, inputs, outputs, num_epochs=1500, batch_size=1024):
519
- """
520
- Entraîne le MLP sur des paires (inputs → outputs) en utilisant un
521
- schéma de mini-batchs et l'AMP (Automatic Mixed Precision).
473
+ Ce training met également à jour dynamiquement le learning rate.
522
474
 
523
475
  Parameters
524
476
  ----------
525
- inputs : array-like or tensor
526
- Données d'entrée du réseau, de shape (N, input_dim).
527
- outputs : array-like or tensor
528
- Cibles associées, de shape (N, output_dim).
477
+ inputs : array-like or torch.Tensor
478
+ Données d'entrée, shape (N, input_dim). Sont converties en
479
+ tenseur PyTorch et envoyées sur `device`.
480
+ outputs : array-like or torch.Tensor
481
+ Cibles correspondantes, shape (N, output_dim).
529
482
  num_epochs : int, optional
530
- Nombre total d'époques d'entraînement (default: 1500).
483
+ Nombre total d'époques d'entraînement.
484
+ Default: 1500.
531
485
  batch_size : int, optional
532
- Taille des mini-batchs utilisés à chaque itération (default: 1024).
486
+ Taille des mini-batchs. Default: 1024.
533
487
 
534
488
  Notes
535
489
  -----
536
- - Utilise torch.amp.autocast + GradScaler pour un entraînement accéléré en FP16.
537
- - Les pertes par époque sont stockées dans `self.losses`.
538
- - Le réseau doit posséder :
539
- * self.model : module PyTorch (MLP)
540
- * self.encoding() : encodage éventuel (Fourier features)
541
- * self.crit : fonction de perte
542
- * self.optim : optimiseur
490
+ - Utilise `torch.amp.autocast` et `GradScaler` pour un entraînement
491
+ accéléré et stable en précision mixte (FP16/FP32).
492
+ - Pour chaque mini-batch :
493
+ * chaque module dans `self.encodings` est appliqué aux entrées,
494
+ * chaque encodage passe dans `self.model`,
495
+ * les sorties sont concaténées,
496
+ * la couche finale `self.f` produit la prédiction,
497
+ * la perte est évaluée via `self.crit`.
498
+ - Le learning rate est ajusté après chaque époque.
499
+ - Les pertes d'époques sont enregistrées dans `self.losses`.
543
500
  """
544
501
 
545
502
  # --- Conversion en tensors et récupération du nombre d'échantillons ---
546
- inputs, outputs, n_samples = tensorise(inputs).to(device), tensorise(outputs).to(device), inputs.size(0)
503
+ inputs, outputs = tensorise(inputs).to(device), tensorise(outputs).to(device)
547
504
  self.model = self.model.to(device)
548
-
505
+ n_samples = inputs.size(0)
506
+
549
507
  # --- Initialisation du scaler pour l'entraînement en précision mixte ---
550
508
  dev = str(device)
551
509
  scaler = GradScaler(dev)
552
-
510
+
511
+ def update_lr(optimizer, loss):
512
+ for param_group in optimizer.param_groups:
513
+ param_group['lr'] = 0.005*np.where(loss <=0, 0,
514
+ np.where(loss >=1, 1,
515
+ np.sqrt(loss)/(2 - loss**2)))
516
+
553
517
  # --- Boucle principale sur les époques ---
554
518
  for epoch in tqdm(range(num_epochs), desc="train epoch"):
555
519
  # Génération d'un ordre aléatoire des indices
556
520
  perm = torch.randperm(n_samples, device=device)
557
521
  epoch_loss = 0.0
558
-
522
+
559
523
  # --- Parcours des mini-batchs ---
560
524
  for i in range(0, n_samples, batch_size):
561
525
  idx = perm[i:i+batch_size]
562
-
526
+
563
527
  # Fonction interne calculant la perte et les gradients
564
528
  def closure():
565
529
  self.optim.zero_grad(set_to_none=True)
566
530
  with autocast(dev): # AMP
567
- loss = self.crit(self.model(self.encoding(inputs[idx])),outputs[idx])
531
+ results_list = []
532
+ for encoding in self.encodings:
533
+ results_list.append(self.model(encoding(inputs[idx])))
534
+ loss = self.crit(self.f(torch.cat(results_list, dim=1)),outputs[idx])
568
535
  scaler.scale(loss).backward()
569
536
  return loss
570
-
537
+
571
538
  # Calcul de la perte et mise à jour des poids
572
539
  loss = closure()
573
540
  scaler.step(self.optim)
574
541
  scaler.update()
575
-
542
+
576
543
  # Accumulation de la perte pour l'époque
577
- epoch_loss += loss
578
-
544
+ epoch_loss += loss.item()
545
+
579
546
  # --- Stockage de la perte de l'époque ---
580
547
  self.losses.append(epoch_loss)
548
+ update_lr(self.optim,self.losses[-1])
549
+
550
+ def losses(*nets):
551
+ """
552
+ Affiche les courbes de pertes (training loss) de plusieurs réseaux MLP.
553
+
554
+ Parameters
555
+ ----------
556
+ nets : MLP
557
+ Un ou plusieurs réseaux possédant un attribut `.losses`
558
+ contenant l'historique des pertes (liste de float).
559
+
560
+ Notes
561
+ -----
562
+ - L’axe X correspond aux itérations (epochs ou steps).
563
+ - L’axe Y correspond à la valeur de la perte.
564
+ - La fonction utilise matplotlib en mode interactif pour affichage dynamique.
565
+ """
566
+
567
+ # --- Initialisation de la figure ---
568
+ fig = plt.figure(figsize=(5, 5))
569
+
570
+ # --- Définition des limites des axes ---
571
+ all_losses = [[loss for loss in net.losses] for net in nets]
572
+ if max(len(lst) for lst in all_losses) == 1:
573
+ lenlosses = 2
574
+ else:
575
+ lenlosses = max(len(lst) for lst in all_losses)
576
+ plt.xlim(1, lenlosses)
577
+
578
+ # --- Tracé des courbes de pertes pour chaque réseau ---
579
+ for k, net in enumerate(nets):
580
+ steps = np.linspace(1, len(net.losses), len(net.losses)) # epochs
581
+ plt.plot(np.arange(1, len(all_losses[k])+1), all_losses[k],label = net.name)
582
+ plt.yscale('log', nonpositive='mask')
583
+ # --- Affichage ---
584
+ plt.legend()
585
+ plt.xlabel("Epoch")
586
+ plt.ylabel("Résidus")
587
+ fig.canvas.draw_idle()
588
+ plt.tight_layout()
589
+ plt.ion() # mode interactif
590
+ plt.show()
591
+
592
+ losses.help = fPrintDoc(losses)
581
593
 
582
594
  MLP.__init__.help = fPrintDoc(MLP.__init__)
583
595
  MLP.__repr__.help = fPrintDoc(MLP.__repr__)
@@ -586,6 +598,4 @@ MLP.help = fPrintDoc(MLP)
586
598
  MLP.params.help = fPrintDoc(MLP.params)
587
599
  MLP.nb_params.help = fPrintDoc(MLP.nb_params)
588
600
  MLP.neurons.help = fPrintDoc(MLP.neurons)
589
- MLP.Create_MLP.help = fPrintDoc(MLP.Create_MLP)
590
- MLP.plot.help = fPrintDoc(MLP.plot)
591
601
  MLP.train.help = fPrintDoc(MLP.train)
@@ -116,13 +116,12 @@ Notes générales
116
116
  # Import des dépendances et utilitaires globaux (device, settings, tensorise, etc.)
117
117
  from .Dependances import norms, crits, optims, rglen, device, pi, e, tensorise
118
118
 
119
- # Fonctions de chargement/preprocessing des images
120
- from .Image import image_from_url
119
+ # Modèle MLP principal + fonction d'entraînement associée
120
+ from .MLP import MLP, losses
121
121
 
122
- # Fonctions d'affichage : reconstruction, comparaison, courbes de pertes
123
- from .Plot import compare, plot, losses, train
122
+ from .Latent import Latent
124
123
 
125
- # Modèle MLP principal + fonction d'entraînement associée
126
- from .MLP import MLP
124
+ # Fonctions de chargement/preprocessing des images
125
+ from .tools import image, MNIST, AirfRANS
127
126
 
128
- __version__ = "0.1.12"
127
+ __version__ = "0.2.0"
@@ -0,0 +1,36 @@
1
+ # NeuralNetworksBeta - Multi-Layer Perceptrons avec encodage Fourier
2
+ # Copyright (C) 2025 Alexandre Brun
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ from ..Dependances import *
9
+ from airfrans import *
10
+
11
+ def download(path,unzip = True, OpenFOAM = False):
12
+ """
13
+ Télécharge le dataset AirfRANS dans le dossier spécifié.
14
+
15
+ Cette fonction est un simple wrapper autour :
16
+ dataset.download(root=path, file_name='AirfRANS', unzip=True, OpenFOAM=True)
17
+
18
+ Les arguments `unzip` et `OpenFOAM` sont actuellement ignorés par la fonction
19
+ et forcés à True dans l’appel interne.
20
+
21
+ Parameters
22
+ ----------
23
+ path : str
24
+ Chemin du dossier dans lequel le dataset doit être téléchargé.
25
+ unzip : bool, optional
26
+ Paramètre non utilisé. Le téléchargement interne force `unzip=True`.
27
+ OpenFOAM : bool, optional
28
+ Paramètre non utilisé. Le téléchargement interne force `OpenFOAM=True`.
29
+
30
+ Notes
31
+ -----
32
+ - Le fichier téléchargé s’appelle `'AirfRANS'`.
33
+ - Le dataset est automatiquement décompressé.
34
+ - Le format OpenFOAM est toujours inclus.
35
+ """
36
+ dataset.download(root = path, file_name = 'AirfRANS', unzip = True, OpenFOAM = True)