mini-torch-from-scratch 0.1.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.
mini_torch/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ from .autodiff import Nombre
2
+ from .nn import Couche, MLP, Neuron
3
+
4
+ __all__ = ["Nombre", "Neuron", "Couche", "MLP"]
mini_torch/autodiff.py ADDED
@@ -0,0 +1,144 @@
1
+ import math
2
+
3
+
4
+ class Nombre:
5
+ def __init__(self, h_val, _parent=(), _op=""):
6
+ self.h_val = h_val
7
+ self.b_val = 0.0
8
+ self._derive = lambda: None
9
+ self._parent = set(_parent)
10
+ self._op = _op
11
+
12
+ def __repr__(self):
13
+ return f"[h_val: {self.h_val}, b_val: {self.b_val}]"
14
+
15
+ def __add__(self, autre):
16
+ autre = autre if isinstance(autre, Nombre) else Nombre(h_val=autre)
17
+ somme = Nombre(
18
+ h_val=self.h_val + autre.h_val,
19
+ _parent=(self, autre),
20
+ _op="+",
21
+ )
22
+
23
+ def _derive():
24
+ self.b_val += somme.b_val
25
+ autre.b_val += somme.b_val
26
+
27
+ somme._derive = _derive
28
+ return somme
29
+
30
+ def __mul__(self, autre):
31
+ autre = autre if isinstance(autre, Nombre) else Nombre(h_val=autre)
32
+ produit = Nombre(
33
+ h_val=self.h_val * autre.h_val,
34
+ _parent=(self, autre),
35
+ _op="*",
36
+ )
37
+
38
+ def _derive():
39
+ self.b_val += autre.h_val * produit.b_val
40
+ autre.b_val += self.h_val * produit.b_val
41
+
42
+ produit._derive = _derive
43
+ return produit
44
+
45
+ def __pow__(self, autre):
46
+ if not isinstance(autre, (int, float)):
47
+ raise TypeError("L'exposant doit être un nombre.")
48
+
49
+ puissance = Nombre(
50
+ h_val=self.h_val**autre,
51
+ _parent=(self,),
52
+ _op=f"**{autre}",
53
+ )
54
+
55
+ def _derive():
56
+ self.b_val += autre * (self.h_val ** (autre - 1)) * puissance.b_val
57
+
58
+ puissance._derive = _derive
59
+ return puissance
60
+
61
+ def maximum(self, autre):
62
+ autre = autre if isinstance(autre, Nombre) else Nombre(h_val=autre)
63
+ max_val = Nombre(
64
+ h_val=max(self.h_val, autre.h_val),
65
+ _parent=(self, autre),
66
+ _op="max",
67
+ )
68
+
69
+ def _derive():
70
+ if self.h_val > autre.h_val:
71
+ self.b_val += max_val.b_val
72
+ elif autre.h_val > self.h_val:
73
+ autre.b_val += max_val.b_val
74
+ else:
75
+ self.b_val += 0.5 * max_val.b_val
76
+ autre.b_val += 0.5 * max_val.b_val
77
+
78
+ max_val._derive = _derive
79
+ return max_val
80
+
81
+ def __neg__(self):
82
+ return self * -1
83
+
84
+ def __sub__(self, autre):
85
+ return self + (-autre)
86
+
87
+ def __rsub__(self, autre):
88
+ return autre + (-self)
89
+
90
+ def __rmul__(self, autre):
91
+ return self * autre
92
+
93
+ def __radd__(self, autre):
94
+ return self + autre
95
+
96
+ def tanh(self):
97
+ t = math.tanh(self.h_val)
98
+ out = Nombre(h_val=t, _parent=(self,), _op="tanh")
99
+
100
+ def _derive():
101
+ self.b_val += (1 - t**2) * out.b_val
102
+
103
+ out._derive = _derive
104
+ return out
105
+
106
+ def exp(self):
107
+ out = Nombre(
108
+ h_val=math.exp(self.h_val),
109
+ _parent=(self,),
110
+ _op="exp",
111
+ )
112
+
113
+ def _derive():
114
+ self.b_val += out.h_val * out.b_val
115
+
116
+ out._derive = _derive
117
+ return out
118
+
119
+ def backward(self):
120
+ topo = []
121
+ seen = set()
122
+
123
+ def construire_graph(nbr):
124
+ if nbr not in seen:
125
+ seen.add(nbr)
126
+
127
+ for parent in nbr._parent:
128
+ construire_graph(parent)
129
+
130
+ topo.append(nbr)
131
+
132
+ construire_graph(self)
133
+
134
+ for nbr in topo:
135
+ if nbr._parent:
136
+ nbr.b_val = 0.0
137
+
138
+ self.b_val = 1.0
139
+
140
+ for nbr in reversed(topo):
141
+ nbr._derive()
142
+
143
+ def _retropropager(self):
144
+ self.backward()
mini_torch/nn.py ADDED
@@ -0,0 +1,55 @@
1
+ from .autodiff import Nombre
2
+
3
+
4
+ class Neuron:
5
+ def __init__(self, poids, biais):
6
+ self.poids = [p if isinstance(p, Nombre) else Nombre(p) for p in poids]
7
+ self.biais = biais if isinstance(biais, Nombre) else Nombre(biais)
8
+
9
+ def propager(self, entrees):
10
+ if len(entrees) != len(self.poids):
11
+ raise ValueError(
12
+ f"Le neurone attend {len(self.poids)} entrées, "
13
+ f"mais en a reçu {len(entrees)}."
14
+ )
15
+
16
+ z = self.biais
17
+
18
+ for x, w in zip(entrees, self.poids):
19
+ x = x if isinstance(x, Nombre) else Nombre(x)
20
+ z = z + x * w
21
+
22
+ return z.tanh()
23
+
24
+ def parameters(self):
25
+ return self.poids + [self.biais]
26
+
27
+
28
+ class Couche:
29
+ def __init__(self, neurons):
30
+ self.neurons = neurons
31
+
32
+ def propager(self, caracteres):
33
+ return [neuron.propager(caracteres) for neuron in self.neurons]
34
+
35
+ def parameters(self):
36
+ params = []
37
+ for neuron in self.neurons:
38
+ params.extend(neuron.parameters())
39
+ return params
40
+
41
+
42
+ class MLP:
43
+ def __init__(self, couches):
44
+ self.couches = couches
45
+
46
+ def propager(self, entrees):
47
+ for couche_actuelle in self.couches:
48
+ entrees = couche_actuelle.propager(entrees)
49
+ return entrees
50
+
51
+ def parameters(self):
52
+ params = []
53
+ for couche_actuelle in self.couches:
54
+ params.extend(couche_actuelle.parameters())
55
+ return params
@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.4
2
+ Name: mini-torch-from-scratch
3
+ Version: 0.1.0
4
+ Summary: A small neural network and automatic differentiation framework
5
+ License-Expression: MIT
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: Programming Language :: Python :: 3
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: license-file
13
+
14
+ # Mini Torch from Scratch
15
+
16
+ Un petit framework Python, sans dependance externe, pour l'autodiff scalaire et
17
+ les reseaux fully connected (MLP). Il ne fournit pas encore de couches CNN.
18
+
19
+ ## Installation
20
+
21
+ ```powershell
22
+ python -m pip install mini-torch-from-scratch
23
+ ```
24
+
25
+ Le nom du paquet sur PyPI est `mini-torch-from-scratch`. Le nom d'import Python
26
+ reste `mini_torch`.
27
+
28
+ ## Exemple
29
+
30
+ ```python
31
+ from mini_torch import Couche, MLP, Neuron, Nombre
32
+
33
+ reseau = MLP(
34
+ [
35
+ Couche([Neuron([0.5, -0.2], 0.1)]),
36
+ Couche([Neuron([0.8], 0.0)]),
37
+ ]
38
+ )
39
+
40
+ sortie = reseau.propager([2.0, 1.0])[0]
41
+ perte = (sortie - 1.0) ** 2
42
+ perte.backward()
43
+
44
+ for parametre in reseau.parameters():
45
+ parametre.h_val -= 0.01 * parametre.b_val
46
+ ```
47
+
48
+ `Nombre.backward()` calcule les gradients et les accumule sur les feuilles du
49
+ graphe. Remets les gradients des parametres a zero avant une nouvelle etape
50
+ d'optimisation si tu ne veux pas les accumuler.
51
+
52
+ Pour voir un exemple d'entrainement complet depuis le depot :
53
+
54
+ ```powershell
55
+ python -m examples.entrainement
56
+ ```
57
+
58
+ ## Tests
59
+
60
+ Depuis la racine du depot :
61
+
62
+ ```powershell
63
+ python -m unittest discover -s tests
64
+ ```
65
+
66
+ ## Construire et publier sur PyPI
67
+
68
+ La publication n'est pas automatique. Pour publier toi-meme :
69
+
70
+ 1. Remplace le titulaire fictif dans `LICENSE` par ton nom ou celui de ton
71
+ organisation, puis cree un compte PyPI et verifie que le nom
72
+ `mini-torch-from-scratch` est toujours disponible. Sa disponibilite peut
73
+ changer.
74
+ 2. Depuis la racine du depot, construis et verifies les distributions :
75
+
76
+ ```powershell
77
+ python -m pip install --upgrade build twine
78
+ python -m build
79
+ python -m twine check dist/*
80
+ ```
81
+
82
+ 3. Configure tes identifiants PyPI selon la documentation officielle de Twine,
83
+ puis envoie les distributions :
84
+
85
+ ```powershell
86
+ python -m twine upload dist/*
87
+ ```
88
+
89
+ Ne place pas de jeton PyPI dans le code source ni dans le depot. Augmente la
90
+ version dans `pyproject.toml` avant chaque nouvelle publication.
@@ -0,0 +1,8 @@
1
+ mini_torch/__init__.py,sha256=isATTvYziM-LW-yR-5BKKz-qx95Y2gQWhUv7XDOABxY,118
2
+ mini_torch/autodiff.py,sha256=Zn4bxlt0G749unlt3eR9aFdxbUu0G1bX2_HIGC-FZ9c,3695
3
+ mini_torch/nn.py,sha256=A97AS9mExiWO_4SWmMcGBNJXXPK0n5pJiQG63SDa7Vw,1526
4
+ mini_torch_from_scratch-0.1.0.dist-info/licenses/LICENSE,sha256=6YR8E1abkg_9lfZxJwAIJPjOMOH-J0HBO2LXtNwR6A8,1092
5
+ mini_torch_from_scratch-0.1.0.dist-info/METADATA,sha256=9bHMWx9beD8De6Bm7mSqxoSooCL-RUivu2V2R3kuYhU,2473
6
+ mini_torch_from_scratch-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
7
+ mini_torch_from_scratch-0.1.0.dist-info/top_level.txt,sha256=Tjy7Wli-5exd4kympiwVtQMpf-8564YZ-koIbi4Be4I,11
8
+ mini_torch_from_scratch-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Salma Izoughar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ mini_torch