Un exemple d'un réseau neuronal simple, par conséquent, comprendre ce qui est

RĂ©seaux de neurones - c'est un sujet qui suscite un grand intĂ©rĂȘt et un dĂ©sir de le comprendre. Mais, malheureusement, il ne se prĂȘte pas Ă  tout le monde. Lorsque vous voyez des volumes de littĂ©rature obscure, vous perdez le dĂ©sir d'Ă©tudier, mais vous voulez toujours vous tenir au courant de ce qui se passe.

En fin de compte, il me semblait qu'il n'y avait pas de meilleure façon de le comprendre que de simplement créer et créer votre propre petit projet.

Vous pouvez lire l'arriÚre-plan lyrique en développant le texte, ou vous pouvez sauter ceci et aller directement à la description du réseau neuronal.

Quel est l'intĂ©rĂȘt de faire votre projet.
Avantages:

  1. Vous comprenez mieux comment les neurones sont organisés
  2. Vous comprenez mieux comment travailler avec les bibliothĂšques existantes
  3. Apprendre quelque chose de nouveau en parallĂšle
  4. Chatouillez votre ego, en créant quelque chose qui vous appartient

Inconvénients:

  1. Vous créez un vélo, probablement pire que les vélos existants
  2. Personne ne se soucie de votre projet.


Le choix de la langue.
Au moment de choisir le langage, je connaissais plus ou moins le C ++ et connaissais les bases de Python. Il est plus facile de travailler avec des neurones en Python, mais C ++ le savait mieux et il n'y a pas de parallélisation plus simple des calculs qu'OpenMP. Par conséquent, j'ai choisi C ++, et l'API pour Python, afin de ne pas déranger, va créer un swig qui fonctionne sur Windows et Linux. ( Un exemple de la façon de créer une bibliothÚque Python à partir de code C ++)

Accélération OpenMP et GPU.
Actuellement, OpenMP version 2.0 est installé dans Visual Studio, dans lequel il n'y a que l'accélération CPU. Cependant, à partir de la version 3.0, OpenMP prend également en charge l'accélération GPU, tandis que la syntaxe des directives n'est pas compliquée. Il ne reste plus qu'à attendre qu'OpenMP 3.0 soit supporté par tous les compilateurs. En attendant, pour plus de simplicité, seul le CPU.

Mon premier rĂąteau.
Dans le calcul de la valeur d'un neurone, il y a le point suivant: avant de calculer la fonction d'activation, nous devons ajouter la multiplication des poids aux données d'entrée. Comment apprendre à le faire à l'université: avant de sommer un grand vecteur de petits nombres, il faut le trier par ordre croissant. Alors voilà. Dans les réseaux de neurones, à part ralentir le programme N fois, cela ne donne rien. Mais je ne l'ai réalisé que lorsque j'avais déjà testé mon réseau sur MNIST.

Mettre un projet sur GitHub.
Je ne suis pas le premier Ă  poster ma crĂ©ation sur GitHub. Mais dans la plupart des cas, en suivant le lien, vous ne voyez qu'un tas de code avec l'inscription dans README.md "Ceci est mon rĂ©seau de neurones, regardez et Ă©tudiez . " Pour ĂȘtre meilleur que les autres, au moins en cela, il a plus ou moins dĂ©crit README.md et rempli le Wiki . Le message est simple - remplissez le Wiki. Une observation intĂ©ressante: si le titre du Wiki sur GitHub est Ă©crit en russe, alors l' ancre de ce titre ne fonctionne pas.

Licence
Lorsque vous créez votre petit projet, une licence est à nouveau un moyen de titiller votre ego. Voici un article intéressant sur l'utilisation d'une licence. J'ai opté pour APACHE 2.0 .

Description du réseau.


CARACTÉRISTIQUES
Le titreFoxNN (Fox-Neural-Network )
SystĂšme d'exploitationWindows Linux
Les languesC ++, Python
AccélérationCPU (GPU dans les plans)
Dépendances externesNon (C ++ pur, STL, OpenMP)
Drapeaux de compilation-std = c ++ 14 -fopenmp
Coucheslinéaire (plans convolutionnels)
OptimisationsAdam, Nesterov
Changement de poids aléatoireIl y a
Wikipédia (instruction)Il y a


Le principal avantage de ma bibliothÚque est la création d'un réseau avec une seule ligne de code.

Il est facile de voir que dans les couches linéaires, le nombre de neurones dans une couche est égal au nombre de paramÚtres d'entrée dans la couche suivante. Une autre déclaration évidente - le nombre de neurones dans la derniÚre couche est égal au nombre de valeurs de sortie du réseau.

Créons un réseau qui reçoit trois paramÚtres à l'entrée, qui a trois couches avec 5, 4 et 2 neurones.

import foxnn nn = foxnn.neural_network([3, 5, 4, 2]) 

Si vous regardez l'image, vous pouvez juste voir: 3 premiers paramÚtres d'entrée, puis une couche avec 5 neurones, puis une couche avec 4 neurones et, enfin, la derniÚre couche avec 2 neurones.



Par défaut, toutes les fonctions d'activation sont sigmoïdes (je les aime plus).
Si vous le souhaitez, sur n'importe quel calque peut ĂȘtre changĂ© pour une autre fonction.

Les fonctionnalités d'activation les plus populaires sont disponibles.


 nn.get_layer(0).set_activation_function("gaussian") 

Ensemble d'entraßnement facile à créer. Le premier vecteur est les données d'entrée, le deuxiÚme vecteur est les données cibles.

 data = foxnn.train_data() data.add_data([1, 2, 3], [1, 0]) #   ,     

Formation réseau:

 nn.train(data_for_train=data, speed=0.01, max_iteration=100, size_train_batch=98) 

Activation de l'optimisation:

 nn.settings.set_mode("Adam") 

Et une méthode pour simplement obtenir la valeur du réseau:

 nn.get_out([0, 1, 0.1]) 

Un peu sur le nom de la méthode.
Séparément, get traduit comment obtenir , et out signifie sortie . Je voulais obtenir le nom " donner la valeur de sortie ", et je l'ai eu. Ce n'est que plus tard que j'ai remarqué qu'il s'est avéré sortir . Mais c'est plus amusant et j'ai décidé de partir.

Test


Il est dĂ©jĂ  devenu une tradition non Ă©crite de tester tout rĂ©seau basĂ© sur MNIST . Et je n'ai pas fait exception. Tout le code avec commentaires peut ĂȘtre trouvĂ© ici .

Crée un exemple de formation:
 from mnist import MNIST import foxnn mndata = MNIST('C:download/') mndata.gz = True imagesTrain, labelsTrain = mndata.load_training() def get_data(images, labels): train_data = foxnn.train_data() for im, lb in zip(images, labels): data_y = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # len(data_y) == 10 data_y[lb] = 1 data_x = im for j in range(len(data_x)): #     (-1, 1) data_x[j] = ((float(data_x[j]) / 255.0) - 0.5) * 2.0 train_data.add_data(data_x, data_y) #     return train_data train_data = get_data(imagesTrain, labelsTrain) 


Créez un réseau: trois couches, 784 paramÚtres pour l'entrée et 10 pour la sortie:
 nn = foxnn.neural_network([784, 512, 512, 10]) nn.settings.n_threads = 7 #     7  nn.settings.set_mode("Adam") #    


Nous formons:
 nn.train(data_for_train=train_data, speed=0.001, max_iteration=10000, size_train_batch=98) 


Que s'est-il passé:

En 10 minutes environ (accĂ©lĂ©ration du processeur uniquement), une prĂ©cision de 75% peut ĂȘtre obtenue. Avec l'optimisation Adam, une prĂ©cision de 88% peut ĂȘtre obtenue en 5 minutes. Au final, j'ai rĂ©ussi Ă  atteindre une prĂ©cision de 97%.

Les principaux inconvénients (il existe déjà des plans de révision):
  1. En Python, aucune erreur n'a encore été commise, c'est-à-dire en python, l'erreur ne sera pas interceptée et le programme se terminera simplement avec une erreur.
  2. Alors que la formation est indiquée dans les itérations, et non dans les époques, comme c'est la coutume dans d'autres réseaux.
  3. Pas d'accélération GPU
  4. Il n'y a pas encore d'autres types de calques.
  5. Nous devons télécharger le projet sur PyPi.


Pour un petit achÚvement du projet, cet article faisait défaut. Si au moins dix personnes sont intéressées et jouent, alors il y aura déjà une victoire. Bienvenue dans mon github .

PS: Si vous avez besoin de crĂ©er quelque chose de vous-mĂȘme pour le comprendre, n'ayez pas peur et crĂ©ez.

Source: https://habr.com/ru/post/fr459822/


All Articles