Quels modèles les réseaux de neurones trouvent-ils?

Dans cet article, je veux parler des modèles que les réseaux de neurones peuvent trouver. De nombreux guides pour débutants se concentrent sur la technique d'écriture de code pour les réseaux de neurones, tandis que les questions de «logique» (que peuvent faire les réseaux de neurones? Quelles architectures sont mieux adaptées à quelles tâches et pourquoi?) Restent souvent en marge. J'espère que mon article aidera les débutants à mieux comprendre les capacités des réseaux de neurones. Pour ce faire, nous allons essayer de voir comment ils gèrent certaines tâches du modèle. Un exemple de code sera fourni en python à l'aide de la bibliothèque keras.

Tâche 1. Commençons par une simple. Nous construisons un réseau neuronal se rapprochant du sinus.

import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, np.pi, n) y = np.sin(X) return X, y n = 40 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(6, input_dim=1, activation='relu')) model.add(Dense(4, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mean_squared_error']) model.fit(X, y, epochs=1000, batch_size=4) X_test = np.linspace(start=0, stop=np.pi, num=500) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Sinus approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show() 

Nous obtenons le graphique suivant:



Comme vous pouvez le voir, le réseau neuronal a réussi à faire face à la tâche d'approximation d'une fonction simple.

Tâche 2. Voyons comment le réseau neuronal fera face à une tâche plus complexe. Nous entrerons x valeurs uniformément réparties sur l'intervalle [0, 1], et y sera défini de manière aléatoire: pour x <0,6, y sera une variable aléatoire prenant la valeur 0 avec une probabilité de 0,75 et 1 avec une probabilité de 0,25 (c'est-à-dire une valeur aléatoire binomiale avec p = 0,25). Pour x> 0,6, y sera une variable aléatoire prenant la valeur 0 avec probabilité 0,3 et la valeur 1 avec probabilité 0,7. En tant que fonction optimisée, nous prenons l'erreur standard.

 import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, 1, n) y0 = np.random.binomial(size=n, n=1, p=0.25) y1 = np.random.binomial(size=n, n=1, p=0.7) y = np.where(X < 0.6, y0, y1) return X, y n_inputs = 1 n_hidden1 = 100 n_hidden2 = 50 n_outputs = 1 n = 2000 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(n_hidden1, input_dim=1, activation='relu')) model.add(Dense(n_hidden2, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy']) model.fit(X, y, epochs=200, batch_size=100) X_test = np.linspace(start=0, stop=1, num=100) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Binomial distribution approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show() 

Nous obtenons le graphique suivant d'un réseau neuronal à fonction approximative:



Comme vous pouvez le voir, le réseau neuronal a approché l'attente mathématique de notre variable aléatoire y. Ainsi, les réseaux de neurones peuvent (en principe) approcher les valeurs moyennes des variables aléatoires qui dépendent des paramètres. Par exemple, nous pouvons nous attendre à ce qu'ils résolvent le problème suivant: les personnes dont le revenu ne dépasse pas 1 000 $ sont en moyenne mécontentes et les personnes dont le revenu est supérieur à 1 000 $ sont en moyenne satisfaites; il faut apprendre à prédire le "niveau de bonheur" en fonction des revenus. Le réseau de neurones pourra trouver la dépendance du niveau moyen de bonheur sur le revenu, malgré le fait que parmi les personnes avec n'importe quel niveau de revenu, il y a à la fois heureux et malheureux.

Problème 3. Passons maintenant à la prédiction des séquences. Nous considérerons les séquences de 0 et 1 données par la règle suivante: 10 membres - équitablement 0 ou 1, et le onzième est égal à 1 si le terme précédent est 0, et également probable 0 ou 1 si le terme précédent 1. Nous générerons de telles séquences de longueur 11 (entrée 10 séquence des membres et un, le dernier, nous prédisons) et les former sur notre réseau neuronal récurrent. Et après l'entraînement, vérifions comment elle gère la prédiction sur les nouvelles séquences (également de longueur 11).

 import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense def get_X_y(m, n): X = np.random.binomial(size=(m,n), n=1, p=0.5) y0 = np.ones(m) y1 = np.random.binomial(size=m, n=1, p=0.5) y = np.where(X[:, n-1]==0, y0, y1) X = np.reshape(X, (X.shape[0], X.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=50)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000, 10) model.fit(X_train, y_train, epochs = 20, batch_size = 32) m_test = 12 n_test = 10 X_test, y_test = get_X_y(m_test, n_test) y_predicted = model.predict(X_test) for i in range(m_test): print("x_last=", X_test[i, n_test-1, 0], "y_predicted=", y_predicted[i, 0]) 

Voyons quelles prévisions notre réseau de neurones donne sur les séquences testées (vos résultats seront différents, car ici l'aléatoire est présent à la fois dans le choix des séquences et dans l'entraînement du réseau de neurones).

Numéro de séquenceAvant-dernier membre de la séquenceValeur prédite
100,96
200,95
300,97
400,96
500,96
610,45
700,94
810,50
900,96
1010,42
1110,44
1200,92


Comme vous pouvez le voir, si l'avant-dernier membre de la séquence est 0, alors le réseau neuronal prédit une valeur proche de 1, et s'il est 1, alors une valeur proche de 0,5. Ceci est proche de la prévision optimale. Un exemple similaire de la "vie" pourrait ressembler à ceci: "si je vais au cinéma aujourd'hui, alors demain je déjeunerai dans un restaurant; si je vais au théâtre aujourd'hui, alors demain je déjeunerai n'importe où. " Comme nous l'avons vu, un réseau de neurones peut capturer des modèles de ce type et prédire un voyage dans un restaurant en allant au cinéma (et en allant au théâtre pour prédire «quelque chose entre les deux»).

Tâche 4. Nous compliquons la tâche du réseau neuronal. Que tout soit comme dans l'exemple précédent, seul le onzième membre de la séquence sera déterminé non pas par le précédent, mais par le deuxième membre de la séquence (par la même règle). Nous ne donnerons pas le code ici, car il ne diffère pratiquement pas du précédent. Mon expérience a montré que le réseau neuronal trouve toujours un schéma, mais pour plus de temps (j'ai dû utiliser 100 époques au lieu de 20 pour l'entraînement).
Ainsi, les réseaux de neurones peuvent (à nouveau, en principe, clarifier) ​​attraper des dépendances à assez long terme (dans notre «exemple de vie», ils peuvent attraper des modèles comme «Je vais au restaurant aujourd'hui si j'étais dans un film il y a une semaine»).

Tâche 5. Voyons comment le réseau neuronal utilise les informations disponibles pour la prévision.
Pour ce faire, nous effectuerons des entraînements sur des séquences de longueur 4. Au total, nous aurons 3 séquences différentes également probables:

0, 0, 1, 1
0, 1, 0, 1
0, 1, 1, 0


Ainsi, après la combinaison initiale de 0, 0, nous rencontrons toujours deux unités, après la combinaison de 0, 1, nous sommes également susceptibles de rencontrer 0 ou 1, mais nous connaîtrons certainement le dernier nombre. Nous allons maintenant demander à notre réseau de neurones de renvoyer des séquences en définissant return_sequences = True. Comme les séquences prédites, nous prenons nos mêmes séquences décalées d'un pas et complétées par zéro à droite. Maintenant, nous pouvons déjà supposer ce qui va se passer: à la première étape, le réseau neuronal produira un nombre proche de 2/3 (car avec une probabilité de 2/3 le deuxième terme est 1), puis pour une combinaison de 0, 0, il produira deux nombres proches de unité, et pour 0, 1, il donnera d'abord un nombre proche de 0,5, puis il donnera un nombre proche de 0 ou 1, selon que nous avons obtenu la séquence 0, 1, 0 ou 0, 1, 1. À la fin du réseau neuronal produira toujours un nombre proche de 0. La vérification avec le code suivant montre que nos hypothèses sont correctes.

 import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense import random def get_X_y(n): X = np.zeros((n, 4)) z = np.array([random.randint(0, 2) for i in range(n)]) X[z == 0, :] = [0, 0, 1, 1] X[z == 1, :] = [0, 1, 0, 1] X[z == 2, :] = [0, 1, 1, 0] y = np.zeros((n, 4)) y[:, :3] = X[:, 1:] X = np.reshape(X, (X.shape[0], X.shape[1], 1)) y = np.reshape(y, (y.shape[0], y.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=20, return_sequences=True)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000) model.fit(X_train, y_train, epochs = 100, batch_size = 32) X_test = np.zeros((3, 4)) X_test[0, :] = [0, 0, 1, 1] X_test[1, :] = [0, 1, 0, 1] X_test[2, :] = [0, 1, 1, 0] X_test = np.reshape(X_test, (3, 4, 1)) y_predicted = model.predict(X_test) print(y_predicted) 


De cet exemple, nous voyons que le réseau de neurones peut changer dynamiquement la prévision en fonction des informations reçues. Nous ferions de même, en essayant de prédire une certaine séquence: lorsque les informations disponibles nous permettent d'estimer les probabilités de résultats à l'étape suivante, nous prédisons sur la base de ces informations; mais lorsque nous trouvons des informations supplémentaires à l'étape suivante, nous modifions les prévisions en fonction de celles-ci.
Donc, si nous voyons que quelqu'un vient de nous du noir, alors nous disons "c'est une personne, nous ne le savons pas plus en détail"; quand on commence à distinguer les cheveux longs dans le noir, on se dit "c'est probablement une femme". Mais si après cela nous considérons qu'une personne a une moustache, alors nous disons que c'est probablement un homme (quoique avec des cheveux longs). Comme nous l'avons vu, un réseau de neurones agit de la même manière, utilisant l'intégralité des informations actuellement disponibles pour la prévision.

Nous avons donc examiné des exemples simples du fonctionnement des réseaux de neurones et des modèles qu'ils peuvent trouver. En général, nous avons vu que les réseaux de neurones se comportent souvent de manière «raisonnablement», faisant des prédictions proches de celles qu'une personne ferait. Bien que, il convient de noter que pour saisir des modèles simples, ils ont besoin de beaucoup plus de données que les personnes.

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


All Articles