Résoudre une équation mathématique de base à l'aide de RNN [avec exemple de codage]
Publié: 2020-12-07Si la vie vous donne RNN, fabriquez une calculatrice
Un réseau de neurones récurrent fait partie d'un réseau de neurones artificiel classique, où les connexions entre les nœuds forment un graphe orienté séquentiel. Les RNN sont réputés pour des applications telles que la reconnaissance vocale, la reconnaissance de l'écriture manuscrite, etc. en raison de leur mémoire d'état interne pour le traitement de séquences de longueur variable.
Les RNN sont en outre classés en deux types. Le premier est une impulsion finie dont le réseau de neurones se présente sous la forme d'un graphe acyclique orienté où un nœud peut être connecté à un ou plusieurs nœuds qui sont en avance sans cycle visible dans le réseau. Un autre est une impulsion infinie dont le réseau de neurones se présente sous la forme d'un graphe cyclique orienté qui ne peut pas être déroulé dans un réseau de neurones à réaction.
Table des matières
Qu'allons-nous faire?
Construisons un modèle qui prédit la sortie d'une expression arithmétique. Par exemple, si je donne une entrée '11+88', alors le modèle devrait prédire le mot suivant dans la séquence comme '99'. L'entrée et la sortie sont une séquence de caractères puisqu'un RNN traite des données séquentielles.
Désormais, la conception de l'architecture du modèle ressemble à une tâche simple par rapport à la collecte d'ensembles de données. La génération de données ou la collecte d'un ensemble de données est une tâche ardue, car les modèles d'IA gourmands en données nécessitent une bonne quantité de données pour une précision acceptable.
Ainsi, ce modèle peut être mis en œuvre en 6 étapes de base :

- Génération de données
- Construire un modèle
- Vectorisation et dé-vectorisation des données
- Faire un jeu de données
- Former le modèle
- Tester le modèle
Avant de plonger dans l'implémentation du modèle, importons simplement toutes les bibliothèques requises.
| importer numpy en tant que np importer tensorflow en tant que tf depuis tensorflow.keras.models import séquentiel à partir de tensorflow.keras.layers , importez Dense, Dropout, SimpleRNN, RepeatVector, TimeDistributed depuis tensorflow.keras.callbacks importer EarlyStopping, LambdaCallback de termcolor import coloré |
1. Génération de données
Définissons une chaîne de caractères contenant tous les caractères dont nous avons besoin pour écrire une équation arithmétique de base. Ainsi, la chaîne se compose de tous les caractères de 0 à 9 et de tous les opérateurs arithmétiques tels que /, *, +, -, .(décimal).
Nous ne pouvons pas alimenter directement les données numériques dans notre modèle, nous devons transmettre les données sous forme de tenseurs. La conversion de la chaîne dans les données en un vecteur codé one-hot nous donnera une performance optimisée du modèle. Un vecteur codé one-hot est un tableau avec une longueur identique à la longueur de notre chaîne de caractères, chaque vecteur one-hot n'en a qu'à l'index respectif du caractère présent dans chaque chaîne.
Par exemple, disons que notre chaîne de caractères est '0123456789', et si nous voulons encoder une chaîne comme '12' alors le vecteur chaud serait [ [0,1,0,0,0,0,0,0 ,0,0], [0,0,1,0,0,0,0,0,0,0] ]. Pour ce faire, nous devons créer deux dictionnaires avec un index comme clés et des caractères comme valeurs et l'autre comme vice-versa.
| char_string = ' 0123456789/*+-. ' num_chars = len (char_string) character_to_index = dict ((c, i) for i, c in enumerate (char_string)) index_to_character = dict ((i, c) for i, c in enumerate (char_string)) |
Écrivons maintenant une fonction qui renvoie une équation arithmétique aléatoire avec le résultat de cette équation.
| def division (n, d): retourne n / d si d != 0 sinon 0 def datagen (): random1 = np.random.randint(faible = 0 ,élevé = 100 ) random2 = np.random.randint(faible = 0 ,élevé = 100 ) op = np.random.randint(faible = 0 , élevé = 4 ) si op == 1 : arith = chaîne (aléatoire1) + ' + ' + chaîne (aléatoire2) res = chaîne (aléatoire1 + aléatoire2) elif op == 1 : arith = chaîne (aléatoire1) + ' – ' + chaîne (aléatoire2) res = str (aléatoire1 – aléatoire2) elif op == 2 : arith = chaîne (aléatoire1) + ' * ' + chaîne (aléatoire2) res = chaîne (aléatoire1 * aléatoire2) sinon : arith = chaîne (aléatoire1) + ' / ' + chaîne (aléatoire2) res = str ( rond (division(random1, random2), 2 )) retour arith, res |
Lisez aussi: Idées intéressantes de projets de réseau de neurones
2. Construire un modèle
Le modèle aura un encodeur et un décodeur. L'encodeur est un modèle RNN simple avec une forme d'entrée comme (None, num_chars) et 128 unités cachées, la raison pour laquelle nous choisissons des unités cachées comme 32,64,128, etc. est due aux meilleures performances du CPU ou du GPU avec des unités cachées comme puissances de 2.
Notre encodeur sera un réseau entièrement connecté et la sortie de ceux-ci sera réinjectée dans le réseau, c'est ainsi que fonctionne un RNN. Une couche RNN utilise l'activation 'tanh' par défaut, nous n'allons pas changer car elle correspond le mieux à l'encodeur. La sortie de cette couche sera un seul vecteur et pour atteindre un seul vecteur de toute la sortie, nous utiliserons la couche RepeatVector() avec le nombre de fois requis comme paramètre.
Maintenant, le vecteur de sortie aura l'essence de l'entrée donnée, et ce vecteur sera introduit dans le décodeur.
Le décodeur est composé d'une simple couche RNN et cela générera la séquence de sortie puisque nous avons besoin de la couche RNN pour renvoyer la séquence prédite, nous allons marquer les 'return_sequences' comme True. En attribuant la valeur 'return_sequences' à True, la couche RNN renverra la séquence prédite pour chaque pas de temps (plusieurs à plusieurs RNN).
La sortie de cette couche RNN est introduite dans une couche Dense avec un nombre d'unités cachées 'num_chars' et nous utiliserons l'activation softmax car nous avons besoin de la probabilité de chaque caractère. Avant de déployer une couche Dense, nous devons abréger cette couche en une couche TimeDistributed car nous devons déployer la couche Dense pour la sortie de chaque pas de temps.
| unités_cachées = 128 max_time_steps = 5 #nous codons en dur la sortie pour qu'elle soit de 5 caractères modèle def (): modèle = Séquentiel() model.add(SimpleRNN(hidden_units, input_shape = ( None , num_chars))) model.add(RepeatVector(max_time_steps)) model.add(SimpleRNN(hidden_units, return_sequences = True )) model.add(TimeDistributed(Dense(num_chars, activation = ' softmax ' ))) modèle de retour modèle = modèle() modèle. résumé () model.compile(loss = ' categorical_crossentropy ' , optimiseur = ' adam ' , metrics = [ ' precision ' ]) |

L'architecture du modèle sera comme indiqué ci-dessus
Doit lire: Tutoriel sur le réseau de neurones
3. Vectorisation et dé-vectorisation des données
Définissons les fonctions de vectorisation et de dé-vectorisation des données.
Voici la fonction pour vectoriser l'expression arithmétique et le résultat ensemble.
| def vectoriser (arith, res): x = np.zeros((max_time_steps, num_chars)) y = np.zeros((max_time_steps, num_chars)) ![]() x_remaining = max_time_steps – len (arith) y_remaining = max_time_steps – len (res) pour i, c dans énumérer (arith): x[x_remaining + i, caractère_vers_index[c]] = 1 pour je dans la plage (x_remaining): x[i, caractère_vers_index[ ' 0 ' ]] = 1 pour i, c dans énumérer (res): y[y_remaining + i, character_to_index[c]] = 1 pour je dans la plage (y_remaining): y[je, caractère_vers_index[ ' 0 ' ]] = 1 retourner x, y |
De même, voici la fonction de dé-vectorisation de la chaîne. Étant donné que la sortie que nous recevons est un vecteur de probabilités, nous utiliserons np.argmax() pour choisir le caractère avec la probabilité la plus élevée. Maintenant, le dictionnaire index_to_character est utilisé pour retracer le caractère à cet index.
| def dévectoriser (entrée): res = [index_to_character[np.argmax(vec)] for i, vec in enumerate ( input )] retourne ' ' .join(res) |
Maintenant, la contrainte que nous avons avec la fonction 'devectorize' est qu'elle va remplir les caractères de fin avec des zéros. Par exemple, si le vecteur d'entrée est ('1-20', '-19') alors la sortie dé-vectorisée sera ('01-20', '00-19'). Nous devons prendre soin de ces zéros rembourrés supplémentaires. Écrivons une fonction pour supprimer la chaîne.
| def décapage (entrée): drapeau = faux sortie = ' ' pour c en entrée : sinon flag et c == ' 0 ' : _ Continuez si c == ' + ' ou c == ' – ' ou c == ' * ' ou c == ' / ' ou c == ' . ' : drapeau = faux sinon : drapeau = Vrai sortie += c sortie de retour |
4. Créer un jeu de données
Maintenant que nous avons fini de définir une fonction pour générer les données, utilisons cette fonction et créons un ensemble de données avec de nombreuses paires (expression arithmétique, résultat).
| def create_dataset (num_equations): x_train = np.zeros((num_equations, max_time_steps, num_chars)) y_train = np.zeros((num_equations, max_time_steps, num_chars)) pour i dans la plage (num_equations) : e, l = datagen() x, y = vectoriser(e, l) x_train[i] = x y_train[i] = y retour x_train, y_train |
5. Formation du modèle
Créons un ensemble de données de 50 000 échantillons, ce qui est un nombre suffisant pour former notre modèle de soif de données, nous utiliserons 25 % de ces données pour la validation. Créons également un rappel pour une interruption d'entraînement intelligente si la précision reste inchangée pendant 8 époques. Ceci peut être réalisé en réglant le paramètre de patience sur 8.

| x_train, y_train = create_dataset( 50000 ) simple_logger = LambdaCallback( on_epoch_end = lambda e, l: print ( ' {:.2f} ' .format(l[ ' val_accuracy ' ]), end = ' _ ' ) ) early_stopping = EarlyStopping(monitor = ' val_loss ' , patience = 8 ) model.fit(x_train, y_train, epochs = 100 , validation_split = 0.25 , verbose = 0 , rappels = [simple_logger, early_stopping]) |
6. Test du modèle
Testons maintenant notre modèle en créant un jeu de données de taille 30.
| x_test, y_test = create_dataset(num_equations = 20 ) preds = model.predict(x_test) full_seq_acc = 0 pour moi , pred dans énumérer (preds): pred_str = décapage(dévectoriser(pred)) y_test_str = stripping(devectorize(y_test[i])) x_test_str = stripping(devectorize(x_test[i])) col = ' vert ' si pred_str == y_test_str sinon ' rouge ' full_seq_acc += 1 / len (preds) * int (pred_str == y_test_str) outstring = ' Entrée : {}, Sortie : {}, Prédiction : {} ' .format(x_test_str, y_test_str, pred_str) print (coloré(outstring, col)) print ( ' \n Précision de la séquence complète : {:.3f} % ' .format( 100 * full_seq_acc)) |
La sortie sera la suivante

Nous pouvons voir que la précision est un peu médiocre ici, de toute façon nous pouvons l'optimiser en ajustant quelques hyperparamètres comme le nombre d'unités cachées, la division de validation, le nombre d'époques, etc.
Conclusion
Nous avons compris le flux de travail de base d'un RNN, compris que les RNN sont les mieux adaptés aux données séquentielles, généré un ensemble de données d'équations arithmétiques aléatoires, développé un modèle séquentiel pour prédire la sortie d'une expression arithmétique de base, entraîné ce modèle avec l'ensemble de données qui nous avons créé et finalement testé ce modèle avec un petit ensemble de données que le modèle n'a jamais vu auparavant.
Si vous souhaitez en savoir plus sur RNN, l'apprentissage automatique, consultez le diplôme PG d'IIIT-B & upGrad en apprentissage automatique et IA, conçu pour les professionnels en activité et offrant plus de 450 heures de formation rigoureuse, plus de 30 études de cas et missions, Statut d'ancien de l'IIIT-B, plus de 5 projets de synthèse pratiques et aide à l'emploi avec les meilleures entreprises.
Quels sont les différents types de réseaux de neurones en machine learning ?
Dans l'apprentissage automatique, les réseaux de neurones artificiels sont essentiellement des modèles informatiques qui ont été conçus pour ressembler au cerveau humain. Il existe différents types de réseaux de neurones artificiels que l'apprentissage automatique utilise en fonction du calcul mathématique qui doit être réalisé. Ces réseaux de neurones sont un sous-ensemble de différentes techniques d'apprentissage automatique qui apprennent des données de différentes manières. Certains des types de réseaux de neurones les plus largement utilisés sont - réseau de neurones récurrent - mémoire à long terme, réseau de neurones à anticipation - neurone artificiel, réseau de neurones à fonction de base radiale, réseau de neurones auto-organisé Kohonen, réseau de neurones convolutifs et réseau de neurones modulaire, entre autres.
Quels sont les avantages d'un réseau de neurones récurrent ?
Les réseaux de neurones récurrents font partie des réseaux de neurones artificiels les plus couramment utilisés en apprentissage profond et en apprentissage automatique. Dans ce type de modèle de réseau de neurones, le résultat obtenu à l'étape précédente est alimenté en entrée de l'étape suivante. Un réseau de neurones récurrent présente plusieurs avantages, tels qu'il peut conserver chaque bit d'information au fil du temps, y compris ses entrées précédentes, ce qui le rend idéal pour la prédiction de séries chronologiques. Ce type est le meilleur exemple de mémoire longue-courte. De plus, les réseaux de neurones récurrents fournissent un voisinage de pixels constructif en utilisant des couches convolutionnelles.
Comment les réseaux de neurones sont-ils utilisés dans les applications du monde réel ?
Les réseaux de neurones artificiels font partie intégrante de l'apprentissage en profondeur, qui est à nouveau une branche super spécialisée de l'apprentissage automatique et de l'intelligence artificielle. Les réseaux de neurones sont utilisés dans différentes industries pour atteindre divers objectifs critiques. Certaines des applications réelles les plus intéressantes des réseaux de neurones artificiels incluent les prévisions boursières, la reconnaissance faciale, le pilotage automatique haute performance et le diagnostic de pannes dans l'industrie aérospatiale, l'analyse des attaques armées et la localisation d'objets dans le secteur de la défense, le traitement d'images, la découverte de médicaments et la détection de maladies dans le secteur de la santé, la vérification de la signature, l'analyse de l'écriture manuscrite, les prévisions météorologiques et la prévision des tendances des médias sociaux, entre autres.

