Add cnn/main and cnn/train documentation

This commit is contained in:
augustin64 2022-12-19 15:48:33 +01:00
parent fb7937f67f
commit 80e82c16f6
3 changed files with 185 additions and 0 deletions

31
doc/cnn/README.md Normal file
View File

@ -0,0 +1,31 @@
# Réseau de neurones convolutif [code](/src/cnn)
Cette partie du code implémente un réseau de neuron convolutif.
## Compilation
```bash
make cnn
```
## Fichiers
- [main](/src/cnn/main.c) [[Documentation](/doc/cnn/main.md)] Contient la fonction main et lit les arguments à son appel
- [train](/src/cnn/train.c) [[Documentation](/doc/cnn/train.md)] Contient la partie plus haut niveau du code entraînant le réseau. Implémente la programmation concurrentielle
- [convolution](/src/cnn/convolution.cu) [[Documentation](/doc/cnn/convolution.md)] Convolution de matrices, en C et en CUDA
- [jpeg](/src/cnn/jpeg.c) [[Documentation](/doc/cnn/jpeg.md)] Lecture d'un jeu de données constitué d'images au format JPEG
- [neuron io](/src/cnn/neuron_io.c) [[Documentation](/doc/cnn/neuron_io.md)] Lecture et écriture du réseau de neurone dans un fichier
- [preview](/src/cnn/preview.c) [[Documentation](/doc/cnn/preview.md)] Visualisation des données chargées pour un jeu de données de type JPEG
- [test network](/src/cnn/test_network.c) [[Documentation](/doc/cnn/test_network.md)] Ensemble de fonctions permettant d'évaluer un réseau depuis un jeu de tests et de classifier des images
- [utils](/src/cnn/utils.c) [[Header](/src/cnn/include/utils.h)] Fonctions utilitaires (Copie de réseau, vérification d'égalité, mélange de Knuth)
- [matrix multiplication](/src/cnn/matrix_multiplication.cu) [[Documentation](/doc/cnn/matrix_multiplication.md)] Maintenant inutilisé, test de multiplication de matrices en CUDA
- [backpropagation](/src/cnn/backpropagation.c) [[Documentation](/doc/cnn/backpropagation.md)]
- [cnn](/src/cnn/cnn.c) [[Documentation](/doc/cnn/cnn.md)]
- [creation](/src/cnn/creation.c) [[Documentation](/doc/cnn/creation.md)]
- [function](/src/cnn/function.c) [[Documentation](/doc/cnn/function.md)]
- [include](/src/cnn/include) [[Documentation](/doc/cnn/include.md)]
- [make](/src/cnn/make.c) [[Documentation](/doc/cnn/make.md)]
- [print](/src/cnn/print.c) [[Documentation](/doc/cnn/print.md)]
- [free](/src/cnn/free.c) [[Header](/src/cnn/include/free.h)]
- [update](/src/cnn/update.c) [[Header](/src/cnn/include/update.h)]
- [initialisation](/src/cnn/initialisation.c) [[Header](/src/cnn/include/initialisation.h)]

127
doc/cnn/main.md Normal file
View File

@ -0,0 +1,127 @@
# Main
## Compilation
#### Deux options sont disponibles à la compilation
Une première fonctionnant sous toutes les machines:
```bash
make cnn-main
```
Une seconde utilisant CUDA pour la convolution, qui sera plus rapide, mais ne fonctionnera que sur les machines équipées d'une carte graphique Nvidia (nécessite `nvcc` disponible sous le paquet `cuda` ou `cuda-tools` pour la compilation):
```bash
make cnn-main-cuda
```
## Options à la compilation
- La taille de la couche d'entrée ainsi que la fonction d'activation utilisée sont définissable dans la [création du réseau](/src/cnn/train.c#L116) (L'architecture utilisée se définit ici également, LeNet5 étant adaptée uniquement au jeu de données MNIST)
- La définition du nombre d'époques par défaut se fait dans la définition [`EPOCHS`](/src/cnn/include/train.h#L7)
- La définition de la taille des batches se fait dans la définition [`BATCHES`](/src/cnn/include/train.h#L8)
- Le multi-threading est activé par défaut, se désactive en enlevant la définition [`USE_MULTITHREADING`](/src/cnn/include/train.h#L9) (le multithreading ne fonctionne pas pour le moment)
- Il y a une option pour conserver l'ensemble du jeu de données JPEG dans la mémoire RAM [détails](/doc/cnn/jpeg.md#STORE_TO_RAM)
### Options spécifiques à CUDA
- La définition de la taille des blocs peut-être trop élevée pour certaines carte graphiques, il faudra alors réduire l'une des définitions de [`BLOCKSIZE`](/src/cnn/convolution.cu#L37)
## Utilisation
```
Usage: build/cnn-main ( train | recognize | test ) [OPTIONS]
OPTIONS:
train:
--dataset | -d (mnist|jpg) Format du set de données.
(mnist) --images | -i [FILENAME] Fichier contenant les images.
(mnist) --labels | -l [FILENAME] Fichier contenant les labels.
(jpg) --datadir | -dd [FOLDER] Dossier contenant les images.
--recover | -r [FILENAME] Récupérer depuis un modèle existant.
--epochs | -e [int] Nombre d'époques.
--out | -o [FILENAME] Fichier où écrire le réseau de neurones.
recognize:
--dataset | -d (mnist|jpg) Format de l'image à reconnaître.
--modele | -m [FILENAME] Fichier contenant le réseau entraîné.
--input | -i [FILENAME] Image jpeg ou fichier binaire à reconnaître.
test:
--modele | -m [FILENAME] Fichier contenant le réseau entraîné.
--dataset | -d (mnist|jpg) Format du set de données.
(mnist) --images | -i [FILENAME] Fichier contenant les images.
(mnist) --labels | -l [FILENAME] Fichier contenant les labels.
(jpg) --datadir | -dd [FOLDER] Dossier contenant les images.
--preview-fails | -p Afficher les images ayant échoué.
```
## Entraînement
Entraînement du réseau de neurones
Exemple (MNIST):
```bash
build/cnn-main train \
--dataset mnist \
--epochs 15 \
--images data/mnist/train-images-idx3-ubyte \
--labels data/mnist/train-labels-idx1-ubyte \
--out reseau.bin
```
Exemple (JPG):
```bash
build/cnn-main train \
--dataset jpg \
--epochs 15 \
--datadir data/50States10K/train \
--out reseau.bin
```
Le réseau de neurones entraîné est sauvegardé dans le fichier de sortie à la fin de chaque époque.
## Reconnaissance d'images
### MNIST
La reconnaissance d'images se fait avec un fichier formaté de la même manière que le jeu de données MNIST.
Le plus simple pour dessiner à la main est d'utiliser le [serveur web](/doc/webserver) prévu à cet effet
Note:
Le serveur web ne prend pour le moment qu'une option pour dessiner et faire reconnaître par le réseau de neurones simple.
Cependant, l'image dessinée est stockée dans le fichier `.cache/image-idx3-ubyte`, la faire reconnaître par le réseau convolutif est donc possible avec la commande suivante:
```bash
build/cnn-main recognize \
--dataset jpg \
--modele reseau.bin \
--input .cache/image-idx3-ubyte \
--output json
```
### JPEG
L'image d'entrée doit conserver la même taille que les images ayant servi à entraîner le réseau (256x256 pixels)
Exemple:
```bash
build/cnn-main recognize \
--dataset jpg \
--modele reseau.bin \
--input image.jpeg \
--output json
```
## Test sur le jeu prévu à cet effet
Exemple (MNIST):
```bash
build/cnn-main test \
--dataset mnist \
-i data/mnist/t10k-images-idx3-ubyte \
-l data/mnist/t10k-labels-idx1-ubyte \
-m reseau.bin
```
Exemple (JPG):
```bash
build/cnn-main test \
--dataset jpg \
--datadir data/50States10K/test \
-m reseau.bin
```

27
doc/cnn/train.md Normal file
View File

@ -0,0 +1,27 @@
# Entraînement du réseau
## Théorie
_définition_: Une **époque** est une itération sur l'entièreté du jeu de données. Une époque est divisée en batchs.
_définition_: Un **batch** est une partie d'une époque à la fin de laquelle les modifications nécessaires calculées sont appliquées au réseau.
Ainsi, chaque époque est divisé en batchs de taille égale.
Les images sont itérées dans un ordre différent à chaque époque, permet d'éviter le sur-apprentissage dans une certaine mesure.
### Programmation en parallèle
Lorsque le multithreading est utilisé, chaque époque est divisé en un certain nombre de parties chacune de taille environ égale.
Chaque fil d'exécution se voir alors assigner une de ces parties.
Lorsque chaque thread a fini son exécution, les modifications sont appliquées au réseau.
## Pratique
Le type [TrainParameters](/src/cnn/include/train.h#L15) est utilisé pour donner des arguments à chaque fil d'exécution ou au thread principal dans le cas échéant.
### Sans multithreading
Aucune copie n'est nécessaire pour lancer la fonction [`train_thread`](/src/cnn/train.c#L27), qui est exécutée sur le fil d'exécution principal.
### Avec multithreading
Le réseau principal est copié dans une partie différente de la mémoire pour chaque thread.
En effet, la partie contenant les informations statiques peut-être conservé le même pour chaque thread,
mais le tableau `input` du réseau de neurones contient les données de chaque forward propagation et se doit d'être différent.
Il serait cependant envisageable de ne différencier que cette partie et d'utiliser des `mutex` pour garantir un accès sans conflit à la partie commune d'un même réseau.