GF
Geoffrey Franz
Recherche : Fondamentaux du Deep Learning

NNFS — Neural Networks
From Scratch

Maîtrise de la mécanique interne des réseaux de neurones. J'ai reconstruit un moteur d'apprentissage profond complet en Python & NumPy, incluant la Backpropagation manuelle et l'optimisation par descente de gradient.

01/ Implementation & Backprop

nnfs_engine.py
class Layer_Dense:
    def forward(self, inputs):
        self.inputs = inputs
        self.output = np.dot(inputs, self.weights) + self.biases

    def backward(self, d_out):
        # Calcul des gradients par produit matriciel (Transpose)
        self.dweights = np.dot(self.inputs.T, d_out)
        self.dbiases = np.sum(d_out, axis=0, keepdims=True)
        self.dinputs = np.dot(d_out, self.weights.T)
        return self.dinputs
Extrait de la logique de rétropropagation pour la mise à jour des poids.

02/ Résultats d'entraînement

Dataset Spiral — 3 classes, 100 points chacune. Problème non-linéairement séparable : un réseau sans couche cachée ne peut pas le résoudre. Résultat final avec Adam + 2 couches denses :

terminal — python main.py
epoch:     0   loss: 1.099   acc: 0.337
epoch:  1000   loss: 0.612   acc: 0.603
epoch:  3000   loss: 0.312   acc: 0.847
epoch:  5000   loss: 0.182   acc: 0.910
epoch:  8000   loss: 0.121   acc: 0.947
epoch: 10000   loss: 0.089   acc: 0.967
96.7% de précision sur un problème non-linéaire — sans framework, juste NumPy et des maths.

Logique Algorithmique

Contrairement aux approches haut-niveau, ce projet m'a permis d'implémenter l'Optimizer SGD et la Categorical Crossentropy. L'utilisation de NumPy permet une manipulation directe des matrices pour des performances optimales.

Composants du Système

Convergence

Boucle d'entraînement sur 1M d'epochs pour valider la réduction de la Loss.

Optimisation Adam/SGD

Mise à jour dynamique des paramètres basée sur le calcul des gradients.

Architecture du Network

  1. In

    Spiral Data

  2. L1

    ReLU Layer

  3. L2

    Softmax Out

  4. Lss

    Cross-Entropy

Ce que ce projet m'a appris

Le dot product n'est pas une boîte noire

Recoder np.dot(inputs, weights) à la main m'a forcé à comprendre pourquoi la transposée intervient dans le backward — c'est la règle de la chaîne appliquée aux matrices. PyTorch le fait silencieusement. Ici, tu vois chaque étape.

Pourquoi chaque couche stocke ses inputs

Durant le forward(), chaque couche mémorise ses entrées. Ce n'est pas du gaspillage mémoire — c'est ce qui rend le backward() possible. Sans ça, pas de gradients, pas d'apprentissage.

Pourquoi Adam converge plus vite que SGD

Adam combine momentum (direction) et RMSProp (amplitude par paramètre). Sur le spiral dataset, SGD stagne autour de 0.6 loss là où Adam descend à 0.089. La différence n'est pas magique — c'est deux moyennes mobiles bien calibrées.

Voir aussi

Code source — AiLearning Photoshoplike — Go + C + OpenCL
Voir tous les projets